Compare commits
342 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b04c4d7fd9 | |||
| 49f3c18ae3 | |||
| 0199ebd592 | |||
| de2025298e | |||
| 46aee256eb | |||
| 094fa85b02 | |||
| 189dde38d3 | |||
| 81a635c831 | |||
| aeba9ff674 | |||
| 564e3af5dd | |||
| 2c4f85f687 | |||
| d410435adc | |||
| 0168efea60 | |||
| 22f76b7e1c | |||
| 66761b3980 | |||
| b62945b5de | |||
| f4b2637c04 | |||
| 806b7319b9 | |||
| 2e40892fd6 | |||
| bd8b5b4b51 | |||
| 16fd28d29b | |||
| 4ce9c483c1 | |||
| b2b80831ca | |||
| 2ef0ea00f4 | |||
| 8abad2b4f7 | |||
| 2d11d907ef | |||
| 66f0ab85d0 | |||
| 3744d0cbed | |||
| 36b09fa1f6 | |||
| 88914c58c7 | |||
| 87c99cb38f | |||
| 2af19a485b | |||
| 44568b5622 | |||
| 85b8717c05 | |||
| c1a0b5aa46 | |||
| 7eacf99f76 | |||
| 11c469648f | |||
| 8f4ba3ec1a | |||
| be45ccd46d | |||
| 06f21899b1 | |||
| 382acca320 | |||
| abe3da54fb | |||
| f2063b7fc3 | |||
| 0d6c3cd6e9 | |||
| 6882611d25 | |||
| 2c89e09a47 | |||
| 90be62be3d | |||
| d2667d48f6 | |||
| 04112b26cc | |||
| 1092e6c0c2 | |||
| f0e4efa238 | |||
| d2bc100656 | |||
| 4535b4a915 | |||
|
|
7868115a8b | ||
|
|
abe7222973 | ||
|
|
134da9209c | ||
|
|
747ec8b1c5 | ||
|
|
b487ff4190 | ||
|
|
d0ae0dfc38 | ||
|
|
b6c076ce19 | ||
|
|
184aa9931e | ||
|
|
eb80f5d5af | ||
|
|
eb0f40b9d6 | ||
|
|
993695a2c4 | ||
|
|
0c8093eded | ||
|
|
646b6e546f | ||
|
|
1a0b1f235d | ||
|
|
5714ecce32 | ||
|
|
dcd4759896 | ||
|
|
a146457ea1 | ||
|
|
d3013b072d | ||
|
|
c12b0622b4 | ||
|
|
0e54a85310 | ||
|
|
ae10361bdd | ||
|
|
d152b3a316 | ||
|
|
0c34152a33 | ||
|
|
039cd756d5 | ||
|
|
7a97a6080c | ||
|
|
7a91cf78ec | ||
|
|
e7e23d5ffc | ||
|
|
146942953a | ||
|
|
f117159ec4 | ||
|
|
66839b1a29 | ||
|
|
8a5b86521c | ||
|
|
4bd023e515 | ||
|
|
e16d82d5bd | ||
|
|
e44cb5152a | ||
|
|
50a58254a7 | ||
|
|
6fd0eebad4 | ||
|
|
a117fe1a22 | ||
|
|
058975c167 | ||
|
|
43b4d80da1 | ||
|
|
5969aa4925 | ||
|
|
2666072867 | ||
|
|
126d9bc103 | ||
|
|
a1c02856ac | ||
|
|
315872a54b | ||
|
|
9ca2927291 | ||
|
|
eae91e97cd | ||
|
|
7e1d684797 | ||
|
|
39212bbcd2 | ||
|
|
7b0507a950 | ||
|
|
4a78d1bff4 | ||
|
|
36e79ecca6 | ||
|
|
344d82f2b4 | ||
|
|
403e55d555 | ||
|
|
104e98aca6 | ||
|
|
cab3ea7faf | ||
|
|
bdaa31ef21 | ||
|
|
d16183c053 | ||
|
|
121d5e5524 | ||
|
|
e5150d0314 | ||
|
|
5b0143eba6 | ||
|
|
60abfeb31f | ||
|
|
3aba452b5b | ||
|
|
a9c457f93f | ||
|
|
09bbaa1e41 | ||
|
|
96c3972c5c | ||
|
|
05edab3f5a | ||
|
|
716bb781eb | ||
|
|
2ba6fba29f | ||
|
|
16ad7bdf77 | ||
|
|
396009c014 | ||
|
|
daf797b9d4 | ||
|
|
c9ba998200 | ||
|
|
ba695194cd | ||
|
|
d0b1508831 | ||
|
|
427f667f9f | ||
|
|
6e2e7c942e | ||
|
|
fb63dfc309 | ||
|
|
b02d8328ee | ||
|
|
09e147ee4b | ||
|
|
d7feeca13e | ||
|
|
1248d326aa | ||
|
|
720c380412 | ||
|
|
8ed9e3381f | ||
|
|
4629d074ab | ||
|
|
5dbf601afb | ||
|
|
37d4e513d9 | ||
|
|
86c433cf80 | ||
|
|
6b70edabf0 | ||
|
|
29037c1f55 | ||
|
|
a032abf0c5 | ||
|
|
cfe1b0b70d | ||
|
|
c2a3f2941d | ||
|
|
843c4cdb91 | ||
|
|
f2c65ea557 | ||
|
|
a6c65dff8d | ||
|
|
0f4f7ec287 | ||
|
|
b36cee06a1 | ||
|
|
6dc740184c | ||
|
|
5c5133348e | ||
|
|
fafe40c530 | ||
|
|
17a959aa29 | ||
|
|
66aaa11580 | ||
|
|
c312a05bbd | ||
|
|
0a710eb995 | ||
|
|
65bc67f300 | ||
|
|
0ecc870a0e | ||
|
|
0ba6949f7d | ||
|
|
de29ba9e4c | ||
|
|
52ed3d1e8f | ||
|
|
c4a33d3457 | ||
|
|
67722db78f | ||
|
|
b0c299b9e9 | ||
|
|
eb2616efaa | ||
|
|
179672fe3b | ||
|
|
666d78d499 | ||
|
|
7f6e3c2bf8 | ||
|
|
da356f1142 | ||
|
|
bfb8f0a078 | ||
|
|
dae46567e7 | ||
|
|
9de5455552 | ||
|
|
583ca38d91 | ||
|
|
548f3d7663 | ||
|
|
c2bbb3fd00 | ||
|
|
55e4d340fe | ||
|
|
d0c296e1cf | ||
|
|
2c13b299b8 | ||
|
|
db79d5a79e | ||
|
|
8131fae1a6 | ||
|
|
1a5b5602db | ||
|
|
9fc48daf28 | ||
|
|
1a4121c6c2 | ||
|
|
05b8fa8dbf | ||
|
|
344e01d4e2 | ||
|
|
e867242cf6 | ||
|
|
4ab51e1c88 | ||
|
|
e907f11488 | ||
|
|
ce006cbbaa | ||
|
|
35b4cb89fc | ||
|
|
fa4500a8d3 | ||
|
|
74b752eb79 | ||
|
|
4d2c096ec0 | ||
|
|
27816ea438 | ||
|
|
3cd43f618c | ||
|
|
0521901e9d | ||
|
|
51caa5588e | ||
|
|
383128d983 | ||
|
|
3729dfad90 | ||
|
|
7ed62f7eed | ||
|
|
3efab05cf2 | ||
|
|
aa7992c65f | ||
|
|
c45ff0c94c | ||
|
|
4a24739c3f | ||
|
|
c63c1796b9 | ||
|
|
c1c874b1a5 | ||
|
|
ef0aeed228 | ||
|
|
b3b22388c9 | ||
|
|
d9248e2e97 | ||
|
|
bdac53511a | ||
|
|
fe3ebd370b | ||
|
|
0f131f2eee | ||
|
|
7cf580a9c5 | ||
|
|
2e32793ed1 | ||
|
|
925ac6bbe4 | ||
|
|
cd21521bfe | ||
|
|
d1b8495510 | ||
|
|
2848951965 | ||
|
|
a7e87a1fc7 | ||
|
|
faa8fe8873 | ||
|
|
de9041bb31 | ||
|
|
b0165cf39c | ||
|
|
8b93b6967d | ||
|
|
b3e994c249 | ||
|
|
444e2b5b89 | ||
|
|
d6b3c757d0 | ||
|
|
3e2201bd80 | ||
| 12920c44e3 | |||
|
|
6dd99e049b | ||
|
|
3f333792ff | ||
|
|
5b8350bc9b | ||
|
|
1cfb4a14ec | ||
|
|
69eba6fd9a | ||
|
|
ee55dabfaa | ||
|
|
a66c305609 | ||
|
|
ff89601306 | ||
|
|
efee1c4130 | ||
|
|
833fcdebc1 | ||
|
|
1fc94ee6f2 | ||
|
|
db725ffaf8 | ||
|
|
99bf152673 | ||
|
|
ddbdcd39cb | ||
|
|
6bc1dd0467 | ||
|
|
9124484719 | ||
|
|
9222e9713b | ||
|
|
b4279d3a12 | ||
|
|
166a26417c | ||
|
|
288b1c7958 | ||
|
|
be28365db4 | ||
|
|
04d718ab9c | ||
|
|
df685433f4 | ||
|
|
8161a8c531 | ||
|
|
23908f3d2f | ||
|
|
721d5695ec | ||
|
|
aca6bd9042 | ||
|
|
d8cc0c5acb | ||
|
|
71c2a7b1a6 | ||
|
|
e064726b64 | ||
|
|
b11208440b | ||
|
|
f784e40548 | ||
|
|
3b8e11322b | ||
|
|
457839df36 | ||
|
|
e0de77d8a4 | ||
|
|
a6639e56cb | ||
|
|
99d030f5e1 | ||
|
|
10bc253dd8 | ||
|
|
eecb9af21e | ||
|
|
8a628d96bc | ||
|
|
b5f8e3c75d | ||
|
|
c609f4cb4b | ||
|
|
cb5bc38f35 | ||
|
|
f14b0bb4bd | ||
|
|
78d7224026 | ||
|
|
506442450e | ||
|
|
9ae2e9c03d | ||
|
|
2a4e68bfae | ||
|
|
a23b30abdc | ||
|
|
e4f8226c62 | ||
|
|
e8f496bb6c | ||
|
|
3a234e24ae | ||
|
|
5dab2ede41 | ||
|
|
4bb58f457b | ||
|
|
d35f7bd37c | ||
|
|
d697f57a97 | ||
|
|
3b809c0a14 | ||
|
|
013c879b41 | ||
|
|
ef9267a58e | ||
|
|
4a2bdd6e86 | ||
|
|
73e148446c | ||
|
|
56666e0db5 | ||
|
|
c70a06ae0a | ||
|
|
385da8ebd0 | ||
|
|
0f3ffd59ce | ||
|
|
fa6912a574 | ||
|
|
add2fced44 | ||
|
|
58f39ec287 | ||
|
|
d1f49c721a | ||
|
|
53118d9314 | ||
|
|
96e051d2bb | ||
|
|
968ef0f7b8 | ||
|
|
2aecf9a79e | ||
| 734de00bfd | |||
|
|
d61d6e5e2f | ||
|
|
7149e5a34d | ||
|
|
7d9fddadce | ||
|
|
64020279cb | ||
|
|
b7825552f8 | ||
|
|
355c5ffeb1 | ||
|
|
62725fb507 | ||
|
|
55aac8e107 | ||
|
|
5f43c9bfce | ||
|
|
06b73c39fa | ||
|
|
524edea8da | ||
|
|
dfb75632ba | ||
|
|
a211bace68 | ||
|
|
5e1b751971 | ||
|
|
27d455389e | ||
|
|
9c6a09890e | ||
|
|
46f3f5aaf4 | ||
|
|
7abcf4e38b | ||
|
|
328cf95816 | ||
|
|
0a6b627914 | ||
|
|
8d9597d80d | ||
|
|
dd58747659 | ||
|
|
0dd36e9a53 | ||
|
|
e9c1aeaa54 | ||
|
|
3ed337ec46 | ||
|
|
bb7072402a | ||
|
|
97fc3f6c0b | ||
|
|
86de4d4052 | ||
|
|
5cd0ce14b0 | ||
|
|
75818fde13 | ||
|
|
c1e6340228 | ||
|
|
4f69e99c45 | ||
|
|
e248f4500d | ||
|
|
0745e735bb | ||
| 187bacc254 | |||
|
|
530cf7ca47 | ||
|
|
7b7e1b254b | ||
| 93fb11017b | |||
| c71691659b |
331 changed files with 41766 additions and 11808 deletions
|
|
@ -3,9 +3,9 @@
|
|||
(require-final-newline . t)
|
||||
(mode . global-whitespace)
|
||||
(bug-reference-bug-regexp
|
||||
. "\\(?:[Ff]ix\\(es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)")
|
||||
. "\\(?1:\\(?:[Ff]ix\\(?:es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)\\)")
|
||||
(bug-reference-url-format
|
||||
. "https://gitlab.lrde.epita.fr/spot/spot/issues/%s")
|
||||
. "https://gitlab.lre.epita.fr/spot/spot/issues/%s")
|
||||
(mode . bug-reference)
|
||||
(magit-branch-adjust-remote-upstream-alist ("origin/next" . "/"))))
|
||||
(c++-mode . ((c-default-style . "gnu")
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,6 +4,7 @@ configure
|
|||
config.log
|
||||
config.status
|
||||
aclocal.m4
|
||||
ltargz.m4
|
||||
autom4te.cache
|
||||
libtool
|
||||
auto
|
||||
|
|
@ -81,3 +82,4 @@ GTAGS
|
|||
*.dsc
|
||||
*.gcov
|
||||
spot.spec
|
||||
default.nix
|
||||
|
|
|
|||
192
.gitlab-ci.yml
192
.gitlab-ci.yml
|
|
@ -19,12 +19,12 @@ debian-stable-gcc:
|
|||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure --enable-max-accsets=256
|
||||
- ./configure --enable-max-accsets=256 --enable-pthread
|
||||
- make
|
||||
- make distcheck
|
||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-max-accsets=256 --enable-pthread'
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
|
|
@ -32,22 +32,47 @@ debian-stable-gcc:
|
|||
- ./*.log
|
||||
- ./*.tar.gz
|
||||
|
||||
# We build on Debian unstable because we want an up-to-date Automake.
|
||||
# (See issue #512.) We do not run distcheck here to speedup this build
|
||||
# that several other builds depend upon. Other builds will run distcheck.
|
||||
make-dist:
|
||||
stage: build
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure --disable-static --enable-doxygen
|
||||
- make
|
||||
- make dist
|
||||
- autoconf --trace='AC_INIT:$2' > VERSION
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- spot-*/_build/sub/tests/*/*.log
|
||||
- ./*.log
|
||||
- ./*.tar.gz
|
||||
- VERSION
|
||||
|
||||
# We --disable-devel for coverage, because debug mode replaces
|
||||
# SPOT_UNREACHABLE by an assertion wich is never reachable, lowering
|
||||
# our coverage.
|
||||
debian-unstable-gcc-coverage:
|
||||
stage: build
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure CXX='g++ --coverage' --enable-devel --disable-static --enable-doxygen
|
||||
- ./configure CXX='g++ --coverage' --disable-devel --enable-warnings --disable-static --enable-doxygen
|
||||
- make
|
||||
- make check
|
||||
- lcov --capture --directory . --no-external --output spot.info
|
||||
- lcov --remove spot.info '*/bin/spot.cc' '*/bin/spot-x.cc' '*/spot/parse*/scan*.cc' '*/spot/parse*/parse*.cc' '*/utf8/*' '*/python/*' '*/buddy/*' '*/doc/org/tmp/*' --output spot2.info
|
||||
- lcov --summary spot2.info
|
||||
- genhtml --legend --demangle-cpp --output-directory coverage spot2.info
|
||||
- gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root $PWD -e 'bin/spot.cc' -e 'bin/spot-x.cc' -e 'spot/bricks/.*' -e 'spot/parse.*/scan.*.cc' -e 'spot/parse.*/parse.*.cc' -e 'utf8/.*' -e 'python/.*' -e 'buddy/.*' -e 'doc/org/tmp/.*' --html-details coverage.html --html-tab-size 8 --fail-under-line 90.7
|
||||
coverage: /^\s*lines:\s*\d+.\d+\%/
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
|
|
@ -55,50 +80,66 @@ debian-unstable-gcc-coverage:
|
|||
- ./*.log
|
||||
- doc/spot.html/
|
||||
- doc/userdoc/
|
||||
- coverage/
|
||||
- coverage*.html
|
||||
- coverage*.css
|
||||
- ./*.tar.gz
|
||||
- spot2.info
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: coverage.xml
|
||||
|
||||
debian-unstable-gcc-pypy:
|
||||
stage: build
|
||||
stage: build2
|
||||
needs:
|
||||
- job: make-dist
|
||||
artifacts: true
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- VERSION=`cat VERSION`
|
||||
- tar xvf spot-$VERSION.tar.gz
|
||||
- cd spot-$VERSION
|
||||
- ./configure PYTHON=/usr/bin/pypy3 --disable-static
|
||||
- make
|
||||
- make check TESTS='$(TESTS_python) $(TESTS_ipython)'
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- tests/*/*.log
|
||||
- ./*.log
|
||||
- spot-*/tests/*/*.log
|
||||
- spot-*/*.log
|
||||
|
||||
# With emacs now using gcc for on-the-fly compilation,
|
||||
# we cannot rebuild the documentation using gcc-snapshot. So we start
|
||||
# from the tarball instead.
|
||||
debian-gcc-snapshot:
|
||||
stage: build
|
||||
stage: build2
|
||||
needs:
|
||||
- job: make-dist
|
||||
artifacts: true
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- export PATH="/usr/lib/gcc-snapshot/bin:$PATH" LD_LIBRARY_PATH="/usr/lib/gcc-snapshot/lib:$LD_LIBRARY_PATH"
|
||||
- autoreconf -vfi
|
||||
- VERSION=`cat VERSION`
|
||||
- tar xvf spot-$VERSION.tar.gz
|
||||
- cd spot-$VERSION
|
||||
- ./configure --with-included-ltdl CXX='g++'
|
||||
- make
|
||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
|
||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
|
||||
allow_failure: true
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- ./spot-*/_build/sub/tests/*/*.log
|
||||
- ./*.log
|
||||
- doc/spot.html/
|
||||
- doc/userdoc/
|
||||
- ./*.tar.gz
|
||||
- spot-*/tests/*/*.log
|
||||
- spot-*/*.log
|
||||
|
||||
alpine-gcc:
|
||||
stage: build
|
||||
|
|
@ -106,12 +147,12 @@ alpine-gcc:
|
|||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/alpine
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/alpine
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure
|
||||
- make
|
||||
- make distcheck || { chmod -R u+w ./spot-*; false; }
|
||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-pthread' || { chmod -R u+w ./spot-*; false; }
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
|
|
@ -125,7 +166,7 @@ arch-clang:
|
|||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure --prefix ~/install_dir CC='clang -Qunused-arguments' CXX='clang++ -Qunused-arguments' --enable-devel --enable-c++20 --enable-doxygen
|
||||
|
|
@ -138,22 +179,30 @@ arch-clang:
|
|||
- ./*.log
|
||||
|
||||
arch-gcc-glibcxxdebug:
|
||||
stage: build
|
||||
stage: build2
|
||||
needs:
|
||||
- job: make-dist
|
||||
artifacts: true
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure --enable-devel --enable-c++20 --enable-glibcxx-debug
|
||||
- VERSION=`cat VERSION`
|
||||
- tar xvf spot-$VERSION.tar.gz
|
||||
- mkdir build-$VERSION
|
||||
- cd build-$VERSION
|
||||
- ../spot-$VERSION/configure --enable-devel --enable-c++20 --enable-glibcxx-debug
|
||||
- make
|
||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-devel --enable-c++20 --enable-glibcxx-debug'
|
||||
artifacts:
|
||||
when: on_failure
|
||||
paths:
|
||||
- ./spot-*/_build/sub/tests/*/*.log
|
||||
- ./*.log
|
||||
- build-*/spot-*/_build/sub/tests/*/*.log
|
||||
- build-*/*.log
|
||||
|
||||
mingw-shared:
|
||||
stage: build2
|
||||
|
|
@ -161,15 +210,17 @@ mingw-shared:
|
|||
# We start from the tarball generated from a non-cross-compiling
|
||||
# job, so that all generated files are included, especially those
|
||||
# built from the executables.
|
||||
- job: debian-stable-gcc
|
||||
- job: make-dist
|
||||
artifacts: true
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- VERSION=`autoconf --trace='AC_INIT:$2'`
|
||||
- VERSION=`cat VERSION`
|
||||
- tar xvf spot-$VERSION.tar.gz
|
||||
- cd spot-$VERSION
|
||||
- ./configure CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++-posix --host i686-w64-mingw32 --disable-python
|
||||
|
|
@ -186,15 +237,17 @@ mingw-static:
|
|||
# We start from the tarball generated from a non-cross-compiling
|
||||
# job, so that all generated files are included, especially those
|
||||
# built from the executables.
|
||||
- job: debian-stable-gcc
|
||||
- job: make-dist
|
||||
artifacts: true
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- /wip/
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
script:
|
||||
- VERSION=`autoconf --trace='AC_INIT:$2'`
|
||||
- VERSION=`cat VERSION`
|
||||
- tar xvf spot-$VERSION.tar.gz
|
||||
- cd spot-$VERSION
|
||||
- mkdir install_dir
|
||||
|
|
@ -214,17 +267,19 @@ mingw-static:
|
|||
|
||||
debpkg-stable:
|
||||
stage: build
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- /-deb$/
|
||||
- master
|
||||
- next
|
||||
- stable
|
||||
script:
|
||||
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
|
||||
- vol=spot-stable-$CI_COMMIT_SHA
|
||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
|
||||
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
||||
- docker volume create $vol
|
||||
- exitcode=0
|
||||
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
|
||||
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
|
||||
- docker cp helper-$vol:/build/result _build_stable || exitcode=$?
|
||||
- docker rm helper-$vol || exitcode=$?
|
||||
- docker volume rm $vol || exitcode=$?
|
||||
|
|
@ -238,6 +293,8 @@ debpkg-stable:
|
|||
|
||||
debpkg-stable-i386:
|
||||
stage: build2
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- /-deb$/
|
||||
- master
|
||||
|
|
@ -246,11 +303,11 @@ debpkg-stable-i386:
|
|||
tags: ["x86"]
|
||||
needs: ["debpkg-stable"]
|
||||
script:
|
||||
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386:stable
|
||||
- vol=spot-stable-$CI_COMMIT_SHA
|
||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386:stable
|
||||
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
||||
- docker volume create $vol
|
||||
- exitcode=0
|
||||
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386:stable ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
|
||||
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386:stable ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
|
||||
- docker cp _build_stable/. helper-$vol:/build/result || exitcode=$?
|
||||
- rm -rf _build_stable
|
||||
- docker start -a helper-$vol || exitcode=$?
|
||||
|
|
@ -267,15 +324,17 @@ debpkg-stable-i386:
|
|||
|
||||
debpkg-unstable:
|
||||
stage: build
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- /-deb$/
|
||||
- next
|
||||
script:
|
||||
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||
- vol=spot-unstable-$CI_COMMIT_SHA
|
||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
||||
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
||||
- docker volume create $vol
|
||||
- exitcode=0
|
||||
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
|
||||
- docker run -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian ./build-spot.sh $CI_COMMIT_REF_NAME -j${NBPROC-1} || exitcode=$?
|
||||
- docker cp helper-$vol:/build/result _build_unstable || exitcode=$?
|
||||
- docker rm helper-$vol || exitcode=$?
|
||||
- docker volume rm $vol || exitcode=$?
|
||||
|
|
@ -289,17 +348,19 @@ debpkg-unstable:
|
|||
|
||||
debpkg-unstable-i386:
|
||||
stage: build2
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- /-deb$/
|
||||
- next
|
||||
tags: ["x86"]
|
||||
needs: ["debpkg-unstable"]
|
||||
script:
|
||||
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386
|
||||
- vol=spot-unstable-$CI_COMMIT_SHA
|
||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386
|
||||
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
||||
- docker volume create $vol
|
||||
- exitcode=0
|
||||
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386 ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
|
||||
- docker create -v $vol:/build/result --name helper-$vol gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386 ./bin-spot.sh -j${NBPROC-1} || exitcode=$?
|
||||
- docker cp _build_unstable/. helper-$vol:/build/result || exitcode=$?
|
||||
- rm -rf _build_unstable
|
||||
- docker start -a helper-$vol || exitcode=$?
|
||||
|
|
@ -321,7 +382,7 @@ rpm-pkg:
|
|||
- master
|
||||
- next
|
||||
- stable
|
||||
image: gitlab-registry.lrde.epita.fr/spot/buildenv/fedora
|
||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/fedora
|
||||
script:
|
||||
- autoreconf -vfi
|
||||
- ./configure
|
||||
|
|
@ -340,6 +401,8 @@ rpm-pkg:
|
|||
|
||||
publish-rpm:
|
||||
stage: publish
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
only:
|
||||
- /-rpm$/
|
||||
- next
|
||||
|
|
@ -350,6 +413,7 @@ publish-rpm:
|
|||
- rpm-pkg
|
||||
script:
|
||||
- case $CI_COMMIT_REF_NAME in stable) rput fedora stable *.rpm;; next) rput fedora unstable *.rpm;; esac
|
||||
- rm -rf ./*
|
||||
|
||||
publish-stable:
|
||||
only:
|
||||
|
|
@ -357,15 +421,23 @@ publish-stable:
|
|||
tags:
|
||||
- dput
|
||||
stage: publish
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
dependencies:
|
||||
- debpkg-stable-i386
|
||||
- make-dist
|
||||
script:
|
||||
- cd _build_stable
|
||||
- ls -l
|
||||
- dput lrde *.changes
|
||||
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
|
||||
- cd ..
|
||||
- ls -l
|
||||
- tgz=`ls spot-*.tar.* | head -n 1`
|
||||
- case $tgz in *[0-9].tar.*) scp $tgz doc@perso:/var/www/dload/spot/;; esac
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=stable" https://gitlab.lrde.epita.fr/api/v4/projects/131/trigger/pipeline
|
||||
- rm -rf ./*
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=stable" https://gitlab.lre.epita.fr/api/v4/projects/131/trigger/pipeline
|
||||
- curl -X POST "https://archive.softwareheritage.org/api/1/origin/save/git/url/https://gitlab.lre.epita.fr/spot/spot/"
|
||||
- curl "https://web.archive.org/save/https://www.lrde.epita.fr/dload/spot/$tgz"
|
||||
|
||||
publish-unstable:
|
||||
only:
|
||||
|
|
@ -373,14 +445,18 @@ publish-unstable:
|
|||
tags:
|
||||
- dput
|
||||
stage: publish
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
dependencies:
|
||||
- debpkg-unstable-i386
|
||||
script:
|
||||
- cd _build_unstable
|
||||
- ls -l
|
||||
- dput lrde *.changes
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=next" https://gitlab.lrde.epita.fr/api/v4/projects/131/trigger/pipeline
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SANDBOX https://gitlab.lrde.epita.fr/api/v4/projects/181/trigger/pipeline
|
||||
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
|
||||
- cd ..
|
||||
- rm -rf _build_unstable
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SPOT_WEB -F "variables[spot_branch]=next" https://gitlab.lre.epita.fr/api/v4/projects/131/trigger/pipeline
|
||||
- curl -X POST -F ref=master -F token=$TRIGGER_SANDBOX https://gitlab.lre.epita.fr/api/v4/projects/181/trigger/pipeline
|
||||
|
||||
raspbian:
|
||||
stage: build
|
||||
|
|
|
|||
20
.mailmap
Normal file
20
.mailmap
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@gaborone.lrde.epita.fr>
|
||||
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@pret-move.rsr.lip6.fr>
|
||||
Ala-Eddine Ben-Salem <ala@lrde.epita.fr> <ala@gaborone.lrde.epita.fr>
|
||||
Antoine Martin <amartin@lrde.epita.fr> <antoine97.martin@gmail.com>
|
||||
Arthur Remaud <aremaud@lrde.epita.fr> <aremaud@avignon.lrde.epita.fr>
|
||||
Arthur Remaud <aremaud@lrde.epita.fr> <aremaud@node7.lrde.epita.fr>
|
||||
Damien Lefortier <dam@lrde.epita.fr> <eg@feather.vurt>
|
||||
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@bosc-guerard.lrde.epita.fr>
|
||||
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@scalea.lrde.epita.fr>
|
||||
Felix Abecassis <felix.abecassis@lrde.epita.fr> <abecassis@lrde.epita.fr>
|
||||
Guillaume Sadegh <sadegh@lrde.epita.fr>
|
||||
Guillaume Sadegh <sadegh@lrde.epita.fr> <guillaume.sadegh@lrde.epita.fr>
|
||||
Henrich Lauko <xlauko@mail.muni.cz>
|
||||
Henrich Lauko <xlauko@mail.muni.cz> <henrich.lau@gmail.com>
|
||||
Jerome Dubois <jdubois@lrde.epita.fr> Jérôme Dubois <jdubois@lrde.epita.fr>
|
||||
Philipp Schlehuber-Caissier <philipp@lrde.epita.fr>
|
||||
Thibaud Michaud <thibaud.michaud@epita.fr> <michau_n@epita.fr>
|
||||
Thomas Badie <badie@lrde.epita.fr> <badie@champoteux.lrde.epita.fr>
|
||||
Rachid Rebiha <rebiha>
|
||||
Thomas Martinez <martinez>
|
||||
50
HACKING
50
HACKING
|
|
@ -5,11 +5,11 @@ Bootstraping from the GIT repository
|
|||
|
||||
Spot's gitlab page is at
|
||||
|
||||
https://gitlab.lrde.epita.fr/spot/spot
|
||||
https://gitlab.lre.epita.fr/spot/spot
|
||||
|
||||
The GIT repository can be cloned with
|
||||
|
||||
git clone https://gitlab.lrde.epita.fr/spot/spot.git
|
||||
git clone https://gitlab.lre.epita.fr/spot/spot.git
|
||||
|
||||
Some files in SPOT's source tree are generated. They are distributed
|
||||
so that users do not need to install tools to rebuild them, but we
|
||||
|
|
@ -25,7 +25,7 @@ since the generated files they produce are distributed.)
|
|||
GNU Automake >= 1.11
|
||||
GNU Libtool >= 2.4
|
||||
GNU Flex >= 2.6
|
||||
GNU Bison >= 3.0
|
||||
GNU Bison >= 3.3
|
||||
GNU Emacs (preferably >= 24 but it may work with older versions)
|
||||
org-mode >= 9.1 (the version that comes bundled with your emacs
|
||||
version is likely out-of-date; but distribution often have
|
||||
|
|
@ -290,8 +290,8 @@ would understand with:
|
|||
make check LOG_DRIVER=$PWD/tools/test-driver-teamcity
|
||||
|
||||
|
||||
Coding conventions
|
||||
==================
|
||||
C++ Coding conventions
|
||||
======================
|
||||
|
||||
Here some of the conventions we follow in Spot, so that the code looks
|
||||
homogeneous. Please follow these strictly. Since this is free
|
||||
|
|
@ -682,3 +682,43 @@ Other style recommandations
|
|||
|
||||
* Always code as if the person who ends up maintaining your code is
|
||||
a violent psychopath who knows where you live.
|
||||
|
||||
|
||||
Coding conventions for Python Tests
|
||||
===================================
|
||||
|
||||
Unless you have some specific reason to write test cases in C++ (for
|
||||
instance do test some specific C++ constructions, or to use valgrind),
|
||||
prefer writing test cases in Python. Writing test cases in C++
|
||||
requires some compilation, which slows down the test suite. Doing the
|
||||
same test in Python is therefore faster, and it has the added benefit
|
||||
of ensuring that the Python bindings works.
|
||||
|
||||
We have two types of Python tests: Python scripts or jupyter
|
||||
notebooks. Jupyter notebooks are usually used for a sequence of
|
||||
examples and comments that can also serve as part of the
|
||||
documentation. Such jupyter notebooks should be added to the list of
|
||||
code examples in doc/org/tut.org. Testing a notebook is done by the
|
||||
tests/python/ipnbdoctest.py scripts, which evaluate each cells, and
|
||||
checks that the obtainted result is equivalent to the result saved in
|
||||
the notebook. The process is a bit slow, so plain Python scripts
|
||||
should be prefered for most tests.
|
||||
|
||||
If you do need a notebook to tests Jupyter-specific code but this
|
||||
notebook should not be shown in the documentation, use a filename
|
||||
starting with '_'.
|
||||
|
||||
Tests written as Python scripts should follow the same convention as
|
||||
shell scripts: exit 0 for PASS, exit 77 for SKIP, and any other exit
|
||||
code for FAIL.
|
||||
|
||||
Do not use assert() in those scripts, as (1) asserts can be disabled,
|
||||
and (2) they provide poor insights in case of failures. Instead do
|
||||
|
||||
from unittest import TestCase
|
||||
tc = TestCase()
|
||||
|
||||
and then use tc.assertTrue(...), tc.assertEqual(..., ...),
|
||||
tc.assertIn(..., ...), etc. In case of failures, those will print
|
||||
useful messages in the trace of the tests. For instance multiline
|
||||
strings that should have been equal will be presented with a diff.
|
||||
|
|
|
|||
13
Makefile.am
13
Makefile.am
|
|
@ -1,5 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2011-2017, 2020 Laboratoire de Recherche et Développement
|
||||
## Copyright (C) 2011-2017, 2020, 2022 Laboratoire de Recherche et Développement
|
||||
## de l'Epita (LRDE).
|
||||
## Copyright (C) 2003, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
|
|
@ -36,8 +36,9 @@ DOC_SUBDIR = doc
|
|||
SUBDIRS = picosat buddy lib ltdl spot bin tests $(PYTHON_SUBDIR) $(DOC_SUBDIR) \
|
||||
$(NEVER_SUBDIRS)
|
||||
|
||||
UTF8 = utf8/README.md utf8/utf8.h \
|
||||
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
|
||||
UTF8 = utf8/README.md utf8/LICENSE utf8/utf8.h \
|
||||
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h \
|
||||
utf8/utf8/cpp11.h utf8/utf8/cpp17.h
|
||||
|
||||
DEBIAN = \
|
||||
debian/changelog \
|
||||
|
|
@ -68,7 +69,8 @@ EXTRA_DIST = HACKING ChangeLog.1 tools/gitlog-to-changelog \
|
|||
tools/help2man tools/man2html.pl \
|
||||
tools/test-driver-teamcity $(UTF8) $(DEBIAN) \
|
||||
m4/gnulib-cache.m4 .dir-locals.el \
|
||||
spot.spec spot.spec.in
|
||||
spot.spec spot.spec.in \
|
||||
default.nix default.nix.in
|
||||
|
||||
dist-hook: gen-ChangeLog
|
||||
|
||||
|
|
@ -114,3 +116,6 @@ deb: dist
|
|||
|
||||
spot.spec: configure.ac spot.spec.in
|
||||
sed 's/[@]VERSION[@]/$(VERSION)/;s/[@]GITPATCH[@]/@@@$(GITPATCH)/;s/@@@\.//' spot.spec.in > $@.tmp && mv $@.tmp $@
|
||||
|
||||
default.nix: configure.ac default.nix.in
|
||||
sed 's/[@]VERSION[@]/$(VERSION)/' default.nix.in > $@.tmp && mv $@.tmp $@
|
||||
|
|
|
|||
338
NEWS
338
NEWS
|
|
@ -1,16 +1,203 @@
|
|||
New in spot 2.10.4.dev (net yet released)
|
||||
New in spot 2.11.5.dev (not yet released)
|
||||
|
||||
Library:
|
||||
|
||||
- The following new trivial simplifications have been implemented for SEREs:
|
||||
- f|[+] = [+] if f rejects [*0]
|
||||
- f|[*] = [*] if f accepts [*0]
|
||||
- f&&[+] = f if f rejects [*0]
|
||||
- b:b[*i..j] = b[*max(i,1)..j]
|
||||
- b[*i..j]:b[*k..l] = b[*max(i,1)+max(k,1)-1, j+l-1]
|
||||
|
||||
- The HOA parser is a bit smarter when merging multiple initial
|
||||
states into a single initial state (Spot's automaton class
|
||||
supports only one): it now reuse the edges leaving initial states
|
||||
without incoming transitions.
|
||||
|
||||
- spot::bdd_to_cnf_formula() is a new variant of spot::bdd_to_formula()
|
||||
that converts a BDD into a CNF instead of a DNF.
|
||||
|
||||
New in spot 2.11.5 (2023-04-20)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fix spurious failure of ltlsynt2.test when Python is not installed
|
||||
(issue #530).
|
||||
|
||||
- Building from the git repository would fail to report a missing
|
||||
emacs (issue #528).
|
||||
|
||||
- Fix exception raised by aut1.intersecting_run(aut2).as_twa()
|
||||
because the run did not match transitions present in aut1
|
||||
verbatim. We also changed the behavior of as_twa() to not merge
|
||||
identical states.
|
||||
|
||||
- Fix segfaults occuring in determinization of 1-state terminal
|
||||
automata.
|
||||
|
||||
- Fix incorrect assertion in game solver when the edge vector
|
||||
contains deleted transitions.
|
||||
|
||||
New in spot 2.11.4 (2023-02-10)
|
||||
|
||||
Python:
|
||||
|
||||
- spot.acd() no longer depends on jQuery for interactivity.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- When merging initial states from state-based automata with
|
||||
multiple initial states (because Spot supports only one), the HOA
|
||||
parser could break state-based acceptance. (Issue #522.)
|
||||
|
||||
- autfilt --highlight-word refused to work on automata with Fin
|
||||
acceptance for historical reasons, however the code has been
|
||||
perfectly able to handle this for a while. (Issue #523.)
|
||||
|
||||
- delay_branching_here(), a new optimization of Spot 2.11 had an
|
||||
incorrect handling of states without successors, causing some
|
||||
segfaults. (Issue #524.)
|
||||
|
||||
- Running delay_branching_here() on state-based automata (this was not
|
||||
done in Spot so far) may require the output to use transition-based
|
||||
acceptance. (Issue #525.)
|
||||
|
||||
- to_finite(), introduce in 2.11, had a bug that could break the
|
||||
completeness of automata and trigger an exception from the HOA
|
||||
printer. (Issue #526.)
|
||||
|
||||
New in spot 2.11.3 (2022-12-09)
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Automata-based implication checks, used to simplify formulas were
|
||||
slower than necessary because the translator was configured to
|
||||
favor determinism unnecessarily. (Issue #521.)
|
||||
|
||||
- Automata-based implication checks for f&g and f|g could be
|
||||
very slow when those n-ary operator had two many arguments.
|
||||
They have been limited to 16 operands, but this value can be changed
|
||||
with option -x tls-max-ops=N. (Issue #521 too.)
|
||||
|
||||
- Running ltl_to_tgba_fm() with an output_aborter (which is done
|
||||
during automata-based implication checks) would leak memory on
|
||||
abort.
|
||||
|
||||
- configure --with-pythondir should also redefine pyexecdir,
|
||||
otherwise, libraries get installed in the wrong place on Debian.
|
||||
(Issue #512.)
|
||||
|
||||
- The HOA parser used to silently declare unused and undefined states
|
||||
(e.g., when the State: header declare many more states than the body
|
||||
of the file). It now warns about those.
|
||||
|
||||
- 'autfilt -c ...' should display a match count even in presence of
|
||||
parse errors.
|
||||
|
||||
- Calling solve_parity_game() multiple times on the same automaton
|
||||
used to append the new strategy to the existing one instead of
|
||||
overwriting it.
|
||||
|
||||
New in spot 2.11.2 (2022-10-26)
|
||||
|
||||
Command-line tools:
|
||||
|
||||
- The --stats specifications %s, %e, %t for printing the number of
|
||||
(reachable) states, edges, and transitions, learned to support
|
||||
options [r], [u], [a] to indicate if only reachable, unreachable,
|
||||
or all elements should be counted.
|
||||
|
||||
Library:
|
||||
|
||||
- spot::reduce_parity() now has a "layered" option to force all
|
||||
transition in the same parity layer to receive the same color;
|
||||
like acd_transform() would do.
|
||||
|
||||
Bugs fixed:
|
||||
|
||||
- Fix pkg-config files containing @LIBSPOT_PTHREAD@ (issue #520)
|
||||
- spot::relabel_bse() was incorrectly relabeling some dependent
|
||||
Boolean subexpressions in SERE. (Note that this had no
|
||||
consequence on automata translated from those SERE.)
|
||||
|
||||
New in spot 2.11.1 (2022-10-10)
|
||||
|
||||
Bugs fixed:
|
||||
|
||||
- Fix a build issue preventing the update of website (issue #516).
|
||||
- Fix a compilation error with clang-14 on FreeBSD (issue #515).
|
||||
|
||||
New in spot 2.11 (2022-10-08)
|
||||
|
||||
Build:
|
||||
|
||||
- configure will now diagnose situations where Python bindings will
|
||||
be installed in a directory that is not part of Python's search
|
||||
path. A new configure option --with-pythondir can be used to
|
||||
modify this installation path.
|
||||
|
||||
- A new configure option --enable-pthread enables the compilation of
|
||||
Spot with -pthread, and render available the parallel version of
|
||||
some algorithms. If Spot is compiled with -pthread enabled, any
|
||||
user linking with Spot should also link with the pthread library.
|
||||
In order to not break existing build setups using Spot, this
|
||||
option is currently disabled by default in this release. We plan
|
||||
to turn it on by default in some future release. Third-party
|
||||
project using Spot may want to start linking with -pthread in
|
||||
prevision for this change.
|
||||
|
||||
Command-line tools:
|
||||
|
||||
- autfilt has a new options --aliases=drop|keep to specify
|
||||
if the output code should attempt to preserve aliases
|
||||
if the HOA printer should attempt to preserve aliases
|
||||
present in the HOA input. This defaults to "keep".
|
||||
|
||||
- autfilt has a new --to-finite option, illustrated on
|
||||
https://spot.lrde.epita.fr/tut12.html
|
||||
|
||||
- ltlfilt has a new --sonf option to produce a formula's Suffix
|
||||
Operator Normal Form, described in [cimatti.06.fmcad]. The
|
||||
associated option --sonf-aps allows listing the newly introduced
|
||||
atomic propositions.
|
||||
|
||||
- autcross learned a --language-complemented option to assist in the
|
||||
case one is testing tools that complement automata. (issue #504).
|
||||
|
||||
- ltlsynt has a new option --tlsf that takes the filename of a TLSF
|
||||
specification and calls syfco (which must be installed) to convert
|
||||
it into an LTL formula.
|
||||
|
||||
- ltlsynt has a new option --from-pgame that takes a parity game in
|
||||
extended HOA format, as used in the Synthesis Competition.
|
||||
|
||||
- ltlsynt has a new option --hide-status to hide the REALIZABLE or
|
||||
UNREALIZABLE output expected by SYNTCOMP. (This line is
|
||||
superfluous, because the exit status of ltlsynt already indicate
|
||||
whether the formula is realizable or not.)
|
||||
|
||||
- ltlsynt has a new option --dot to request GraphViz output instead
|
||||
of most output. This works for displaying Mealy machines, games,
|
||||
or AIG circuits. See https://spot.lrde.epita.fr/ltlsynt.html for
|
||||
examples.
|
||||
|
||||
- genaut learned the --cyclist-trace-nba and --cyclist-proof-dba
|
||||
options. Those are used to generate pairs of automata that should
|
||||
include each other, and are used to show a regression (in speed)
|
||||
present in Spot 2.10.x and fixed in 2.11.
|
||||
|
||||
- genltl learned --eil-gsi to generate a familly a function whose
|
||||
translation and simplification used to be very slow. In particular
|
||||
|
||||
genltl --eil-gsi=23 | ltlfilt --from-ltlf | ltl2tgba
|
||||
|
||||
was reported as taking 9 days. This is now instantaneous.
|
||||
|
||||
Library:
|
||||
|
||||
- The new function suffix_operator_normal_form() implements
|
||||
transformation of formulas to Suffix Operator Normal Form,
|
||||
described in [cimatti.06.fmcad].
|
||||
|
||||
- "original-classes" is a new named property similar to
|
||||
"original-states". It maps an each state to an unsigned integer
|
||||
such that if two classes are in the same class, they are expected
|
||||
|
|
@ -21,16 +208,20 @@ New in spot 2.10.4.dev (net yet released)
|
|||
- tgba_determinize() learned to fill the "original-classes" property.
|
||||
States of the determinized automaton that correspond to the same
|
||||
subset of states of the original automaton belong to the same
|
||||
class. Filling this property is only done on demand has it inccurs
|
||||
on small overhead.
|
||||
class. Filling this property is only done on demand as it inccurs
|
||||
a small overhead.
|
||||
|
||||
- sbacc() learned to take the "original-classes" property into
|
||||
account and preserve it.
|
||||
account and to preserve it.
|
||||
|
||||
- The HOA parser and printer learned to map the synthesis-outputs
|
||||
property of Spot to the controllable-AP header for the Extended
|
||||
HOA format used in SyntComp. https://arxiv.org/abs/1912.05793
|
||||
|
||||
- The automaton parser learned to parse games in the PGSolver format.
|
||||
See the bottom of https://spot.lrde.epita.fr/ipynb/games.html for
|
||||
an example.
|
||||
|
||||
- "aliases" is a new named property that is filled by the HOA parser
|
||||
using the list of aliases declared in the HOA file, and then used
|
||||
by the HOA printer on a best-effort basis. Aliases can be used to
|
||||
|
|
@ -57,14 +248,147 @@ New in spot 2.10.4.dev (net yet released)
|
|||
- purge_dead_states() will now also remove edges labeled by false
|
||||
(except self-loops).
|
||||
|
||||
- When parsing formulas with a huge number of operands for an n-ary
|
||||
operator (for instance 'p1 | p2 | ... | p1000') the LTL parser
|
||||
would construct that formula two operand at a time, and the
|
||||
formula constructor for that operator would be responsible for
|
||||
inlining, sorting, deduplicating, ... all operands at each step.
|
||||
This resulted in a worst-than-quadratic slowdown. This is now
|
||||
averted in the parser by delaying the construction of such n-ary
|
||||
nodes until all children are known.
|
||||
|
||||
- complement() used to always turn tautological acceptance conditions
|
||||
into Büchi. It now only does that if the automaton is modified.
|
||||
|
||||
- The zielonka_tree construction was optimized using the same
|
||||
memoization trick that is used in ACD. Additionally it can now be
|
||||
run with additional options to abort when the tree as an unwanted
|
||||
shape, or to turn the tree into a DAG.
|
||||
|
||||
- contains() can now take a twa as a second argument, not just a
|
||||
twa_graph. This allows for instance to do contains(ltl, kripke)
|
||||
to obtain a simple model checker (that returns true or false,
|
||||
without counterexample).
|
||||
|
||||
- degeneralize() and degeneralize_tba() learned to work on
|
||||
generalized-co-Büchi as well.
|
||||
|
||||
- product() learned that the product of two co-Büchi automata
|
||||
is a co-Büchi automaton. And product_or() learned that the
|
||||
"or"-product of two Büchi automata is a Büchi automaton.
|
||||
|
||||
- spot::postprocessor has a new extra option "merge-states-min" that
|
||||
indicates above how many states twa_graph::merge_states() (which
|
||||
perform a very cheap pass to fuse states with identicall
|
||||
succesors) should be called before running simulation-based
|
||||
reductions.
|
||||
|
||||
- A new function delay_branching_here(aut) can be used to simplify
|
||||
some non-deterministic branching. If two transitions (q₁,ℓ,M,q₂)
|
||||
and (q₁,ℓ,M,q₃) differ only by their destination state, and are
|
||||
the only incoming transitions of their destination states, then q₂
|
||||
and q₃ can be merged (taking the union of their outgoing
|
||||
transitions). This is cheap function is automatically called by
|
||||
spot::translate() after translation of a formula to GBA, before
|
||||
further simplification. This was introduced to help with automata
|
||||
produced from formulas output by "genltl --eil-gsi" (see above).
|
||||
|
||||
- spot::postprocessor has new configuration variable branch-post
|
||||
that can be used to control the use of branching-postponement
|
||||
(disabled by default) or delayed-branching (see above, enabled by
|
||||
default). See the spot-x(7) man page for details.
|
||||
|
||||
- spot::postprocessor is now using acd_transform() by default when
|
||||
building parity automata. Setting option "acd=0" will revert
|
||||
to using "to_parity()" instead.
|
||||
|
||||
- to_parity() has been almost entirely rewritten and is a bit
|
||||
faster.
|
||||
|
||||
- When asked to build parity automata, spot::translator is now more
|
||||
aggressively using LTL decomposition, as done in the Generic
|
||||
acceptance case before paritizing the result. This results in
|
||||
much smaller automata in many cases.
|
||||
|
||||
- spot::parallel_policy is an object that can be passed to some
|
||||
algorithm to specify how many threads can be used if Spot has been
|
||||
compiled with --enable-pthread. Currently, only
|
||||
twa_graph::merge_states() supports it.
|
||||
|
||||
Python bindings:
|
||||
|
||||
- The to_str() method of automata can now export a parity game into
|
||||
the PG-Solver format by passing option 'pg'. See
|
||||
https://spot.lrde.epita.fr/ipynb/games.html for an example.
|
||||
|
||||
Deprectation notice:
|
||||
|
||||
- spot::pg_print() has been deprecated in favor of spot::print_pg()
|
||||
for consistency with the rest of the API.
|
||||
|
||||
Bugs fixed:
|
||||
|
||||
- calling twa_graph::new_univ_edge(src, begin, end, cond, acc) could
|
||||
produce unexpected result if begin and end where already pointing
|
||||
into the universal edge vector, since the later can be
|
||||
reallocated during that process.
|
||||
|
||||
- Printing an alternating automaton with print_dot() using 'u' to
|
||||
hide true state could produce some incorrect GraphViz output if
|
||||
the automaton as a true state as part of a universal group.
|
||||
|
||||
- Due to an optimization introduces in 2.10 to parse HOA label more
|
||||
efficiently, the automaton parser could crash when parsing random
|
||||
input (not HOA) containing '[' (issue #509).
|
||||
|
||||
New in spot 2.10.6 (2022-05-18)
|
||||
|
||||
Bugs fixed:
|
||||
|
||||
- Fix compilation error on MacOS X.
|
||||
|
||||
- Using -Ffile/N to read column N of a CSV file would not reset the
|
||||
/N specification for the next file.
|
||||
|
||||
- make_twa_graph() will now preserve state number when copying a
|
||||
kripke_graph object. As a consequence, print_dot() and
|
||||
print_hoa() will now use state numbers matching those of the
|
||||
kripke_graph (issue #505).
|
||||
|
||||
- Fix several compilation warning introduced by newer versions
|
||||
of GCC and Clang.
|
||||
|
||||
New in spot 2.10.5 (2022-05-03)
|
||||
|
||||
Bugs fixed:
|
||||
|
||||
- reduce_parity() produced incorrect results when applied to
|
||||
automata with deleted edges.
|
||||
|
||||
- work around a portability issue in Flex 2.6.4 preventing
|
||||
- An optimization of Zielonka could result in incorrect results
|
||||
in some cases.
|
||||
|
||||
- ltlsynt --print-pg incorrectly solved the game in addition to
|
||||
printing it.
|
||||
|
||||
- ltlsynt would fail if only one of --ins or --outs was set, and
|
||||
if it was set empty.
|
||||
|
||||
- Work around a portability issue in Flex 2.6.4 preventing
|
||||
compilation on OpenBSD.
|
||||
|
||||
- Do not use the seq command in test cases, it is not available
|
||||
everywhere.
|
||||
|
||||
- Do not erase the previous contents of the PYTHONPATH environment
|
||||
variable when running tests, prepend to it instead.
|
||||
|
||||
- Simplify Debian instructions for LTO build to work around newer
|
||||
libtool version.
|
||||
|
||||
- Fix invalid read in digraph::sort_edges_of_(), currently unused in
|
||||
Spot.
|
||||
|
||||
New in spot 2.10.4 (2022-02-01)
|
||||
|
||||
Bug fixed:
|
||||
|
|
@ -1424,7 +1748,7 @@ New in spot 2.6.2 (2018-09-28)
|
|||
|
||||
- We no longer distribute the Python-based CGI script + javascript
|
||||
code for the online translator. Its replacement has its own
|
||||
repository: https://gitlab.lrde.epita.fr/spot/spot-web-app/
|
||||
repository: https://gitlab.lre.epita.fr/spot/spot-web-app/
|
||||
|
||||
Library:
|
||||
|
||||
|
|
|
|||
50
README
50
README
|
|
@ -110,16 +110,16 @@ Spot follows the traditional `./configure && make && make check &&
|
|||
make install' process. People unfamiliar with the GNU Build System
|
||||
should read the file INSTALL for generic instructions.
|
||||
|
||||
If you plan to use the Python binding, we recommend you use one
|
||||
of the following --prefix options when calling configure:
|
||||
If you plan to use the Python bindings, we recommend you use the
|
||||
following --prefix options when calling configure:
|
||||
|
||||
--prefix /usr
|
||||
--prefix /usr/local (the default)
|
||||
--prefix ~/.local (if you do not have root permissions)
|
||||
--prefix ~/.local
|
||||
|
||||
The reason is that all these locations are usually automatically
|
||||
searched by Python. If you use a different prefix directory, you may
|
||||
have to tune the PYTHONPATH environment variable.
|
||||
The reason is that ~/.local/lib/python3.X/site-packages, where Spot's
|
||||
Python bindings will be installed, is automatically searched by
|
||||
Python. If you use a different prefix directory, you may have to tune
|
||||
the PYTHONPATH environment variable, or use the --with-pythondir
|
||||
option to specify different installation paths.
|
||||
|
||||
In addition to its usual options, ./configure will accept some
|
||||
flags specific to Spot:
|
||||
|
|
@ -173,6 +173,12 @@ flags specific to Spot:
|
|||
client code should be compiled with -D_GLIBCXX_DEBUG as well. This
|
||||
options should normally only be useful to run Spot's test-suite.
|
||||
|
||||
--enable-pthread
|
||||
Build and link with the -pthread option, and activate a few
|
||||
parallel variants of the algorithms. This is currently disabled
|
||||
by default, as it require all third-party tools using Spot to
|
||||
build with -pthread as well.
|
||||
|
||||
--enable-c++20
|
||||
Build everything in C++20 mode. We use that in our build farm to
|
||||
ensure that Spot can be used in C++20 projects as well.
|
||||
|
|
@ -244,17 +250,31 @@ To test the Python bindings, try running
|
|||
>>> import spot
|
||||
>>> print(spot.version())
|
||||
|
||||
If you installed Spot with a prefix that is not one of those suggested
|
||||
in the "Building and installing" section, it is likely that the above
|
||||
import statement will fail to locate the spot package. You can show
|
||||
the list of directories that are searched by Python using:
|
||||
If you installed Spot with a prefix that is not searched by Python by
|
||||
default it is likely that the above import statement will fail to
|
||||
locate the spot package. You can show the list of directories that
|
||||
are searched by Python using:
|
||||
|
||||
% python3
|
||||
>>> import sys
|
||||
>>> print(sys.path)
|
||||
|
||||
And you can modify that list of searched directories using the
|
||||
PYTHONPATH environment variable.
|
||||
PYTHONPATH environment variable. Alternatively, you can instruct Spot
|
||||
to install its Python files in one of those directory using the
|
||||
--with-pythondir configure option. As an example, an issue in
|
||||
distributions derived from Debian is that if you run
|
||||
|
||||
./configure && make && make install
|
||||
|
||||
Python files get installed in /usr/local/lib/python3.X/site-packages
|
||||
while Debian's version of Python only looks for them into
|
||||
/usr/local/lib/python3.X/dist-packages instead. You can fix that by
|
||||
instructing configure that you want packages installed into the right
|
||||
directory instead:
|
||||
|
||||
./configure --with-pythondir=/usr/local/lib/python3.X/dist-packages \
|
||||
&& make && make install
|
||||
|
||||
To test if man pages can be found, simply try:
|
||||
|
||||
|
|
@ -319,13 +339,13 @@ bench/ Benchmarks for ...
|
|||
wdba/ ... WDBA minimization (for obligation properties).
|
||||
python/ Python bindings for Spot and BuDDy
|
||||
|
||||
Third party software
|
||||
Third-party software
|
||||
--------------------
|
||||
|
||||
buddy/ A customized version of BuDDy 2.3 (a BDD library).
|
||||
ltdl/ Libtool's portable dlopen() wrapper library.
|
||||
lib/ Gnulib's portability modules.
|
||||
utf8/ Nemanja Trifunovic's utf-8 routines.
|
||||
utf8/ Trifunovic's utf-8 routines. https://github.com/nemtrif/utfcpp
|
||||
elisp/ Related emacs modes, used for building the documentation.
|
||||
picosat/ A distribution of PicoSAT 965 (a satsolver library).
|
||||
spot/bricks/ A collection of useful C++ code provided by DiVinE
|
||||
|
|
|
|||
12
THANKS
12
THANKS
|
|
@ -11,9 +11,12 @@ Christian Dax
|
|||
Christopher Ziegler
|
||||
Clément Tamines
|
||||
David Müller
|
||||
Dávid Smolka
|
||||
Edmond Irani Liu
|
||||
Ernesto Posse
|
||||
Étienne Renault
|
||||
Fabrice Kordon
|
||||
Fangyi Zhou
|
||||
Felix Klaedtke
|
||||
Florian Perlié-Long
|
||||
František Blahoudek
|
||||
|
|
@ -21,6 +24,7 @@ Gerard J. Holzmann
|
|||
Hashim Ali
|
||||
Heikki Tauriainen
|
||||
Henrich Lauko
|
||||
Jacopo Binchi
|
||||
Jan Strejček
|
||||
Jean-Michel Couvreur
|
||||
Jean-Michel Ilié
|
||||
|
|
@ -41,14 +45,18 @@ Michael Weber
|
|||
Mikuláš Klokočka
|
||||
Ming-Hsien Tsai
|
||||
Nikos Gorogiannis
|
||||
Ondřej Lengál
|
||||
Paul Guénézan
|
||||
Pierre Ganty
|
||||
Raven Beutner
|
||||
Reuben Rowe
|
||||
Roei Nahum
|
||||
Rüdiger Ehlers
|
||||
Silien Hong
|
||||
Simon Jantsch
|
||||
Shachar Itzhaky
|
||||
Shengping Shaw
|
||||
Shufang Zhu
|
||||
Silien Hong
|
||||
Simon Jantsch
|
||||
Sonali Dutta
|
||||
Tereza Šťastná
|
||||
Tobias Meggendorfer.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (C) 2016-2018 Laboratoire de Recherche et Développement de
|
||||
# Copyright (C) 2016-2018, 2023 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
|
|
@ -55,12 +55,12 @@ class BenchConfig(object):
|
|||
if line[0] == '#' or line.isspace():
|
||||
continue
|
||||
elif line[0:2] == "sh":
|
||||
sh = re.search('sh (.+?)$', line).group(1)
|
||||
sh = re.search('sh (.+)$', line).group(1)
|
||||
continue
|
||||
else:
|
||||
name = re.search('(.+?):', line).group(1)
|
||||
code = re.search(':(.+?)>', line).group(1)
|
||||
xoptions = re.search('>(.+?)$', line).group(1)
|
||||
xoptions = re.search('>(.+)$', line).group(1)
|
||||
b = Bench(name=name, code=code, xoptions=xoptions)
|
||||
self.l.append(b)
|
||||
self.sh.append(sh)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015, 2016, 2017 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2014, 2015, 2016, 2017, 2022 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include <spot/misc/timer.hh>
|
||||
#include <argp.h>
|
||||
|
||||
const char argp_program_doc[] ="";
|
||||
static const char argp_program_doc[] = "";
|
||||
|
||||
const struct argp_child children[] =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017-2020 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
// Copyright (C) 2017-2020, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
#include <spot/misc/escape.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Call several tools that process automata and cross-compare their output \
|
||||
to detect bugs, or to gather statistics. The list of automata to use \
|
||||
should be supplied on standard input, or using the -F option.\v\
|
||||
|
|
@ -64,6 +64,7 @@ Exit status:\n\
|
|||
|
||||
enum {
|
||||
OPT_BOGUS = 256,
|
||||
OPT_COMPLEMENTED,
|
||||
OPT_CSV,
|
||||
OPT_HIGH,
|
||||
OPT_FAIL_ON_TIMEOUT,
|
||||
|
|
@ -94,6 +95,8 @@ static const argp_option options[] =
|
|||
"consider timeouts as errors", 0 },
|
||||
{ "language-preserved", OPT_LANG, nullptr, 0,
|
||||
"expect that each tool preserves the input language", 0 },
|
||||
{ "language-complemented", OPT_COMPLEMENTED, nullptr, 0,
|
||||
"expect that each tool complements the input language", 0 },
|
||||
{ "no-checks", OPT_NOCHECKS, nullptr, 0,
|
||||
"do not perform any sanity checks", 0 },
|
||||
/**************************************************/
|
||||
|
|
@ -144,6 +147,7 @@ static bool fail_on_timeout = false;
|
|||
static bool stop_on_error = false;
|
||||
static bool no_checks = false;
|
||||
static bool opt_language_preserved = false;
|
||||
static bool opt_language_complemented = false;
|
||||
static bool opt_omit = false;
|
||||
static const char* csv_output = nullptr;
|
||||
static unsigned round_num = 0;
|
||||
|
|
@ -158,7 +162,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
switch (key)
|
||||
{
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
case 'q':
|
||||
quiet = true;
|
||||
|
|
@ -170,6 +174,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
bogus_output_filename = arg;
|
||||
break;
|
||||
}
|
||||
case OPT_COMPLEMENTED:
|
||||
opt_language_complemented = true;
|
||||
break;
|
||||
case OPT_CSV:
|
||||
csv_output = arg ? arg : "-";
|
||||
break;
|
||||
|
|
@ -209,7 +216,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (arg[0] == '-' && !arg[1])
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
else
|
||||
tools_push_autproc(arg);
|
||||
break;
|
||||
|
|
@ -338,7 +345,6 @@ struct in_statistics
|
|||
|
||||
struct out_statistics
|
||||
{
|
||||
|
||||
// If OK is false, output statistics are not available.
|
||||
bool ok;
|
||||
const char* status_str;
|
||||
|
|
@ -346,7 +352,7 @@ struct out_statistics
|
|||
double time;
|
||||
aut_statistics output;
|
||||
|
||||
out_statistics()
|
||||
out_statistics() noexcept
|
||||
: ok(false),
|
||||
status_str(nullptr),
|
||||
status_code(0),
|
||||
|
|
@ -533,25 +539,32 @@ namespace
|
|||
const spot::const_twa_graph_ptr& aut_j,
|
||||
size_t i, size_t j)
|
||||
{
|
||||
auto is_really_comp = [lc = opt_language_complemented,
|
||||
ts = tools.size()](unsigned i) {
|
||||
return lc && i == ts;
|
||||
};
|
||||
|
||||
if (aut_i->num_sets() + aut_j->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets())
|
||||
{
|
||||
if (!quiet)
|
||||
std::cerr << "info: building " << autname(i)
|
||||
<< '*' << autname(j, true)
|
||||
std::cerr << "info: building " << autname(i, is_really_comp(i))
|
||||
<< '*' << autname(j, !is_really_comp(j))
|
||||
<< " requires more acceptance sets than supported\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
std::cerr << "info: check_empty "
|
||||
<< autname(i) << '*' << autname(j, true) << '\n';
|
||||
<< autname(i, is_really_comp(i))
|
||||
<< '*' << autname(j, !is_really_comp(j)) << '\n';
|
||||
|
||||
auto w = aut_i->intersecting_word(aut_j);
|
||||
if (w)
|
||||
{
|
||||
std::ostream& err = global_error();
|
||||
err << "error: " << autname(i) << '*' << autname(j, true)
|
||||
err << "error: " << autname(i, is_really_comp(i))
|
||||
<< '*' << autname(j, !is_really_comp(j))
|
||||
<< (" is nonempty; both automata accept the infinite word:\n"
|
||||
" ");
|
||||
example() << *w << '\n';
|
||||
|
|
@ -600,7 +613,7 @@ namespace
|
|||
return src.str();
|
||||
}();
|
||||
|
||||
input_statistics.push_back(in_statistics());
|
||||
input_statistics.emplace_back(in_statistics());
|
||||
|
||||
input_statistics[round_num].input_source = std::move(source);
|
||||
if (auto name = input->get_named_prop<std::string>("automaton-name"))
|
||||
|
|
@ -621,12 +634,15 @@ namespace
|
|||
|
||||
int problems = 0;
|
||||
size_t m = tools.size();
|
||||
size_t mi = m + opt_language_preserved;
|
||||
size_t mi = m + opt_language_preserved + opt_language_complemented;
|
||||
std::vector<spot::twa_graph_ptr> pos(mi);
|
||||
std::vector<spot::twa_graph_ptr> neg(mi);
|
||||
vector_tool_statistics stats(m);
|
||||
|
||||
if (opt_language_preserved)
|
||||
// For --language-complemented, we store the input automata in
|
||||
// pos and will compute its complement in neg. Before running
|
||||
// checks we will swap both automata.
|
||||
if (opt_language_preserved || opt_language_complemented)
|
||||
pos[mi - 1] = input;
|
||||
|
||||
if (verbose)
|
||||
|
|
@ -642,7 +658,7 @@ namespace
|
|||
problems += prob;
|
||||
}
|
||||
spot::cleanup_tmpfiles();
|
||||
output_statistics.push_back(std::move(stats));
|
||||
output_statistics.emplace_back(std::move(stats));
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
|
|
@ -718,6 +734,9 @@ namespace
|
|||
};
|
||||
}
|
||||
|
||||
if (opt_language_complemented)
|
||||
std::swap(pos[mi - 1], neg[mi - 1]);
|
||||
|
||||
// Just make a circular implication check
|
||||
// A0 <= A1, A1 <= A2, ..., AN <= A0
|
||||
unsigned ok = 0;
|
||||
|
|
@ -824,10 +843,15 @@ main(int argc, char** argv)
|
|||
|
||||
check_no_automaton();
|
||||
|
||||
if (s == 1 && !opt_language_preserved && !no_checks)
|
||||
error(2, 0, "Since --language-preserved is not used, you need "
|
||||
"at least two tools to compare.");
|
||||
if (s == 1 && !no_checks
|
||||
&& !opt_language_preserved
|
||||
&& !opt_language_complemented)
|
||||
error(2, 0, "Since --language-preserved and --language-complemented "
|
||||
"are not used, you need at least two tools to compare.");
|
||||
|
||||
if (opt_language_preserved && opt_language_complemented)
|
||||
error(2, 0, "Options --language-preserved and --language-complemented "
|
||||
"are incompatible.");
|
||||
|
||||
setup_color();
|
||||
setup_sig_handler();
|
||||
|
|
|
|||
134
bin/autfilt.cc
134
bin/autfilt.cc
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
#include <spot/twaalgos/sum.hh>
|
||||
#include <spot/twaalgos/totgba.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Convert, transform, and filter omega-automata.\v\
|
||||
Exit status:\n\
|
||||
0 if some automata were output\n\
|
||||
|
|
@ -448,7 +448,7 @@ struct canon_aut
|
|||
std::vector<tr_t> edges;
|
||||
std::string acc;
|
||||
|
||||
canon_aut(const spot::const_twa_graph_ptr& aut)
|
||||
explicit canon_aut(const spot::const_twa_graph_ptr& aut)
|
||||
: num_states(aut->num_states())
|
||||
, edges(aut->edge_vector().begin() + 1,
|
||||
aut->edge_vector().end())
|
||||
|
|
@ -713,10 +713,12 @@ ensure_deterministic(const spot::twa_graph_ptr& aut, bool nonalt = false)
|
|||
return p.run(aut);
|
||||
}
|
||||
|
||||
static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
|
||||
static spot::twa_graph_ptr
|
||||
ensure_tba(spot::twa_graph_ptr aut,
|
||||
spot::postprocessor::output_type type = spot::postprocessor::Buchi)
|
||||
{
|
||||
spot::postprocessor p;
|
||||
p.set_type(spot::postprocessor::Buchi);
|
||||
p.set_type(type);
|
||||
p.set_pref(spot::postprocessor::Any);
|
||||
p.set_level(spot::postprocessor::Low);
|
||||
return p.run(aut);
|
||||
|
|
@ -726,12 +728,14 @@ static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
|
|||
static spot::twa_graph_ptr
|
||||
product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
||||
{
|
||||
if ((type == spot::postprocessor::Buchi)
|
||||
&& (left->num_sets() + right->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets()))
|
||||
// Are we likely to fail because of too many colors?
|
||||
if ((left->num_sets() + right->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets())
|
||||
&& (type == spot::postprocessor::Buchi
|
||||
|| type == spot::postprocessor::CoBuchi))
|
||||
{
|
||||
left = ensure_tba(left);
|
||||
right = ensure_tba(right);
|
||||
left = ensure_tba(left, type);
|
||||
right = ensure_tba(right, type);
|
||||
}
|
||||
return spot::product(left, right);
|
||||
}
|
||||
|
|
@ -739,16 +743,34 @@ product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
|||
static spot::twa_graph_ptr
|
||||
product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
||||
{
|
||||
if ((type == spot::postprocessor::Buchi)
|
||||
&& (left->num_sets() + right->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets()))
|
||||
// Are we likely to fail because of too many colors?
|
||||
if ((left->num_sets() + right->num_sets() >
|
||||
spot::acc_cond::mark_t::max_accsets())
|
||||
&& (type == spot::postprocessor::Buchi
|
||||
|| type == spot::postprocessor::CoBuchi))
|
||||
{
|
||||
left = ensure_tba(left);
|
||||
right = ensure_tba(right);
|
||||
left = ensure_tba(left, type);
|
||||
right = ensure_tba(right, type);
|
||||
}
|
||||
return spot::product_or(left, right);
|
||||
}
|
||||
|
||||
static spot::twa_graph_ptr
|
||||
word_to_aut(const char* word, const char *argname)
|
||||
{
|
||||
try
|
||||
{
|
||||
return spot::parse_word(word, opt->dict)->as_automaton();
|
||||
}
|
||||
catch (const spot::parse_error& e)
|
||||
{
|
||||
error(2, 0, "failed to parse the argument of --%s:\n%s",
|
||||
argname, e.what());
|
||||
}
|
||||
SPOT_UNREACHABLE();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_opt(int key, char* arg, struct argp_state*)
|
||||
{
|
||||
|
|
@ -761,7 +783,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
automaton_format = Count;
|
||||
break;
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
case 'n':
|
||||
opt_max_count = to_pos_int(arg, "-n/--max-count");
|
||||
|
|
@ -770,17 +792,14 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
opt_nth = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||
break;
|
||||
case 'u':
|
||||
opt->uniq = std::unique_ptr<unique_aut_t>(new std::set<canon_aut>());
|
||||
opt->uniq = std::make_unique<unique_aut_t>();
|
||||
break;
|
||||
case 'v':
|
||||
opt_invert = true;
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
const char* opt = extra_options.parse_options(arg);
|
||||
if (opt)
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
}
|
||||
if (const char* opt = extra_options.parse_options(arg))
|
||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||
break;
|
||||
case OPT_ALIASES:
|
||||
opt_aliases = XARGMATCH("--aliases", arg, aliases_args, aliases_types);
|
||||
|
|
@ -796,16 +815,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
opt_art_sccs_set = true;
|
||||
break;
|
||||
case OPT_ACCEPT_WORD:
|
||||
try
|
||||
{
|
||||
opt->acc_words.push_back(spot::parse_word(arg, opt->dict)
|
||||
->as_automaton());
|
||||
}
|
||||
catch (const spot::parse_error& e)
|
||||
{
|
||||
error(2, 0, "failed to parse the argument of --accept-word:\n%s",
|
||||
e.what());
|
||||
}
|
||||
opt->acc_words.emplace_back(word_to_aut(arg, "accept-word"));
|
||||
break;
|
||||
case OPT_ACCEPTANCE_IS:
|
||||
{
|
||||
|
|
@ -958,16 +968,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
"%d should be followed by a comma and WORD", res);
|
||||
arg = endptr + 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
opt->hl_words.emplace_back(spot::parse_word(arg, opt->dict)
|
||||
->as_automaton(), res);
|
||||
}
|
||||
catch (const spot::parse_error& e)
|
||||
{
|
||||
error(2, 0, "failed to parse the argument of --highlight-word:\n%s",
|
||||
e.what());
|
||||
}
|
||||
opt->hl_words.emplace_back(word_to_aut(arg, "highlight-word"), res);
|
||||
}
|
||||
break;
|
||||
case OPT_HIGHLIGHT_LANGUAGES:
|
||||
|
|
@ -988,7 +989,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
if (!opt->included_in)
|
||||
opt->included_in = aut;
|
||||
else
|
||||
opt->included_in = spot::product_or(opt->included_in, aut);
|
||||
opt->included_in = ::product_or(opt->included_in, aut);
|
||||
}
|
||||
break;
|
||||
case OPT_INHERENTLY_WEAK_SCCS:
|
||||
|
|
@ -1151,16 +1152,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
opt_art_sccs_set = true;
|
||||
break;
|
||||
case OPT_REJECT_WORD:
|
||||
try
|
||||
{
|
||||
opt->rej_words.push_back(spot::parse_word(arg, opt->dict)
|
||||
->as_automaton());
|
||||
}
|
||||
catch (const spot::parse_error& e)
|
||||
{
|
||||
error(2, 0, "failed to parse the argument of --reject-word:\n%s",
|
||||
e.what());
|
||||
}
|
||||
opt->rej_words.emplace_back(word_to_aut(arg, "reject-word"));
|
||||
break;
|
||||
case OPT_REM_AP:
|
||||
opt->rem_ap.add_ap(arg);
|
||||
|
|
@ -1252,7 +1244,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
opt_art_sccs_set = true;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1285,7 +1277,7 @@ namespace
|
|||
static
|
||||
bool match_acceptance(spot::twa_graph_ptr aut)
|
||||
{
|
||||
auto& acc = aut->acc();
|
||||
const spot::acc_cond& acc = aut->acc();
|
||||
switch (opt_acceptance_is)
|
||||
{
|
||||
case ACC_Any:
|
||||
|
|
@ -1340,8 +1332,7 @@ namespace
|
|||
{
|
||||
bool max;
|
||||
bool odd;
|
||||
bool is_p = acc.is_parity(max, odd, true);
|
||||
if (!is_p)
|
||||
if (!acc.is_parity(max, odd, true))
|
||||
return false;
|
||||
switch (opt_acceptance_is)
|
||||
{
|
||||
|
|
@ -1454,7 +1445,7 @@ namespace
|
|||
if (matched && opt_acceptance_is)
|
||||
matched = match_acceptance(aut);
|
||||
|
||||
if (matched && (opt_sccs_set | opt_art_sccs_set))
|
||||
if (matched && (opt_sccs_set || opt_art_sccs_set))
|
||||
{
|
||||
spot::scc_info si(aut);
|
||||
unsigned n = si.scc_count();
|
||||
|
|
@ -1534,14 +1525,14 @@ namespace
|
|||
&& spot::contains(aut, opt->equivalent_pos);
|
||||
|
||||
if (matched && !opt->acc_words.empty())
|
||||
for (auto& word_aut: opt->acc_words)
|
||||
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
|
||||
if (spot::product(aut, word_aut)->is_empty())
|
||||
{
|
||||
matched = false;
|
||||
break;
|
||||
}
|
||||
if (matched && !opt->rej_words.empty())
|
||||
for (auto& word_aut: opt->rej_words)
|
||||
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
|
||||
if (!spot::product(aut, word_aut)->is_empty())
|
||||
{
|
||||
matched = false;
|
||||
|
|
@ -1675,14 +1666,9 @@ namespace
|
|||
aut->accepting_run()->highlight(opt_highlight_accepting_run);
|
||||
|
||||
if (!opt->hl_words.empty())
|
||||
for (auto& word_aut: opt->hl_words)
|
||||
{
|
||||
if (aut->acc().uses_fin_acceptance())
|
||||
error(2, 0,
|
||||
"--highlight-word does not yet work with Fin acceptance");
|
||||
if (auto run = spot::product(aut, word_aut.first)->accepting_run())
|
||||
run->project(aut)->highlight(word_aut.second);
|
||||
}
|
||||
for (auto& [word_aut, color]: opt->hl_words)
|
||||
if (auto run = spot::product(aut, word_aut)->accepting_run())
|
||||
run->project(aut)->highlight(color);
|
||||
|
||||
timer.stop();
|
||||
if (opt->uniq)
|
||||
|
|
@ -1757,15 +1743,17 @@ main(int argc, char** argv)
|
|||
post.set_level(level);
|
||||
|
||||
autfilt_processor processor(post, o.dict);
|
||||
if (processor.run())
|
||||
return 2;
|
||||
|
||||
// Diagnose unused -x options
|
||||
extra_options.report_unused_options();
|
||||
int err = processor.run();
|
||||
|
||||
if (automaton_format == Count)
|
||||
std::cout << match_count << std::endl;
|
||||
|
||||
// Diagnose unused -x options
|
||||
if (!err)
|
||||
extra_options.report_unused_options();
|
||||
else
|
||||
return 2;
|
||||
|
||||
check_cout();
|
||||
return match_count ? 0 : 1;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
#include <spot/twaalgos/isdet.hh>
|
||||
|
||||
automaton_format_t automaton_format = Hoa;
|
||||
static const char* automaton_format_opt = nullptr;
|
||||
const char* automaton_format_opt = nullptr;
|
||||
const char* opt_name = nullptr;
|
||||
static const char* opt_output = nullptr;
|
||||
static const char* stats = "";
|
||||
|
|
@ -203,12 +203,18 @@ static const argp_option io_options[] =
|
|||
"to specify additional options as in --hoa=opt)", 0 },
|
||||
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"name of the automaton", 0 },
|
||||
{ "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable states", 0 },
|
||||
{ "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable edges", 0 },
|
||||
{ "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable transitions", 0 },
|
||||
{ "%S, %s, %[LETTER]S, %[LETTER]s",
|
||||
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of states (add one LETTER to select (r) reachable [default], "
|
||||
"(u) unreachable, (a) all).", 0 },
|
||||
{ "%E, %e, %[LETTER]E, %[LETTER]e",
|
||||
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of edges (add one LETTER to select (r) reachable [default], "
|
||||
"(u) unreachable, (a) all).", 0 },
|
||||
{ "%T, %t, %[LETTER]E, %[LETTER]e",
|
||||
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of transitions (add one LETTER to select (r) reachable "
|
||||
"[default], (u) unreachable, (a) all).", 0 },
|
||||
{ "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of acceptance sets", 0 },
|
||||
{ "%G, %g, %[LETTERS]G, %[LETTERS]g", 0, nullptr,
|
||||
|
|
@ -221,7 +227,7 @@ static const argp_option io_options[] =
|
|||
"(iw) inherently weak. Use uppercase letters to negate them.", 0 },
|
||||
{ "%R, %[LETTERS]R", 0, nullptr,
|
||||
OPTION_DOC | OPTION_NO_USAGE,
|
||||
"CPU time (excluding parsing), in seconds; Add LETTERS to restrict to"
|
||||
"CPU time (excluding parsing), in seconds; Add LETTERS to restrict to "
|
||||
"(u) user time, (s) system time, (p) parent process, "
|
||||
"or (c) children processes.", 0 },
|
||||
{ "%N, %n", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
|
|
@ -268,12 +274,15 @@ static const argp_option o_options[] =
|
|||
"to specify additional options as in --hoa=opt)", 0 },
|
||||
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"name of the automaton", 0 },
|
||||
{ "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable states", 0 },
|
||||
{ "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable edges", 0 },
|
||||
{ "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of reachable transitions", 0 },
|
||||
{ "%s, %[LETTER]s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of states (add one LETTER to select (r) reachable [default], "
|
||||
"(u) unreachable, (a) all).", 0 },
|
||||
{ "%e, %[LETTER]e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of edges (add one LETTER to select (r) reachable [default], "
|
||||
"(u) unreachable, (a) all).", 0 },
|
||||
{ "%t, %[LETTER]t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of transitions (add one LETTER to select (r) reachable "
|
||||
"[default], (u) unreachable, (a) all).", 0 },
|
||||
{ "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||
"number of acceptance sets", 0 },
|
||||
{ "%g, %[LETTERS]g", 0, nullptr,
|
||||
|
|
@ -444,7 +453,7 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
|
|||
const spot::const_twa_graph_ptr& aut,
|
||||
spot::formula f,
|
||||
const char* filename, int loc,
|
||||
spot::process_timer& ptimer,
|
||||
const spot::process_timer& ptimer,
|
||||
const char* csv_prefix, const char* csv_suffix)
|
||||
{
|
||||
timer_ = ptimer;
|
||||
|
|
@ -472,15 +481,15 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
|
|||
if (has('T'))
|
||||
{
|
||||
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
|
||||
haut_states_ = s.states;
|
||||
haut_edges_ = s.edges;
|
||||
haut_trans_ = s.transitions;
|
||||
haut_states_.set(s.states, haut->aut->num_states());
|
||||
haut_edges_.set(s.edges, haut->aut->num_edges());
|
||||
haut_trans_.set(s.transitions, count_all_transitions(haut->aut));
|
||||
}
|
||||
else if (has('E') || has('S'))
|
||||
{
|
||||
spot::twa_statistics s = stats_reachable(haut->aut);
|
||||
haut_states_ = s.states;
|
||||
haut_edges_ = s.edges;
|
||||
haut_states_.set(s.states, haut->aut->num_states());
|
||||
haut_edges_.set(s.edges, haut->aut->num_edges());
|
||||
}
|
||||
if (has('M'))
|
||||
{
|
||||
|
|
@ -624,10 +633,10 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
|||
outputnamer.print(haut, aut, f, filename, loc, ptimer,
|
||||
csv_prefix, csv_suffix);
|
||||
std::string fname = outputname.str();
|
||||
auto p = outputfiles.emplace(fname, nullptr);
|
||||
if (p.second)
|
||||
p.first->second.reset(new output_file(fname.c_str()));
|
||||
out = &p.first->second->ostream();
|
||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
||||
if (b)
|
||||
it->second.reset(new output_file(fname.c_str()));
|
||||
out = &it->second->ostream();
|
||||
}
|
||||
|
||||
// Output it.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014-2018, 2020 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2014-2018, 2020, 2022, 2023 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -47,6 +47,7 @@ enum automaton_format_t {
|
|||
|
||||
// The format to use in output_automaton()
|
||||
extern automaton_format_t automaton_format;
|
||||
extern const char* automaton_format_opt;
|
||||
// Set to the argument of --name, else nullptr.
|
||||
extern const char* opt_name;
|
||||
// Output options
|
||||
|
|
@ -154,7 +155,7 @@ public:
|
|||
print(const spot::const_parsed_aut_ptr& haut,
|
||||
const spot::const_twa_graph_ptr& aut,
|
||||
spot::formula f,
|
||||
const char* filename, int loc, spot::process_timer& ptimer,
|
||||
const char* filename, int loc, const spot::process_timer& ptimer,
|
||||
const char* csv_prefix, const char* csv_suffix);
|
||||
|
||||
private:
|
||||
|
|
@ -165,9 +166,9 @@ private:
|
|||
spot::printable_value<std::string> aut_word_;
|
||||
spot::printable_value<std::string> haut_word_;
|
||||
spot::printable_acc_cond haut_gen_acc_;
|
||||
spot::printable_value<unsigned> haut_states_;
|
||||
spot::printable_value<unsigned> haut_edges_;
|
||||
spot::printable_value<unsigned long long> haut_trans_;
|
||||
spot::printable_size haut_states_;
|
||||
spot::printable_size haut_edges_;
|
||||
spot::printable_long_size haut_trans_;
|
||||
spot::printable_value<unsigned> haut_acc_;
|
||||
printable_varset haut_ap_;
|
||||
printable_varset aut_ap_;
|
||||
|
|
@ -195,7 +196,7 @@ class automaton_printer
|
|||
std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||
|
||||
public:
|
||||
automaton_printer(stat_style input = no_input);
|
||||
explicit automaton_printer(stat_style input = no_input);
|
||||
~automaton_printer();
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2015, 2018, 2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -25,10 +25,15 @@ int
|
|||
to_int(const char* s, const char* where)
|
||||
{
|
||||
char* endptr;
|
||||
int res = strtol(s, &endptr, 10);
|
||||
errno = 0;
|
||||
long int lres = strtol(s, &endptr, 10);
|
||||
if (*endptr)
|
||||
error(2, 0, "failed to parse '%s' as an integer (in argument of %s).",
|
||||
s, where);
|
||||
int res = lres;
|
||||
if (res != lres || errno == ERANGE)
|
||||
error(2, 0, "value '%s' is too large for an int (in argument of %s).",
|
||||
s, where);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -45,11 +50,17 @@ unsigned
|
|||
to_unsigned (const char *s, const char* where)
|
||||
{
|
||||
char* endptr;
|
||||
unsigned res = strtoul(s, &endptr, 10);
|
||||
errno = 0;
|
||||
unsigned long lres = strtoul(s, &endptr, 10);
|
||||
if (*endptr)
|
||||
error(2, 0,
|
||||
"failed to parse '%s' as an unsigned integer (in argument of %s).",
|
||||
s, where);
|
||||
unsigned res = lres;
|
||||
if (res != lres || errno == ERANGE)
|
||||
error(2, 0,
|
||||
"value '%s' is too large for a unsigned int (in argument of %s).",
|
||||
s, where);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -57,8 +68,9 @@ float
|
|||
to_float(const char* s, const char* where)
|
||||
{
|
||||
char* endptr;
|
||||
errno = 0;
|
||||
float res = strtof(s, &endptr);
|
||||
if (*endptr)
|
||||
if (*endptr || errno == ERANGE)
|
||||
error(2, 0, "failed to parse '%s' as a float (in argument of %s)",
|
||||
s, where);
|
||||
return res;
|
||||
|
|
@ -80,8 +92,9 @@ to_longs(const char* arg)
|
|||
while (*arg)
|
||||
{
|
||||
char* endptr;
|
||||
errno = 0;
|
||||
long value = strtol(arg, &endptr, 10);
|
||||
if (endptr == arg)
|
||||
if (endptr == arg || errno)
|
||||
error(2, 0, "failed to parse '%s' as an integer.", arg);
|
||||
res.push_back(value);
|
||||
while (*endptr == ' ' || *endptr == ',')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
// Copyright (C) 2015, 2016, 2022, 2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -21,25 +21,27 @@
|
|||
#include <error.h>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
output_file::output_file(const char* name)
|
||||
output_file::output_file(const char* name, bool force_append)
|
||||
{
|
||||
std::ios_base::openmode mode = std::ios_base::trunc;
|
||||
if (name[0] == '>' && name[1] == '>')
|
||||
{
|
||||
mode = std::ios_base::app;
|
||||
append_ = true;
|
||||
name += 2;
|
||||
}
|
||||
if (force_append)
|
||||
append_ = true;
|
||||
if (append_)
|
||||
mode = std::ios_base::app;
|
||||
if (name[0] == '-' && name[1] == 0)
|
||||
{
|
||||
os_ = &std::cout;
|
||||
return;
|
||||
}
|
||||
of_ = new std::ofstream(name, mode);
|
||||
of_ = std::make_unique<std::ofstream>(name, mode);
|
||||
if (!*of_)
|
||||
error(2, errno, "cannot open '%s'", name);
|
||||
os_ = of_;
|
||||
os_ = of_.get();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
// Copyright (C) 2015-2016, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -21,27 +21,22 @@
|
|||
|
||||
#include "common_sys.hh"
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <error.h>
|
||||
|
||||
class output_file
|
||||
{
|
||||
std::ostream* os_;
|
||||
std::ofstream* of_ = nullptr;
|
||||
std::unique_ptr<std::ofstream> of_;
|
||||
bool append_ = false;
|
||||
public:
|
||||
// Open a file for output. "-" is interpreted as stdout.
|
||||
// Names that start with ">>" are opened for append.
|
||||
// The function calls error() on... error.
|
||||
output_file(const char* name);
|
||||
output_file(const char* name, bool force_append = false);
|
||||
|
||||
void close(const std::string& name);
|
||||
|
||||
~output_file()
|
||||
{
|
||||
delete of_;
|
||||
}
|
||||
|
||||
bool append() const
|
||||
{
|
||||
return append_;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2017, 2019, 2021 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2017, 2019, 2021-2023 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -68,10 +68,10 @@ parse_opt_finput(int key, char* arg, struct argp_state*)
|
|||
switch (key)
|
||||
{
|
||||
case 'f':
|
||||
jobs.emplace_back(arg, false);
|
||||
jobs.emplace_back(arg, job_type::LTL_STRING);
|
||||
break;
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||||
break;
|
||||
case OPT_LBT:
|
||||
lbt_input = true;
|
||||
|
|
@ -96,12 +96,6 @@ parse_formula(const std::string& s)
|
|||
(s, spot::default_environment::instance(), false, lenient);
|
||||
}
|
||||
|
||||
job_processor::job_processor()
|
||||
: abort_run(false), real_filename(nullptr),
|
||||
col_to_read(0), prefix(nullptr), suffix(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
job_processor::~job_processor()
|
||||
{
|
||||
if (real_filename)
|
||||
|
|
@ -303,8 +297,22 @@ job_processor::process_stream(std::istream& is,
|
|||
}
|
||||
|
||||
int
|
||||
job_processor::process_file(const char* filename)
|
||||
job_processor::process_aut_file(const char*)
|
||||
{
|
||||
throw std::runtime_error("process_aut_file not defined for this tool");
|
||||
}
|
||||
|
||||
int
|
||||
job_processor::process_tlsf_file(const char*)
|
||||
{
|
||||
throw std::runtime_error("process_tlsf_file not defined for this tool");
|
||||
}
|
||||
|
||||
int
|
||||
job_processor::process_ltl_file(const char* filename)
|
||||
{
|
||||
col_to_read = 0;
|
||||
|
||||
// Special case for stdin.
|
||||
if (filename[0] == '-' && filename[1] == 0)
|
||||
return process_stream(std::cin, filename);
|
||||
|
|
@ -356,12 +364,25 @@ int
|
|||
job_processor::run()
|
||||
{
|
||||
int error = 0;
|
||||
for (auto& j: jobs)
|
||||
for (const auto& j: jobs)
|
||||
{
|
||||
if (!j.file_p)
|
||||
error |= process_string(j.str);
|
||||
else
|
||||
error |= process_file(j.str);
|
||||
switch (j.type)
|
||||
{
|
||||
case job_type::LTL_STRING:
|
||||
error |= process_string(j.str);
|
||||
break;
|
||||
case job_type::LTL_FILENAME:
|
||||
error |= process_ltl_file(j.str);
|
||||
break;
|
||||
case job_type::AUT_FILENAME:
|
||||
error |= process_aut_file(j.str);
|
||||
break;
|
||||
case job_type::TLSF_FILENAME:
|
||||
error |= process_tlsf_file(j.str);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("unexpected job type");
|
||||
}
|
||||
if (abort_run)
|
||||
break;
|
||||
}
|
||||
|
|
@ -376,7 +397,7 @@ void check_no_formula()
|
|||
error(2, 0, "No formula to translate? Run '%s --help' for help.\n"
|
||||
"Use '%s -' to force reading formulas from the standard "
|
||||
"input.", program_name, program_name);
|
||||
jobs.emplace_back("-", true);
|
||||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
||||
}
|
||||
|
||||
void check_no_automaton()
|
||||
|
|
@ -387,5 +408,5 @@ void check_no_automaton()
|
|||
error(2, 0, "No automaton to process? Run '%s --help' for help.\n"
|
||||
"Use '%s -' to force reading automata from the standard "
|
||||
"input.", program_name, program_name);
|
||||
jobs.emplace_back("-", true);
|
||||
jobs.emplace_back("-", job_type::AUT_FILENAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2017 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2017, 2022, 2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -25,13 +25,18 @@
|
|||
#include <vector>
|
||||
#include <spot/tl/parse.hh>
|
||||
|
||||
enum class job_type : char { LTL_STRING,
|
||||
LTL_FILENAME,
|
||||
AUT_FILENAME,
|
||||
TLSF_FILENAME };
|
||||
|
||||
struct job
|
||||
{
|
||||
const char* str;
|
||||
bool file_p; // true if str is a filename, false if it is a formula
|
||||
job_type type;
|
||||
|
||||
job(const char* str, bool file_p) noexcept
|
||||
: str(str), file_p(file_p)
|
||||
job(const char* str, job_type type) noexcept
|
||||
: str(str), type(type)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
@ -51,9 +56,11 @@ spot::parsed_formula parse_formula(const std::string& s);
|
|||
class job_processor
|
||||
{
|
||||
protected:
|
||||
bool abort_run; // Set to true in process_formula() to abort run().
|
||||
bool abort_run = false; // Set to true in process_formula() to abort run().
|
||||
public:
|
||||
job_processor();
|
||||
job_processor() = default;
|
||||
job_processor(const job_processor&) = delete;
|
||||
job_processor& operator=(const job_processor&) = delete;
|
||||
|
||||
virtual ~job_processor();
|
||||
|
||||
|
|
@ -68,15 +75,21 @@ public:
|
|||
process_stream(std::istream& is, const char* filename);
|
||||
|
||||
virtual int
|
||||
process_file(const char* filename);
|
||||
process_ltl_file(const char* filename);
|
||||
|
||||
virtual int
|
||||
process_aut_file(const char* filename);
|
||||
|
||||
virtual int
|
||||
process_tlsf_file(const char* filename);
|
||||
|
||||
virtual int
|
||||
run();
|
||||
|
||||
char* real_filename;
|
||||
long int col_to_read;
|
||||
char* prefix;
|
||||
char* suffix;
|
||||
char* real_filename = nullptr;
|
||||
long int col_to_read = 0;
|
||||
char* prefix = nullptr;
|
||||
char* suffix = nullptr;
|
||||
};
|
||||
|
||||
// Report and error message or add a default job depending on whether
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2017, 2018 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE).
|
||||
// Copyright (C) 2015, 2017, 2018, 2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -80,8 +80,10 @@ public:
|
|||
}
|
||||
|
||||
int
|
||||
process_file(const char* filename) override
|
||||
process_aut_file(const char* filename) override
|
||||
{
|
||||
col_to_read = 0;
|
||||
|
||||
// If we have a filename like "foo/NN" such
|
||||
// that:
|
||||
// ① foo/NN is not a file,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2012-2019, 2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#include "common_setup.hh"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/tl/length.hh>
|
||||
#include <spot/tl/apcollect.hh>
|
||||
|
|
@ -297,9 +298,9 @@ namespace
|
|||
};
|
||||
}
|
||||
|
||||
static formula_printer* format = nullptr;
|
||||
static std::unique_ptr<formula_printer> format;
|
||||
static std::ostringstream outputname;
|
||||
static formula_printer* outputnamer = nullptr;
|
||||
static std::unique_ptr<formula_printer> outputnamer;
|
||||
static std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||
|
||||
int
|
||||
|
|
@ -320,7 +321,7 @@ parse_opt_output(int key, char* arg, struct argp_state*)
|
|||
output_format = lbt_output;
|
||||
break;
|
||||
case 'o':
|
||||
outputnamer = new formula_printer(outputname, arg);
|
||||
outputnamer = std::make_unique<formula_printer>(outputname, arg);
|
||||
break;
|
||||
case 'p':
|
||||
full_parenth = true;
|
||||
|
|
@ -341,8 +342,7 @@ parse_opt_output(int key, char* arg, struct argp_state*)
|
|||
output_format = wring_output;
|
||||
break;
|
||||
case OPT_FORMAT:
|
||||
delete format;
|
||||
format = new formula_printer(std::cout, arg);
|
||||
format = std::make_unique<formula_printer>(std::cout, arg);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
|
|
@ -417,10 +417,10 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
|||
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
||||
outputnamer->print(fl, ptimer);
|
||||
std::string fname = outputname.str();
|
||||
auto p = outputfiles.emplace(fname, nullptr);
|
||||
if (p.second)
|
||||
p.first->second.reset(new output_file(fname.c_str()));
|
||||
out = &p.first->second->ostream();
|
||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
||||
if (b)
|
||||
it->second.reset(new output_file(fname.c_str()));
|
||||
out = &it->second->ostream();
|
||||
}
|
||||
output_formula(*out, f, ptimer, filename, linenum, prefix, suffix);
|
||||
*out << output_terminator;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2014, 2016 Laboratoire de Recherche et
|
||||
// Copyright (C) 2012, 2014, 2016, 2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -36,13 +36,17 @@ parse_range(const char* str, int missing_left, int missing_right)
|
|||
{
|
||||
range res;
|
||||
char* end;
|
||||
res.min = strtol(str, &end, 10);
|
||||
errno = 0;
|
||||
long lres = strtol(str, &end, 10);
|
||||
res.min = lres;
|
||||
if (res.min != lres || errno == ERANGE)
|
||||
error(2, 0, "start of range '%s' is too large for an int.", str);
|
||||
if (end == str)
|
||||
{
|
||||
// No leading number. It's OK as long as the string is not
|
||||
// empty.
|
||||
if (!*end)
|
||||
error(1, 0, "invalid empty range");
|
||||
error(2, 0, "invalid empty range");
|
||||
res.min = missing_left;
|
||||
}
|
||||
if (!*end)
|
||||
|
|
@ -66,19 +70,23 @@ parse_range(const char* str, int missing_left, int missing_right)
|
|||
{
|
||||
// Parse the next integer.
|
||||
char* end2;
|
||||
res.max = strtol(end, &end2, 10);
|
||||
errno = 0;
|
||||
lres = strtol(end, &end2, 10);
|
||||
res.max = lres;
|
||||
if (res.max != lres || errno == ERANGE)
|
||||
error(2, 0, "end of range '%s' is too large for an int.", str);
|
||||
if (str == end2)
|
||||
error(1, 0, "invalid range '%s' "
|
||||
error(2, 0, "invalid range '%s' "
|
||||
"(should start with digits, dots, or colon)", str);
|
||||
if (end == end2)
|
||||
error(1, 0, "invalid range '%s' (missing end?)", str);
|
||||
error(2, 0, "invalid range '%s' (missing end?)", str);
|
||||
if (*end2)
|
||||
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
|
||||
error(2, 0, "invalid range '%s' (trailing garbage?)", str);
|
||||
}
|
||||
}
|
||||
|
||||
if (res.min < 0 || res.max < 0)
|
||||
error(1, 0, "invalid range '%s': values must be positive", str);
|
||||
error(2, 0, "invalid range '%s': values must be positive", str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2022 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -20,13 +20,14 @@
|
|||
#include "common_setup.hh"
|
||||
#include "common_aoutput.hh"
|
||||
|
||||
#include "argp.h"
|
||||
#include "closeout.h"
|
||||
#include <argp.h>
|
||||
#include <closeout.h>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <error.h>
|
||||
#include <spot/misc/tmpfile.hh>
|
||||
|
||||
static void
|
||||
|
|
@ -35,7 +36,7 @@ display_version(FILE *stream, struct argp_state*)
|
|||
fputs(program_name, stream);
|
||||
fputs(" (" PACKAGE_NAME ") " PACKAGE_VERSION "\n\
|
||||
\n\
|
||||
Copyright (C) 2022 Laboratoire de Recherche et Développement de l'Epita.\n\
|
||||
Copyright (C) 2023 Laboratoire de Recherche de l'Epita (LRE)\n\
|
||||
License GPLv3+: \
|
||||
GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
|
||||
This is free software: you are free to change and redistribute it.\n\
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2018, 2019 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2013, 2018-2019, 2023 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -34,5 +34,5 @@ int protected_main(char** progname, std::function<int()> mainfun);
|
|||
|
||||
// Diagnose exceptions.
|
||||
[[noreturn]] void handle_any_exception();
|
||||
#define BEGIN_EXCEPTION_PROTECT try { (void)0;
|
||||
#define BEGIN_EXCEPTION_PROTECT try { (void)0
|
||||
#define END_EXCEPTION_PROTECT } catch (...) { handle_any_exception(); }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2022 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2015-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#if __has_include(<spawn.h>)
|
||||
#define HAVE_SPAWN_H 1
|
||||
#include <spawn.h>
|
||||
|
|
@ -52,7 +53,7 @@ struct shorthands_t
|
|||
};
|
||||
#define SHORTHAND(PRE, POST) { PRE, std::regex("^" PRE), POST }
|
||||
|
||||
static shorthands_t shorthands_ltl[] = {
|
||||
static const shorthands_t shorthands_ltl[] = {
|
||||
SHORTHAND("delag", " %f>%O"),
|
||||
SHORTHAND("lbt", " <%L>%O"),
|
||||
SHORTHAND("ltl2ba", " -f %s>%O"),
|
||||
|
|
@ -72,7 +73,7 @@ static shorthands_t shorthands_ltl[] = {
|
|||
SHORTHAND("owl.* ltl-utilities\\b", " -f %f"),
|
||||
};
|
||||
|
||||
static shorthands_t shorthands_autproc[] = {
|
||||
static const shorthands_t shorthands_autproc[] = {
|
||||
SHORTHAND("autfilt", " %H>%O"),
|
||||
SHORTHAND("dra2dpa", " <%H>%O"),
|
||||
SHORTHAND("dstar2tgba", " %H>%O"),
|
||||
|
|
@ -84,7 +85,7 @@ static shorthands_t shorthands_autproc[] = {
|
|||
" <%H>%O"),
|
||||
};
|
||||
|
||||
static void show_shorthands(shorthands_t* begin, shorthands_t* end)
|
||||
static void show_shorthands(const shorthands_t* begin, const shorthands_t* end)
|
||||
{
|
||||
std::cout
|
||||
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
|
||||
|
|
@ -99,7 +100,8 @@ static void show_shorthands(shorthands_t* begin, shorthands_t* end)
|
|||
}
|
||||
|
||||
|
||||
tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
||||
tool_spec::tool_spec(const char* spec,
|
||||
const shorthands_t* begin, const shorthands_t* end,
|
||||
bool is_ref) noexcept
|
||||
: spec(spec), cmd(spec), name(spec), reference(is_ref)
|
||||
{
|
||||
|
|
@ -112,15 +114,15 @@ tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
|||
{
|
||||
if (*pos == '{')
|
||||
++count;
|
||||
else if (*pos == '}')
|
||||
if (!--count)
|
||||
{
|
||||
name = strndup(cmd + 1, pos - cmd - 1);
|
||||
cmd = pos + 1;
|
||||
while (*cmd == ' ' || *cmd == '\t')
|
||||
++cmd;
|
||||
break;
|
||||
}
|
||||
else if (*pos == '}' && --count == 0)
|
||||
{
|
||||
name = strndup(cmd + 1, pos - cmd - 1);
|
||||
cmd = pos + 1;
|
||||
// skip leading whitespace
|
||||
while (*cmd == ' ' || *cmd == '\t')
|
||||
++cmd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there is no % in the string, look for a known
|
||||
|
|
@ -146,11 +148,11 @@ tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
|||
auto& p = *begin++;
|
||||
if (std::regex_search(basename, p.rprefix))
|
||||
{
|
||||
int m = strlen(p.suffix);
|
||||
int q = strlen(cmd);
|
||||
size_t m = strlen(p.suffix);
|
||||
size_t q = strlen(cmd);
|
||||
char* tmp = static_cast<char*>(malloc(q + m + 1));
|
||||
strcpy(tmp, cmd);
|
||||
strcpy(tmp + q, p.suffix);
|
||||
memcpy(tmp, cmd, q);
|
||||
memcpy(tmp + q, p.suffix, m + 1);
|
||||
cmd = tmp;
|
||||
allocated = true;
|
||||
break;
|
||||
|
|
@ -461,6 +463,92 @@ autproc_runner::round_automaton(spot::const_twa_graph_ptr aut, unsigned serial)
|
|||
filename_automaton.new_round(aut, serial);
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
read_stdout_of_command(char* const* args)
|
||||
{
|
||||
#if HAVE_SPAWN_H
|
||||
int cout_pipe[2];
|
||||
if (int err = pipe(cout_pipe))
|
||||
error(2, err, "pipe() failed");
|
||||
|
||||
posix_spawn_file_actions_t actions;
|
||||
if (int err = posix_spawn_file_actions_init(&actions))
|
||||
error(2, err, "posix_spawn_file_actions_init() failed");
|
||||
|
||||
posix_spawn_file_actions_addclose(&actions, STDIN_FILENO);
|
||||
posix_spawn_file_actions_addclose(&actions, cout_pipe[0]);
|
||||
posix_spawn_file_actions_adddup2(&actions, cout_pipe[1], STDOUT_FILENO);
|
||||
posix_spawn_file_actions_addclose(&actions, cout_pipe[1]);
|
||||
|
||||
pid_t pid;
|
||||
if (int err = posix_spawnp(&pid, args[0], &actions, nullptr, args, environ))
|
||||
error(2, err, "failed to run '%s'", args[0]);
|
||||
|
||||
if (int err = posix_spawn_file_actions_destroy(&actions))
|
||||
error(2, err, "posix_spawn_file_actions_destroy() failed");
|
||||
|
||||
if (close(cout_pipe[1]) < 0)
|
||||
error(2, errno, "closing write-side of pipe failed");
|
||||
|
||||
std::string results;
|
||||
ssize_t bytes_read;
|
||||
for (;;)
|
||||
{
|
||||
static char buffer[512];
|
||||
bytes_read = read(cout_pipe[0], buffer, sizeof(buffer));
|
||||
if (bytes_read > 0)
|
||||
results.insert(results.end(), buffer, buffer + bytes_read);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (bytes_read < 0)
|
||||
error(2, bytes_read, "failed to read from pipe");
|
||||
|
||||
if (cout_pipe[0] < 0)
|
||||
error(2, errno, "closing read-side of pipe failed");
|
||||
|
||||
int exit_code = 0;
|
||||
if (waitpid(pid, &exit_code, 0) == -1)
|
||||
error(2, errno, "waitpid() failed");
|
||||
|
||||
if (exit_code)
|
||||
error(2, 0, "'%s' exited with status %d", args[0], exit_code);
|
||||
|
||||
return results;
|
||||
#else
|
||||
// We could provide a pipe+fork+exec alternative implementation, but
|
||||
// systems without posix_spawn() might also not have fork and exec.
|
||||
// For instance MinGW does not. So let's fallback to system+tmpfile
|
||||
// instead for maximum portability.
|
||||
char prefix[30];
|
||||
snprintf(prefix, sizeof prefix, "spot-tmp");
|
||||
spot::temporary_file* tmpfile = spot::create_tmpfile(prefix);
|
||||
std::string tmpname = tmpfile->name();
|
||||
std::ostringstream cmd;
|
||||
for (auto t = args; *t != nullptr; ++t)
|
||||
spot::quote_shell_string(cmd, *t) << ' ';
|
||||
cmd << '>';
|
||||
spot::quote_shell_string(cmd, tmpfile->name());
|
||||
std::string cmdstr = cmd.str();
|
||||
int exit_code = system(cmdstr.c_str());
|
||||
if (exit_code < 0)
|
||||
error(2, errno, "failed to execute %s", cmdstr.c_str());
|
||||
if (exit_code > 0)
|
||||
error(2, 0, "'%s' exited with status %d", args[0], exit_code);
|
||||
|
||||
std::ifstream ifs(tmpname, std::ifstream::in);
|
||||
if (!ifs)
|
||||
error(2, 0, "failed to open %s (output of %s)", tmpname.c_str(), args[0]);
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
std::stringstream buffer;
|
||||
buffer << ifs.rdbuf();
|
||||
delete tmpfile;
|
||||
return buffer.str();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::atomic<bool> timed_out{false};
|
||||
unsigned timeout_count = 0;
|
||||
|
||||
|
|
@ -524,7 +612,7 @@ get_arg(const char*& cmd)
|
|||
{
|
||||
const char* start = cmd;
|
||||
std::string arg;
|
||||
while (int c = *cmd)
|
||||
while (char c = *cmd)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -554,14 +642,14 @@ get_arg(const char*& cmd)
|
|||
goto end_loop;
|
||||
case '\'':
|
||||
{
|
||||
int d = 0;
|
||||
char d = '\0';
|
||||
while ((d = *++cmd))
|
||||
{
|
||||
if (d == '\'')
|
||||
break;
|
||||
arg.push_back(d);
|
||||
}
|
||||
if (d == 0)
|
||||
if (d == '\0')
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
|
|
@ -706,6 +794,7 @@ parse_simple_command(const char* cmd)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_SPAWN_H
|
||||
static void
|
||||
exec_command(const char* cmd)
|
||||
|
|
@ -751,8 +840,6 @@ exec_command(const char* cmd)
|
|||
SPOT_UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2018, 2020 Laboratoire de Recherche et
|
||||
// Copyright (C) 2015-2018, 2020, 2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -51,7 +51,8 @@ struct tool_spec
|
|||
// Whether the tool is a reference.
|
||||
bool reference;
|
||||
|
||||
tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
||||
tool_spec(const char* spec,
|
||||
const shorthands_t* begin, const shorthands_t* end,
|
||||
bool is_ref) noexcept;
|
||||
tool_spec(const tool_spec& other) noexcept;
|
||||
tool_spec& operator=(const tool_spec& other);
|
||||
|
|
@ -71,7 +72,7 @@ struct quoted_formula final: public spot::printable_value<spot::formula>
|
|||
|
||||
struct filed_formula final: public spot::printable
|
||||
{
|
||||
filed_formula(const quoted_formula& ltl) : f_(ltl)
|
||||
explicit filed_formula(const quoted_formula& ltl) : f_(ltl)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -89,9 +90,7 @@ struct filed_formula final: public spot::printable
|
|||
|
||||
struct filed_automaton final: public spot::printable
|
||||
{
|
||||
filed_automaton()
|
||||
{
|
||||
}
|
||||
filed_automaton() = default;
|
||||
|
||||
void print(std::ostream& os, const char* pos) const override;
|
||||
|
||||
|
|
@ -112,7 +111,7 @@ struct printable_result_filename final:
|
|||
unsigned translator_num;
|
||||
|
||||
printable_result_filename();
|
||||
~printable_result_filename();
|
||||
~printable_result_filename() override;
|
||||
void reset(unsigned n);
|
||||
void cleanup();
|
||||
|
||||
|
|
@ -126,7 +125,7 @@ protected:
|
|||
spot::bdd_dict_ptr dict;
|
||||
// Round-specific variables
|
||||
quoted_formula ltl_formula;
|
||||
filed_formula filename_formula = ltl_formula;
|
||||
filed_formula filename_formula{ltl_formula};
|
||||
// Run-specific variables
|
||||
printable_result_filename output;
|
||||
public:
|
||||
|
|
@ -151,9 +150,9 @@ protected:
|
|||
public:
|
||||
using spot::formater::has;
|
||||
|
||||
autproc_runner(// whether we accept the absence of output
|
||||
// specifier
|
||||
bool no_output_allowed = false);
|
||||
explicit autproc_runner(// whether we accept the absence of output
|
||||
// specifier
|
||||
bool no_output_allowed = false);
|
||||
void round_automaton(spot::const_twa_graph_ptr aut, unsigned serial);
|
||||
};
|
||||
|
||||
|
|
@ -175,3 +174,9 @@ int exec_with_timeout(const char* cmd);
|
|||
#define exec_with_timeout(cmd) system(cmd)
|
||||
#define setup_sig_handler() while (0);
|
||||
#endif // !ENABLE_TIMEOUT
|
||||
|
||||
// Run a command (whose args[0], args[1], etc. are given by args), and
|
||||
// return its captured stdout. Stderr is not captured. Will abort
|
||||
// with an error message if the command is not found, or if it exit
|
||||
// with a non-zero status code.
|
||||
std::string read_stdout_of_command(char* const* args);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2019 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2013-2019, 2022, 2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
#include <spot/parseaut/public.hh>
|
||||
#include <spot/twaalgos/sccinfo.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Convert automata with any acceptance condition into variants of \
|
||||
Büchi automata.\n\nThis reads automata into any supported format \
|
||||
(HOA, LBTT, ltl2dstar, never claim) and outputs a \
|
||||
|
|
@ -89,7 +89,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
switch (key)
|
||||
{
|
||||
case 'F':
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
|
|
@ -99,7 +99,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
}
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
|
|
@ -117,7 +117,7 @@ namespace
|
|||
spot::postprocessor& post;
|
||||
automaton_printer printer;
|
||||
|
||||
dstar_processor(spot::postprocessor& post)
|
||||
explicit dstar_processor(spot::postprocessor& post)
|
||||
: hoa_processor(spot::make_bdd_dict()), post(post), printer(aut_input)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017-2019 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2017-2019, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -43,7 +43,8 @@
|
|||
|
||||
using namespace spot;
|
||||
|
||||
const char argp_program_doc[] ="Generate ω-automata from predefined patterns.";
|
||||
static const char argp_program_doc[] =
|
||||
"Generate ω-automata from predefined patterns.";
|
||||
|
||||
static const argp_option options[] =
|
||||
{
|
||||
|
|
@ -62,6 +63,11 @@ static const argp_option options[] =
|
|||
{ "m-nba", gen::AUT_M_NBA, "RANGE", 0,
|
||||
"An NBA with N+1 states whose determinization needs at least "
|
||||
"N! states", 0},
|
||||
{ "cyclist-trace-nba", gen::AUT_CYCLIST_TRACE_NBA, "RANGE", 0,
|
||||
"An NBA with N+2 states that should include cyclist-proof-dba=B.", 0},
|
||||
{ "cyclist-proof-dba", gen::AUT_CYCLIST_PROOF_DBA, "RANGE", 0,
|
||||
"A DBA with N+2 states that should be included "
|
||||
"in cyclist-trace-nba=B.", 0},
|
||||
RANGE_DOC,
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
|
|
@ -122,7 +128,7 @@ output_pattern(gen::aut_pattern_id pattern, int n)
|
|||
static void
|
||||
run_jobs()
|
||||
{
|
||||
for (auto& j: jobs)
|
||||
for (const auto& j: jobs)
|
||||
{
|
||||
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
||||
int n = j.range.min;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012, 2013, 2015-2019 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2012, 2013, 2015-2019, 2022-2023 Laboratoire de
|
||||
// Recherche et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
using namespace spot;
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Generate temporal logic formulas from predefined patterns.";
|
||||
|
||||
// We reuse the values from gen::ltl_pattern_id as option keys.
|
||||
|
|
@ -84,6 +84,8 @@ static const argp_option options[] =
|
|||
{ "eh-patterns", gen::LTL_EH_PATTERNS, "RANGE", OPTION_ARG_OPTIONAL,
|
||||
"Etessami and Holzmann [Concur'00] patterns "
|
||||
"(range should be included in 1..12)", 0 },
|
||||
{ "eil-gsi", gen::LTL_EIL_GSI, "RANGE", 0,
|
||||
"G[0..n]((a S b) -> c) rewritten using future operators", 0 },
|
||||
{ "fxg-or", gen::LTL_FXG_OR, "RANGE", 0,
|
||||
"F(p0 | XG(p1 | XG(p2 | ... XG(pn))))", 0},
|
||||
{ "gf-equiv", gen::LTL_GF_EQUIV, "RANGE", 0,
|
||||
|
|
@ -315,7 +317,7 @@ output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
|||
static void
|
||||
run_jobs()
|
||||
{
|
||||
for (auto& j: jobs)
|
||||
for (const auto& j: jobs)
|
||||
{
|
||||
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
||||
int n = j.range.min;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2019, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
#include <spot/misc/optionmap.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
|
||||
static const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Translate linear-time formulas (LTL/PSL) into various types of automata.\n\n\
|
||||
By default it will apply all available optimizations to output \
|
||||
the smallest Transition-based Generalized Büchi Automata, \
|
||||
|
|
@ -105,10 +105,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
if (*arg == '-' && !arg[1])
|
||||
jobs.emplace_back(arg, true);
|
||||
else
|
||||
jobs.emplace_back(arg, false);
|
||||
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
|
||||
? job_type::LTL_FILENAME
|
||||
: job_type::LTL_STRING));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -125,10 +124,10 @@ namespace
|
|||
{
|
||||
public:
|
||||
spot::translator& trans;
|
||||
automaton_printer printer;
|
||||
automaton_printer printer{ltl_input};
|
||||
|
||||
trans_processor(spot::translator& trans)
|
||||
: trans(trans), printer(ltl_input)
|
||||
explicit trans_processor(spot::translator& trans)
|
||||
: trans(trans)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2020, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
#include <spot/taalgos/minimize.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Translate linear-time formulas (LTL/PSL) into Testing Automata.\n\n\
|
||||
By default it outputs a transition-based generalized Testing Automaton \
|
||||
the smallest Transition-based Generalized Büchi Automata, \
|
||||
|
|
@ -148,10 +148,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
if (*arg == '-' && !arg[1])
|
||||
jobs.emplace_back(arg, true);
|
||||
else
|
||||
jobs.emplace_back(arg, false);
|
||||
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
|
||||
? job_type::LTL_FILENAME
|
||||
: job_type::LTL_STRING));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -169,7 +168,7 @@ namespace
|
|||
public:
|
||||
spot::translator& trans;
|
||||
|
||||
trans_processor(spot::translator& trans)
|
||||
explicit trans_processor(spot::translator& trans)
|
||||
: trans(trans)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2020, 2022, 2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
#include <spot/misc/tmpfile.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Call several LTL/PSL translators and cross-compare their output to detect \
|
||||
bugs, or to gather statistics. The list of formulas to use should be \
|
||||
supplied on standard input, or using the -f or -F options.\v\
|
||||
|
|
@ -264,55 +264,32 @@ end_error()
|
|||
|
||||
struct statistics
|
||||
{
|
||||
statistics()
|
||||
: ok(false),
|
||||
alternating(false),
|
||||
status_str(nullptr),
|
||||
status_code(0),
|
||||
time(0),
|
||||
states(0),
|
||||
edges(0),
|
||||
transitions(0),
|
||||
acc(0),
|
||||
scc(0),
|
||||
nonacc_scc(0),
|
||||
terminal_scc(0),
|
||||
weak_scc(0),
|
||||
strong_scc(0),
|
||||
nondetstates(0),
|
||||
nondeterministic(false),
|
||||
terminal_aut(false),
|
||||
weak_aut(false),
|
||||
strong_aut(false)
|
||||
{
|
||||
}
|
||||
|
||||
// If OK is false, only the status_str, status_code, and time fields
|
||||
// should be valid.
|
||||
bool ok;
|
||||
bool alternating;
|
||||
const char* status_str;
|
||||
int status_code;
|
||||
double time;
|
||||
unsigned states;
|
||||
unsigned edges;
|
||||
unsigned long long transitions;
|
||||
unsigned acc;
|
||||
unsigned scc;
|
||||
unsigned nonacc_scc;
|
||||
unsigned terminal_scc;
|
||||
unsigned weak_scc;
|
||||
unsigned strong_scc;
|
||||
unsigned nondetstates;
|
||||
bool nondeterministic;
|
||||
bool terminal_aut;
|
||||
bool weak_aut;
|
||||
bool strong_aut;
|
||||
bool ok = false;
|
||||
bool alternating = false;
|
||||
const char* status_str = nullptr;
|
||||
int status_code = 0;
|
||||
double time = 0.0;
|
||||
unsigned states = 0;
|
||||
unsigned edges = 0;
|
||||
unsigned long long transitions = 0;
|
||||
unsigned acc = 0;
|
||||
unsigned scc = 0;
|
||||
unsigned nonacc_scc = 0;
|
||||
unsigned terminal_scc = 0;
|
||||
unsigned weak_scc = 0;
|
||||
unsigned strong_scc = 0;
|
||||
unsigned nondetstates = 0;
|
||||
bool nondeterministic = false;
|
||||
bool terminal_aut = false;
|
||||
bool weak_aut = false;
|
||||
bool strong_aut = false;
|
||||
std::vector<double> product_states;
|
||||
std::vector<double> product_transitions;
|
||||
std::vector<double> product_scc;
|
||||
bool ambiguous;
|
||||
bool complete;
|
||||
bool ambiguous = false;
|
||||
bool complete = false;
|
||||
std::string hoa_str;
|
||||
|
||||
static void
|
||||
|
|
@ -484,7 +461,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (arg[0] == '-' && !arg[1])
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||||
else
|
||||
tools_push_trans(arg);
|
||||
break;
|
||||
|
|
@ -581,7 +558,7 @@ namespace
|
|||
class xtranslator_runner final: public translator_runner
|
||||
{
|
||||
public:
|
||||
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||
: translator_runner(dict)
|
||||
{
|
||||
}
|
||||
|
|
@ -1095,17 +1072,14 @@ namespace
|
|||
}
|
||||
|
||||
// Make sure we do not translate the same formula twice.
|
||||
if (!allow_dups)
|
||||
if (!allow_dups && !unique_set.insert(f).second)
|
||||
{
|
||||
if (!unique_set.insert(f).second)
|
||||
{
|
||||
if (!quiet)
|
||||
std::cerr
|
||||
<< ("warning: This formula or its negation has already"
|
||||
" been checked.\n Use --allow-dups if it "
|
||||
"should not be ignored.\n\n");
|
||||
return 0;
|
||||
}
|
||||
if (!quiet)
|
||||
std::cerr
|
||||
<< ("warning: This formula or its negation has already"
|
||||
" been checked.\n Use --allow-dups if it "
|
||||
"should not be ignored.\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int problems = 0;
|
||||
|
|
|
|||
18
bin/ltldo.cc
18
bin/ltldo.cc
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2020 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2015-2020, 2022-2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
#include <spot/twaalgos/totgba.hh>
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Run LTL/PSL formulas through another program, performing conversion\n\
|
||||
of input and output as required.";
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (arg[0] == '-' && !arg[1])
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||||
else
|
||||
tools_push_trans(arg);
|
||||
break;
|
||||
|
|
@ -209,7 +209,7 @@ namespace
|
|||
class xtranslator_runner final: public translator_runner
|
||||
{
|
||||
public:
|
||||
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||
: translator_runner(dict, true)
|
||||
{
|
||||
}
|
||||
|
|
@ -224,8 +224,6 @@ namespace
|
|||
format(command, tools[translator_num].cmd);
|
||||
|
||||
std::string cmd = command.str();
|
||||
//std::cerr << "Running [" << l << translator_num << "]: "
|
||||
// << cmd << std::endl;
|
||||
timer.start();
|
||||
int es = exec_with_timeout(cmd.c_str());
|
||||
timer.stop();
|
||||
|
|
@ -312,7 +310,7 @@ namespace
|
|||
spot::printable_value<std::string> inputf;
|
||||
|
||||
public:
|
||||
processor(spot::postprocessor& post)
|
||||
explicit processor(spot::postprocessor& post)
|
||||
: runner(dict), best_printer(best_stream, best_format), post(post)
|
||||
{
|
||||
printer.add_stat('T', &cmdname);
|
||||
|
|
@ -323,9 +321,7 @@ namespace
|
|||
best_printer.declare('f', &inputf);
|
||||
}
|
||||
|
||||
~processor()
|
||||
{
|
||||
}
|
||||
~processor() override = default;
|
||||
|
||||
int
|
||||
process_string(const std::string& input,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
#include <spot/misc/hash.hh>
|
||||
#include <spot/misc/timer.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/tl/sonf.hh>
|
||||
#include <spot/tl/length.hh>
|
||||
#include <spot/tl/relabel.hh>
|
||||
#include <spot/tl/unabbrev.hh>
|
||||
|
|
@ -58,7 +59,7 @@
|
|||
#include <spot/twaalgos/totgba.hh>
|
||||
#include <spot/twaalgos/word.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Read a list of formulas and output them back after some optional processing.\v\
|
||||
Exit status:\n\
|
||||
0 if some formulas were output (skipped syntax errors do not count)\n\
|
||||
|
|
@ -100,6 +101,8 @@ enum {
|
|||
OPT_SIZE_MAX,
|
||||
OPT_SIZE_MIN,
|
||||
OPT_SKIP_ERRORS,
|
||||
OPT_SONF,
|
||||
OPT_SONF_APS,
|
||||
OPT_STUTTER_INSENSITIVE,
|
||||
OPT_SUSPENDABLE,
|
||||
OPT_SYNTACTIC_GUARANTEE,
|
||||
|
|
@ -127,6 +130,11 @@ static const argp_option options[] =
|
|||
{ "negate", OPT_NEGATE, nullptr, 0, "negate each formula", 0 },
|
||||
{ "nnf", OPT_NNF, nullptr, 0,
|
||||
"rewrite formulas in negative normal form", 0 },
|
||||
{ "sonf", OPT_SONF, "PREFIX", OPTION_ARG_OPTIONAL,
|
||||
"rewrite formulas in suffix operator normal form", 0 },
|
||||
{ "sonf-aps", OPT_SONF_APS, "FILENAME", OPTION_ARG_OPTIONAL,
|
||||
"when used with --sonf, output the newly introduced atomic "
|
||||
"propositions", 0 },
|
||||
{ "relabel", OPT_RELABEL, "abc|pnn", OPTION_ARG_OPTIONAL,
|
||||
"relabel all atomic propositions, alphabetically unless " \
|
||||
"specified otherwise", 0 },
|
||||
|
|
@ -316,6 +324,7 @@ static range opt_nth = { 0, std::numeric_limits<int>::max() };
|
|||
static int opt_max_count = -1;
|
||||
static long int match_count = 0;
|
||||
static const char* from_ltlf = nullptr;
|
||||
static const char* sonf = nullptr;
|
||||
|
||||
|
||||
// We want all these variables to be destroyed when we exit main, to
|
||||
|
|
@ -327,6 +336,7 @@ static struct opt_t
|
|||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||||
spot::exclusive_ap excl_ap;
|
||||
std::unique_ptr<output_file> output_define = nullptr;
|
||||
std::unique_ptr<output_file> output_sonf = nullptr;
|
||||
spot::formula implied_by = nullptr;
|
||||
spot::formula imply = nullptr;
|
||||
spot::formula equivalent_to = nullptr;
|
||||
|
|
@ -377,7 +387,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||||
break;
|
||||
case OPT_ACCEPT_WORD:
|
||||
try
|
||||
|
|
@ -460,6 +470,12 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
case OPT_NNF:
|
||||
nnf = true;
|
||||
break;
|
||||
case OPT_SONF:
|
||||
sonf = arg ? arg : "sonf_";
|
||||
break;
|
||||
case OPT_SONF_APS:
|
||||
opt->output_sonf.reset(new output_file(arg ? arg : "-"));
|
||||
break;
|
||||
case OPT_OBLIGATION:
|
||||
obligation = true;
|
||||
break;
|
||||
|
|
@ -570,7 +586,7 @@ namespace
|
|||
fset_t unique_set;
|
||||
spot::relabeling_map relmap;
|
||||
|
||||
ltl_processor(spot::tl_simplifier& simpl)
|
||||
explicit ltl_processor(spot::tl_simplifier& simpl)
|
||||
: simpl(simpl)
|
||||
{
|
||||
}
|
||||
|
|
@ -650,6 +666,25 @@ namespace
|
|||
if (nnf)
|
||||
f = simpl.negative_normal_form(f);
|
||||
|
||||
if (sonf != nullptr)
|
||||
{
|
||||
std::vector<std::string> new_aps;
|
||||
std::tie(f, new_aps) = suffix_operator_normal_form(f, sonf);
|
||||
|
||||
if (opt->output_sonf
|
||||
&& output_format != count_output
|
||||
&& output_format != quiet_output)
|
||||
{
|
||||
for (size_t i = 0; i < new_aps.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
opt->output_sonf->ostream() << ' ';
|
||||
opt->output_sonf->ostream() << new_aps[i];
|
||||
}
|
||||
opt->output_sonf->ostream() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
switch (relabeling)
|
||||
{
|
||||
case ApRelabeling:
|
||||
|
|
@ -687,7 +722,7 @@ namespace
|
|||
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
|
||||
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
|
||||
{
|
||||
auto s = atomic_prop_collect(f);
|
||||
spot::atomic_prop_set* s = atomic_prop_collect(f);
|
||||
int n = s->size();
|
||||
delete s;
|
||||
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
|
||||
|
|
@ -726,7 +761,7 @@ namespace
|
|||
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
|
||||
|
||||
if (matched && !opt->acc_words.empty())
|
||||
for (auto& word_aut: opt->acc_words)
|
||||
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
|
||||
if (spot::product(aut, word_aut)->is_empty())
|
||||
{
|
||||
matched = false;
|
||||
|
|
@ -734,7 +769,7 @@ namespace
|
|||
}
|
||||
|
||||
if (matched && !opt->rej_words.empty())
|
||||
for (auto& word_aut: opt->rej_words)
|
||||
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
|
||||
if (!spot::product(aut, word_aut)->is_empty())
|
||||
{
|
||||
matched = false;
|
||||
|
|
@ -808,12 +843,12 @@ namespace
|
|||
{
|
||||
// Sort the formulas alphabetically.
|
||||
std::map<std::string, spot::formula> m;
|
||||
for (auto& p: relmap)
|
||||
m.emplace(str_psl(p.first), p.second);
|
||||
for (auto& p: m)
|
||||
for (const auto& [newformula, oldname]: relmap)
|
||||
m.emplace(str_psl(newformula), oldname);
|
||||
for (const auto& [newname, oldname]: m)
|
||||
stream_formula(opt->output_define->ostream()
|
||||
<< "#define " << p.first << " (",
|
||||
p.second, filename,
|
||||
<< "#define " << newname << " (",
|
||||
oldname, filename,
|
||||
std::to_string(linenum).c_str()) << ")\n";
|
||||
}
|
||||
one_match = true;
|
||||
|
|
@ -841,7 +876,7 @@ main(int argc, char** argv)
|
|||
exit(err);
|
||||
|
||||
if (jobs.empty())
|
||||
jobs.emplace_back("-", 1);
|
||||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
||||
|
||||
if (boolean_to_isop && simplification_level == 0)
|
||||
simplification_level = 1;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et
|
||||
// Copyright (C) 2014-2019, 2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -143,7 +143,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
// FIXME: use stat() to distinguish filename from string?
|
||||
jobs.emplace_back(arg, true);
|
||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
||||
break;
|
||||
case OPT_AP2CONST:
|
||||
opt_all = 0;
|
||||
|
|
|
|||
557
bin/ltlsynt.cc
557
bin/ltlsynt.cc
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2017-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -23,8 +23,10 @@
|
|||
|
||||
#include "common_aoutput.hh"
|
||||
#include "common_finput.hh"
|
||||
#include "common_hoaread.hh"
|
||||
#include "common_setup.hh"
|
||||
#include "common_sys.hh"
|
||||
#include "common_trans.hh"
|
||||
|
||||
#include <spot/misc/bddlt.hh>
|
||||
#include <spot/misc/escape.hh>
|
||||
|
|
@ -35,6 +37,7 @@
|
|||
#include <spot/twaalgos/aiger.hh>
|
||||
#include <spot/twaalgos/game.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/minimize.hh>
|
||||
#include <spot/twaalgos/mealy_machine.hh>
|
||||
#include <spot/twaalgos/product.hh>
|
||||
|
|
@ -44,8 +47,12 @@
|
|||
enum
|
||||
{
|
||||
OPT_ALGO = 256,
|
||||
OPT_BYPASS,
|
||||
OPT_CSV,
|
||||
OPT_DECOMPOSE,
|
||||
OPT_DOT,
|
||||
OPT_FROM_PGAME,
|
||||
OPT_HIDE,
|
||||
OPT_INPUT,
|
||||
OPT_OUTPUT,
|
||||
OPT_PRINT,
|
||||
|
|
@ -53,6 +60,7 @@ enum
|
|||
OPT_PRINT_HOA,
|
||||
OPT_REAL,
|
||||
OPT_SIMPLIFY,
|
||||
OPT_TLSF,
|
||||
OPT_VERBOSE,
|
||||
OPT_VERIFY
|
||||
};
|
||||
|
|
@ -63,13 +71,19 @@ static const argp_option options[] =
|
|||
{ nullptr, 0, nullptr, 0, "Input options:", 1 },
|
||||
{ "outs", OPT_OUTPUT, "PROPS", 0,
|
||||
"comma-separated list of controllable (a.k.a. output) atomic"
|
||||
" propositions", 0},
|
||||
" propositions", 0 },
|
||||
{ "ins", OPT_INPUT, "PROPS", 0,
|
||||
"comma-separated list of controllable (a.k.a. output) atomic"
|
||||
" propositions", 0},
|
||||
"comma-separated list of uncontrollable (a.k.a. input) atomic"
|
||||
" propositions", 0 },
|
||||
{ "tlsf", OPT_TLSF, "FILENAME", 0,
|
||||
"Read a TLSF specification from FILENAME, and call syfco to "
|
||||
"convert it into LTL", 0 },
|
||||
{ "from-pgame", OPT_FROM_PGAME, "FILENAME", 0,
|
||||
"Read a parity game in Extended HOA format instead of building it.",
|
||||
0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Fine tuning:", 10 },
|
||||
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old", 0,
|
||||
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old|acd", 0,
|
||||
"choose the algorithm for synthesis:"
|
||||
" \"sd\": translate to tgba, split, then determinize;"
|
||||
" \"ds\": translate to tgba, determinize, then split;"
|
||||
|
|
@ -77,45 +91,60 @@ static const argp_option options[] =
|
|||
" \"lar\": translate to a deterministic automaton with arbitrary"
|
||||
" acceptance condition, then use LAR to turn to parity,"
|
||||
" then split (default);"
|
||||
" \"lar.old\": old version of LAR, for benchmarking.\n", 0 },
|
||||
" \"lar.old\": old version of LAR, for benchmarking;"
|
||||
" \"acd\": translate to a deterministic automaton with arbitrary"
|
||||
" acceptance condition, then use ACD to turn to parity,"
|
||||
" then split.\n", 0 },
|
||||
{ "bypass", OPT_BYPASS, "yes|no", 0,
|
||||
"whether to try to avoid to construct a parity game "
|
||||
"(enabled by default)", 0},
|
||||
{ "decompose", OPT_DECOMPOSE, "yes|no", 0,
|
||||
"whether to decompose the specification as multiple output-disjoint "
|
||||
"problems to solve independently (enabled by default)", 0 },
|
||||
{ "simplify", OPT_SIMPLIFY, "no|bisim|bwoa|sat|bisim-sat|bwoa-sat", 0,
|
||||
"simplification to apply to the controler (no) nothing, "
|
||||
"(bisim) bisimulation-based reduction, (bwoa) bissimulation-based "
|
||||
"simplification to apply to the controller (no) nothing, "
|
||||
"(bisim) bisimulation-based reduction, (bwoa) bisimulation-based "
|
||||
"reduction with output assignment, (sat) SAT-based minimization, "
|
||||
"(bisim-sat) SAT after bisim, (bwoa-sat) SAT after bwoa. Defaults "
|
||||
"to 'bwoa'.", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Output options:", 20 },
|
||||
{ "print-pg", OPT_PRINT, nullptr, 0,
|
||||
"print the parity game in the pgsolver format, do not solve it", 0},
|
||||
"print the parity game in the pgsolver format, do not solve it", 0 },
|
||||
{ "print-game-hoa", OPT_PRINT_HOA, "options", OPTION_ARG_OPTIONAL,
|
||||
"print the parity game in the HOA format, do not solve it", 0},
|
||||
"print the parity game in the HOA format, do not solve it", 0 },
|
||||
{ "realizability", OPT_REAL, nullptr, 0,
|
||||
"realizability only, do not compute a winning strategy", 0},
|
||||
"realizability only, do not compute a winning strategy", 0 },
|
||||
{ "aiger", OPT_PRINT_AIGER, "ite|isop|both[+ud][+dc]"
|
||||
"[+sub0|sub1|sub2]", OPTION_ARG_OPTIONAL,
|
||||
"prints a winning strategy as an AIGER circuit. The first, and only "
|
||||
"mandatory option defines the method to be used. \"ite\" for "
|
||||
"If-then-else normal form; "
|
||||
"\"isop\" for irreducible sum of producs; "
|
||||
"\"both\" tries both encodings and keeps the smaller one. "
|
||||
"The other options further "
|
||||
"refine the encoding, see aiger::encode_bdd.", 0},
|
||||
{ "verbose", OPT_VERBOSE, nullptr, 0,
|
||||
"verbose mode", -1 },
|
||||
{ "verify", OPT_VERIFY, nullptr, 0,
|
||||
"verifies the strategy or (if demanded) aiger against the spec.", -1 },
|
||||
"encode the winning strategy as an AIG circuit and print it in AIGER"
|
||||
" format. The first word indicates the encoding to used: \"ite\" for "
|
||||
"If-Then-Else normal form; "
|
||||
"\"isop\" for irreducible sum of products; "
|
||||
"\"both\" tries both and keeps the smaller one. "
|
||||
"Other options further "
|
||||
"refine the encoding, see aiger::encode_bdd. Defaults to \"ite\".", 0 },
|
||||
{ "dot", OPT_DOT, "options", OPTION_ARG_OPTIONAL,
|
||||
"Use dot format when printing the result (game, strategy, or "
|
||||
"AIG circuit, depending on other options). The options that "
|
||||
"may be passed to --dot depend on the nature of what is printed. "
|
||||
"For games and strategies, standard automata rendering "
|
||||
"options are supported (e.g., see ltl2tgba --dot). For AIG circuit, "
|
||||
"use (h) for horizontal and (v) for vertical layouts.", 0 },
|
||||
{ "csv", OPT_CSV, "[>>]FILENAME", OPTION_ARG_OPTIONAL,
|
||||
"output statistics as CSV in FILENAME or on standard output "
|
||||
"(if '>>' is used to request append mode, the header line is "
|
||||
"not output)", 0 },
|
||||
{ "hide-status", OPT_HIDE, nullptr, 0,
|
||||
"Hide the REALIZABLE or UNREALIZABLE line. (Hint: exit status "
|
||||
"is enough of an indication.)", 0 },
|
||||
/**************************************************/
|
||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||
{ "extra-options", 'x', "OPTS", 0,
|
||||
"fine-tuning options (see spot-x (7))", 0 },
|
||||
{ "verbose", OPT_VERBOSE, nullptr, 0, "verbose mode", 0 },
|
||||
{ "verify", OPT_VERIFY, nullptr, 0,
|
||||
"verify the strategy or (if demanded) AIG against the formula", 0 },
|
||||
{ nullptr, 0, nullptr, 0, nullptr, 0 },
|
||||
};
|
||||
|
||||
|
|
@ -123,20 +152,19 @@ static const struct argp_child children[] =
|
|||
{
|
||||
{ &finput_argp_headless, 0, nullptr, 0 },
|
||||
{ &aoutput_argp, 0, nullptr, 0 },
|
||||
//{ &aoutput_o_format_argp, 0, nullptr, 0 },
|
||||
{ &misc_argp, 0, nullptr, 0 },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
const char argp_program_doc[] = "\
|
||||
static const char argp_program_doc[] = "\
|
||||
Synthesize a controller from its LTL specification.\v\
|
||||
Exit status:\n\
|
||||
0 if the input problem is realizable\n\
|
||||
1 if the input problem is not realizable\n\
|
||||
0 if all input problems were realizable\n\
|
||||
1 if at least one input problem was not realizable\n\
|
||||
2 if any error has been reported";
|
||||
|
||||
static std::vector<std::string> all_output_aps;
|
||||
static std::vector<std::string> all_input_aps;
|
||||
static std::optional<std::vector<std::string>> all_output_aps;
|
||||
static std::optional<std::vector<std::string>> all_input_aps;
|
||||
|
||||
static const char* opt_csv = nullptr;
|
||||
static bool opt_print_pg = false;
|
||||
|
|
@ -145,8 +173,10 @@ static const char* opt_print_hoa_args = nullptr;
|
|||
static bool opt_real = false;
|
||||
static bool opt_do_verify = false;
|
||||
static const char* opt_print_aiger = nullptr;
|
||||
|
||||
static const char* opt_dot_arg = nullptr;
|
||||
static bool opt_dot = false;
|
||||
static spot::synthesis_info* gi;
|
||||
static bool show_status = true;
|
||||
|
||||
static char const *const algo_names[] =
|
||||
{
|
||||
|
|
@ -154,7 +184,8 @@ static char const *const algo_names[] =
|
|||
"sd",
|
||||
"ps",
|
||||
"lar",
|
||||
"lar.old"
|
||||
"lar.old",
|
||||
"acd",
|
||||
};
|
||||
|
||||
static char const *const algo_args[] =
|
||||
|
|
@ -164,6 +195,7 @@ static char const *const algo_args[] =
|
|||
"dpasplit", "ps",
|
||||
"lar",
|
||||
"lar.old",
|
||||
"acd",
|
||||
nullptr
|
||||
};
|
||||
static spot::synthesis_info::algo const algo_types[] =
|
||||
|
|
@ -173,9 +205,24 @@ static spot::synthesis_info::algo const algo_types[] =
|
|||
spot::synthesis_info::algo::DPA_SPLIT, spot::synthesis_info::algo::DPA_SPLIT,
|
||||
spot::synthesis_info::algo::LAR,
|
||||
spot::synthesis_info::algo::LAR_OLD,
|
||||
spot::synthesis_info::algo::ACD,
|
||||
};
|
||||
ARGMATCH_VERIFY(algo_args, algo_types);
|
||||
|
||||
static const char* const bypass_args[] =
|
||||
{
|
||||
"yes", "true", "enabled", "1",
|
||||
"no", "false", "disabled", "0",
|
||||
nullptr
|
||||
};
|
||||
static bool bypass_values[] =
|
||||
{
|
||||
true, true, true, true,
|
||||
false, false, false, false,
|
||||
};
|
||||
ARGMATCH_VERIFY(bypass_args, bypass_values);
|
||||
bool opt_bypass = true;
|
||||
|
||||
static const char* const decompose_args[] =
|
||||
{
|
||||
"yes", "true", "enabled", "1",
|
||||
|
|
@ -221,7 +268,22 @@ namespace
|
|||
};
|
||||
|
||||
static void
|
||||
print_csv(const spot::formula& f)
|
||||
dispatch_print_hoa(const spot::const_twa_graph_ptr& game)
|
||||
{
|
||||
if (opt_dot)
|
||||
spot::print_dot(std::cout, game, opt_print_hoa_args);
|
||||
else if (opt_print_pg)
|
||||
spot::print_pg(std::cout, game);
|
||||
else
|
||||
spot::print_hoa(std::cout, game, opt_print_hoa_args) << '\n';
|
||||
}
|
||||
|
||||
// If filename is passed, it is printed instead of the formula. We
|
||||
// use that when processing games since we have no formula to print.
|
||||
// It would be cleaner to have two columns: one for location (that's
|
||||
// filename + line number if known), and one for formula (if known).
|
||||
static void
|
||||
print_csv(const spot::formula& f, const char* filename = nullptr)
|
||||
{
|
||||
auto& vs = gi->verbose_stream;
|
||||
auto& bv = gi->bv;
|
||||
|
|
@ -230,7 +292,9 @@ namespace
|
|||
if (vs)
|
||||
*vs << "writing CSV to " << opt_csv << '\n';
|
||||
|
||||
output_file outf(opt_csv);
|
||||
static bool not_first_time = false;
|
||||
output_file outf(opt_csv, not_first_time);
|
||||
not_first_time = true; // force append on next print.
|
||||
std::ostream& out = outf.ostream();
|
||||
|
||||
// Do not output the header line if we append to a file.
|
||||
|
|
@ -255,10 +319,15 @@ namespace
|
|||
out << '\n';
|
||||
}
|
||||
std::ostringstream os;
|
||||
os << f;
|
||||
spot::escape_rfc4180(out << '"', os.str());
|
||||
out << "\",\"" << algo_names[(int) gi->s]
|
||||
<< "\"," << bv->total_time
|
||||
if (filename)
|
||||
os << filename;
|
||||
else
|
||||
os << f;
|
||||
spot::escape_rfc4180(out << '"', os.str()) << "\",";
|
||||
// if a filename was given, assume the game has been read directly
|
||||
if (!filename)
|
||||
out << '"' << algo_names[(int) gi->s] << '"';
|
||||
out << ',' << bv->total_time
|
||||
<< ',' << bv->trans_time
|
||||
<< ',' << bv->split_time
|
||||
<< ',' << bv->paritize_time;
|
||||
|
|
@ -285,11 +354,13 @@ namespace
|
|||
outf.close(opt_csv);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
solve_formula(const spot::formula& f,
|
||||
const std::vector<std::string>& input_aps,
|
||||
const std::vector<std::string>& output_aps)
|
||||
{
|
||||
if (opt_csv) // reset benchmark data
|
||||
gi->bv = spot::synthesis_info::bench_var();
|
||||
spot::stopwatch sw;
|
||||
if (gi->bv)
|
||||
sw.start();
|
||||
|
|
@ -305,6 +376,12 @@ namespace
|
|||
if (opt_decompose_ltl)
|
||||
{
|
||||
auto subs = split_independant_formulas(f, output_aps);
|
||||
if (gi->verbose_stream)
|
||||
{
|
||||
*gi->verbose_stream << "there are "
|
||||
<< subs.first.size()
|
||||
<< " subformulas\n";
|
||||
}
|
||||
if (subs.first.size() > 1)
|
||||
{
|
||||
sub_form = subs.first;
|
||||
|
|
@ -347,17 +424,6 @@ namespace
|
|||
auto sub_o = sub_outs_str.begin();
|
||||
std::vector<spot::mealy_like> mealy_machines;
|
||||
|
||||
auto print_game = want_game ?
|
||||
[](const spot::twa_graph_ptr& game)->void
|
||||
{
|
||||
if (opt_print_pg)
|
||||
pg_print(std::cout, game);
|
||||
else
|
||||
spot::print_hoa(std::cout, game, opt_print_hoa_args) << '\n';
|
||||
}
|
||||
:
|
||||
[](const spot::twa_graph_ptr&)->void{};
|
||||
|
||||
for (; sub_f != sub_form.end(); ++sub_f, ++sub_o)
|
||||
{
|
||||
spot::mealy_like m_like
|
||||
|
|
@ -368,15 +434,16 @@ namespace
|
|||
};
|
||||
// If we want to print a game,
|
||||
// we never use the direct approach
|
||||
if (!want_game)
|
||||
if (!want_game && opt_bypass)
|
||||
m_like =
|
||||
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi);
|
||||
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi, !opt_real);
|
||||
|
||||
switch (m_like.success)
|
||||
{
|
||||
case spot::mealy_like::realizability_code::UNREALIZABLE:
|
||||
{
|
||||
std::cout << "UNREALIZABLE" << std::endl;
|
||||
if (show_status)
|
||||
std::cout << "UNREALIZABLE" << std::endl;
|
||||
safe_tot_time();
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -394,13 +461,20 @@ namespace
|
|||
assert((spptr->at(arena->get_init_state_number()) == false)
|
||||
&& "Env needs first turn");
|
||||
}
|
||||
print_game(arena);
|
||||
if (want_game)
|
||||
{
|
||||
dispatch_print_hoa(arena);
|
||||
continue;
|
||||
}
|
||||
if (!spot::solve_game(arena, *gi))
|
||||
{
|
||||
std::cout << "UNREALIZABLE" << std::endl;
|
||||
if (show_status)
|
||||
std::cout << "UNREALIZABLE" << std::endl;
|
||||
safe_tot_time();
|
||||
return 1;
|
||||
}
|
||||
if (gi->bv)
|
||||
gi->bv->realizable = true;
|
||||
// Create the (partial) strategy
|
||||
// only if we need it
|
||||
if (!opt_real)
|
||||
|
|
@ -408,14 +482,13 @@ namespace
|
|||
spot::mealy_like ml;
|
||||
ml.success =
|
||||
spot::mealy_like::realizability_code::REALIZABLE_REGULAR;
|
||||
if (opt_print_aiger)
|
||||
// we do not care about the type,
|
||||
// machine to aiger can handle it
|
||||
ml.mealy_like =
|
||||
spot::solved_game_to_mealy(arena, *gi);
|
||||
else
|
||||
ml.mealy_like =
|
||||
spot::solved_game_to_separated_mealy(arena, *gi);
|
||||
// By default this produces a split machine
|
||||
ml.mealy_like =
|
||||
spot::solved_game_to_mealy(arena, *gi);
|
||||
// Keep the machine split for aiger
|
||||
// else -> separated
|
||||
spot::simplify_mealy_here(ml.mealy_like, *gi,
|
||||
opt_print_aiger);
|
||||
ml.glob_cond = bddfalse;
|
||||
mealy_machines.push_back(ml);
|
||||
}
|
||||
|
|
@ -426,54 +499,14 @@ namespace
|
|||
// the direct approach yielded a strategy
|
||||
// which can now be minimized
|
||||
// We minimize only if we need it
|
||||
assert(m_like.mealy_like && "Expected success but found no mealy!");
|
||||
assert(opt_real ||
|
||||
(m_like.mealy_like && "Expected success but found no mealy!"));
|
||||
if (!opt_real)
|
||||
{
|
||||
spot::stopwatch sw_direct;
|
||||
sw_direct.start();
|
||||
|
||||
if ((0 < gi->minimize_lvl) && (gi->minimize_lvl < 3))
|
||||
// Uses reduction or not,
|
||||
// both work with mealy machines (non-separated)
|
||||
reduce_mealy_here(m_like.mealy_like, gi->minimize_lvl == 2);
|
||||
|
||||
auto delta = sw_direct.stop();
|
||||
|
||||
sw_direct.start();
|
||||
// todo better algo here?
|
||||
m_like.mealy_like =
|
||||
split_2step(m_like.mealy_like,
|
||||
spot::get_synthesis_outputs(m_like.mealy_like),
|
||||
false);
|
||||
if (gi->bv)
|
||||
gi->bv->split_time += sw_direct.stop();
|
||||
|
||||
sw_direct.start();
|
||||
if (gi->minimize_lvl >= 3)
|
||||
{
|
||||
sw_direct.start();
|
||||
// actual minimization, works on split mealy
|
||||
m_like.mealy_like = minimize_mealy(m_like.mealy_like,
|
||||
gi->minimize_lvl - 4);
|
||||
delta = sw_direct.stop();
|
||||
}
|
||||
|
||||
// If our goal is to have an aiger,
|
||||
// we can use split or separated machines
|
||||
if (!opt_print_aiger)
|
||||
// Unsplit to have separated mealy
|
||||
m_like.mealy_like = unsplit_mealy(m_like.mealy_like);
|
||||
|
||||
if (gi->bv)
|
||||
gi->bv->strat2aut_time += delta;
|
||||
if (gi->verbose_stream)
|
||||
*gi->verbose_stream << "final strategy has "
|
||||
<< m_like.mealy_like->num_states()
|
||||
<< " states and "
|
||||
<< m_like.mealy_like->num_edges()
|
||||
<< " edges\n"
|
||||
<< "minimization took " << delta
|
||||
<< " seconds\n";
|
||||
// Keep the machine split for aiger
|
||||
// else -> separated
|
||||
spot::simplify_mealy_here(m_like.mealy_like, *gi,
|
||||
opt_print_aiger);
|
||||
}
|
||||
SPOT_FALLTHROUGH;
|
||||
}
|
||||
|
|
@ -494,7 +527,8 @@ namespace
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "REALIZABLE" << std::endl;
|
||||
if (show_status)
|
||||
std::cout << "REALIZABLE" << std::endl;
|
||||
if (opt_real)
|
||||
{
|
||||
safe_tot_time();
|
||||
|
|
@ -503,8 +537,8 @@ namespace
|
|||
// If we reach this line
|
||||
// a strategy was found for each subformula
|
||||
assert(mealy_machines.size() == sub_form.size()
|
||||
&& "There are subformula for which no mealy like object"
|
||||
"has been created.");
|
||||
&& ("There are subformula for which no mealy like object"
|
||||
" has been created."));
|
||||
|
||||
spot::aig_ptr saig = nullptr;
|
||||
spot::twa_graph_ptr tot_strat = nullptr;
|
||||
|
|
@ -533,7 +567,10 @@ namespace
|
|||
<< " latches and "
|
||||
<< saig->num_gates() << " gates\n";
|
||||
}
|
||||
spot::print_aiger(std::cout, saig) << '\n';
|
||||
if (opt_dot)
|
||||
spot::print_dot(std::cout, saig, opt_dot_arg);
|
||||
else
|
||||
spot::print_aiger(std::cout, saig) << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -545,7 +582,8 @@ namespace
|
|||
&& "ltlsynt: Cannot handle TGBA as strategy.");
|
||||
tot_strat = mealy_machines.front().mealy_like;
|
||||
for (size_t i = 1; i < mealy_machines.size(); ++i)
|
||||
tot_strat = spot::product(tot_strat, mealy_machines[i].mealy_like);
|
||||
tot_strat = spot::mealy_product(tot_strat,
|
||||
mealy_machines[i].mealy_like);
|
||||
printer.print(tot_strat, timer_printer_dummy);
|
||||
}
|
||||
|
||||
|
|
@ -583,15 +621,27 @@ namespace
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
split_aps(const std::string& arg, std::vector<std::string>& where)
|
||||
{
|
||||
std::istringstream aps(arg);
|
||||
std::string ap;
|
||||
while (std::getline(aps, ap, ','))
|
||||
{
|
||||
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
|
||||
where.push_back(str_tolower(ap));
|
||||
}
|
||||
}
|
||||
|
||||
class ltl_processor final : public job_processor
|
||||
{
|
||||
private:
|
||||
std::vector<std::string> input_aps_;
|
||||
std::vector<std::string> output_aps_;
|
||||
std::optional<std::vector<std::string>> input_aps_;
|
||||
std::optional<std::vector<std::string>> output_aps_;
|
||||
|
||||
public:
|
||||
ltl_processor(std::vector<std::string> input_aps_,
|
||||
std::vector<std::string> output_aps_)
|
||||
ltl_processor(std::optional<std::vector<std::string>> input_aps_,
|
||||
std::optional<std::vector<std::string>> output_aps_)
|
||||
: input_aps_(std::move(input_aps_)),
|
||||
output_aps_(std::move(output_aps_))
|
||||
{
|
||||
|
|
@ -601,11 +651,13 @@ namespace
|
|||
const char* filename, int linenum) override
|
||||
{
|
||||
auto unknown_aps = [](spot::formula f,
|
||||
const std::vector<std::string>& known,
|
||||
const std::vector<std::string>* known2 = nullptr)
|
||||
const std::optional<std::vector<std::string>>& known,
|
||||
const std::optional<std::vector<std::string>>& known2 = {})
|
||||
{
|
||||
std::vector<std::string> unknown;
|
||||
std::set<spot::formula> seen;
|
||||
// If we don't have --ins and --outs, we must not find an AP.
|
||||
bool can_have_ap = known.has_value();
|
||||
f.traverse([&](const spot::formula& s)
|
||||
{
|
||||
if (s.is(spot::op::ap))
|
||||
|
|
@ -613,10 +665,11 @@ namespace
|
|||
if (!seen.insert(s).second)
|
||||
return false;
|
||||
const std::string& a = s.ap_name();
|
||||
if (std::find(known.begin(), known.end(), a) == known.end()
|
||||
&& (!known2
|
||||
if (!can_have_ap
|
||||
|| (std::find(known->begin(), known->end(), a) == known->end()
|
||||
&& (!known2.has_value()
|
||||
|| std::find(known2->begin(),
|
||||
known2->end(), a) == known2->end()))
|
||||
known2->end(), a) == known2->end())))
|
||||
unknown.push_back(a);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -626,36 +679,233 @@ namespace
|
|||
|
||||
// Decide which atomic propositions are input or output.
|
||||
int res;
|
||||
if (input_aps_.empty() && !output_aps_.empty())
|
||||
if (!input_aps_.has_value() && output_aps_.has_value())
|
||||
{
|
||||
res = solve_formula(f, unknown_aps(f, output_aps_), output_aps_);
|
||||
res = solve_formula(f, unknown_aps(f, output_aps_), *output_aps_);
|
||||
}
|
||||
else if (output_aps_.empty() && !input_aps_.empty())
|
||||
else if (!output_aps_.has_value() && input_aps_.has_value())
|
||||
{
|
||||
res = solve_formula(f, input_aps_, unknown_aps(f, input_aps_));
|
||||
res = solve_formula(f, *input_aps_, unknown_aps(f, input_aps_));
|
||||
}
|
||||
else if (output_aps_.empty() && input_aps_.empty())
|
||||
else if (!output_aps_.has_value() && !input_aps_.has_value())
|
||||
{
|
||||
for (const std::string& ap: unknown_aps(f, input_aps_, &output_aps_))
|
||||
for (const std::string& ap: unknown_aps(f, input_aps_, output_aps_))
|
||||
error_at_line(2, 0, filename, linenum,
|
||||
"one of --ins or --outs should list '%s'",
|
||||
ap.c_str());
|
||||
res = solve_formula(f, input_aps_, output_aps_);
|
||||
res = solve_formula(f, *input_aps_, *output_aps_);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const std::string& ap: unknown_aps(f, input_aps_, &output_aps_))
|
||||
for (const std::string& ap: unknown_aps(f, input_aps_, output_aps_))
|
||||
error_at_line(2, 0, filename, linenum,
|
||||
"both --ins and --outs are specified, "
|
||||
"but '%s' is unlisted",
|
||||
ap.c_str());
|
||||
res = solve_formula(f, input_aps_, output_aps_);
|
||||
res = solve_formula(f, *input_aps_, *output_aps_);
|
||||
}
|
||||
|
||||
if (opt_csv)
|
||||
print_csv(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
process_tlsf_file(const char* filename) override
|
||||
{
|
||||
static char arg0[] = "syfco";
|
||||
static char arg1[] = "-f";
|
||||
static char arg2[] = "ltlxba";
|
||||
static char arg3[] = "-m";
|
||||
static char arg4[] = "fully";
|
||||
char* command[] = { arg0, arg1, arg2, arg3, arg4,
|
||||
const_cast<char*>(filename), nullptr };
|
||||
std::string tlsf_string = read_stdout_of_command(command);
|
||||
|
||||
// The set of atomic proposition will be temporary set to those
|
||||
// given by syfco, unless they were forced from the command-line.
|
||||
bool reset_aps = false;
|
||||
if (!input_aps_.has_value() && !output_aps_.has_value())
|
||||
{
|
||||
reset_aps = true;
|
||||
static char arg5[] = "--print-output-signals";
|
||||
char* command[] = { arg0, arg5,
|
||||
const_cast<char*>(filename), nullptr };
|
||||
std::string res = read_stdout_of_command(command);
|
||||
|
||||
output_aps_.emplace(std::vector<std::string>{});
|
||||
split_aps(res, *output_aps_);
|
||||
}
|
||||
int res = process_string(tlsf_string, filename);
|
||||
if (reset_aps)
|
||||
output_aps_.reset();
|
||||
return res;
|
||||
}
|
||||
|
||||
int process_pgame(spot::twa_graph_ptr arena,
|
||||
const std::string& location)
|
||||
{
|
||||
if (opt_csv) // reset benchmark data
|
||||
gi->bv = spot::synthesis_info::bench_var();
|
||||
spot::stopwatch sw_global;
|
||||
spot::stopwatch sw_local;
|
||||
if (gi->bv)
|
||||
{
|
||||
sw_global.start();
|
||||
sw_local.start();
|
||||
}
|
||||
if (!arena->get_named_prop<bdd>("synthesis-outputs"))
|
||||
{
|
||||
std::cerr << location << ": controllable-AP is not specified\n";
|
||||
return 2;
|
||||
}
|
||||
if (!arena->get_named_prop<std::vector<bool>>("state-player"))
|
||||
arena = spot::split_2step(arena, true);
|
||||
else
|
||||
{
|
||||
// Check if the game is alternating and fix trivial cases
|
||||
const unsigned N = arena->num_states();
|
||||
// Can not use get_state_players because we need a non-const version
|
||||
auto spptr =
|
||||
arena->get_named_prop<std::vector<bool>>("state-player");
|
||||
assert(spptr);
|
||||
const bdd& outs = get_synthesis_outputs(arena);
|
||||
for (unsigned n = 0; n < N; ++n)
|
||||
{
|
||||
const bool p = (*spptr)[n];
|
||||
for (auto& e : arena->out(n))
|
||||
{
|
||||
if (p != (*spptr)[e.dst])
|
||||
continue; // All good
|
||||
// Check if the condition is a simply conjunction of input and
|
||||
// output. If so insert an intermediate state
|
||||
// This also covers trivial self-loops
|
||||
bdd cond = e.cond;
|
||||
bdd i_cond = bdd_exist(cond, outs);
|
||||
bdd o_cond = bdd_existcomp(cond, outs);
|
||||
if ((i_cond & o_cond) == cond)
|
||||
{
|
||||
unsigned inter = arena->new_state();
|
||||
spptr->push_back(!p);
|
||||
e.cond = p ? o_cond : i_cond;
|
||||
e.dst = inter;
|
||||
arena->new_edge(inter, e.dst, !p ? o_cond : i_cond);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("ltlsynt: given parity game is not"
|
||||
"alternating and not trivially fixable!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gi->bv)
|
||||
{
|
||||
gi->bv->split_time += sw_local.stop();
|
||||
gi->bv->nb_states_arena += arena->num_states();
|
||||
auto spptr =
|
||||
arena->get_named_prop<std::vector<bool>>("state-player");
|
||||
assert(spptr);
|
||||
gi->bv->nb_states_arena_env +=
|
||||
std::count(spptr->cbegin(), spptr->cend(), false);
|
||||
}
|
||||
if (opt_print_pg || opt_print_hoa)
|
||||
{
|
||||
dispatch_print_hoa(arena);
|
||||
return 0;
|
||||
}
|
||||
auto safe_tot_time = [&]() {
|
||||
if (gi->bv)
|
||||
gi->bv->total_time = sw_global.stop();
|
||||
};
|
||||
if (!spot::solve_game(arena, *gi))
|
||||
{
|
||||
if (show_status)
|
||||
std::cout << "UNREALIZABLE" << std::endl;
|
||||
safe_tot_time();
|
||||
return 1;
|
||||
}
|
||||
if (gi->bv)
|
||||
gi->bv->realizable = true;
|
||||
if (show_status)
|
||||
std::cout << "REALIZABLE" << std::endl;
|
||||
if (opt_real)
|
||||
{
|
||||
safe_tot_time();
|
||||
return 0;
|
||||
}
|
||||
sw_local.start();
|
||||
spot::twa_graph_ptr mealy_like =
|
||||
spot::solved_game_to_mealy(arena, *gi);
|
||||
// Keep the machine split for aiger otherwise, separate it.
|
||||
spot::simplify_mealy_here(mealy_like, *gi, opt_print_aiger);
|
||||
|
||||
automaton_printer printer;
|
||||
spot::process_timer timer_printer_dummy;
|
||||
if (opt_print_aiger)
|
||||
{
|
||||
if (gi->bv)
|
||||
sw_local.start();
|
||||
spot::aig_ptr saig =
|
||||
spot::mealy_machine_to_aig(mealy_like, opt_print_aiger);
|
||||
if (gi->bv)
|
||||
{
|
||||
gi->bv->aig_time = sw_local.stop();
|
||||
gi->bv->nb_latches = saig->num_latches();
|
||||
gi->bv->nb_gates = saig->num_gates();
|
||||
}
|
||||
if (gi->verbose_stream)
|
||||
{
|
||||
*gi->verbose_stream << "AIG circuit was created in "
|
||||
<< gi->bv->aig_time
|
||||
<< " seconds and has " << saig->num_latches()
|
||||
<< " latches and "
|
||||
<< saig->num_gates() << " gates\n";
|
||||
}
|
||||
spot::print_aiger(std::cout, saig) << '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
printer.print(mealy_like, timer_printer_dummy);
|
||||
}
|
||||
safe_tot_time();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
process_aut_file(const char* filename) override
|
||||
{
|
||||
spot::automaton_stream_parser hp(filename);
|
||||
int err = 0;
|
||||
while (!abort_run)
|
||||
{
|
||||
spot::parsed_aut_ptr haut = hp.parse(spot::make_bdd_dict());
|
||||
if (!haut->aut && haut->errors.empty())
|
||||
break;
|
||||
if (haut->format_errors(std::cerr))
|
||||
err = 2;
|
||||
if (!haut->aut /*|| (err && abort_on_error_)*/)
|
||||
{
|
||||
error(2, 0, "failed to read automaton from %s",
|
||||
haut->filename.c_str());
|
||||
}
|
||||
else if (haut->aborted)
|
||||
{
|
||||
std::cerr << haut->filename << ':' << haut->loc
|
||||
<< ": aborted input automaton\n";
|
||||
err = std::max(err, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << haut->filename << ':' << haut->loc;
|
||||
std::string loc = os.str();
|
||||
int res = process_pgame(haut->aut, loc);
|
||||
if (res < 2 && opt_csv)
|
||||
print_csv(nullptr, loc.c_str());
|
||||
err = std::max(err, res);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -669,35 +919,37 @@ parse_opt(int key, char *arg, struct argp_state *)
|
|||
case OPT_ALGO:
|
||||
gi->s = XARGMATCH("--algo", arg, algo_args, algo_types);
|
||||
break;
|
||||
case OPT_BYPASS:
|
||||
opt_bypass = XARGMATCH("--bypass", arg, bypass_args, bypass_values);
|
||||
break;
|
||||
case OPT_CSV:
|
||||
opt_csv = arg ? arg : "-";
|
||||
if (not gi->bv)
|
||||
gi->bv = spot::synthesis_info::bench_var();
|
||||
break;
|
||||
case OPT_DECOMPOSE:
|
||||
opt_decompose_ltl = XARGMATCH("--decompose", arg,
|
||||
decompose_args, decompose_values);
|
||||
break;
|
||||
case OPT_DOT:
|
||||
opt_dot = true;
|
||||
automaton_format_opt = opt_dot_arg = arg;
|
||||
automaton_format = Dot;
|
||||
break;
|
||||
case OPT_FROM_PGAME:
|
||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
||||
break;
|
||||
case OPT_HIDE:
|
||||
show_status = false;
|
||||
break;
|
||||
case OPT_INPUT:
|
||||
{
|
||||
std::istringstream aps(arg);
|
||||
std::string ap;
|
||||
while (std::getline(aps, ap, ','))
|
||||
{
|
||||
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
|
||||
all_input_aps.push_back(str_tolower(ap));
|
||||
}
|
||||
all_input_aps.emplace(std::vector<std::string>{});
|
||||
split_aps(arg, *all_input_aps);
|
||||
break;
|
||||
}
|
||||
case OPT_OUTPUT:
|
||||
{
|
||||
std::istringstream aps(arg);
|
||||
std::string ap;
|
||||
while (std::getline(aps, ap, ','))
|
||||
{
|
||||
ap.erase(remove_if(ap.begin(), ap.end(), isspace), ap.end());
|
||||
all_output_aps.push_back(str_tolower(ap));
|
||||
}
|
||||
all_output_aps.emplace(std::vector<std::string>{});
|
||||
split_aps(arg, *all_output_aps);
|
||||
break;
|
||||
}
|
||||
case OPT_PRINT:
|
||||
|
|
@ -718,6 +970,9 @@ parse_opt(int key, char *arg, struct argp_state *)
|
|||
gi->minimize_lvl = XARGMATCH("--simplify", arg,
|
||||
simplify_args, simplify_values);
|
||||
break;
|
||||
case OPT_TLSF:
|
||||
jobs.emplace_back(arg, job_type::TLSF_FILENAME);
|
||||
break;
|
||||
case OPT_VERBOSE:
|
||||
gi->verbose_stream = &std::cerr;
|
||||
if (not gi->bv)
|
||||
|
|
@ -754,13 +1009,15 @@ main(int argc, char **argv)
|
|||
argp_program_doc, children, nullptr, nullptr };
|
||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||
exit(err);
|
||||
|
||||
check_no_formula();
|
||||
|
||||
// Check if inputs and outputs are distinct
|
||||
for (const std::string& ai : all_input_aps)
|
||||
if (std::find(all_output_aps.begin(), all_output_aps.end(), ai)
|
||||
!= all_output_aps.end())
|
||||
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
|
||||
if (all_input_aps.has_value() && all_output_aps.has_value())
|
||||
for (const std::string& ai : *all_input_aps)
|
||||
if (std::find(all_output_aps->begin(), all_output_aps->end(), ai)
|
||||
!= all_output_aps->end())
|
||||
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
|
||||
|
||||
ltl_processor processor(all_input_aps, all_output_aps);
|
||||
if (int res = processor.run(); res == 0 || res == 1)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2016, 2018-2020 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2016, 2018-2020, 2022 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
#include <spot/twaalgos/canonicalize.hh>
|
||||
|
||||
|
||||
const char argp_program_doc[] = "\
|
||||
static const char argp_program_doc[] = "\
|
||||
Generate random connected automata.\n\n\
|
||||
The automata are built over the atomic propositions named by PROPS...\n\
|
||||
or, if N is a nonnegative number, using N arbitrary names.\n\
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2012-2016, 2018-2019, 2022, 2023 Laboratoire de
|
||||
// Recherche et Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
#include <spot/misc/random.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Generate random temporal logic formulas.\n\n\
|
||||
The formulas are built over the atomic propositions named by PROPS...\n\
|
||||
or, if N is a nonnegative number, using N arbitrary names.\v\
|
||||
|
|
@ -65,7 +65,6 @@ enum {
|
|||
OPT_DUMP_PRIORITIES,
|
||||
OPT_DUPS,
|
||||
OPT_LTL_PRIORITIES,
|
||||
OPT_PSL_PRIORITIES,
|
||||
OPT_SEED,
|
||||
OPT_SERE_PRIORITIES,
|
||||
OPT_TREE_SIZE,
|
||||
|
|
@ -194,7 +193,6 @@ parse_opt(int key, char* arg, struct argp_state* as)
|
|||
case OPT_DUMP_PRIORITIES:
|
||||
opt_dump_priorities = true;
|
||||
break;
|
||||
// case OPT_PSL_PRIORITIES: break;
|
||||
case OPT_SERE_PRIORITIES:
|
||||
opt_pS = arg;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
#include <argp.h>
|
||||
#include "common_setup.hh"
|
||||
|
||||
const char argp_program_doc[] ="\
|
||||
static const char argp_program_doc[] = "\
|
||||
Common fine-tuning options for programs installed with Spot.\n\
|
||||
\n\
|
||||
The argument of -x or --extra-options is a comma-separated list of KEY=INT \
|
||||
|
|
@ -47,9 +47,17 @@ depends on the --low, --medium, or --high settings.") },
|
|||
{ DOC("tls-max-states",
|
||||
"Maximum number of states of automata involved in automata-based \
|
||||
implication checks for formula simplifications. Defaults to 64.") },
|
||||
{ DOC("tls-max-ops",
|
||||
"Maximum number of operands in n-ary opertors (or, and) on which \
|
||||
implication-based simplifications are attempted. Defaults to 16.") },
|
||||
{ nullptr, 0, nullptr, 0, "Translation options:", 0 },
|
||||
{ DOC("ltl-split", "Set to 0 to disable the translation of automata \
|
||||
as product or sum of subformulas.") },
|
||||
{ DOC("branch-post", "Set to 0 to disable branching-postponement \
|
||||
(done during translation, may create more states) and delayed-branching \
|
||||
(almost similar, but done after translation to only remove states). \
|
||||
Set to 1 to force branching-postponement, and to 2 \
|
||||
to force delayed-branching. By default delayed-branching is used.") },
|
||||
{ DOC("comp-susp", "Set to 1 to enable compositional suspension, \
|
||||
as described in our SPIN'13 paper (see Bibliography below). Set to 2, \
|
||||
to build only the skeleton TGBA without composing it. Set to 0 (the \
|
||||
|
|
@ -75,6 +83,9 @@ only if it is smaller than the original skeleton. This option is only \
|
|||
used when comp-susp=1 and default to 1 or 2 depending on whether --small \
|
||||
or --deterministic is specified.") },
|
||||
{ nullptr, 0, nullptr, 0, "Postprocessing options:", 0 },
|
||||
{ DOC("acd", "Set to 1 (the default) to use paritize automata using \
|
||||
the alternatinc cycle decomposition. Set to 0 to use paritization based \
|
||||
on latest appearance record variants.") },
|
||||
{ DOC("scc-filter", "Set to 1 (the default) to enable \
|
||||
SCC-pruning and acceptance simplification at the beginning of \
|
||||
post-processing. Transitions that are outside of accepting SCC are \
|
||||
|
|
@ -164,6 +175,10 @@ Set to 1 to use only direct simulation. Set to 2 to use only reverse \
|
|||
simulation. Set to 3 to iterate both direct and reverse simulations. \
|
||||
The default is the value of parameter \"simul\" in --high mode, and 0 \
|
||||
therwise.") },
|
||||
{ DOC("merge-states-min", "Number of states above which states are \
|
||||
merged using a cheap approximation of a bisimulation quotient before \
|
||||
attempting simulation-based reductions. Defaults to 128. Set to 0 to \
|
||||
never merge states.") },
|
||||
{ DOC("simul-max", "Number of states above which simulation-based \
|
||||
reductions are skipped. Defaults to 4096. Set to 0 to disable. This \
|
||||
applies to all simulation-based optimization, including thoses of the \
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2018 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2013-2018, 2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -24,7 +24,8 @@
|
|||
#include <argp.h>
|
||||
#include "common_setup.hh"
|
||||
|
||||
const char argp_program_doc[] ="Command-line tools installed by Spot.";
|
||||
static const char argp_program_doc[] =
|
||||
"Command-line tools installed by Spot.";
|
||||
|
||||
#define DOC(NAME, TXT) NAME, 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, TXT, 0
|
||||
|
||||
|
|
|
|||
|
|
@ -501,6 +501,7 @@ BUDDY_API_VAR const BDD bddtrue;
|
|||
*************************************************************************/
|
||||
#ifdef CPLUSPLUS
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
/*=== User BDD class ===================================================*/
|
||||
|
||||
|
|
@ -1092,6 +1093,11 @@ inline bddxfalse bdd_false(void)
|
|||
{ return bddxfalse(); }
|
||||
|
||||
|
||||
template<>
|
||||
struct std::default_delete<bddPair> {
|
||||
void operator()(bddPair *p) const { bdd_freepair(p); };
|
||||
};
|
||||
|
||||
/*=== Iostream printing ================================================*/
|
||||
|
||||
class BUDDY_API bdd_ioformat
|
||||
|
|
|
|||
|
|
@ -210,7 +210,6 @@ static BddTree *reorder_win2ite(BddTree *t)
|
|||
{
|
||||
BddTree *this, *first=t;
|
||||
int lastsize;
|
||||
int c=1;
|
||||
|
||||
if (t == NULL)
|
||||
return t;
|
||||
|
|
@ -246,7 +245,6 @@ static BddTree *reorder_win2ite(BddTree *t)
|
|||
|
||||
if (verbose > 1)
|
||||
printf(" %d nodes\n", reorder_nodenum());
|
||||
c++;
|
||||
}
|
||||
while (reorder_nodenum() != lastsize);
|
||||
|
||||
|
|
|
|||
43
configure.ac
43
configure.ac
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2008-2022, Laboratoire de Recherche et Développement
|
||||
# Copyright (C) 2008-2023, Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
# Copyright (C) 2003-2007 Laboratoire d'Informatique de Paris 6
|
||||
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([spot], [2.10.4.dev], [spot@lrde.epita.fr])
|
||||
AC_INIT([spot], [2.11.5.dev], [spot@lrde.epita.fr])
|
||||
AC_CONFIG_AUX_DIR([tools])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests])
|
||||
|
|
@ -53,6 +53,15 @@ AC_ARG_ENABLE([c++20],
|
|||
[Compile in C++20 mode.])],
|
||||
[enable_20=$enableval], [enable_20=no])
|
||||
|
||||
AC_ARG_ENABLE([pthread],
|
||||
[AS_HELP_STRING([--enable-pthread],
|
||||
[Allow libspot to use POSIX threads.])],
|
||||
[enable_pthread=$enableval], [enable_pthread=no])
|
||||
if test "$enable_pthread" = yes; then
|
||||
AC_DEFINE([ENABLE_PTHREAD], [1], [Whether Spot is compiled with -pthread.])
|
||||
AC_SUBST([LIBSPOT_PTHREAD], [-pthread])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([doxygen],
|
||||
[AS_HELP_STRING([--enable-doxygen],
|
||||
[enable generation of Doxygen documentation (requires Doxygen)])],
|
||||
|
|
@ -70,6 +79,7 @@ if test 0 -eq `expr $enable_max_accsets % $default_max_accsets`
|
|||
then
|
||||
AC_DEFINE_UNQUOTED([MAX_ACCSETS], [$enable_max_accsets],
|
||||
[The maximal number of acceptance sets supported (also known as acceptance marks)])
|
||||
AC_SUBST([MAX_ACCSETS], [$enable_max_accsets])
|
||||
else
|
||||
AC_MSG_ERROR([The argument of --enable-max-accsets must be a multiple of $default_max_accsets])
|
||||
fi
|
||||
|
|
@ -150,7 +160,7 @@ AX_CHECK_BUDDY
|
|||
AC_CHECK_FUNCS([times kill alarm sigaction sched_getcpu])
|
||||
|
||||
oLIBS=$LIBS
|
||||
LIBS="$LIBS -lpthread"
|
||||
LIBS="$LIBS -pthread"
|
||||
AC_CHECK_FUNCS([pthread_setaffinity_np])
|
||||
LIBS=$oLIBS
|
||||
|
||||
|
|
@ -179,9 +189,14 @@ if test "x${enable_python:-yes}" = xyes; then
|
|||
AC_MSG_NOTICE([You may configure with --disable-python ]dnl
|
||||
[if you do not need Python bindings.])
|
||||
adl_CHECK_PYTHON
|
||||
|
||||
AC_ARG_WITH([pythondir],
|
||||
[AS_HELP_STRING([--with-pythondir], [override the computed pythondir])],
|
||||
[pythondir=$withval pyexecdir=$withval], [])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
adl_ENABLE_DEBUG
|
||||
ad_GCC_OPTIM
|
||||
adl_NDEBUG
|
||||
|
|
@ -202,7 +217,7 @@ AC_CHECK_PROG([LTL3BA], [ltl3ba], [ltl3ba])
|
|||
AC_CHECK_PROG([PERL], [perl], [perl])
|
||||
AC_CHECK_PROG([SPIN], [spin], [spin])
|
||||
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
|
||||
AC_CHECK_PROG([EMACS], [emacs], [emacs])
|
||||
AM_MISSING_PROG([EMACS], [emacs])
|
||||
AC_CHECK_PROGS([IPYTHON], [ipython3 ipython], [ipython])
|
||||
AC_CHECK_PROGS([JUPYTER], [jupyter], [jupyter])
|
||||
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
|
||||
|
|
@ -280,3 +295,23 @@ case $VERSION:$enable_devel in
|
|||
echo '==================================================================='
|
||||
;;
|
||||
esac
|
||||
|
||||
case $enable_python in
|
||||
yes)
|
||||
pd=$pythondir
|
||||
eval pd=$pd
|
||||
eval pd=$pd
|
||||
$PYTHON -c "
|
||||
import sys
|
||||
if '$pd' in sys.path:
|
||||
exit()
|
||||
else:
|
||||
print('\nWARNING: Python bindings will be installed in $pd')
|
||||
print(' however this path is not searched by default by $PYTHON.')
|
||||
print('\n$PYTHON\'s sys.path contains the following paths:\n',
|
||||
'\n'.join(sys.path))
|
||||
print('\nUse --with-pythondir=... if you wish '
|
||||
'to change this installation path.')
|
||||
"
|
||||
;;
|
||||
esac
|
||||
|
|
|
|||
2
debian/control
vendored
2
debian/control
vendored
|
|
@ -2,7 +2,7 @@ Source: spot
|
|||
Section: science
|
||||
Priority: optional
|
||||
Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
Build-Depends: debhelper (>= 12), python3-all-dev, ipython3-notebook | python3-ipykernel, ipython3-notebook | python3-nbconvert, libltdl-dev, dh-python
|
||||
Build-Depends: debhelper (>= 12), python3-all-dev, ipython3-notebook | python3-ipykernel, ipython3-notebook | python3-nbconvert, libltdl-dev, dh-python, graphviz, jupyter-nbconvert, doxygen
|
||||
Standards-Version: 4.5.1
|
||||
Homepage: http://spot.lrde.epita.fr/
|
||||
|
||||
|
|
|
|||
2
debian/copyright
vendored
2
debian/copyright
vendored
|
|
@ -1,6 +1,6 @@
|
|||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: spot
|
||||
Source: http://spot.lrde.epita.fr/dload/spot/
|
||||
Source: http://www.lrde.epita.fr/dload/spot/
|
||||
|
||||
Files: *
|
||||
Copyright: 2003-2007 Laboratoire d'Informatique de Paris 6 (LIP6)
|
||||
|
|
|
|||
22
debian/rules
vendored
22
debian/rules
vendored
|
|
@ -20,20 +20,16 @@ include /usr/share/dpkg/default.mk
|
|||
%:
|
||||
dh $@ --with=python3
|
||||
|
||||
# Find the LTO plugin, which we need to pass to ar, nm, and ranlib.
|
||||
LTOPLUG := $(shell gcc -v 2>&1 | \
|
||||
sed -n 's:COLLECT_LTO_WRAPPER=\(/.*/\)[^/]*:\1:p')liblto_plugin.so
|
||||
|
||||
# ARFLAGS is for Automake
|
||||
# AR_FLAGS is for Libtool
|
||||
# These activate the LTO pluggin, but also remove the 'u' option
|
||||
# from ar, since its now ignored with Debian's default to 'D'.
|
||||
LTOSETUP = \
|
||||
LDFLAGS='-fuse-linker-plugin' \
|
||||
NM='nm --plugin $(LTOPLUG)' \
|
||||
ARFLAGS='cr --plugin $(LTOPLUG)' \
|
||||
AR_FLAGS='cr --plugin $(LTOPLUG)' \
|
||||
RANLIB='ranlib --plugin $(LTOPLUG)' \
|
||||
# AR_FLAGS is for Libtool, (but libtool 2.4.7 will now use ARFLAGS as well)
|
||||
# The gcc-tools activate the LTO plugin.
|
||||
LTOSETUP = \
|
||||
LDFLAGS='-fuse-linker-plugin' \
|
||||
NM='gcc-nm' \
|
||||
AR='gcc-ar' \
|
||||
ARFLAGS='cr' \
|
||||
AR_FLAGS='cr' \
|
||||
RANLIB='gcc-ranlib' \
|
||||
VALGRIND=false
|
||||
GCDADIR := $(shell pwd)/gcda
|
||||
|
||||
|
|
|
|||
35
default.nix.in
Normal file
35
default.nix.in
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# -*- mode: nix; coding: utf-8 -*-
|
||||
# Copyright (C) 2022 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/>.
|
||||
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
let
|
||||
version = "@VERSION@";
|
||||
in
|
||||
pkgs.stdenv.mkDerivation {
|
||||
inherit version;
|
||||
pname = "spot";
|
||||
|
||||
buildInputs = [
|
||||
pkgs.python3
|
||||
];
|
||||
|
||||
src = ./.;
|
||||
|
||||
enableParallelBuilding = true;
|
||||
}
|
||||
|
|
@ -27,6 +27,9 @@
|
|||
(setenv "SPOT_DOTEXTRA" "node[fontsize=12] fontsize=12 stylesheet=\"spot.css\" edge[arrowhead=vee, arrowsize=.7, fontsize=12]")
|
||||
(setq org-babel-temporary-directory "@abs_top_builddir@/doc/org/tmp")
|
||||
(make-directory org-babel-temporary-directory t)
|
||||
; has to be set globally, not buffer-local
|
||||
(setq ess-ask-for-ess-directory nil)
|
||||
(setq ess-startup-directory 'default-directory)
|
||||
(org-babel-do-load-languages 'org-babel-load-languages
|
||||
`((,(if (version< org-version "8.3") 'sh 'shell) . t)
|
||||
(python . t)
|
||||
|
|
@ -39,7 +42,6 @@
|
|||
(org-babel-python-command . "@PYTHON@")
|
||||
(org-babel-C++-compiler . "./g++wrap")
|
||||
(shell-file-name . "@SHELL@")
|
||||
(ess-ask-for-ess-directory . nil)
|
||||
(org-export-html-postamble . nil)
|
||||
(org-html-table-header-tags
|
||||
"<th scope=\"%s\"%s><div><span>" . "</span></div></th>")
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ EOF
|
|||
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | AF | ok | 0 | 0.0211636 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 |
|
||||
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | L2D | ok | 0 | 0.0028508 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 |
|
||||
|
||||
* Language preserving transformation
|
||||
* Transformation that preserve or complement languages
|
||||
|
||||
By default =autcross= assumes that for a given input the automata
|
||||
produced by all tools should be equivalent. However it does not
|
||||
|
|
@ -261,6 +261,13 @@ automaton, it is worth to pass the =--language-preserved= option to
|
|||
=autfilt=. Doing so a bit like adding =cat %H>%O= as another tool: it
|
||||
will also ensure that the output is equivalent to the input.
|
||||
|
||||
Similarly, if the tools being tested implement complementation
|
||||
algorithm, adding the =--language-complemented= will additionally
|
||||
compare the outputs using this own complementation algorithm. Using
|
||||
this option is more efficient than passing =autfilt --complement= as a
|
||||
tool, since =autcross= can save on complementation by using the input
|
||||
automaton.
|
||||
|
||||
* Detecting problems
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: checks
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
|||
(iw) inherently weak. Use uppercase letters to
|
||||
negate them.
|
||||
%d 1 if the output is deterministic, 0 otherwise
|
||||
%e number of reachable edges
|
||||
%e, %[LETTER]e number of edges (add one LETTER to select (r)
|
||||
reachable [default], (u) unreachable, (a) all).
|
||||
%f the formula, in Spot's syntax
|
||||
%F name of the input file
|
||||
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
|
||||
|
|
@ -170,8 +171,11 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
|||
LETTERS to restrict to(u) user time, (s) system
|
||||
time, (p) parent process, or (c) children
|
||||
processes.
|
||||
%s number of reachable states
|
||||
%t number of reachable transitions
|
||||
%s, %[LETTER]s number of states (add one LETTER to select (r)
|
||||
reachable [default], (u) unreachable, (a) all).
|
||||
%t, %[LETTER]t number of transitions (add one LETTER to select
|
||||
(r) reachable [default], (u) unreachable, (a)
|
||||
all).
|
||||
%u, %[e]u number of states (or [e]dges) with universal
|
||||
branching
|
||||
%u, %[LETTER]u 1 if the automaton contains some universal
|
||||
|
|
|
|||
|
|
@ -6,18 +6,22 @@
|
|||
|
||||
* Generic reference
|
||||
|
||||
If you need to cite the Spot project in some academic paper, please
|
||||
use the following reference:
|
||||
If you need to cite the Spot project, the latest tool paper about
|
||||
it is the following reference:
|
||||
|
||||
- *Spot 2.0 — a framework for LTL and ω-automata manipulation*,
|
||||
/Alexandre Duret-Lutz/, /Alexandre Lewkowicz/, /Amaury Fauchille/,
|
||||
/Thibaud Michaud/, /Etienne Renault/, and /Laurent Xu/. In Proc.
|
||||
of ATVA'16, LNCS 9938, pp. 122--129. Chiba, Japan, Oct. 2016.
|
||||
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.16.atva2][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][pdf]])
|
||||
- *From Spot 2.0 to Spot 2.10: What's new?*, /Alexandre Duret-Lutz/,
|
||||
/Etienne Renault/, /Maximilien Colange/, /Florian Renkin/,
|
||||
/Alexandre Gbaguidi Aisse/, /Philipp Schlehuber-Caissier/, /Thomas
|
||||
Medioni/, /Antoine Martin/, /Jérôme Dubois/, /Clément Gillard/, and
|
||||
Henrich Lauko/. In Proc. of CAV'22, LNCS 13372, pp. 174--187.
|
||||
Haifa, Israel, Aug. 2022.
|
||||
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.22.cav][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.22.cav.pdf][pdf]])
|
||||
|
||||
This provides a quick overview of the entire project (the features
|
||||
of the library, [[file:tools.org][the tools]], the Python bindings), and provides many
|
||||
references detailing more specific aspects.
|
||||
#+begin_note
|
||||
Tools evolve while published papers don't. Please always specify
|
||||
the version of Spot (or any other tool) you are using when citing it
|
||||
in a paper. Future versions might have different behaviors.
|
||||
#+end_note
|
||||
|
||||
* Other, more specific, references
|
||||
|
||||
|
|
@ -76,12 +80,28 @@ be more specific about a particular aspect of Spot.
|
|||
- *Generic Emptiness Check for Fun and Profit*,
|
||||
/Christel Baier/, /František Blahoudek/, /Alexandre Duret-Lutz/,
|
||||
/Joachim Klein/, /David Müller/, and /Jan Strejček/.
|
||||
In. Proc. of ATVA'19, LNCS 11781, pp. 11781, Oct 2019. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#baier.19.atva][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.pdf][pdf]] |
|
||||
In. Proc. of ATVA'19, LNCS 11781, pp. 445--461, Oct 2019. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#baier.19.atva][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.pdf][pdf]] |
|
||||
[[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.slides.mefosyloma.pdf][slides1]] | [[https://www.lrde.epita.fr/~adl/dl/adl/baier.19.atva.slides.pdf][slides2]])
|
||||
|
||||
Presents the generic emptiness-check implemented in Spot.
|
||||
|
||||
* Obsolete reference
|
||||
- *Practical Applications of the Alternating Cycle Decomposition*,
|
||||
/Antonio Casares/, /Alexandre Duret-Lutz/, /Klara J. Meyer/, /Florian Renkin/,
|
||||
and /Salomon Sickert/.
|
||||
In. Proc. of TACAS'22, LNCS 13244, pp. 99--117, Apr 2022. ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#casares.22.tacas][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.pdf][pdf]] |
|
||||
[[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.slides.pdf][slides1]] | [[https://www.lrde.epita.fr/~adl/dl/adl/casares.22.tacas.slides2.pdf][slides2]])
|
||||
|
||||
* Obsolete references
|
||||
|
||||
- *Spot 2.0 — a framework for LTL and ω-automata manipulation*,
|
||||
/Alexandre Duret-Lutz/, /Alexandre Lewkowicz/, /Amaury Fauchille/,
|
||||
/Thibaud Michaud/, /Etienne Renault/, and /Laurent Xu/. In Proc.
|
||||
of ATVA'16, LNCS 9938, pp. 122--129. Chiba, Japan, Oct. 2016.
|
||||
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.16.atva2][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][pdf]])
|
||||
|
||||
This provides a quick overview of the entire project (the features
|
||||
of the library, [[file:tools.org][the tools]], the Python bindings), and provides many
|
||||
references detailing more specific aspects.
|
||||
|
||||
- *Spot: an extensible model checking library using transition-based
|
||||
generalized Büchi automata*, /Alexandre Duret-Lutz/ and /Denis
|
||||
|
|
|
|||
|
|
@ -210,11 +210,14 @@ one library requiring another, you will need to link with the =bddx=
|
|||
library. This should be as simple as adding =-lbddx= after =-lspot=
|
||||
in the first three cases.
|
||||
|
||||
Similarly, if Spot has been configured with =--enable-pthread=, you
|
||||
will need to add =-pthread= to the compiler flags.
|
||||
|
||||
In the fourth case where =libtool= is used to link against
|
||||
=libspot.la= linking against =libbddx.la= should not be necessary because
|
||||
Libtool already handles such dependencies. However the version of =libtool=
|
||||
distributed with Debian is patched to ignore those dependencies, so in this
|
||||
case you 2
|
||||
case you have to list all dependencies.
|
||||
|
||||
* Additional suggestions
|
||||
|
||||
|
|
|
|||
|
|
@ -381,13 +381,14 @@ When /transition-based acceptance/ is used, acceptance sets are now
|
|||
sets of /edges/ (or set of /transitions/ if you prefer), and runs are
|
||||
accepting if the edges they visit satisfy the acceptance condition.
|
||||
|
||||
Here is an example of Transition-based Generalized Büchi Automaton
|
||||
(TGBA).
|
||||
Here is an example of Transition-based Büchi Automaton
|
||||
(TBA).
|
||||
|
||||
#+NAME: tgba-example1
|
||||
#+BEGIN_SRC sh
|
||||
ltl2tgba 'GF(a & X(a U b))' -d
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results
|
||||
$txt
|
||||
#+END_SRC
|
||||
|
|
@ -399,27 +400,13 @@ This automaton accept all ω-words that infinitely often match the
|
|||
pattern $a^+;b$ (that is: a positive number of letters where $a$ is
|
||||
true are followed by one letter where $b$ is true).
|
||||
|
||||
Using transition-based acceptance allows for more compact automata.
|
||||
The typical example is the LTL formula =GFa= (infinitely often $a$)
|
||||
that can be represented using a one-state transition-based Büchi
|
||||
automaton:
|
||||
#+NAME: tgba-example2
|
||||
#+BEGIN_SRC sh
|
||||
ltl2tgba 'GFa' -d
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC dot :file concept-tgba2.svg :var txt=tgba-example2 :exports results
|
||||
$txt
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:concept-tgba2.svg]]
|
||||
|
||||
While the same property require a 2-state Büchi automaton using
|
||||
Using transition-based acceptance often allows for more compact automata.
|
||||
For instance the above automaton would need at least 3 states with
|
||||
state-based acceptance:
|
||||
|
||||
#+NAME: tgba-example3
|
||||
#+BEGIN_SRC sh
|
||||
ltl2tgba 'GFa' -B -d
|
||||
ltl2tgba 'GF(a & X(a U b))' -B -d
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results
|
||||
$txt
|
||||
|
|
@ -1035,7 +1022,7 @@ layers.
|
|||
dynamic libraries that [[http://fmt.cs.utwente.nl/tools/ltsmin/][LTSmin]] uses to represent state-spaces. It
|
||||
currently supports libraries generated from Promela models using
|
||||
SpinS or a patched version of DiVinE, but you have to install
|
||||
those third-party tools first. See [[https://gitlab.lrde.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
|
||||
those third-party tools first. See [[https://gitlab.lre.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
|
||||
for details.
|
||||
- In addition to the C++17 API, we also provide Python bindings for
|
||||
=libspotgen=, =libspotltsmin=, =libbddx=, and most of =libspot=.
|
||||
|
|
@ -1047,8 +1034,8 @@ layers.
|
|||
distributed with the rest of Spot, their source-code is publicly
|
||||
available (in case you want to contribute or run a local version).
|
||||
The [[https://spot-sandbox.lrde.epita.fr/][=spot-sandbox=]] website runs from a Docker container whose
|
||||
configuration can be found in [[https://gitlab.lrde.epita.fr/spot/sandbox/tree/master=][this repository]]. The client and
|
||||
server parts of the [[https://spot.lrde.epita.fr/app/][online LTL translator]] can be found in [[https://gitlab.lrde.epita.fr/spot/spot-web-app/][this
|
||||
configuration can be found in [[https://gitlab.lre.epita.fr/spot/sandbox/tree/master=][this repository]]. The client and
|
||||
server parts of the [[https://spot.lrde.epita.fr/app/][online LTL translator]] can be found in [[https://gitlab.lre.epita.fr/spot/spot-web-app/][this
|
||||
repository]].
|
||||
|
||||
* Automaton property flags
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
# This is a wrapper around the compiler, to ensure that the code
|
||||
# example run from the org-mode file are all linked with Spot.
|
||||
# examples run from org-mode files are all linked with Spot.
|
||||
#
|
||||
# Also we save errors to org.errors, so that we can detect issues
|
||||
# after org-mode has exported everything. Otherwise these errors
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
@top_builddir@/libtool link @CXX@ @CXXFLAGS@ @CPPFLAGS@ -Wall -Werror \
|
||||
-I@abs_top_builddir@ -I@abs_top_srcdir@ -I@abs_top_srcdir@/buddy/src \
|
||||
"$@" @abs_top_builddir@/spot/libspot.la \
|
||||
@abs_top_builddir@/buddy/src/libbddx.la 2> errors.$$
|
||||
@abs_top_builddir@/buddy/src/libbddx.la @LIBSPOT_PTHREAD@ 2> errors.$$
|
||||
code=$?
|
||||
if test $code -ne 0 && test -s errors.$$; then
|
||||
cat errors.$$ >>org.errors
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ the HOA format, the output may not be exactly the same as the input.
|
|||
sets.
|
||||
|
||||
This hard-coded limit can be augmented at configure time
|
||||
using option `--enable-max-accsets=N`, but doing so will consume
|
||||
using option =--enable-max-accsets=N=, but doing so will consume
|
||||
more memory and time.
|
||||
|
||||
- Multiple (or missing) initial states are emulated.
|
||||
|
|
@ -76,7 +76,8 @@ the HOA format, the output may not be exactly the same as the input.
|
|||
is transformed into an equivalent TωA by merging the initial states
|
||||
into a single one. The merged state can either be one of the
|
||||
original initial states (if one of those has no incoming edge) or a
|
||||
new state introduced for that purpose.
|
||||
new state introduced for that purpose. This "conversion" may change
|
||||
the completeness property of the automaton.
|
||||
|
||||
Similarly, when an automaton with no initial state is loaded (this
|
||||
includes the case where the automaton has no state), a disconnected
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ checking. It has the following notable features:
|
|||
weak-DBA, removal of useless SCCs, acceptance-condition
|
||||
transformations, determinization, [[file:satmin.org][SAT-based minimization of
|
||||
deterministic automata]], [[https://spot.lrde.epita.fr/ipynb/zlktree.html][Alternating Cycle Decomposition]], etc.
|
||||
- Support for [[file:tut40.org][Safety]] and [[https://spot-dev.lrde.epita.fr/ipynb/games.html][parity games]].
|
||||
- Support for [[file:tut40.org][Safety]] and [[https://spot.lrde.epita.fr/ipynb/games.html][parity games]].
|
||||
- Applications to [[file:ltlsynt.org][reactive synthesis]] and [[https://spot.lrde.epita.fr/ipynb/atva16-fig2b.html][model checking]].
|
||||
- In addition to the C++ interface, most of its algorithms are usable
|
||||
via [[file:tools.org][command-line tools]], and via [[file:tut.org][Python bindings]].
|
||||
|
|
@ -37,7 +37,7 @@ checking. It has the following notable features:
|
|||
|
||||
* Latest version
|
||||
|
||||
The latest version is *{{{LASTRELEASE}}}* and was released on
|
||||
The latest version is *call_SPOT_VERSION()* and was released on
|
||||
*{{{LASTDATE}}}*. Please see the [[file:install.org][download and installation instructions]].
|
||||
|
||||
* Documentation
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
(package-install ess)))))
|
||||
|
||||
(require 'ox-publish)
|
||||
(require 'org-install)
|
||||
(require 'hoa-mode)
|
||||
|
||||
; See https://github.com/emacs-ess/ESS/issues/1052
|
||||
|
|
@ -89,7 +88,9 @@
|
|||
(setq org-babel-C++-compiler "./g++wrap")
|
||||
(setq shell-file-name "@SHELL@")
|
||||
(setq ess-ask-for-ess-directory nil)
|
||||
|
||||
; setting ess-startup-directory to 'default-directory is enough with
|
||||
; newer ESS version (after Fev 2022) but does not work with older ones.
|
||||
(setq ess-startup-directory "@abs_top_builddir@/doc/org")
|
||||
(setq org-babel-default-header-args:plantuml
|
||||
'((:results . "file")
|
||||
(:exports . "results")
|
||||
|
|
@ -159,7 +160,7 @@ up.html points to index.html, then the result is:
|
|||
(setq body res)
|
||||
(not cmp)))
|
||||
(concat "#+TITLE: " title
|
||||
"\n#+SETUPFILE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
|
||||
"\n#+INCLUDE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
|
||||
body)))
|
||||
|
||||
(setq org-publish-project-alist
|
||||
|
|
@ -184,6 +185,49 @@ up.html points to index.html, then the result is:
|
|||
:publishing-function org-publish-attachment)
|
||||
("spot-all" :components ("spot-html" "spot-static"))))
|
||||
|
||||
|
||||
|
||||
|
||||
;;; Org-mode 9.5 is now using <img> to render SVG images.
|
||||
;;; Unfortunately, this breaks SVG images that use external style
|
||||
;;; sheets as <img> are expected to be self-contained.
|
||||
;;;
|
||||
;;; Since we do use such external style-sheets and never had
|
||||
;;; any issue with <object type="image/svg+xml"...>, we revert
|
||||
;;; to the previous behavior.
|
||||
;;;
|
||||
;;; The following function is based on org-html--svg-image from
|
||||
;;; Org-mode 9.4.5, with the addition of the SVG extension test.
|
||||
(defun spot-svg-output-as-object (source attributes info)
|
||||
"If source is an SVG file, return an \"object\" embedding svg file
|
||||
SOURCE with given ATTRIBUTES.
|
||||
INFO is a plist used as a communication channel. Otherwise return nil.
|
||||
|
||||
The special attribute \"fallback\" can be used to specify a
|
||||
fallback image file to use if the object embedding is not
|
||||
supported. CSS class \"org-svg\" is assigned as the class of the
|
||||
object unless a different class is specified with an attribute."
|
||||
(when (string= "svg" (file-name-extension source))
|
||||
(let ((fallback (plist-get attributes :fallback))
|
||||
(attrs (org-html--make-attribute-string
|
||||
(org-combine-plists
|
||||
;; Remove fallback attribute, which is not meant to
|
||||
;; appear directly in the attributes string, and
|
||||
;; provide a default class if none is set.
|
||||
'(:class "org-svg") attributes '(:fallback nil)))))
|
||||
(format "<object type=\"image/svg+xml\" data=\"%s\" %s>\n%s</object>"
|
||||
source
|
||||
attrs
|
||||
(if fallback
|
||||
(org-html-close-tag
|
||||
"img" (format "src=\"%s\" %s" fallback attrs) info)
|
||||
"Sorry, your browser does not support SVG.")))))
|
||||
;;; Hack org-html--format-image to call the above first.
|
||||
;;; (The org-html--svg-image function was removed when the formater code
|
||||
;;; switched to <img> for SVG.)
|
||||
(unless (fboundp 'org-html--svg-image)
|
||||
(advice-add 'org-html--format-image :before-until 'spot-svg-output-as-object))
|
||||
|
||||
(org-publish-all t)
|
||||
;;; org-babel-remove-temporary-directory does not correctly remove
|
||||
;;; nested directories and we have some files in tmp/.libs/ because of
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@
|
|||
:CUSTOM_ID: tar
|
||||
:END:
|
||||
|
||||
The latest release of Spot is version {{{LASTRELEASE}}}:
|
||||
The latest release of Spot is version call_SPOT_VERSION() and was released on {{{LASTDATE}}}:
|
||||
|
||||
- {{{LASTTARBALL}}} (see also the {{{LASTNEWS}}})
|
||||
- call_TARBALL_LINK() (see also the call_NEWS_LINK())
|
||||
|
||||
Past releases can be found [[https://www.lrde.epita.fr/dload/spot/][in the same directory]]. If you are
|
||||
interested in /future/ releases, you can always peek at the [[https://gitlab.lrde.epita.fr/spot/spot/-/jobs/artifacts/next/browse?job=debian-stable-gcc][last
|
||||
interested in /future/ releases, you can always peek at the [[https://gitlab.lre.epita.fr/spot/spot/-/jobs/artifacts/next/browse?job=make-dist][last
|
||||
successful development build]].
|
||||
|
||||
** Requirements
|
||||
|
|
@ -52,10 +52,13 @@ make
|
|||
make install
|
||||
#+END_SRC
|
||||
|
||||
Before running =make install=, you might want to run =make check= to
|
||||
run our test-suite.
|
||||
|
||||
Files =INSTALL= and =README= included in the tarball contains more
|
||||
explanations about the various options you can use during this
|
||||
process. Also note that =README= has a section about troubleshooting
|
||||
installations.
|
||||
explanations about the various options you can use during the
|
||||
compilation process. Also note that =README= has a section about
|
||||
troubleshooting installations.
|
||||
|
||||
* Installing the Debian packages
|
||||
:PROPERTIES:
|
||||
|
|
@ -88,7 +91,9 @@ apt-get install spot libspot-dev spot-doc python3-spot # Or a subset of those
|
|||
Note that our Debian repository is signed since that is the new Debian
|
||||
policy, and both of the above command blocks start with a download of
|
||||
our [[https://www.lrde.epita.fr/repo/debian.gpg][GPG key]]. Its fingerprint is =209B 7362 CFD6 FECF B41D 717F 03D9
|
||||
9E74 44F2 A84A=, if you want to verify it.
|
||||
9E74 44F2 A84A=, if you want to verify it. If you have an old copy of
|
||||
the GPG key that expired, please download it again: the current
|
||||
version should be valid until 2032.
|
||||
|
||||
The package =spot= contains the [[file:tools.org][command-line tools]]. =libspot-dev=
|
||||
contains the header files if you plan to use Spot in a C++17
|
||||
|
|
@ -162,11 +167,11 @@ the (working) code that should be part of the next major release.
|
|||
To clone the git repository, use
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
git clone https://gitlab.lrde.epita.fr/spot/spot.git
|
||||
git clone https://gitlab.lre.epita.fr/spot/spot.git
|
||||
#+END_SRC
|
||||
|
||||
This should put you on the =next= branch by default. From there, read
|
||||
the [[https://gitlab.lrde.epita.fr/spot/spot/blob/next/HACKING][HACKING]] file that should be at the top of your cloned repository:
|
||||
the [[https://gitlab.lre.epita.fr/spot/spot/blob/next/HACKING][HACKING]] file that should be at the top of your cloned repository:
|
||||
it lists all the tools you should install before attempting to compile
|
||||
the source tree.
|
||||
|
||||
|
|
|
|||
|
|
@ -924,7 +924,7 @@ compare the number of states produced by the two configurations of
|
|||
=ltl2tgba= for each formula, we just need to plot column
|
||||
=dt2$state.small= against =dt2$state.deter=.
|
||||
|
||||
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r.svg
|
||||
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r.svg
|
||||
library(ggplot2)
|
||||
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
||||
geom_abline(colour='white') + geom_point()
|
||||
|
|
@ -937,7 +937,7 @@ ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
|||
We should probably print the formulas for the cases where the two
|
||||
sizes differ.
|
||||
|
||||
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r2.svg
|
||||
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r2.svg
|
||||
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
||||
geom_abline(colour='white') + geom_point() +
|
||||
geom_text(data=subset(dt2, states.small != states.deter),
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@
|
|||
|
||||
* Basic usage
|
||||
|
||||
This tool synthesizes controllers from LTL/PSL formulas.
|
||||
This tool synthesizes reactive controllers from LTL/PSL formulas.
|
||||
|
||||
Consider a set $I$ of /input/ atomic propositions, a set $O$ of output atomic
|
||||
propositions, and a PSL formula \phi over the propositions in $I \cup O$. A
|
||||
=controller= realizing \phi is a function $c: (2^{I})^\star \times 2^I \mapsto
|
||||
*reactive controller* realizing \phi is a function $c: (2^{I})^\star \times 2^I \mapsto
|
||||
2^O$ such that, for every \omega-word $(u_i)_{i \in N} \in (2^I)^\omega$ over
|
||||
the input propositions, the word $(u_i \cup c(u_0 \dots u_{i-1}, u_i))_{i \in
|
||||
N}$ satisfies \phi.
|
||||
|
||||
If a controller exists, then one with finite memory exists. Such controllers
|
||||
are easily represented as automata (or more specifically as I/O automata or
|
||||
transducers). In the automaton representing the controller, the acceptance
|
||||
condition is irrelevant and trivially true.
|
||||
If a reactive controller exists, then one with finite memory
|
||||
exists. Such controllers are easily represented as automata (or more
|
||||
specifically as Mealy machines). In the automaton representing the
|
||||
controller, the acceptance condition is irrelevant and trivially true.
|
||||
|
||||
=ltlsynt= has three mandatory options:
|
||||
- =--ins=: a comma-separated list of input atomic propositions;
|
||||
|
|
@ -27,45 +27,52 @@ condition is irrelevant and trivially true.
|
|||
- =--formula= or =--file=: a specification in LTL or PSL.
|
||||
|
||||
One of =--ins= or =--outs= may be omitted, as any atomic proposition not listed
|
||||
as input can be assumed to be an output and vice-versa.
|
||||
as input can be assumed to be output and vice-versa.
|
||||
|
||||
The following example illustrates the synthesis of a controller acting as an
|
||||
=AND= gate. We have two inputs =a= and =b= and one output =c=, and we want =c=
|
||||
to always be the =AND= of the two inputs:
|
||||
The following example illustrates the synthesis of a controller
|
||||
ensuring that input =i1= and =i2= are both true initially if and only
|
||||
if eventually output =o1= will go from true to false at some point.
|
||||
Note that this is an equivalence, not an implication.
|
||||
|
||||
#+NAME: example
|
||||
#+BEGIN_SRC sh :exports both
|
||||
ltlsynt --ins=a,b -f 'G (a & b <=> c)'
|
||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))'
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: example
|
||||
#+begin_example
|
||||
REALIZABLE
|
||||
HOA: v1
|
||||
States: 1
|
||||
States: 3
|
||||
Start: 0
|
||||
AP: 3 "a" "b" "c"
|
||||
AP: 3 "i1" "i2" "o1"
|
||||
acc-name: all
|
||||
Acceptance: 0 t
|
||||
properties: trans-labels explicit-labels state-acc deterministic
|
||||
controllable-AP: 2
|
||||
--BODY--
|
||||
State: 0
|
||||
[!0&!2 | !1&!2] 0
|
||||
[0&1&2] 0
|
||||
[0&1&2] 1
|
||||
[!0&2 | !1&2] 2
|
||||
State: 1
|
||||
[!2] 0
|
||||
State: 2
|
||||
[2] 2
|
||||
--END--
|
||||
#+end_example
|
||||
|
||||
The output is composed of two parts:
|
||||
- the first one is a single line =REALIZABLE= or =UNREALIZABLE;=
|
||||
- the second one, only present in the =REALIZABLE= case is an automaton describing the controller.
|
||||
In this example, the controller has a single
|
||||
state, with two loops labeled by =a & b & c= and =(!a | !b) & !c=.
|
||||
- The first one is a single line =REALIZABLE= or =UNREALIZABLE=; the presence of this
|
||||
line, required by the [[http://http://www.syntcomp.org/][SyntComp competition]], can be disabled with option =--hide-status=.
|
||||
- The second one, only present in the =REALIZABLE= case, is an automaton describing the controller.
|
||||
|
||||
The controller contains the line =controllable-AP: 2=, which means that this automaton
|
||||
should be interpreted as a Mealy machine where =o0= is part of the output.
|
||||
Using the =--dot= option, makes it easier to visualize this machine.
|
||||
|
||||
#+NAME: exampledot
|
||||
#+BEGIN_SRC sh :exports none :noweb yes
|
||||
sed 1d <<EOF | autfilt --dot=.A
|
||||
<<example()>>
|
||||
EOF
|
||||
#+BEGIN_SRC sh :exports code
|
||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --dot
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC dot :file ltlsyntex.svg :var txt=exampledot :exports results
|
||||
|
|
@ -75,9 +82,6 @@ EOF
|
|||
#+RESULTS:
|
||||
[[file:ltlsyntex.svg]]
|
||||
|
||||
The label =a & b & c= should be understood as: "if the input is =a&b=,
|
||||
the output should be =c=".
|
||||
|
||||
The following example illustrates the case of an unrealizable specification. As
|
||||
=a= is an input proposition, there is no way to guarantee that it will
|
||||
eventually hold.
|
||||
|
|
@ -90,11 +94,68 @@ ltlsynt --ins=a -f 'F a'
|
|||
: UNREALIZABLE
|
||||
|
||||
By default, the controller is output in HOA format, but it can be
|
||||
output as an [[http://fmv.jku.at/aiger/][AIGER]] circuit thanks to the =--aiger= flag. This is the
|
||||
output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
|
||||
output as an And-Inverter-Graph in [[http://fmv.jku.at/aiger/][AIGER format]] using the =--aiger=
|
||||
flag. This is the output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
|
||||
|
||||
The generation of a controller can be disabled with the flag =--realizability=.
|
||||
In this case, =ltlsynt= output is limited to =REALIZABLE= or =UNREALIZABLE=.
|
||||
#+NAME: exampleaig
|
||||
#+BEGIN_SRC sh :exports both
|
||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --aiger
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS: exampleaig
|
||||
#+begin_example
|
||||
REALIZABLE
|
||||
aag 14 2 2 1 10
|
||||
2
|
||||
4
|
||||
6 14
|
||||
8 29
|
||||
7
|
||||
10 7 9
|
||||
12 4 10
|
||||
14 2 12
|
||||
16 7 8
|
||||
18 4 16
|
||||
20 5 7
|
||||
22 21 19
|
||||
24 2 23
|
||||
26 3 7
|
||||
28 27 25
|
||||
i0 i1
|
||||
i1 i2
|
||||
o0 o1
|
||||
#+end_example
|
||||
|
||||
The above format is not very human friendly. Again, by passing both
|
||||
=--aiger= and =--dot=, one can display the And-Inverter-Graph representing
|
||||
the controller:
|
||||
|
||||
#+NAME: exampleaigdot
|
||||
#+BEGIN_SRC sh :exports code
|
||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --aiger --dot
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC dot :file ltlsyntexaig.svg :var txt=exampleaigdot :exports results
|
||||
$txt
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:ltlsyntexaig.svg]]
|
||||
|
||||
In the above diagram, round nodes represent AND gates. Small black
|
||||
circles represent inversions (or negations), colored triangles are
|
||||
used to represent input signals (at the bottom) and output signals (at
|
||||
the top), and finally rectangles represent latches. A latch is a one
|
||||
bit register that delays the signal by one step. Initially, all
|
||||
latches are assumed to contain =false=, and them emit their value from
|
||||
the =L0_out= and =L1_out= rectangles at the bottom. Their input value,
|
||||
to be emitted at the next step, is received via the =L0_in= and =L1_in=
|
||||
boxes at the top. In =ltlsynt='s encoding, the set of latches is used
|
||||
to keep track of the current state of the Mealy machine.
|
||||
|
||||
The generation of a controller can be disabled with the flag
|
||||
=--realizability=. In this case, =ltlsynt='s output is limited to
|
||||
=REALIZABLE= or =UNREALIZABLE=.
|
||||
|
||||
* TLSF
|
||||
|
||||
|
|
@ -104,14 +165,20 @@ specification language created for the purpose of this competition.
|
|||
Fortunately, the SYNTCOMP organizers also provide a tool called
|
||||
[[https://github.com/reactive-systems/syfco][=syfco=]] which can translate a TLSF specification to an LTL formula.
|
||||
|
||||
The following four steps show you how a TLSF specification called =FILE= can
|
||||
The following line shows how a TLSF specification called =FILE= can
|
||||
be synthesized using =syfco= and =ltlsynt=:
|
||||
|
||||
#+BEGIN_SRC sh :export code
|
||||
LTL=$(syfco FILE -f ltlxba -m fully)
|
||||
IN=$(syfco FILE --print-input-signals)
|
||||
OUT=$(syfco FILE --print-output-signals)
|
||||
ltlsynt --formula="$LTL" --ins="$IN" --outs="$OUT"
|
||||
ltlsynt --tlsf FILE
|
||||
#+END_SRC
|
||||
|
||||
The above =--tlsf= option will call =syfco= to perform the conversion
|
||||
and extract output signals, as if you had used:
|
||||
|
||||
#+BEGIN_SRC sh :export code
|
||||
LTL=$(syfco -f ltlxba -m fully FILE)
|
||||
OUT=$(syfco --print-output-signals FILE)
|
||||
ltlsynt --formula="$LTL" --outs="$OUT"
|
||||
#+END_SRC
|
||||
|
||||
* Internal details
|
||||
|
|
@ -171,7 +238,18 @@ be tried by separating them using commas. For instance
|
|||
You can also ask =ltlsynt= to print to obtained parity game into
|
||||
[[https://github.com/tcsprojects/pgsolver][PGSolver]] format, with the flag =--print-pg=, or in the HOA format,
|
||||
using =--print-game-hoa=. These flag deactivate the resolution of the
|
||||
parity game.
|
||||
parity game. Note that if any of those flag is used with =--dot=, the game
|
||||
will be printed in the Dot format instead:
|
||||
|
||||
#+NAME: examplegamedot
|
||||
#+BEGIN_SRC sh :exports code
|
||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --print-game-hoa --dot
|
||||
#+END_SRC
|
||||
#+BEGIN_SRC dot :file ltlsyntexgame.svg :var txt=examplegamedot :exports results
|
||||
$txt
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
[[file:ltlsyntexgame.svg]]
|
||||
|
||||
For benchmarking purpose, the =--csv= option can be used to record
|
||||
intermediate statistics about the resolution.
|
||||
|
|
@ -194,6 +272,11 @@ Further improvements are described in the following paper:
|
|||
/Alexandre Duret-Lutz/, and /Adrien Pommellet/. Presented at the
|
||||
SYNT'21 workshop. ([[https://www.lrde.epita.fr/~adl/dl/adl/renkin.21.synt.pdf][pdf]] | [[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#renkin.21.synt][bib]])
|
||||
|
||||
Simplification of Mealy machines is discussed in:
|
||||
|
||||
- *Effective reductions of Mealy machines*, /Florian Renkin/,
|
||||
/Philipp Schlehuber-Caissier/, /Alexandre Duret-Lutz/, and /Adrien Pommellet/.
|
||||
Presented at FORTE'22. ([[https://www.lrde.epita.fr/~adl/dl/adl/renkin.22.forte.pdf][pdf]] | [[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#renkin.22.forte][bib]])
|
||||
|
||||
# LocalWords: utf ltlsynt AIGER html args mapsto SRC acc aiger TLSF
|
||||
# LocalWords: UNREALIZABLE unrealizable SYNTCOMP realizability Proc
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil
|
||||
#+EMAIL: spot@lrde.epita.fr
|
||||
#+HTML_LINK_HOME: index.html
|
||||
#+MACRO: SPOTVERSION 2.10.4
|
||||
#+MACRO: LASTRELEASE 2.10.4
|
||||
#+MACRO: LASTTARBALL [[http://www.lrde.epita.fr/dload/spot/spot-2.10.4.tar.gz][=spot-2.10.4.tar.gz=]]
|
||||
#+MACRO: LASTNEWS [[https://gitlab.lrde.epita.fr/spot/spot/blob/spot-2-10-4/NEWS][summary of the changes]]
|
||||
#+MACRO: LASTDATE 2022-02-01
|
||||
#+MACRO: LASTDATE 2023-04-20
|
||||
|
||||
#+NAME: SPOT_VERSION
|
||||
#+BEGIN_SRC python :exports none :results value :wrap org
|
||||
return "2.11.5"
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: TARBALL_LINK
|
||||
#+BEGIN_SRC python :exports none :var version=SPOT_VERSION :results output :wrap org
|
||||
print(f"[[http://www.lrde.epita.fr/dload/spot/spot-{version}.tar.gz][=spot-{version}.tar.gz=]]")
|
||||
#+END_SRC
|
||||
|
||||
#+NAME: NEWS_LINK
|
||||
#+BEGIN_SRC python :exports none :var version=SPOT_VERSION :results output :wrap org
|
||||
version = version.replace('.', '-')
|
||||
print(f"[[https://gitlab.lre.epita.fr/spot/spot/blob/spot-{version}/NEWS][summary of the changes]]")
|
||||
#+END_SRC
|
||||
|
||||
#+ATTR_HTML: :id spotlogo
|
||||
[[file:spot2.svg]]
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ h1::before{content:"";position:absolute;z-index:-1;background-color:#ffe35e;left
|
|||
#table-of-contents #text-table-of-contents{text-align:left}
|
||||
#org-div-home-and-up{text-align:center;font-size:100%}
|
||||
.outline-2 h2{display:block;width:100%;position:relative}
|
||||
.outline-2 h2::before{content:"";height:100%;width:calc(100% + 2em);position:absolute;z-index:-1;bottom:0em;left:-1em;background-color:#ffe35e;background:linear-gradient(45deg,#ffe35e 50%,transparent 75%);transform:skew(10deg);border-radius:5px;}
|
||||
.outline-2 h2::before{content:"";height:100%;width:calc(100% + 2em);position:absolute;z-index:-1;bottom:0em;left:-1em;background:linear-gradient(45deg,#ffe35e 50%,transparent 75%);transform:skew(10deg);border-radius:5px;}
|
||||
.outline-3 h3{display:block;width:auto;position:relative}
|
||||
.outline-3 h3::before{content:"";position:absolute;z-index:-1;width:calc(100% + 2em);height:100%;left:-1em;bottom:0em;;background-color:#ffe35e;background:linear-gradient(45deg,#ffe35e 25%,transparent 50%);transform:skew(10deg);border-radius:3px}
|
||||
.outline-3 h3::before{content:"";position:absolute;z-index:-1;width:calc(100% + 2em);height:100%;left:-1em;bottom:0em;background:linear-gradient(45deg,#ffe35e 25%,transparent 50%);transform:skew(10deg);border-radius:3px}
|
||||
.outline-2 h2:hover::before,.outline-3 h3:hover::before{background-color:#ffe35e}
|
||||
pre{margin:1.2ex}
|
||||
pre.src{padding-top:8px;border-left-style:solid;border-color:#00adad;overflow:auto;margin-top:0;margin-bottom:0}
|
||||
|
|
@ -77,11 +77,13 @@ thead tr{background:#ffe35e}
|
|||
.org-hoa-ap-number{color:#d70079}
|
||||
.implem{background:#fff0a6;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#ffe35e;border-style:solid none}
|
||||
.implem::before{background:#ffe35e;content:"Implementation detail";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
|
||||
.note{background:#fff0a6;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#ffe35e;border-style:solid none}
|
||||
.note::before{background:#ffe35e;content:"Note";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
|
||||
.caveat{background:#ef99c9;padding:0.5ex 1ex 0.5ex 1ex;margin:1ex;border-color:#d70079;border-style:solid none}
|
||||
.caveat::before{background:#d70079;content:"Caveat";padding:.5ex;position:relative;top:0;left:0;font-weight:bold}
|
||||
.spotlogo{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogo}
|
||||
g.spotlogobg{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogobg}
|
||||
g#version{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
|
||||
g.spotlogover{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
|
||||
@keyframes animspotlogo{
|
||||
0%{transform:rotateY(90deg)}
|
||||
80%{transform:rotateY(0deg)}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.83905%,93.728638%);fill-opacity:1;" d="M 29.054688 0.707031 L 0.707031 29.054688 L 29.054688 57.402344 L 43.226562 43.226562 L 43.226562 14.882812 Z M 29.054688 0.707031 "/>
|
||||
<path style="fill:none;stroke-width:1.41731;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(30.000305%,77.487183%,95.610046%);stroke-opacity:1;stroke-miterlimit:10;" d="M -0.0003125 28.347969 L -28.347969 0.0003125 L -0.0003125 -28.347344 L 14.171563 -14.171563 L 14.171563 14.172187 Z M -0.0003125 28.347969 " transform="matrix(1,0,0,-1,29.055,29.055)"/>
|
||||
</g>
|
||||
<g id="version">
|
||||
<g class="spotlogover">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,94.898987%,0%);fill-opacity:1;" d="M 34.84375 29.054688 C 34.84375 25.855469 32.253906 23.265625 29.054688 23.265625 C 25.855469 23.265625 23.265625 25.855469 23.265625 29.054688 C 23.265625 32.253906 25.855469 34.84375 29.054688 34.84375 C 32.253906 34.84375 34.84375 32.253906 34.84375 29.054688 Z M 34.84375 29.054688 "/>
|
||||
<path style="fill:none;stroke-width:2.83466;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.78875 0.0003125 C 5.78875 3.199531 3.198906 5.789375 -0.0003125 5.789375 C -3.199531 5.789375 -5.789375 3.199531 -5.789375 0.0003125 C -5.789375 -3.198906 -3.199531 -5.78875 -0.0003125 -5.78875 C 3.198906 -5.78875 5.78875 -3.198906 5.78875 0.0003125 Z M 5.78875 0.0003125 " transform="matrix(1,0,0,-1,29.055,29.055)"/>
|
||||
<path style="fill:none;stroke-width:5.66934;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 10.499688 15.965156 C 9.312188 18.754219 7.015313 21.062812 3.945 22.18 C -1.941719 24.320625 -8.445625 21.289375 -10.590156 15.402656 C -11.972969 11.597969 -11.222969 7.340156 -8.621406 4.234687 C -6.465156 1.668281 -3.285469 0.187812 0.0660938 0.187812 C 6.327813 0.187812 11.405938 -4.890313 11.405938 -11.152031 C 11.405938 -17.41375 6.327813 -22.491875 0.0660938 -22.491875 C -6.195625 -22.491875 -11.27375 -17.41375 -11.27375 -11.152031 " transform="matrix(1,0,0,-1,29.055,29.055)"/>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
|
@ -1,12 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#+TITLE: Command-line tools installed by Spot {{{SPOTVERSION}}}
|
||||
#+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}}
|
||||
#+INCLUDE: setup.org
|
||||
#+TITLE: Command-line tools installed by Spot
|
||||
#+DESCRIPTION: List of all the command-line tools installed by Spot
|
||||
#+HTML_LINK_UP: index.html
|
||||
#+PROPERTY: header-args:sh :results verbatim :exports both
|
||||
|
||||
This document introduces command-line tools that are installed with
|
||||
the Spot library. We give some examples to highlight possible
|
||||
Spot call_SPOT_VERSION(). We give some examples to highlight possible
|
||||
use-cases but shall not attempt to cover all features exhaustively
|
||||
(please check the man pages for further inspiration).
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ real notebooks instead.
|
|||
automata.
|
||||
- [[https://spot.lrde.epita.fr/ipynb/atva16-fig2a.html][=atva16-fig2a.ipynb=]] first example from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][ATVA'16 tool paper]].
|
||||
- [[https://spot.lrde.epita.fr/ipynb/atva16-fig2b.html][=atva16-fig2b.ipynb=]] second example from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.16.atva2.pdf][ATVA'16 tool paper]].
|
||||
- [[https://spot.lrde.epita.fr/ipynb/cav22-figs.html][=cav22-figs.ipynb=]] figures from our [[https://www.lrde.epita.fr/~adl/dl/adl/duret.22.cav.pdf][CAV'22 tool paper]].
|
||||
- [[https://spot.lrde.epita.fr/ipynb/alternation.html][=alternation.ipynb=]] examples of alternating automata.
|
||||
- [[https://spot.lrde.epita.fr/ipynb/stutter-inv.html][=stutter-inv.ipynb=]] working with stutter-invariant formulas properties.
|
||||
- [[https://spot.lrde.epita.fr/ipynb/satmin.html][=satmin.ipynb=]] Python interface for [[file:satmin.org][SAT-based minimization of deterministic ω-automata]].
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ simplifications called /trivial identities/. For instance
|
|||
=formula::F(formula::X(formula::tt()))= will return the same formula
|
||||
as =formula::tt()=. These simplifications are those that involve the
|
||||
true and false constants, impotence (=F(F(e))=F(e)=), involutions
|
||||
(=Not(Not(e)=e=), associativity
|
||||
(=Not(Not(e))=e=), associativity
|
||||
(=And({And({e1,e2},e3})=And({e1,e2,e3})=). See [[https://spot.lrde.epita.fr/tl.pdf][tl.pdf]] for a list of
|
||||
these /trivial identities/.
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ detail of the top-level operator in the formula.
|
|||
|
||||
std::cout << f << '\n';
|
||||
|
||||
// kindstar() prints the name of the operator
|
||||
// kindstr() prints the name of the operator
|
||||
// size() return the number of operands of the operators
|
||||
std::cout << f.kindstr() << ", " << f.size() << " children\n";
|
||||
// operator[] accesses each operand
|
||||
|
|
@ -157,7 +157,7 @@ The Python equivalent is similar:
|
|||
|
||||
print(f)
|
||||
|
||||
# kindstar() prints the name of the operator
|
||||
# kindstr() prints the name of the operator
|
||||
# size() return the number of operands of the operators
|
||||
print("{}, {} children".format(f.kindstr(), f.size()))
|
||||
# [] accesses each operand
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ automaton. Finally, the output as a never claim is done via the
|
|||
|
||||
int main()
|
||||
{
|
||||
spot::parsed_formula pf = spot::parse_infix_psl("[]<>a || <>[]b");
|
||||
spot::parsed_formula pf = spot::parse_infix_psl("GFa -> GFb");
|
||||
if (pf.format_errors(std::cerr))
|
||||
return 1;
|
||||
spot::translator trans;
|
||||
|
|
@ -158,22 +158,22 @@ never {
|
|||
T0_init:
|
||||
if
|
||||
:: (true) -> goto T0_init
|
||||
:: (a) -> goto accept_S1
|
||||
:: (b) -> goto accept_S2
|
||||
:: (b) -> goto accept_S1
|
||||
:: (!(a)) -> goto accept_S2
|
||||
fi;
|
||||
accept_S1:
|
||||
if
|
||||
:: (a) -> goto accept_S1
|
||||
:: (!(a)) -> goto T0_S3
|
||||
:: (b) -> goto accept_S1
|
||||
:: (!(b)) -> goto T0_S3
|
||||
fi;
|
||||
accept_S2:
|
||||
if
|
||||
:: (b) -> goto accept_S2
|
||||
:: (!(a)) -> goto accept_S2
|
||||
fi;
|
||||
T0_S3:
|
||||
if
|
||||
:: (a) -> goto accept_S1
|
||||
:: (!(a)) -> goto T0_S3
|
||||
:: (b) -> goto accept_S1
|
||||
:: (!(b)) -> goto T0_S3
|
||||
fi;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,9 +144,11 @@ states.
|
|||
|
||||
We now look at how to create such a game in Python.
|
||||
|
||||
Essentially, a game in Spot is just an automaton equiped with a
|
||||
special property to indicate the owner of each states. So it can be
|
||||
created using the usual interface:
|
||||
Essentially, a game in Spot is just an automaton equiped with a [[file:concepts.org::#named-properties][named
|
||||
property "state-player"]] that hold a Boolean vector indicating the
|
||||
owner of each state. The game can be created using the usual
|
||||
automaton interface, and the owners are set by calling
|
||||
=game.set_state_players()= with a vector of Boolean at the very end.
|
||||
|
||||
#+NAME: build_game
|
||||
#+BEGIN_SRC python :exports code
|
||||
|
|
@ -173,7 +175,7 @@ created using the usual interface:
|
|||
todo = []
|
||||
|
||||
# Create the state (i, j) for a player if it does not exist yet and
|
||||
# returns the state's number in the game.
|
||||
# return the state's number in the game.
|
||||
def get_game_state(player, i, j):
|
||||
orig_state = s_orig_states if player else d_orig_states
|
||||
if (i, j) in orig_state:
|
||||
|
|
|
|||
94
doc/spot.bib
94
doc/spot.bib
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
@InProceedings{ babiak.12.tacas,
|
||||
author = {Tom{\'a}{\v{s}} Babiak and Mojm{\'i}r
|
||||
K{\v{r}}et{\'i}nsk{\'y} and Vojt{\v{e}}ch {\v{R}}eh{\'a}k
|
||||
|
|
@ -173,6 +172,22 @@
|
|||
doi = {10.4230/LIPIcs.ICALP.2021.123}
|
||||
}
|
||||
|
||||
@InProceedings{ casares.22.tacas,
|
||||
author = {Antonio Casares and Alexandre Duret-Lutz and Klara J.
|
||||
Meyer and Florian Renkin and Salomon Sickert},
|
||||
title = {Practical Applications of the {A}lternating {C}ycle
|
||||
{D}ecomposition},
|
||||
booktitle = {Proceedings of the 28th International Conference on Tools
|
||||
and Algorithms for the Construction and Analysis of
|
||||
Systems},
|
||||
year = {2022},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
month = apr,
|
||||
volume = {13244},
|
||||
pages = {99--117},
|
||||
doi = {10.1007/978-3-030-99527-0_6},
|
||||
}
|
||||
|
||||
@InProceedings{ cerna.03.mfcs,
|
||||
author = {Ivana {\v{C}}ern{\'a} and Radek Pel{\'a}nek},
|
||||
title = {Relating Hierarchy of Temporal Properties to Model
|
||||
|
|
@ -214,6 +229,18 @@
|
|||
doi = {10.1109/DepCoS-RELCOMEX.2009.31}
|
||||
}
|
||||
|
||||
@InProceedings{ cimatti.06.fmcad,
|
||||
author = {Cimatti, Alessandro and Roveri, Marco and Semprini, Simone
|
||||
and Tonetta, Stefano},
|
||||
title = {From {PSL} to {NBA}: a Modular Symbolic Encoding},
|
||||
booktitle = {Proceedings of the 6th conference on Formal Methods in
|
||||
Computer Aided Design (FMCAD'06)},
|
||||
pages = {125--133},
|
||||
year = {2006},
|
||||
publisher = {IEEE Computer Society},
|
||||
doi = {10.1109/FMCAD.2006.19}
|
||||
}
|
||||
|
||||
@Article{ cimatti.08.tcad,
|
||||
author = {Alessandro Cimatti and Marco Roveri and Stefano Tonetta},
|
||||
journal = {IEEE Transactions on Computer Aided Design of Integrated
|
||||
|
|
@ -341,6 +368,41 @@
|
|||
doi = {10.1504/IJCCBS.2014.059594}
|
||||
}
|
||||
|
||||
@InProceedings{ duret.16.atva,
|
||||
author = {Alexandre Duret-Lutz and Fabrice Kordon and Denis
|
||||
Poitrenaud and Etienne Renault},
|
||||
title = {Heuristics for Checking Liveness Properties with Partial
|
||||
Order Reductions},
|
||||
booktitle = {Proceedings of the 14th International Symposium on
|
||||
Automated Technology for Verification and Analysis
|
||||
(ATVA'16)},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
publisher = {Springer},
|
||||
volume = {9938},
|
||||
pages = {340--356},
|
||||
year = {2016},
|
||||
month = oct,
|
||||
doi = {10.1007/978-3-319-46520-3_22}
|
||||
}
|
||||
|
||||
@InProceedings{ duret.22.cav,
|
||||
author = {Alexandre~Duret-Lutz and Etienne Renault and Maximilien
|
||||
Colange and Florian Renkin and Alexandre Gbaguidi~Aisse and
|
||||
Philipp Schlehuber-Caissier and Thomas Medioni and Antoine
|
||||
Martin and J{\'e}r{\^o}me Dubois and Cl{\'e}ment Gillard
|
||||
and Henrich Lauko},
|
||||
title = {From {S}pot 2.0 to {S}pot 2.10: What's New?},
|
||||
booktitle = {Proceedings of the 34th International Conference on
|
||||
Computer Aided Verification (CAV'22)},
|
||||
year = 2022,
|
||||
volume = {13372},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
pages = {174--187},
|
||||
month = aug,
|
||||
publisher = {Springer},
|
||||
doi = {10.1007/978-3-031-13188-2_9}
|
||||
}
|
||||
|
||||
@InProceedings{ dwyer.98.fmsp,
|
||||
author = {Matthew B. Dwyer and George S. Avrunin and James C.
|
||||
Corbett},
|
||||
|
|
@ -846,6 +908,22 @@
|
|||
doi = {10.1007/978-3-030-59152-6_7}
|
||||
}
|
||||
|
||||
@InProceedings{ renkin.22.forte,
|
||||
author = {Florian Renkin and Philipp Schlehuber-Caissier and
|
||||
Alexandre Duret-Lutz and Adrien Pommellet},
|
||||
title = {Effective Reductions of {M}ealy Machines},
|
||||
year = 2022,
|
||||
booktitle = {Proceedings of the 42nd International Conference on Formal
|
||||
Techniques for Distributed Objects, Components, and Systems
|
||||
(FORTE'22)},
|
||||
series = {Lecture Notes in Computer Science},
|
||||
volume = 13273,
|
||||
pages = {170--187},
|
||||
month = jun,
|
||||
publisher = {Springer},
|
||||
doi = {10.1007/978-3-031-08679-3_8}
|
||||
}
|
||||
|
||||
@InProceedings{ rozier.07.spin,
|
||||
author = {Kristin Y. Rozier and Moshe Y. Vardi},
|
||||
title = {LTL Satisfiability Checking},
|
||||
|
|
@ -1008,7 +1086,19 @@
|
|||
publisher = {Elsevier},
|
||||
editor = {Rance Cleaveland and Hubert Garavel},
|
||||
year = {2002},
|
||||
month = jul,
|
||||
month = jul, pdf = {adl/duret.16.atva.pdf},
|
||||
abstract = {Checking liveness properties with partial-order reductions
|
||||
requires a cycle proviso to ensure that an action cannot be
|
||||
postponed forever. The proviso forces each cycle to contain
|
||||
at least one fully expanded state. We present new
|
||||
heuristics to select which state to expand, hoping to
|
||||
reduce the size of the resulting graph. The choice of the
|
||||
state to expand is done when encountering a
|
||||
\emph{dangerous} edge. Almost all existing provisos expand
|
||||
the source of this edge, while this paper also explores the
|
||||
expansion of the destination and the use of SCC-based
|
||||
information.},
|
||||
|
||||
address = {M{\'a}laga, Spain},
|
||||
doi = {10.1016/S1571-0661(04)80409-2}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ following Boolean operators:
|
|||
(allowing better compatibility with Wring and VIS) may only used in
|
||||
temporal formulas. Boolean expressions that occur inside SERE (see
|
||||
Section~\ref{sec:sere}) may not use this form because the $\STARALT$
|
||||
symbol is used as the Kleen star.}
|
||||
symbol is used as the Kleene star.}
|
||||
|
||||
Additionally, an atomic proposition $a$ can be negated using the
|
||||
syntax \samp{$a$=0}, which is equivalent to \samp{$\NOT a$}. Also
|
||||
|
|
@ -600,7 +600,7 @@ the source. It can mean either ``\textit{Sequential Extended Regular
|
|||
``\textit{Semi-Extended Regular Expression}''~\citep{eisner.08.hvc}.
|
||||
In any case, the intent is the same: regular expressions with
|
||||
traditional operations (union `$\OR$', concatenation `$\CONCAT$',
|
||||
Kleen star `$\STAR{}$') are extended with operators such as
|
||||
Kleene star `$\STAR{}$') are extended with operators such as
|
||||
intersection `$\ANDALT$', and fusion `$\FUSION$'.
|
||||
|
||||
Any Boolean formula (section~\ref{def:boolform}) is a SERE. SERE can
|
||||
|
|
@ -638,7 +638,7 @@ denote arbitrary SERE.
|
|||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
\footnotetext{\emph{Non-Length-Matching} interesction.}
|
||||
\footnotetext{\emph{Non-Length-Matching} intersection.}
|
||||
|
||||
The character \samp{\$} or the string \samp{inf} can also be used as
|
||||
value for $\mvar{j}$ in the above operators to denote an unbounded
|
||||
|
|
@ -668,20 +668,17 @@ $a$ is an atomic proposition.
|
|||
\sigma\VDash f\FUSION g&\iff \exists k\in\N,\,(\sigma^{0..k} \VDash f)\land(\sigma^{k..} \VDash g)\\
|
||||
\sigma\VDash f\STAR{\mvar{i}..\mvar{j}}& \iff
|
||||
\begin{cases}
|
||||
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
|
||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\STAR{\mvar{0}..\mvar{j-1}}))\\
|
||||
\text{either} & \mvar{i}=0 \land\mvar{j}=0\land \sigma=\varepsilon \\
|
||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma = \varepsilon) \lor (\sigma
|
||||
\VDash f\STAR{\mvar{1}..\mvar{j}})\bigr)\\
|
||||
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\STAR{\mvar{i-1}..\mvar{j-1}}))\\
|
||||
\end{cases}\\
|
||||
\sigma\VDash f\STAR{\mvar{i}..} & \iff
|
||||
\begin{cases}
|
||||
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
|
||||
\text{or} & \mvar{i}=0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\STAR{\mvar{0}..}))\\
|
||||
\text{either} & \mvar{i}=0 \land \bigl((\sigma=\varepsilon)\lor(\sigma
|
||||
\VDash f\STAR{\mvar{1}..})\bigr)\\
|
||||
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\STAR{\mvar{i-1}..}))\\
|
||||
|
|
@ -689,25 +686,22 @@ $a$ is an atomic proposition.
|
|||
\sigma\VDash f\FSTAR{\mvar{i}..\mvar{j}}& \iff
|
||||
\begin{cases}
|
||||
\text{either} & \mvar{i}=0 \land \mvar{j}=0 \land \sigma\VDash\1 \\
|
||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\FSTAR{\mvar{0}..\mvar{j-1}}))\\
|
||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma\VDash\1)\lor(\sigma
|
||||
\VDash f\FSTAR{\mvar{1}..\mvar{j}})\bigr)\\
|
||||
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\FSTAR{\mvar{i-1}..\mvar{j-1}}))\\
|
||||
\end{cases}\\
|
||||
\sigma\VDash f\FSTAR{\mvar{i}..} & \iff
|
||||
\begin{cases}
|
||||
\text{either} & \mvar{i}=0 \land \sigma\VDash\1 \\
|
||||
\text{or} & \mvar{i}=0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\FSTAR{\mvar{0}..}))\\
|
||||
\text{either} & \mvar{i}=0 \land \bigl((\sigma\VDash\1)
|
||||
\lor(\sigma \VDash f\FSTAR{\mvar{1}..})\bigr)\\
|
||||
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||
\VDash f\FSTAR{\mvar{i-1}..}))\\
|
||||
\end{cases}\\
|
||||
\sigma\VDash \FIRSTMATCH\code(f\code) & \iff
|
||||
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k}\nVDash f)
|
||||
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k-1}\nVDash f)
|
||||
\end{align*}}
|
||||
|
||||
Notes:
|
||||
|
|
@ -859,10 +853,18 @@ The following rules are all valid with the two arguments swapped.
|
|||
\1\OR b &\equiv \1 &
|
||||
\1 \FUSION f & \equiv f\mathrlap{\text{~if~}\varepsilon\nVDash f}\\
|
||||
&&
|
||||
\STAR{} \AND f &\equiv f &
|
||||
\STAR{} \OR f &\equiv \1\mathrlap{\STAR{}} &
|
||||
\STAR{} \ANDALT f &\equiv f &
|
||||
\STAR{} \OR f &\equiv \mathrlap{\STAR{}} &
|
||||
&&
|
||||
\STAR{} \CONCAT f &\equiv \STAR{}\mathrlap{\text{~if~}\varepsilon\VDash f}& \\
|
||||
\STAR{} \CONCAT f &\equiv \STAR{}\text{~if~}\varepsilon\VDash f& \\
|
||||
&&
|
||||
\PLUS{} \ANDALT f &\equiv f \text{~if~}\varepsilon\nVDash f&
|
||||
\PLUS{} \OR f &\equiv \begin{cases}
|
||||
\mathrlap{\STAR{}\text{~if~} \varepsilon\VDash f} \\
|
||||
\mathrlap{\PLUS{}\text{~if~} \varepsilon\nVDash f} \\
|
||||
\end{cases} &
|
||||
&&
|
||||
&& \\
|
||||
\eword\AND f &\equiv f &
|
||||
\eword\ANDALT f &\equiv
|
||||
\begin{cases}
|
||||
|
|
@ -886,7 +888,9 @@ The following rules are all valid with the two arguments swapped.
|
|||
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f&\equiv f\STAR{\mvar{i+1}..\mvar{j+1}} &
|
||||
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f\STAR{\mvar{k}..\mvar{l}}&\equiv f\STAR{\mvar{i+k}..\mvar{j+l}}\\
|
||||
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f&\equiv f\FSTAR{\mvar{i+1}..\mvar{j+1}} &
|
||||
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f\FSTAR{\mvar{k}..\mvar{l}}&\equiv f\FSTAR{\mvar{i+k}..\mvar{j+l}}
|
||||
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f\FSTAR{\mvar{k}..\mvar{l}}&\equiv f\FSTAR{\mvar{i+k}..\mvar{j+l}}\\
|
||||
b\STAR{\mvar{i}..\mvar{j}}\FUSION b &\equiv b\STAR{\mvar{\max(i,1)}..\mvar{j}} &
|
||||
b\STAR{\mvar{i}..\mvar{j}}\FUSION b\STAR{\mvar{k}..\mvar{l}} &\equiv b\mathrlap{\STAR{\mvar{\max(i,1)+\max(k,1)-1}..\mvar{j+l-1}}}
|
||||
\end{align*}
|
||||
\section{SERE-LTL Binding Operators}
|
||||
|
||||
|
|
@ -1069,7 +1073,7 @@ psl2ba, Modella, and NuSMV all have $\U$ and $\R$ as left-associative,
|
|||
while Goal (hence Büchi store), LTL2AUT, and LTL2Büchi (from
|
||||
JavaPathFinder) have $\U$ and $\R$ as right-associative. Vis and LBTT
|
||||
have these two operators as non-associative (parentheses required).
|
||||
Similarly the tools do not aggree on the associativity of $\IMPLIES$
|
||||
Similarly the tools do not agree on the associativity of $\IMPLIES$
|
||||
and $\EQUIV$: some tools handle both operators as left-associative, or
|
||||
both right-associative, other have only $\IMPLIES$ as right-associative.
|
||||
|
||||
|
|
@ -1429,7 +1433,7 @@ $\NOT$ operator.
|
|||
\end{align*}
|
||||
|
||||
Note that the above rules include the ``unabbreviation'' of operators
|
||||
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', correspondings to the
|
||||
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', corresponding to the
|
||||
rules \texttt{"ei\^"} of function `\verb=unabbreviate()= as described
|
||||
in Section~\ref{sec:unabbrev}. Therefore it is never necessary to
|
||||
apply these abbreviations before or after
|
||||
|
|
@ -1926,6 +1930,12 @@ Many of the above rules were collected from the
|
|||
literature~\cite{somenzi.00.cav,tauriainen.03.tr,babiak.12.tacas} and
|
||||
sometimes generalized to support operators such as $\M$ and $\W$.
|
||||
|
||||
The first six rules, about n-ary operators $\AND$ and $\OR$, are
|
||||
implemented for $n$ operands by testing each operand against all
|
||||
other. To prevent the complexity to escalate, this is only performed
|
||||
with up to 16 operands. That value can be changed in
|
||||
``\verb|tl_simplifier_options::containment_max_ops|''.
|
||||
|
||||
The following rules mix implication-based checks with formulas that
|
||||
are pure eventualities ($e$) or that are purely universal ($u$).
|
||||
|
||||
|
|
@ -2097,3 +2107,14 @@ $f_1\AND f_2$ & \bor{f_1}{g}{f_2}{g} & & &
|
|||
%%% TeX-master: t
|
||||
%%% coding: utf-8
|
||||
%%% End:
|
||||
|
||||
% LocalWords: tabu Alexandre Duret Lutz toc subsequence Kripke unary
|
||||
% LocalWords: LTL GFa INISHED ZX FX cccccrl UTF syntaxes disjunction
|
||||
% LocalWords: VIS Kleene overline overbar ary cccrl EF sep FB LTLf
|
||||
% LocalWords: rewritings TSLF NLM iter un SVA PSL SEREs DFA ccccc ba
|
||||
% LocalWords: SystemVerilog clc ltl psl Modella NuSMV Büchi AUT Vis
|
||||
% LocalWords: JavaPathFinder LBTT AST subtrees boolean nenoform lbt
|
||||
% LocalWords: eword nn LBT's automata subformulas ottom unabbreviate
|
||||
% LocalWords: Unabbreviations ei GRW RW WR unabbreviator simplifier
|
||||
% LocalWords: tl unabbreviation indeterminism dnf cnf SNF rl iff BDD
|
||||
% LocalWords: subformula
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2015, 2016, 2017, 2018 Laboratoire de Recherche et Développement
|
||||
## de l'Epita (LRDE).
|
||||
## Copyright (C) 2015-2018, 2022 Laboratoire de Recherche et
|
||||
## Développement de l'Epita (LRDE).
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
EXTRA_DIST = hoa-mode.el
|
||||
|
||||
GIT = https://gitlab.lrde.epita.fr/spot/emacs-modes/raw/master/
|
||||
GIT = https://gitlab.lre.epita.fr/spot/emacs-modes/raw/master/
|
||||
|
||||
.PHONY: update-el
|
||||
update-el:
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
;;; hoa-mode.el --- Major mode for the HOA format -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2015, 2017, 2019 Alexandre Duret-Lutz
|
||||
;; Copyright (C) 2015, 2017, 2019, 2022 Alexandre Duret-Lutz
|
||||
|
||||
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||
;; URL: https://gitlab.lrde.epita.fr/spot/emacs-modes
|
||||
;; URL: https://gitlab.lre.epita.fr/spot/emacs-modes
|
||||
;; Keywords: major-mode, automata, convenience
|
||||
;; Created: 2015-11-13
|
||||
|
||||
|
|
|
|||
43
flake.lock
generated
Normal file
43
flake.lock
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1642700792,
|
||||
"narHash": "sha256-XqHrk7hFb+zBvRg6Ghl+AZDq03ov6OshJLiSWOoX5es=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "846b2ae0fc4cc943637d3d1def4454213e203cba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1673800717,
|
||||
"narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-22.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
211
flake.nix
Normal file
211
flake.nix
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
outputs = { self, nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachSystem
|
||||
[
|
||||
"x86_64-linux"
|
||||
]
|
||||
|
||||
(system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
lib = pkgs.lib;
|
||||
|
||||
mkSpotApps = appNames:
|
||||
pkgs.lib.genAttrs appNames
|
||||
(name: flake-utils.lib.mkApp {
|
||||
drv = self.packages.${system}.spot;
|
||||
name = name;
|
||||
});
|
||||
|
||||
spotPackage =
|
||||
let
|
||||
inherit (builtins)
|
||||
filter
|
||||
head
|
||||
isString
|
||||
match
|
||||
readFile
|
||||
split
|
||||
;
|
||||
|
||||
# NOTE: Maintaining the version separately would be a pain, and we
|
||||
# can't have a flake.nix.in with a @VERSION@ because it would make
|
||||
# the flake unusable without running autoconf first, defeating some
|
||||
# of its purpose.
|
||||
#
|
||||
# So let's get it the hard way instead :)
|
||||
extractVersionRegex = ''^AC_INIT\(\[spot], \[([^]]+)], \[spot@lrde\.epita\.fr]\)$'';
|
||||
getLines = (fileContent:
|
||||
filter isString (split "\n" fileContent)
|
||||
);
|
||||
findVersionLine = (lines:
|
||||
lib.lists.findFirst
|
||||
(l: lib.strings.hasPrefix "AC_INIT(" l)
|
||||
null
|
||||
lines
|
||||
);
|
||||
getVersion = (file:
|
||||
let
|
||||
lines = getLines (readFile file);
|
||||
versionLine = findVersionLine lines;
|
||||
version = head (match extractVersionRegex versionLine);
|
||||
in
|
||||
version
|
||||
);
|
||||
in
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
stdenv,
|
||||
# FIXME: do we want this flag?
|
||||
buildOrgDoc ? false,
|
||||
# Whether to enable Spot's Python 3 bindings
|
||||
enablePython ? false
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "spot";
|
||||
version = getVersion ./configure.ac;
|
||||
|
||||
src = self;
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
# NOTE: Nix enables a lot of hardening flags by default, some of
|
||||
# these probably harm performance so I've disabled everything
|
||||
# (haven't benchmarked with vs without these, though).
|
||||
hardeningDisable = [ "all" ];
|
||||
|
||||
# NOTE: mktexpk fails without a HOME set
|
||||
preBuild = ''
|
||||
export HOME=$TMPDIR
|
||||
patchShebangs tools
|
||||
'' + (if buildOrgDoc then ''
|
||||
ln -s ${pkgs.plantuml}/lib/plantuml.jar doc/org/plantuml.jar
|
||||
'' else ''
|
||||
touch doc/org-stamp
|
||||
'');
|
||||
|
||||
configureFlags = [
|
||||
"--disable-devel"
|
||||
"--enable-optimizations"
|
||||
] ++ lib.optional (!enablePython) [
|
||||
"--disable-python"
|
||||
];
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
autoreconfHook
|
||||
|
||||
autoconf
|
||||
automake
|
||||
bison
|
||||
flex
|
||||
libtool
|
||||
perl
|
||||
] ++ lib.optional buildOrgDoc [
|
||||
graphviz
|
||||
groff
|
||||
plantuml
|
||||
pdf2svg
|
||||
R
|
||||
] ++ lib.optional enablePython [
|
||||
python3
|
||||
swig4
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
# should provide the minimum amount of packages necessary for
|
||||
# building tl.pdf
|
||||
(texlive.combine {
|
||||
inherit (texlive)
|
||||
scheme-basic
|
||||
latexmk
|
||||
|
||||
booktabs
|
||||
cm-super
|
||||
doi
|
||||
doublestroke
|
||||
etoolbox
|
||||
koma-script
|
||||
mathabx-type1
|
||||
mathpazo
|
||||
metafont
|
||||
microtype
|
||||
nag
|
||||
pgf
|
||||
standalone
|
||||
stmaryrd
|
||||
tabulary
|
||||
todonotes
|
||||
wasy-type1
|
||||
wasysym
|
||||
;
|
||||
})
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
defaultPackage = self.packages.${system}.spot;
|
||||
|
||||
packages = {
|
||||
# binaries + library only
|
||||
spot = pkgs.callPackage spotPackage {};
|
||||
|
||||
# NOTE: clang build is broken on Nix when linking to stdlib++, using
|
||||
# libcxx instead. See:
|
||||
# https://github.com/NixOS/nixpkgs/issues/91285
|
||||
spotClang = pkgs.callPackage spotPackage {
|
||||
stdenv = pkgs.llvmPackages.libcxxStdenv;
|
||||
};
|
||||
|
||||
spotWithOrgDoc = pkgs.callPackage spotPackage {
|
||||
buildOrgDoc = true;
|
||||
};
|
||||
|
||||
spotWithPython = pkgs.python3Packages.toPythonModule (
|
||||
pkgs.callPackage spotPackage {
|
||||
enablePython = true;
|
||||
}
|
||||
);
|
||||
|
||||
spotFull = pkgs.python3Packages.toPythonModule (
|
||||
pkgs.callPackage spotPackage {
|
||||
buildOrgDoc = true; enablePython = true;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
apps = mkSpotApps [
|
||||
"autcross"
|
||||
"autfilt"
|
||||
"dstar2tgba"
|
||||
"genaut"
|
||||
"genltl"
|
||||
"ltl2tgba"
|
||||
"ltl2tgta"
|
||||
"ltlcross"
|
||||
"ltldo"
|
||||
"ltlfilt"
|
||||
"ltlgrind"
|
||||
"ltlsynt"
|
||||
"randaut"
|
||||
"randltl"
|
||||
];
|
||||
|
||||
devShell = pkgs.mkShell {
|
||||
name = "spot-dev";
|
||||
inputsFrom = [ self.packages.${system}.spotFull ];
|
||||
buildInputs = [
|
||||
pkgs.gdb
|
||||
|
||||
(pkgs.python3.withPackages (p: [
|
||||
p.jupyter
|
||||
p.ipython # otherwise ipython module isn't found when running ipynb tests
|
||||
]))
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
46
m4/environ.m4
Normal file
46
m4/environ.m4
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# environ.m4 serial 8
|
||||
dnl Copyright (C) 2001-2004, 2006-2021 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN_ONCE([gl_ENVIRON],
|
||||
[
|
||||
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
|
||||
dnl Persuade glibc <unistd.h> to declare environ.
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
|
||||
AC_CHECK_HEADERS_ONCE([unistd.h])
|
||||
gt_CHECK_VAR_DECL(
|
||||
[#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
|
||||
#include <stdlib.h>
|
||||
],
|
||||
[environ])
|
||||
if test $gt_cv_var_environ_declaration != yes; then
|
||||
HAVE_DECL_ENVIRON=0
|
||||
fi
|
||||
])
|
||||
|
||||
# Check if a variable is properly declared.
|
||||
# gt_CHECK_VAR_DECL(includes,variable)
|
||||
AC_DEFUN([gt_CHECK_VAR_DECL],
|
||||
[
|
||||
define([gt_cv_var], [gt_cv_var_]$2[_declaration])
|
||||
AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[$1
|
||||
typedef struct { int foo; } foo_t;
|
||||
extern foo_t $2;]],
|
||||
[[$2.foo = 1;]])],
|
||||
[gt_cv_var=no],
|
||||
[gt_cv_var=yes])])
|
||||
if test $gt_cv_var = yes; then
|
||||
AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1,
|
||||
[Define if you have the declaration of $2.])
|
||||
fi
|
||||
undefine([gt_cv_var])
|
||||
])
|
||||
|
|
@ -21,6 +21,14 @@ AC_DEFUN([CF_GXX_WARNINGS],
|
|||
cat > conftest.$ac_ext <<EOF
|
||||
#line __oline__ "configure"
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
// From GCC bug 106159
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106159
|
||||
struct left { virtual ~left() {} };
|
||||
struct right { virtual ~right() {} };
|
||||
struct both: public left, public right {};
|
||||
|
||||
int main(int argc, char *argv[[]])
|
||||
{
|
||||
// This string comparison is here to detect superfluous
|
||||
|
|
@ -33,19 +41,26 @@ int main(int argc, char *argv[[]])
|
|||
std::string a{"foo"}, b{"bar"};
|
||||
if (b < a)
|
||||
return 1;
|
||||
// GCC 12 has spurious warnings about ininialized values in regex.
|
||||
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105562
|
||||
// We need -Wno-maybe-uninitialized in this case.
|
||||
std::regex r{"a"};
|
||||
(void)r;
|
||||
return argv[[argc-1]] == nullptr;
|
||||
}
|
||||
EOF
|
||||
cf_save_CXXFLAGS="$CXXFLAGS"
|
||||
ac_cv_prog_gxx_warn_flags="-W -Wall"
|
||||
ac_cv_prog_gxx_warn_flags="-W -Werror"
|
||||
dnl The following list has options of the form OPT:BAD:GOOD
|
||||
dnl if -OPT fails we try -OPT -BAD. If -OPT succeeds we add -GOOD.
|
||||
for cf_opt in \
|
||||
Werror \
|
||||
Wall:Wno-maybe-uninitialized:\
|
||||
Wint-to-void-pointer-cast \
|
||||
Wzero-as-null-pointer-constant \
|
||||
Wcast-align \
|
||||
Wpointer-arith \
|
||||
Wwrite-strings \
|
||||
Wcast-qual \
|
||||
Wcast-qual::DXTSTRINGDEFINES \
|
||||
Wdocumentation \
|
||||
Wmissing-declarations \
|
||||
Wnoexcept \
|
||||
|
|
@ -58,11 +73,26 @@ EOF
|
|||
Wsuggest-override \
|
||||
Wpedantic
|
||||
do
|
||||
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$cf_opt"
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$cf_opt"
|
||||
test "$cf_opt" = Wcast-qual && ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -DXTSTRINGDEFINES"
|
||||
fi
|
||||
fopt=${cf_opt%%:*}
|
||||
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$fopt"
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$fopt"
|
||||
case $cf_opt in
|
||||
*:*:);;
|
||||
*:*:*)ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -${cf_opt##*:}";;
|
||||
esac
|
||||
else
|
||||
case $cf_opt in
|
||||
*::*);;
|
||||
*:*:*)
|
||||
sopt=${cf_opt%:*}
|
||||
sopt=${sopt#*:}
|
||||
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$fopt -$sopt"
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$fopt -$sopt"
|
||||
fi;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
rm -f conftest*
|
||||
CXXFLAGS="$cf_save_CXXFLAGS"])
|
||||
|
|
|
|||
12
m4/getopt.m4
12
m4/getopt.m4
|
|
@ -1,5 +1,5 @@
|
|||
# getopt.m4 serial 47
|
||||
dnl Copyright (C) 2002-2006, 2008-2020 Free Software Foundation, Inc.
|
||||
dnl Copyright (C) 2002-2006, 2008-2020, 2022 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
|
@ -363,13 +363,9 @@ dnl is ambiguous with environment values that contain newlines.
|
|||
|
||||
AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
|
||||
[
|
||||
AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
|
||||
if test $ac_cv_header_sys_cdefs_h = yes; then
|
||||
HAVE_SYS_CDEFS_H=1
|
||||
else
|
||||
HAVE_SYS_CDEFS_H=0
|
||||
fi
|
||||
AC_SUBST([HAVE_SYS_CDEFS_H])
|
||||
# pretend HAVE_SYS_CDEFS_H is always 0 including <sys/defs.h> isn't
|
||||
# really necessary and causes warning on Alpine Linux.
|
||||
AC_SUBST([HAVE_SYS_CDEFS_H], [0])
|
||||
|
||||
AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
|
||||
[Define to rpl_ if the getopt replacement functions and variables
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -57,6 +57,7 @@ gl_MODULES([
|
|||
argmatch
|
||||
argp
|
||||
closeout
|
||||
environ
|
||||
error
|
||||
isatty
|
||||
mkstemp
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -246,6 +246,8 @@ AC_SUBST([LTALLOCA])
|
|||
AC_LIBOBJ([lstat])
|
||||
gl_PREREQ_LSTAT
|
||||
fi
|
||||
gl_ENVIRON
|
||||
gl_UNISTD_MODULE_INDICATOR([environ])
|
||||
gl_SYS_STAT_MODULE_INDICATOR([lstat])
|
||||
gl_FUNC_MALLOC_GNU
|
||||
if test $REPLACE_MALLOC = 1; then
|
||||
|
|
|
|||
74
m4/ltargz.m4
74
m4/ltargz.m4
|
|
@ -1,74 +0,0 @@
|
|||
# Portability macros for glibc argz. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004-2007, 2011-2015 Free Software Foundation, Inc.
|
||||
# Written by Gary V. Vaughan <gary@gnu.org>
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 1 ltargz.m4
|
||||
|
||||
AC_DEFUN([LT_FUNC_ARGZ], [
|
||||
AC_CHECK_HEADERS([argz.h], [], [], [AC_INCLUDES_DEFAULT])
|
||||
|
||||
AC_CHECK_TYPES([error_t],
|
||||
[],
|
||||
[AC_DEFINE([error_t], [int],
|
||||
[Define to a type to use for 'error_t' if it is not otherwise available.])
|
||||
AC_DEFINE([__error_t_defined], [1], [Define so that glibc/gnulib argp.h
|
||||
does not typedef error_t.])],
|
||||
[#if defined(HAVE_ARGZ_H)
|
||||
# include <argz.h>
|
||||
#endif])
|
||||
|
||||
LT_ARGZ_H=
|
||||
AC_CHECK_FUNCS([argz_add argz_append argz_count argz_create_sep argz_insert \
|
||||
argz_next argz_stringify], [], [LT_ARGZ_H=lt__argz.h; AC_LIBOBJ([lt__argz])])
|
||||
|
||||
dnl if have system argz functions, allow forced use of
|
||||
dnl libltdl-supplied implementation (and default to do so
|
||||
dnl on "known bad" systems). Could use a runtime check, but
|
||||
dnl (a) detecting malloc issues is notoriously unreliable
|
||||
dnl (b) only known system that declares argz functions,
|
||||
dnl provides them, yet they are broken, is cygwin
|
||||
dnl releases prior to 16-Mar-2007 (1.5.24 and earlier)
|
||||
dnl So, it's more straightforward simply to special case
|
||||
dnl this for known bad systems.
|
||||
AS_IF([test -z "$LT_ARGZ_H"],
|
||||
[AC_CACHE_CHECK(
|
||||
[if argz actually works],
|
||||
[lt_cv_sys_argz_works],
|
||||
[[case $host_os in #(
|
||||
*cygwin*)
|
||||
lt_cv_sys_argz_works=no
|
||||
if test no != "$cross_compiling"; then
|
||||
lt_cv_sys_argz_works="guessing no"
|
||||
else
|
||||
lt_sed_extract_leading_digits='s/^\([0-9\.]*\).*/\1/'
|
||||
save_IFS=$IFS
|
||||
IFS=-.
|
||||
set x `uname -r | sed -e "$lt_sed_extract_leading_digits"`
|
||||
IFS=$save_IFS
|
||||
lt_os_major=${2-0}
|
||||
lt_os_minor=${3-0}
|
||||
lt_os_micro=${4-0}
|
||||
if test 1 -lt "$lt_os_major" \
|
||||
|| { test 1 -eq "$lt_os_major" \
|
||||
&& { test 5 -lt "$lt_os_minor" \
|
||||
|| { test 5 -eq "$lt_os_minor" \
|
||||
&& test 24 -lt "$lt_os_micro"; }; }; }; then
|
||||
lt_cv_sys_argz_works=yes
|
||||
fi
|
||||
fi
|
||||
;; #(
|
||||
*) lt_cv_sys_argz_works=yes ;;
|
||||
esac]])
|
||||
AS_IF([test yes = "$lt_cv_sys_argz_works"],
|
||||
[AC_DEFINE([HAVE_WORKING_ARGZ], 1,
|
||||
[This value is set to 1 to indicate that the system argz facility works])],
|
||||
[LT_ARGZ_H=lt__argz.h
|
||||
AC_LIBOBJ([lt__argz])])])
|
||||
|
||||
AC_SUBST([LT_ARGZ_H])
|
||||
])
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2021 Laboratoire de
|
||||
# Recherche et Développement de l'Epita (LRDE).
|
||||
# Copyright (C) 2014-2023 Laboratoire de Recherche et Développement de
|
||||
# l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
|
|
@ -104,19 +104,22 @@ def setup(**kwargs):
|
|||
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():
|
||||
# Swig versions prior to 4.1.0 export formula.X as formula_X as well,
|
||||
# for all operators. Swig 4.1.0 stops doing this, breaking some
|
||||
# existing code.
|
||||
if 'formula_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]
|
||||
'Fusion', 'Star', 'FStar', 'nested_unop_range',
|
||||
'sugar_goto', 'sugar_equal', 'sugar_delay', 'unop',
|
||||
'binop', 'bunop', 'multop', 'first_match', 'unbounded'):
|
||||
globals()['formula_' + i] = formula.__dict__[i].__func__
|
||||
if 'trival_maybe' not in globals():
|
||||
for i in ('maybe',):
|
||||
globals()['trival_' + i] = trival.__dict__[i].__func__
|
||||
|
||||
|
||||
# Global BDD dict so that we do not have to create one in user code.
|
||||
|
|
@ -261,6 +264,12 @@ class twa:
|
|||
ostr = ostringstream()
|
||||
print_lbtt(ostr, a, opt)
|
||||
return ostr.str()
|
||||
if format == 'pg':
|
||||
if opt is not None:
|
||||
raise ValueError("print_pg() has no option")
|
||||
ostr = ostringstream()
|
||||
print_pg(ostr, a)
|
||||
return ostr.str()
|
||||
raise ValueError("unknown string format: " + format)
|
||||
|
||||
def save(a, filename, format='hoa', opt=None, append=False):
|
||||
|
|
@ -493,51 +502,57 @@ class acd:
|
|||
.acdacc polygon{fill:green;}
|
||||
'''
|
||||
js = '''
|
||||
function acd{num}_clear(){{
|
||||
$("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge")
|
||||
.removeClass("acdhigh acdbold acdacc acdrej");
|
||||
function acdremclasses(sel, classes) {{
|
||||
document.querySelectorAll(sel).forEach(n=>{{n.classList.remove(...classes)}});}}
|
||||
function acdaddclasses(sel, classes) {{
|
||||
document.querySelectorAll(sel).forEach(n=>{{n.classList.add(...classes)}});}}
|
||||
function acdonclick(sel, fn) {{
|
||||
document.querySelectorAll(sel).forEach(n=>
|
||||
{{n.addEventListener("click", fn)}});
|
||||
}}
|
||||
function acd{num}_clear() {{
|
||||
acdremclasses("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge",
|
||||
["acdhigh", "acdbold", "acdacc", "acdrej"]);
|
||||
}};
|
||||
function acd{num}_state(state){{
|
||||
acd{num}_clear();
|
||||
$("#acd{num} .acdS" + state).addClass("acdhigh acdbold");
|
||||
$("#acdaut{num} #S" + state).addClass("acdbold");
|
||||
acd{num}_clear();
|
||||
acdaddclasses("#acd{num} .acdS" + state, ["acdhigh", "acdbold"]);
|
||||
acdaddclasses("#acdaut{num} #S" + state, ["acdbold"]);
|
||||
}};
|
||||
function acd{num}_edge(edge){{
|
||||
acd{num}_clear();
|
||||
var theedge = $('#acdaut{num} #E' + edge)
|
||||
var classList = theedge.attr('class').split(/\s+/);
|
||||
$.each(classList, function(index, item) {{
|
||||
if (item.startsWith('acdN')) {{
|
||||
$("#acd{num} #" + item.substring(3)).addClass("acdhigh acdbold");
|
||||
}}
|
||||
}});
|
||||
theedge.addClass("acdbold");
|
||||
acd{num}_clear();
|
||||
var theedge = document.querySelector('#acdaut{num} #E' + edge);
|
||||
theedge.classList.forEach(function(item, index) {{
|
||||
if (item.startsWith('acdN')) {{
|
||||
acdaddclasses("#acd{num} #" + item.substring(3), ["acdhigh", "acdbold"]);
|
||||
}}
|
||||
}});
|
||||
theedge.classList.add("acdbold");
|
||||
}};
|
||||
function acd{num}_node(node, acc){{
|
||||
acd{num}_clear();
|
||||
$("#acdaut{num} .acdN" + node).addClass(acc
|
||||
? "acdacc acdbold"
|
||||
: "acdrej acdbold");
|
||||
$("#acd{num} #N" + node).addClass("acdbold acdhigh");
|
||||
acdaddclasses("#acdaut{num} .acdN" + node,
|
||||
[acc ? "acdacc" : "acdrej", "acdbold"]);
|
||||
acdaddclasses("#acd{num} #N" + node, ["acdbold", "acdhigh"]);
|
||||
}};'''.format(num=num)
|
||||
me = 0
|
||||
for n in range(self.node_count()):
|
||||
for e in self.edges_of_node(n):
|
||||
me = max(e, me)
|
||||
js += '$("#acdaut{num} #E{e}").addClass("acdN{n}");'\
|
||||
js += 'acdaddclasses("#acdaut{num} #E{e}", ["acdN{n}"]);\n'\
|
||||
.format(num=num, e=e, n=n)
|
||||
for e in range(1, me + 1):
|
||||
js += '$("#acdaut{num} #E{e}")'\
|
||||
'.click(function(){{acd{num}_edge({e});}});'\
|
||||
js += 'acdonclick("#acdaut{num} #E{e}",'\
|
||||
'function(){{acd{num}_edge({e});}});\n'\
|
||||
.format(num=num, e=e)
|
||||
for s in range(self.get_aut().num_states()):
|
||||
js += '$("#acdaut{num} #S{s}")'\
|
||||
'.click(function(){{acd{num}_state({s});}});'\
|
||||
js += 'acdonclick("#acdaut{num} #S{s}",'\
|
||||
'function(){{acd{num}_state({s});}});\n'\
|
||||
.format(num=num, s=s)
|
||||
for n in range(self.node_count()):
|
||||
v = int(self.node_acceptance(n))
|
||||
js += '$("#acd{num} #N{n}")'\
|
||||
'.click(function(){{acd{num}_node({n}, {v});}});'\
|
||||
js += 'acdonclick("#acd{num} #N{n}",'\
|
||||
'function(){{acd{num}_node({n}, {v});}});\n'\
|
||||
.format(num=num, n=n, v=v)
|
||||
html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\
|
||||
.format(style,
|
||||
|
|
@ -1292,6 +1307,36 @@ def sat_minimize(aut, acc=None, colored=False,
|
|||
else:
|
||||
return sm(aut, args, state_based)
|
||||
|
||||
# Adding the inline csv-display option
|
||||
def minimize_mealy(mm, opt = -1, display_log = False, return_log = False):
|
||||
from spot.impl import minimize_mealy as minmealy
|
||||
|
||||
try:
|
||||
lvl = int(opt)
|
||||
opt = synthesis_info()
|
||||
opt.minimize_lvl = lvl + 4
|
||||
except (ValueError, TypeError) as _:
|
||||
pass
|
||||
|
||||
if display_log or return_log:
|
||||
import pandas as pd
|
||||
with tempfile.NamedTemporaryFile(dir='.', suffix='.minlog') as t:
|
||||
opt.opt.set_str("satlogcsv", t.name)
|
||||
resmm = minmealy(mm, opt)
|
||||
|
||||
dfrm = pd.read_csv(t.name, dtype=object)
|
||||
if display_log:
|
||||
from IPython.display import display
|
||||
del dfrm['instance']
|
||||
display(dfrm)
|
||||
if return_log:
|
||||
return resmm, dfrm
|
||||
else:
|
||||
return resmm
|
||||
else:
|
||||
return minmealy(mm, opt)
|
||||
|
||||
|
||||
|
||||
def parse_word(word, dic=_bdd_dict):
|
||||
from spot.impl import parse_word as pw
|
||||
|
|
@ -1302,6 +1347,10 @@ def bdd_to_formula(b, dic=_bdd_dict):
|
|||
from spot.impl import bdd_to_formula as bf
|
||||
return bf(b, dic)
|
||||
|
||||
def bdd_to_cnf_formula(b, dic=_bdd_dict):
|
||||
from spot.impl import bdd_to_cnf_formula as bf
|
||||
return bf(b, dic)
|
||||
|
||||
|
||||
def language_containment_checker(dic=_bdd_dict):
|
||||
from spot.impl import language_containment_checker as c
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009-2022 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2009-2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
|
||||
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||
|
|
@ -90,10 +90,13 @@
|
|||
|
||||
#include <spot/tl/apcollect.hh>
|
||||
#include <spot/tl/contain.hh>
|
||||
#include <spot/tl/derive.hh>
|
||||
#include <spot/tl/dot.hh>
|
||||
#include <spot/tl/expansions.hh>
|
||||
#include <spot/tl/nenoform.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/tl/sonf.hh>
|
||||
#include <spot/tl/unabbrev.hh>
|
||||
#include <spot/tl/randomltl.hh>
|
||||
#include <spot/tl/length.hh>
|
||||
|
|
@ -113,13 +116,14 @@
|
|||
#include <spot/twaalgos/aiger.hh>
|
||||
#include <spot/twaalgos/alternation.hh>
|
||||
#include <spot/twaalgos/cleanacc.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/dualize.hh>
|
||||
#include <spot/twaalgos/cobuchi.hh>
|
||||
#include <spot/twaalgos/copy.hh>
|
||||
#include <spot/twaalgos/complete.hh>
|
||||
#include <spot/twaalgos/complement.hh>
|
||||
#include <spot/twaalgos/dbranch.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/dualize.hh>
|
||||
#include <spot/twaalgos/emptiness.hh>
|
||||
#include <spot/twaalgos/gtec/gtec.hh>
|
||||
#include <spot/twaalgos/genem.hh>
|
||||
|
|
@ -159,6 +163,7 @@
|
|||
#include <spot/twaalgos/stutter.hh>
|
||||
#include <spot/twaalgos/synthesis.hh>
|
||||
#include <spot/twaalgos/translate.hh>
|
||||
#include <spot/twaalgos/translate_aa.hh>
|
||||
#include <spot/twaalgos/toweak.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/twaalgos/dtwasat.hh>
|
||||
|
|
@ -485,6 +490,7 @@ static void handle_any_exception()
|
|||
}
|
||||
}
|
||||
|
||||
%implicitconv spot::parallel_policy;
|
||||
%include <spot/misc/common.hh>
|
||||
%include <spot/misc/version.hh>
|
||||
%include <spot/misc/minato.hh>
|
||||
|
|
@ -517,8 +523,12 @@ namespace std {
|
|||
%template(vectorbdd) vector<bdd>;
|
||||
%template(aliasvector) vector<pair<string, bdd>>;
|
||||
%template(vectorstring) vector<string>;
|
||||
%template(vectorint) vector<int>;
|
||||
%template(pair_formula_vectorstring) pair<spot::formula, vector<string>>;
|
||||
%template(atomic_prop_set) set<spot::formula>;
|
||||
%template(relabeling_map) map<spot::formula, spot::formula>;
|
||||
%template(pair_formula) pair<spot::formula, spot::formula>;
|
||||
%template(vector_pair_formula) vector<pair<spot::formula, spot::formula>>;
|
||||
}
|
||||
|
||||
%include <spot/tl/environment.hh>
|
||||
|
|
@ -531,6 +541,8 @@ namespace std {
|
|||
%include <spot/twa/bdddict.hh>
|
||||
%include <spot/twa/bddprint.hh>
|
||||
%include <spot/twa/formula2bdd.hh>
|
||||
%template(formula_to_bdd) spot::formula_to_bdd<spot::twa_graph>;
|
||||
|
||||
%include <spot/twa/fwd.hh>
|
||||
/* These operators may raise exceptions, and we do not
|
||||
want Swig4 to convert those exceptions to NotImplemented. */
|
||||
|
|
@ -547,6 +559,27 @@ namespace std {
|
|||
}
|
||||
%apply std::vector<unsigned> &OUTPUT {std::vector<unsigned>& pairs}
|
||||
%apply std::vector<spot::acc_cond::rs_pair> &OUTPUT {std::vector<spot::acc_cond::rs_pair>& pairs}
|
||||
// Must occur before the twa declaration
|
||||
%typemap(out) SWIGTYPE spot::acc_cond::fin_unit_one_split %{
|
||||
{
|
||||
auto& v = static_cast<const std::tuple<int, spot::acc_cond, spot::acc_cond>>($1);
|
||||
$result = PyTuple_Pack(3,
|
||||
swig::from(std::get<0>(v)),
|
||||
swig::from(std::get<1>(v)),
|
||||
swig::from(std::get<2>(v)));
|
||||
}
|
||||
%}
|
||||
// Must occur before the twa declaration
|
||||
%typemap(out) SWIGTYPE spot::acc_cond::fin_unit_one_split_improved %{
|
||||
{
|
||||
auto& v = static_cast<const std::tuple<int, spot::acc_cond, spot::acc_cond>>($1);
|
||||
$result = PyTuple_Pack(3,
|
||||
swig::from(std::get<0>(v)),
|
||||
swig::from(std::get<1>(v)),
|
||||
swig::from(std::get<2>(v)));
|
||||
}
|
||||
%}
|
||||
|
||||
%include <spot/twa/acc.hh>
|
||||
%template(pair_bool_mark) std::pair<bool, spot::acc_cond::mark_t>;
|
||||
|
||||
|
|
@ -575,8 +608,11 @@ namespace std {
|
|||
|
||||
%include <spot/tl/apcollect.hh>
|
||||
%include <spot/tl/contain.hh>
|
||||
%include <spot/tl/derive.hh>
|
||||
%include <spot/tl/expansions.hh>
|
||||
%include <spot/tl/dot.hh>
|
||||
%include <spot/tl/nenoform.hh>
|
||||
%include <spot/tl/sonf.hh>
|
||||
%include <spot/tl/print.hh>
|
||||
%include <spot/tl/simplify.hh>
|
||||
%include <spot/tl/unabbrev.hh>
|
||||
|
|
@ -661,11 +697,14 @@ def state_is_accepting(self, src) -> "bool":
|
|||
%include <spot/twaalgos/aiger.hh>
|
||||
%include <spot/twaalgos/alternation.hh>
|
||||
%include <spot/twaalgos/cleanacc.hh>
|
||||
%include <spot/twaalgos/degen.hh>
|
||||
%include <spot/twaalgos/dot.hh>
|
||||
%include <spot/twaalgos/cobuchi.hh>
|
||||
%include <spot/twaalgos/copy.hh>
|
||||
%include <spot/twaalgos/complete.hh>
|
||||
%include <spot/twaalgos/dbranch.hh>
|
||||
%include <spot/twaalgos/degen.hh>
|
||||
%include <spot/twaalgos/determinize.hh>
|
||||
%include <spot/twaalgos/dot.hh>
|
||||
%include <spot/twaalgos/dualize.hh>
|
||||
%feature("flatnested") spot::twa_run::step;
|
||||
%include <spot/twaalgos/emptiness.hh>
|
||||
%template(list_step) std::list<spot::twa_run::step>;
|
||||
|
|
@ -677,8 +716,6 @@ def state_is_accepting(self, src) -> "bool":
|
|||
%include <spot/twaalgos/gfguarantee.hh>
|
||||
%include <spot/twaalgos/compsusp.hh>
|
||||
%include <spot/twaalgos/contains.hh>
|
||||
%include <spot/twaalgos/determinize.hh>
|
||||
%include <spot/twaalgos/dualize.hh>
|
||||
%include <spot/twaalgos/langmap.hh>
|
||||
%include <spot/twaalgos/magic.hh>
|
||||
%include <spot/twaalgos/minimize.hh>
|
||||
|
|
@ -725,6 +762,7 @@ def state_is_accepting(self, src) -> "bool":
|
|||
%include <spot/twaalgos/stutter.hh>
|
||||
%include <spot/twaalgos/synthesis.hh>
|
||||
%include <spot/twaalgos/translate.hh>
|
||||
%include <spot/twaalgos/translate_aa.hh>
|
||||
%include <spot/twaalgos/toweak.hh>
|
||||
%include <spot/twaalgos/hoa.hh>
|
||||
%include <spot/twaalgos/dtwasat.hh>
|
||||
|
|
|
|||
10
spot.spec.in
10
spot.spec.in
|
|
@ -71,16 +71,16 @@ logic (LTL & PSL).
|
|||
|
||||
%files -n libspot
|
||||
%{_libdir}/libbddx.a
|
||||
%{_libdir}/libbddx.la
|
||||
%exclude %{_libdir}/libbddx.la
|
||||
%{_libdir}/libbddx.so*
|
||||
%{_libdir}/libspot.a
|
||||
%{_libdir}/libspot.la
|
||||
%exclude %{_libdir}/libspot.la
|
||||
%{_libdir}/libspot.so*
|
||||
%{_libdir}/libspotgen.a
|
||||
%{_libdir}/libspotgen.la
|
||||
%exclude %{_libdir}/libspotgen.la
|
||||
%{_libdir}/libspotgen.so*
|
||||
%{_libdir}/libspotltsmin.a
|
||||
%{_libdir}/libspotltsmin.la
|
||||
%exclude %{_libdir}/libspotltsmin.la
|
||||
%{_libdir}/libspotltsmin.so*
|
||||
%license COPYING
|
||||
%doc AUTHORS COPYING NEWS README THANKS
|
||||
|
|
@ -121,7 +121,7 @@ temporal logic (LTL & PSL).
|
|||
%dir %{python3_sitearch}/spot
|
||||
%{python3_sitearch}/spot/*
|
||||
%{python3_sitearch}/_buddy.*.a
|
||||
%{python3_sitearch}/_buddy.*.la
|
||||
%exclude %{python3_sitearch}/_buddy.*.la
|
||||
%{python3_sitearch}/_buddy.*.so
|
||||
%license COPYING
|
||||
%doc AUTHORS COPYING NEWS README THANKS
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020
|
||||
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020, 2022
|
||||
## 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
|
||||
|
|
@ -35,7 +35,7 @@ SUBDIRS = misc priv tl graph twa twacube twaalgos ta taalgos kripke \
|
|||
|
||||
lib_LTLIBRARIES = libspot.la
|
||||
libspot_la_SOURCES =
|
||||
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined $(SYMBOLIC_LDFLAGS)
|
||||
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined @LIBSPOT_PTHREAD@ $(SYMBOLIC_LDFLAGS)
|
||||
libspot_la_LIBADD = \
|
||||
kripke/libkripke.la \
|
||||
misc/libmisc.la \
|
||||
|
|
@ -68,6 +68,7 @@ libspot.pc: $(srcdir)/libspot.pc.in Makefile
|
|||
-e 's![@]includedir[@]!$(includedir)!g' \
|
||||
-e 's![@]libdir[@]!$(libdir)!g' \
|
||||
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
|
||||
-e 's![@]LIBSPOT_PTHREAD[@]!$(LIBSPOT_PTHREAD)!g' \
|
||||
$(srcdir)/libspot.pc.in > $@.tmp && mv $@.tmp $@
|
||||
|
||||
CLEANFILES = libspot.pc
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ struct _ConcurrentHashSet : HashSetBase< Cell >
|
|||
return begin() + size();
|
||||
}
|
||||
|
||||
Row() : _data( nullptr ), _size( 0 ) {}
|
||||
Row() noexcept : _data( nullptr ), _size( 0 ) {}
|
||||
~Row() { free(); }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017-2019, 2021 Laboratoire de Recherche et
|
||||
// Copyright (C) 2017-2019, 2021-2022 Laboratoire de Recherche et
|
||||
// Developpement de l'EPITA (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -220,13 +220,48 @@ namespace spot
|
|||
return aut;
|
||||
}
|
||||
|
||||
static twa_graph_ptr
|
||||
cyclist_trace_or_proof(unsigned n, bool trace, bdd_dict_ptr dict)
|
||||
{
|
||||
auto aut = make_twa_graph(dict);
|
||||
acc_cond::mark_t m = aut->set_buchi();
|
||||
aut->new_states(n + 2);
|
||||
aut->set_init_state(0);
|
||||
if (trace)
|
||||
m = {};
|
||||
aut->prop_state_acc(true);
|
||||
|
||||
// How many AP to we need to represent n letters
|
||||
unsigned nap = ulog2(n + 1);
|
||||
std::vector<int> apvars(nap);
|
||||
for (unsigned a = 0; a < nap; ++a)
|
||||
apvars[a] = aut->register_ap("p" + std::to_string(a));
|
||||
|
||||
if (trace)
|
||||
aut->new_edge(0, 0, bddtrue); // the only non-deterministic edge
|
||||
else
|
||||
aut->prop_universal(true);
|
||||
|
||||
bdd zero = bdd_ibuildcube(0, nap, apvars.data());
|
||||
aut->new_edge(0, 1, zero, m);
|
||||
for (unsigned letter = 1; letter <= n; ++letter)
|
||||
{
|
||||
bdd cond = bdd_ibuildcube(letter, nap, apvars.data());
|
||||
aut->new_acc_edge(1, letter + 1, cond);
|
||||
aut->new_edge(letter + 1, 1, zero, m);
|
||||
}
|
||||
|
||||
return aut;
|
||||
}
|
||||
|
||||
|
||||
twa_graph_ptr aut_pattern(aut_pattern_id pattern, int n, bdd_dict_ptr dict)
|
||||
{
|
||||
if (n < 0)
|
||||
{
|
||||
std::ostringstream err;
|
||||
err << "pattern argument for " << aut_pattern_name(pattern)
|
||||
<< " should be positive";
|
||||
<< " should be non-negative";
|
||||
throw std::runtime_error(err.str());
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +276,10 @@ namespace spot
|
|||
return l_dsa(n, dict);
|
||||
case AUT_M_NBA:
|
||||
return m_nba(n, dict);
|
||||
case AUT_CYCLIST_TRACE_NBA:
|
||||
return cyclist_trace_or_proof(n, true, dict);
|
||||
case AUT_CYCLIST_PROOF_DBA:
|
||||
return cyclist_trace_or_proof(n, false, dict);
|
||||
case AUT_END:
|
||||
break;
|
||||
}
|
||||
|
|
@ -255,6 +294,8 @@ namespace spot
|
|||
"l-nba",
|
||||
"l-dsa",
|
||||
"m-nba",
|
||||
"cyclist-trace-nba",
|
||||
"cyclist-proof-dba",
|
||||
};
|
||||
// Make sure we do not forget to update the above table every
|
||||
// time a new pattern is added.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017, 2019 Laboratoire de Recherche et Developpement de
|
||||
// Copyright (C) 2017, 2019, 2022 Laboratoire de Recherche et Developpement de
|
||||
// l'EPITA (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -79,6 +79,24 @@ namespace spot
|
|||
/// propositions to encode the $n+1$ letters used in the
|
||||
/// original alphabet.
|
||||
AUT_M_NBA,
|
||||
/// \brief An NBA with (n+2) states derived from a Cyclic test
|
||||
/// case.
|
||||
///
|
||||
/// This familly of automata is derived from a couple of
|
||||
/// examples supplied by Reuben Rowe. The task is to
|
||||
/// check that the automaton generated with AUT_CYCLIST_TRACE_NBA
|
||||
/// for a given n contain the automaton generated with
|
||||
/// AUT_CYCLIST_PROOF_DBA for the same n.
|
||||
AUT_CYCLIST_TRACE_NBA,
|
||||
/// \brief A DBA with (n+2) states derived from a Cyclic test
|
||||
/// case.
|
||||
///
|
||||
/// This familly of automata is derived from a couple of
|
||||
/// examples supplied by Reuben Rowe. The task is to
|
||||
/// check that the automaton generated with AUT_CYCLIST_TRACE_NBA
|
||||
/// for a given n contain the automaton generated with
|
||||
/// AUT_CYCLIST_PROOF_DBA for the same n.
|
||||
AUT_CYCLIST_PROOF_DBA,
|
||||
AUT_END
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2012-2019 Laboratoire de Recherche et Developpement
|
||||
// Copyright (C) 2012-2019, 2022 Laboratoire de Recherche et Developpement
|
||||
// de l'EPITA (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -1198,13 +1198,13 @@ namespace spot
|
|||
}
|
||||
|
||||
static formula
|
||||
pps_arbiter(std::string r_, std::string g_, int n, bool strict_)
|
||||
pps_arbiter(std::string r_, std::string g_, unsigned n, bool strict_)
|
||||
{
|
||||
formula* r = new formula[n];
|
||||
formula* g = new formula[n];
|
||||
std::vector<formula> res;
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
{
|
||||
r[i] = formula::ap(r_ + std::to_string(i + 1));
|
||||
g[i] = formula::ap(g_ + std::to_string(i + 1));
|
||||
|
|
@ -1218,17 +1218,17 @@ namespace spot
|
|||
formula phi_s;
|
||||
{
|
||||
std::vector<formula> res;
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
res.push_back(formula::Not(r[i]));
|
||||
theta_e = formula::And(res);
|
||||
|
||||
res.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
res.push_back(formula::Not(g[i]));
|
||||
theta_s = formula::And(res);
|
||||
|
||||
res.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
{
|
||||
formula left = formula::Xor(r[i], g[i]);
|
||||
formula right = formula::Equiv(r[i], formula::X(r[i]));
|
||||
|
|
@ -1237,9 +1237,9 @@ namespace spot
|
|||
psi_e = formula::And(res);
|
||||
|
||||
res.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
{
|
||||
for (int j = 0; j < i; ++j)
|
||||
for (unsigned j = 0; j < i; ++j)
|
||||
res.push_back(formula::Not(formula::And({g[i], g[j]})));
|
||||
formula left = formula::Equiv(r[i], g[i]);
|
||||
formula right = formula::Equiv(g[i], formula::X(g[i]));
|
||||
|
|
@ -1248,7 +1248,7 @@ namespace spot
|
|||
psi_s = formula::And(res);
|
||||
|
||||
res.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
{
|
||||
formula f = formula::Not(formula::And({r[i], g[i]}));
|
||||
res.push_back(formula::G(formula::F(f)));
|
||||
|
|
@ -1256,7 +1256,7 @@ namespace spot
|
|||
phi_e = formula::And(res);
|
||||
|
||||
res.clear();
|
||||
for (int i = 0; i < n; ++i)
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
{
|
||||
res.push_back(formula::G(formula::F(formula::Equiv(r[i], g[i]))));
|
||||
}
|
||||
|
|
@ -1267,9 +1267,9 @@ namespace spot
|
|||
|
||||
if (!strict_)
|
||||
{
|
||||
formula left = formula::And({formula::G(psi_e), phi_e});
|
||||
formula imp =
|
||||
formula::Implies(formula::And({formula::G(psi_e), phi_e}),
|
||||
formula::And({formula::G(psi_s), phi_s}));
|
||||
formula::Implies(left, formula::And({formula::G(psi_s), phi_s}));
|
||||
return formula::Implies(theta_e, formula::And({theta_s, imp}));
|
||||
}
|
||||
else
|
||||
|
|
@ -1281,6 +1281,21 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
// G[0..n]((a S b) -> c) rewritten using future operators,
|
||||
// from Edmond Irani Liu (EIL). GSI stands for "Globally Since Implies."
|
||||
static formula eil_gsi(int n, std::string a, std::string b, std::string c)
|
||||
{
|
||||
formula fa = formula::ap(a);
|
||||
formula fb = formula::ap(b);
|
||||
formula res = fb;
|
||||
for (int i = 1; i <= n; ++i)
|
||||
{
|
||||
formula tmp = formula::And({formula::strong_X(i, fa), res});
|
||||
res = formula::Or({formula::strong_X(i, fb), tmp});
|
||||
}
|
||||
return formula::Implies(res, formula::strong_X(n, formula::ap(c)));
|
||||
}
|
||||
|
||||
formula ltl_pattern(ltl_pattern_id pattern, int n, int m)
|
||||
{
|
||||
if (n < 0)
|
||||
|
|
@ -1317,6 +1332,8 @@ namespace spot
|
|||
return dac_pattern(n);
|
||||
case LTL_EH_PATTERNS:
|
||||
return eh_pattern(n);
|
||||
case LTL_EIL_GSI:
|
||||
return eil_gsi(n, "a", "b", "c");
|
||||
case LTL_FXG_OR:
|
||||
return FXG_or_n("p", n);
|
||||
case LTL_GF_EQUIV:
|
||||
|
|
@ -1418,6 +1435,7 @@ namespace spot
|
|||
"ccj-beta-prime",
|
||||
"dac-patterns",
|
||||
"eh-patterns",
|
||||
"eil-gsi",
|
||||
"fxg-or",
|
||||
"gf-equiv",
|
||||
"gf-equiv-xn",
|
||||
|
|
@ -1485,6 +1503,7 @@ namespace spot
|
|||
return 55;
|
||||
case LTL_EH_PATTERNS:
|
||||
return 12;
|
||||
case LTL_EIL_GSI:
|
||||
case LTL_FXG_OR:
|
||||
case LTL_GF_EQUIV:
|
||||
case LTL_GF_EQUIV_XN:
|
||||
|
|
@ -1554,6 +1573,7 @@ namespace spot
|
|||
case LTL_CCJ_BETA_PRIME:
|
||||
case LTL_DAC_PATTERNS:
|
||||
case LTL_EH_PATTERNS:
|
||||
case LTL_EIL_GSI:
|
||||
case LTL_FXG_OR:
|
||||
case LTL_GF_EQUIV:
|
||||
case LTL_GF_EQUIV_XN:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017, 2018, 2019 Laboratoire de Recherche et Developpement de
|
||||
// l'EPITA (LRDE).
|
||||
// Copyright (C) 2017-2019, 2022 Laboratoire de Recherche et
|
||||
// Developpement de l'EPITA (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -56,6 +56,8 @@ namespace spot
|
|||
/// 12 formulas from Etessami and Holzmann.
|
||||
/// \cite etessami.00.concur
|
||||
LTL_EH_PATTERNS,
|
||||
/// Familly sent by Edmond Irani Liu
|
||||
LTL_EIL_GSI,
|
||||
/// `F(p0 | XG(p1 | XG(p2 | ... XG(pn))))`
|
||||
LTL_FXG_OR,
|
||||
/// `(GFa1 & GFa2 & ... & GFan) <-> GFz`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014-2018, 2020, 2021 Laboratoire de Recherche et
|
||||
// Copyright (C) 2014-2018, 2020-2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita.
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <spot/misc/common.hh>
|
||||
#include <spot/misc/_config.h>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <tuple>
|
||||
|
|
@ -28,6 +29,9 @@
|
|||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#ifdef SPOT_ENABLE_PTHREAD
|
||||
# include <thread>
|
||||
#endif // SPOT_ENABLE_PTHREAD
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
|
@ -553,10 +557,11 @@ namespace spot
|
|||
{
|
||||
std::map<std::vector<unsigned>, unsigned> uniq_;
|
||||
G& g_;
|
||||
unsigned acc_sink_;
|
||||
public:
|
||||
|
||||
univ_dest_mapper(G& graph)
|
||||
: g_(graph)
|
||||
univ_dest_mapper(G& graph, unsigned sink = -1u)
|
||||
: g_(graph), acc_sink_(sink)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -566,6 +571,9 @@ namespace spot
|
|||
std::vector<unsigned> tmp(begin, end);
|
||||
std::sort(tmp.begin(), tmp.end());
|
||||
tmp.erase(std::unique(tmp.begin(), tmp.end()), tmp.end());
|
||||
if (acc_sink_ != -1u && tmp.size() > 1)
|
||||
tmp.erase(std::remove(tmp.begin(), tmp.end(), acc_sink_),
|
||||
tmp.end());
|
||||
auto p = uniq_.emplace(tmp, 0);
|
||||
if (p.second)
|
||||
p.first->second = g_.new_univ_dests(tmp.begin(), tmp.end());
|
||||
|
|
@ -800,8 +808,23 @@ namespace spot
|
|||
return *dst_begin;
|
||||
SPOT_ASSERT(sz > 1);
|
||||
unsigned d = dests_.size();
|
||||
dests_.emplace_back(sz);
|
||||
dests_.insert(dests_.end(), dst_begin, dst_end);
|
||||
if (!dests_.empty()
|
||||
&& &*dst_begin >= &dests_.front()
|
||||
&& &*dst_begin <= &dests_.back()
|
||||
&& (dests_.capacity() - dests_.size()) < (sz + 1))
|
||||
{
|
||||
// If dst_begin...dst_end points into dests_ and dests_ risk
|
||||
// being reallocated, we have to savea the destination
|
||||
// states before we lose them.
|
||||
std::vector<unsigned> tmp(dst_begin, dst_end);
|
||||
dests_.emplace_back(sz);
|
||||
dests_.insert(dests_.end(), tmp.begin(), tmp.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
dests_.emplace_back(sz);
|
||||
dests_.insert(dests_.end(), dst_begin, dst_end);
|
||||
}
|
||||
return ~d;
|
||||
}
|
||||
|
||||
|
|
@ -1226,6 +1249,78 @@ namespace spot
|
|||
std::stable_sort(edges_.begin() + 1, edges_.end(), p);
|
||||
}
|
||||
|
||||
/// \brief Sort all edges by src first, then, within edges of the same
|
||||
/// source use the predicate
|
||||
///
|
||||
/// This will invalidate all iterators, and also destroy edge
|
||||
/// chains. Call chain_edges_() immediately afterwards unless you
|
||||
/// know what you are doing.
|
||||
/// \note: for performance this will work in parallel (if enabled)
|
||||
/// and make a temporary copy of the edges (needs more ram)
|
||||
/// \pre This needs the edge_vector to be in a coherent state when called
|
||||
template<class Predicate = std::less<edge_storage_t>>
|
||||
void sort_edges_srcfirst_(Predicate p = Predicate(),
|
||||
parallel_policy ppolicy = parallel_policy())
|
||||
{
|
||||
SPOT_ASSERT(!edges_.empty());
|
||||
const unsigned ns = num_states();
|
||||
std::vector<unsigned> idx_list(ns+1);
|
||||
edge_vector_t new_edges;
|
||||
new_edges.reserve(edges_.size());
|
||||
new_edges.resize(1);
|
||||
// This causes edge 0 to be considered as dead.
|
||||
new_edges[0].next_succ = 0;
|
||||
// Copy all edges so that they are sorted by src
|
||||
for (unsigned s = 0; s < ns; ++s)
|
||||
{
|
||||
idx_list[s] = new_edges.size();
|
||||
for (const auto& e : out(s))
|
||||
new_edges.push_back(e);
|
||||
}
|
||||
idx_list[ns] = new_edges.size();
|
||||
// New edge sorted by source
|
||||
// If we have few edge or only one threads
|
||||
// Benchmark few?
|
||||
auto bne = new_edges.begin();
|
||||
#ifndef SPOT_ENABLE_PTHREAD
|
||||
(void) ppolicy;
|
||||
#else
|
||||
unsigned nthreads = ppolicy.nthreads();
|
||||
if (nthreads <= 1)
|
||||
#endif
|
||||
{
|
||||
for (unsigned s = 0u; s < ns; ++s)
|
||||
std::stable_sort(bne + idx_list[s],
|
||||
bne + idx_list[s+1], p);
|
||||
}
|
||||
#ifdef SPOT_ENABLE_PTHREAD
|
||||
else
|
||||
{
|
||||
static std::vector<std::thread> tv;
|
||||
SPOT_ASSERT(tv.empty());
|
||||
tv.resize(nthreads);
|
||||
// FIXME: Due to the way these thread advance into the state
|
||||
// vector, they access very close memory location. It would
|
||||
// seems more cache friendly to have threads work on blocks
|
||||
// of continuous states.
|
||||
for (unsigned id = 0; id < nthreads; ++id)
|
||||
tv[id] = std::thread(
|
||||
[bne, id, ns, &idx_list, p, nthreads]()
|
||||
{
|
||||
for (unsigned s = id; s < ns; s += nthreads)
|
||||
std::stable_sort(bne + idx_list[s],
|
||||
bne + idx_list[s+1], p);
|
||||
return;
|
||||
});
|
||||
for (auto& t : tv)
|
||||
t.join();
|
||||
tv.clear();
|
||||
}
|
||||
#endif
|
||||
std::swap(edges_, new_edges);
|
||||
// Like after normal sort_edges, they need to be chained before usage
|
||||
}
|
||||
|
||||
/// \brief Sort edges of the given states
|
||||
///
|
||||
/// \tparam Predicate : Comparison type
|
||||
|
|
@ -1243,14 +1338,19 @@ namespace spot
|
|||
//dump_storage(std::cerr);
|
||||
auto pi = [&](unsigned t1, unsigned t2)
|
||||
{return p(edges_[t1], edges_[t2]); };
|
||||
|
||||
// Sort the outgoing edges of each selected state according
|
||||
// to predicate p. Do that in place.
|
||||
std::vector<unsigned> sort_idx_;
|
||||
for (unsigned i = 0; i < num_states(); ++i)
|
||||
unsigned ns = num_states();
|
||||
for (unsigned i = 0; i < ns; ++i)
|
||||
{
|
||||
if (to_sort_ptr && !(*to_sort_ptr)[i])
|
||||
continue;
|
||||
|
||||
sort_idx_.clear();
|
||||
unsigned t = states_[i].succ;
|
||||
if (t == 0)
|
||||
continue;
|
||||
sort_idx_.clear();
|
||||
do
|
||||
{
|
||||
sort_idx_.push_back(t);
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ Description: A library of LTL and omega-automata algorithms for model checking
|
|||
URL: https://spot.lrde.epita.fr/
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lspot
|
||||
Libs: -L${libdir} -lspot @LIBSPOT_PTHREAD@
|
||||
Requires: libbddx
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017, 2018, 2020 Laboratoire de Recherche et Développement de
|
||||
// l'Epita (LRDE)
|
||||
// Copyright (C) 2017, 2018, 2020, 2022 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE)
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -400,10 +400,10 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME I think we only need visbles aps, i.e. if the system has
|
||||
// following variables, i.e. P_0.var1 and P_0.var2 but the property
|
||||
// automaton only mention P_0.var2, we do not need to capture (in
|
||||
// the resulting cube) any atomic proposition for P_0.var1
|
||||
// FIXME: I think we only need visible aps. E.g., if the system has
|
||||
// variables P_0.var1 and P_0.var2 but the property automaton only
|
||||
// mentions P_0.var2, we do not need to capture (in the resulting
|
||||
// cube) any atomic proposition for P_0.var1
|
||||
void
|
||||
kripkecube<cspins_state,
|
||||
cspins_iterator>::match_aps(std::vector<std::string>& aps,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -127,7 +127,7 @@ namespace spot
|
|||
bool b = it.isnew();
|
||||
|
||||
// Insertion failed, delete element
|
||||
// FIXME Should we add a local cache to avoid useless allocations?
|
||||
// FIXME: Should we add a local cache to avoid useless allocations?
|
||||
if (!b)
|
||||
p_.deallocate(v);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -251,7 +251,7 @@ namespace spot
|
|||
uf_element* q;
|
||||
uf_element* r;
|
||||
|
||||
while (true)
|
||||
do
|
||||
{
|
||||
a_root = find(a);
|
||||
b_root = find(b);
|
||||
|
|
@ -261,28 +261,24 @@ namespace spot
|
|||
// Update acceptance condition
|
||||
{
|
||||
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
||||
a_root->acc |= acc;
|
||||
acc |= a_root->acc;
|
||||
a_root->acc = acc;
|
||||
}
|
||||
|
||||
while (a_root->parent.load() != a_root)
|
||||
{
|
||||
a_root = find(a_root);
|
||||
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
||||
a_root->acc |= acc;
|
||||
acc |= a_root->acc;
|
||||
a_root->acc = acc;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
r = std::max(a_root, b_root);
|
||||
q = std::min(a_root, b_root);
|
||||
|
||||
if (!lock_root(q))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
while (!lock_root(q));
|
||||
|
||||
uf_element* a_list = lock_list(a);
|
||||
if (a_list == nullptr)
|
||||
|
|
@ -329,9 +325,8 @@ namespace spot
|
|||
{
|
||||
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
||||
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
||||
q->acc |= acc;
|
||||
r->acc |= q->acc;
|
||||
acc |= r->acc;
|
||||
acc |= r->acc | q->acc;
|
||||
r->acc = q->acc = acc;
|
||||
}
|
||||
|
||||
while (r->parent.load() != r)
|
||||
|
|
@ -339,8 +334,8 @@ namespace spot
|
|||
r = find(r);
|
||||
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
||||
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
||||
r->acc |= q->acc;
|
||||
acc |= r->acc;
|
||||
acc |= r->acc | q->acc;
|
||||
r->acc = acc;
|
||||
}
|
||||
|
||||
unlock_list(a_list);
|
||||
|
|
@ -360,9 +355,7 @@ namespace spot
|
|||
a_status = a->list_status_.load();
|
||||
|
||||
if (a_status == list_status::BUSY)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
return a;
|
||||
|
||||
if (a_status == list_status::DONE)
|
||||
break;
|
||||
|
|
@ -407,9 +400,7 @@ namespace spot
|
|||
b_status = b->list_status_.load();
|
||||
|
||||
if (b_status == list_status::BUSY)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
return b;
|
||||
|
||||
if (b_status == list_status::DONE)
|
||||
break;
|
||||
|
|
@ -556,8 +547,8 @@ namespace spot
|
|||
|
||||
{
|
||||
auto root = uf_.find(w.second);
|
||||
std::lock_guard<std::mutex> lock(w.second->acc_mutex_);
|
||||
scc_acc = w.second->acc;
|
||||
std::lock_guard<std::mutex> lock(root->acc_mutex_);
|
||||
scc_acc = root->acc;
|
||||
}
|
||||
|
||||
// cycle found in SCC and it contains acceptance condition
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -191,9 +191,7 @@ namespace spot
|
|||
{
|
||||
// Try to insert the new state in the shared map.
|
||||
auto it = map_.insert(s);
|
||||
bool b = it.isnew();
|
||||
|
||||
SPOT_ASSERT(!b); // should never be new in a red DFS
|
||||
SPOT_ASSERT(!it.isnew()); // should never be new in a red DFS
|
||||
bool red = ((*it)).colors->red.load();
|
||||
bool cyan = ((*it)).colors->l[tid_].cyan;
|
||||
bool in_Rp = ((*it)).colors->l[tid_].is_in_Rp;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2016, 2018-2021 Laboratoire de Recherche et
|
||||
// Copyright (C) 2015-2016, 2018-, 20222022 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -32,9 +32,9 @@ namespace spot
|
|||
{
|
||||
/// \brief This class implements the sequential emptiness check as
|
||||
/// presented in "Three SCC-based Emptiness Checks for Generalized
|
||||
/// B\¨uchi Automata" (Renault et al, LPAR 2013). Among the three
|
||||
/// emptiness check that has been proposed we opted to implement
|
||||
/// the Gabow's one.
|
||||
/// Büchi Automata" (Renault et al, LPAR 2013). Among the three
|
||||
/// emptiness checks that have been proposed, we opted to implement
|
||||
/// yGabow's one.
|
||||
template<typename State, typename SuccIterator,
|
||||
typename StateHash, typename StateEqual>
|
||||
class SPOT_API lpar13
|
||||
|
|
@ -62,8 +62,8 @@ namespace spot
|
|||
size_t
|
||||
operator()(const product_state that) const noexcept
|
||||
{
|
||||
// FIXME! wang32_hash(that.st_prop) could have
|
||||
// been pre-calculated!
|
||||
// FIXME: wang32_hash(that.st_prop) could have been
|
||||
// pre-calculated!
|
||||
StateHash hasher;
|
||||
return wang32_hash(that.st_prop) ^ hasher(that.st_kripke);
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ namespace spot
|
|||
map[newtop])))
|
||||
{
|
||||
sys_.recycle(todo.back().it_kripke, tid_);
|
||||
// FIXME a local storage for twacube iterator?
|
||||
// FIXME: a local storage for twacube iterator?
|
||||
todo.pop_back();
|
||||
if (SPOT_UNLIKELY(found_))
|
||||
{
|
||||
|
|
@ -346,7 +346,7 @@ namespace spot
|
|||
ctrx_element* current = front;
|
||||
while (current != nullptr)
|
||||
{
|
||||
// FIXME also display acc?
|
||||
// FIXME: also display acc?
|
||||
res = res + " " +
|
||||
std::to_string(current->prod_st->st_prop) +
|
||||
+ "*" +
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2011-2014, 2016-2018, 2020-2021 Laboratoire de
|
||||
## Copyright (C) 2011-2014, 2016-2018, 2020-2022 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),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2013-2021, 2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -111,22 +111,22 @@ namespace spot
|
|||
return;
|
||||
if (storage_ == &local_storage_)
|
||||
{
|
||||
block_t* new_storage_ = static_cast<block_t*>
|
||||
block_t* new_storage = static_cast<block_t*>
|
||||
(malloc(new_block_count * sizeof(block_t)));
|
||||
if (SPOT_UNLIKELY(!new_storage))
|
||||
throw std::bad_alloc();
|
||||
for (size_t i = 0; i < block_count_; ++i)
|
||||
new_storage_[i] = storage_[i];
|
||||
storage_ = new_storage_;
|
||||
new_storage[i] = storage_[i];
|
||||
storage_ = new_storage;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto old = storage_;
|
||||
storage_ = static_cast<block_t*>
|
||||
(realloc(old, new_block_count * sizeof(block_t)));
|
||||
if (!storage_)
|
||||
{
|
||||
free(old);
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
block_t* new_storage = static_cast<block_t*>
|
||||
(realloc(storage_, new_block_count * sizeof(block_t)));
|
||||
if (SPOT_UNLIKELY(!new_storage))
|
||||
// storage_, untouched, will be freed by the destructor.
|
||||
throw std::bad_alloc();
|
||||
storage_ = new_storage;
|
||||
}
|
||||
block_count_ = new_block_count;
|
||||
}
|
||||
|
|
@ -134,8 +134,8 @@ namespace spot
|
|||
private:
|
||||
void grow()
|
||||
{
|
||||
size_t new_block_count_ = (block_count_ + 1) * 7 / 5;
|
||||
reserve_blocks(new_block_count_);
|
||||
size_t new_block_count = (block_count_ + 1) * 7 / 5;
|
||||
reserve_blocks(new_block_count);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -145,6 +145,27 @@ namespace spot
|
|||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This class is used to tell parallel algorithms what
|
||||
/// resources they may use.
|
||||
///
|
||||
/// Currently, this simply stores an integer indicating the number
|
||||
/// of threads that the algorithm may create, but in the future it
|
||||
/// will probably do more.
|
||||
class SPOT_API parallel_policy
|
||||
{
|
||||
unsigned nthreads_;
|
||||
public:
|
||||
parallel_policy(unsigned nthreads = 1) : nthreads_(nthreads)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned nthreads() const
|
||||
{
|
||||
return nthreads_;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// This is a workaround for the issue described in GNU GCC bug 89303.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue