Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bdae5563c6 | |||
| 0505ee9310 |
327 changed files with 12007 additions and 41491 deletions
|
|
@ -3,9 +3,9 @@
|
||||||
(require-final-newline . t)
|
(require-final-newline . t)
|
||||||
(mode . global-whitespace)
|
(mode . global-whitespace)
|
||||||
(bug-reference-bug-regexp
|
(bug-reference-bug-regexp
|
||||||
. "\\(?1:\\(?:[Ff]ix\\(?:es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)\\)")
|
. "\\(?:[Ff]ix\\(es\\)? \\|[Ii]ssue \\)#\\(?2:[0-9]+\\)")
|
||||||
(bug-reference-url-format
|
(bug-reference-url-format
|
||||||
. "https://gitlab.lre.epita.fr/spot/spot/issues/%s")
|
. "https://gitlab.lrde.epita.fr/spot/spot/issues/%s")
|
||||||
(mode . bug-reference)
|
(mode . bug-reference)
|
||||||
(magit-branch-adjust-remote-upstream-alist ("origin/next" . "/"))))
|
(magit-branch-adjust-remote-upstream-alist ("origin/next" . "/"))))
|
||||||
(c++-mode . ((c-default-style . "gnu")
|
(c++-mode . ((c-default-style . "gnu")
|
||||||
|
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,7 +4,6 @@ configure
|
||||||
config.log
|
config.log
|
||||||
config.status
|
config.status
|
||||||
aclocal.m4
|
aclocal.m4
|
||||||
ltargz.m4
|
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
libtool
|
libtool
|
||||||
auto
|
auto
|
||||||
|
|
@ -82,4 +81,3 @@ GTAGS
|
||||||
*.dsc
|
*.dsc
|
||||||
*.gcov
|
*.gcov
|
||||||
spot.spec
|
spot.spec
|
||||||
default.nix
|
|
||||||
|
|
|
||||||
190
.gitlab-ci.yml
190
.gitlab-ci.yml
|
|
@ -19,12 +19,12 @@ debian-stable-gcc:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
|
||||||
script:
|
script:
|
||||||
- autoreconf -vfi
|
- autoreconf -vfi
|
||||||
- ./configure --enable-max-accsets=256 --enable-pthread
|
- ./configure --enable-max-accsets=256
|
||||||
- make
|
- make
|
||||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-max-accsets=256 --enable-pthread'
|
- make distcheck
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
|
|
@ -32,47 +32,22 @@ debian-stable-gcc:
|
||||||
- ./*.log
|
- ./*.log
|
||||||
- ./*.tar.gz
|
- ./*.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:
|
debian-unstable-gcc-coverage:
|
||||||
stage: build
|
stage: build
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
script:
|
script:
|
||||||
- autoreconf -vfi
|
- autoreconf -vfi
|
||||||
- ./configure CXX='g++ --coverage' --disable-devel --enable-warnings --disable-static --enable-doxygen
|
- ./configure CXX='g++ --coverage' --enable-devel --disable-static --enable-doxygen
|
||||||
- make
|
- make
|
||||||
- make check
|
- make check
|
||||||
- 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
|
- lcov --capture --directory . --no-external --output spot.info
|
||||||
coverage: /^\s*lines:\s*\d+.\d+\%/
|
- 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
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
|
|
@ -80,57 +55,38 @@ debian-unstable-gcc-coverage:
|
||||||
- ./*.log
|
- ./*.log
|
||||||
- doc/spot.html/
|
- doc/spot.html/
|
||||||
- doc/userdoc/
|
- doc/userdoc/
|
||||||
- coverage*.html
|
- coverage/
|
||||||
- coverage*.css
|
|
||||||
- ./*.tar.gz
|
- ./*.tar.gz
|
||||||
reports:
|
- spot2.info
|
||||||
coverage_report:
|
|
||||||
coverage_format: cobertura
|
|
||||||
path: coverage.xml
|
|
||||||
|
|
||||||
debian-unstable-gcc-pypy:
|
debian-unstable-gcc-pypy:
|
||||||
stage: build2
|
stage: build
|
||||||
needs:
|
|
||||||
- job: make-dist
|
|
||||||
artifacts: true
|
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
script:
|
script:
|
||||||
- VERSION=`cat VERSION`
|
- autoreconf -vfi
|
||||||
- tar xvf spot-$VERSION.tar.gz
|
|
||||||
- cd spot-$VERSION
|
|
||||||
- ./configure PYTHON=/usr/bin/pypy3 --disable-static
|
- ./configure PYTHON=/usr/bin/pypy3 --disable-static
|
||||||
- make
|
- make
|
||||||
- make check TESTS='$(TESTS_python) $(TESTS_ipython)'
|
- make check TESTS='$(TESTS_python) $(TESTS_ipython)'
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- spot-*/tests/*/*.log
|
- tests/*/*.log
|
||||||
- spot-*/*.log
|
- ./*.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:
|
debian-gcc-snapshot:
|
||||||
stage: build2
|
stage: build
|
||||||
needs:
|
|
||||||
- job: make-dist
|
|
||||||
artifacts: true
|
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
script:
|
script:
|
||||||
- export PATH="/usr/lib/gcc-snapshot/bin:$PATH" LD_LIBRARY_PATH="/usr/lib/gcc-snapshot/lib:$LD_LIBRARY_PATH"
|
- export PATH="/usr/lib/gcc-snapshot/bin:$PATH" LD_LIBRARY_PATH="/usr/lib/gcc-snapshot/lib:$LD_LIBRARY_PATH"
|
||||||
- VERSION=`cat VERSION`
|
- autoreconf -vfi
|
||||||
- tar xvf spot-$VERSION.tar.gz
|
|
||||||
- cd spot-$VERSION
|
|
||||||
- ./configure --with-included-ltdl CXX='g++'
|
- ./configure --with-included-ltdl CXX='g++'
|
||||||
- make
|
- make
|
||||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
|
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--with-included-ltdl'
|
||||||
|
|
@ -138,8 +94,11 @@ debian-gcc-snapshot:
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
- spot-*/tests/*/*.log
|
- ./spot-*/_build/sub/tests/*/*.log
|
||||||
- spot-*/*.log
|
- ./*.log
|
||||||
|
- doc/spot.html/
|
||||||
|
- doc/userdoc/
|
||||||
|
- ./*.tar.gz
|
||||||
|
|
||||||
alpine-gcc:
|
alpine-gcc:
|
||||||
stage: build
|
stage: build
|
||||||
|
|
@ -147,12 +106,12 @@ alpine-gcc:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/alpine
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/alpine
|
||||||
script:
|
script:
|
||||||
- autoreconf -vfi
|
- autoreconf -vfi
|
||||||
- ./configure
|
- ./configure
|
||||||
- make
|
- make
|
||||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-pthread' || { chmod -R u+w ./spot-*; false; }
|
- make distcheck || { chmod -R u+w ./spot-*; false; }
|
||||||
artifacts:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
paths:
|
paths:
|
||||||
|
|
@ -166,7 +125,7 @@ arch-clang:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
|
||||||
script:
|
script:
|
||||||
- autoreconf -vfi
|
- autoreconf -vfi
|
||||||
- ./configure --prefix ~/install_dir CC='clang -Qunused-arguments' CXX='clang++ -Qunused-arguments' --enable-devel --enable-c++20 --enable-doxygen
|
- ./configure --prefix ~/install_dir CC='clang -Qunused-arguments' CXX='clang++ -Qunused-arguments' --enable-devel --enable-c++20 --enable-doxygen
|
||||||
|
|
@ -179,30 +138,22 @@ arch-clang:
|
||||||
- ./*.log
|
- ./*.log
|
||||||
|
|
||||||
arch-gcc-glibcxxdebug:
|
arch-gcc-glibcxxdebug:
|
||||||
stage: build2
|
stage: build
|
||||||
needs:
|
|
||||||
- job: make-dist
|
|
||||||
artifacts: true
|
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/arch
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/arch
|
||||||
script:
|
script:
|
||||||
- VERSION=`cat VERSION`
|
- autoreconf -vfi
|
||||||
- tar xvf spot-$VERSION.tar.gz
|
- ./configure --enable-devel --enable-c++20 --enable-glibcxx-debug
|
||||||
- mkdir build-$VERSION
|
|
||||||
- cd build-$VERSION
|
|
||||||
- ../spot-$VERSION/configure --enable-devel --enable-c++20 --enable-glibcxx-debug
|
|
||||||
- make
|
- make
|
||||||
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-devel --enable-c++20 --enable-glibcxx-debug'
|
- make distcheck DISTCHECK_CONFIGURE_FLAGS='--enable-devel --enable-c++20 --enable-glibcxx-debug'
|
||||||
artifacts:
|
artifacts:
|
||||||
when: on_failure
|
when: on_failure
|
||||||
paths:
|
paths:
|
||||||
- build-*/spot-*/_build/sub/tests/*/*.log
|
- ./spot-*/_build/sub/tests/*/*.log
|
||||||
- build-*/*.log
|
- ./*.log
|
||||||
|
|
||||||
mingw-shared:
|
mingw-shared:
|
||||||
stage: build2
|
stage: build2
|
||||||
|
|
@ -210,17 +161,15 @@ mingw-shared:
|
||||||
# We start from the tarball generated from a non-cross-compiling
|
# We start from the tarball generated from a non-cross-compiling
|
||||||
# job, so that all generated files are included, especially those
|
# job, so that all generated files are included, especially those
|
||||||
# built from the executables.
|
# built from the executables.
|
||||||
- job: make-dist
|
- job: debian-stable-gcc
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
script:
|
script:
|
||||||
- VERSION=`cat VERSION`
|
- VERSION=`autoconf --trace='AC_INIT:$2'`
|
||||||
- tar xvf spot-$VERSION.tar.gz
|
- tar xvf spot-$VERSION.tar.gz
|
||||||
- cd spot-$VERSION
|
- cd spot-$VERSION
|
||||||
- ./configure CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++-posix --host i686-w64-mingw32 --disable-python
|
- ./configure CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++-posix --host i686-w64-mingw32 --disable-python
|
||||||
|
|
@ -237,17 +186,15 @@ mingw-static:
|
||||||
# We start from the tarball generated from a non-cross-compiling
|
# We start from the tarball generated from a non-cross-compiling
|
||||||
# job, so that all generated files are included, especially those
|
# job, so that all generated files are included, especially those
|
||||||
# built from the executables.
|
# built from the executables.
|
||||||
- job: make-dist
|
- job: debian-stable-gcc
|
||||||
artifacts: true
|
artifacts: true
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
except:
|
except:
|
||||||
- /wip/
|
- /wip/
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
script:
|
script:
|
||||||
- VERSION=`cat VERSION`
|
- VERSION=`autoconf --trace='AC_INIT:$2'`
|
||||||
- tar xvf spot-$VERSION.tar.gz
|
- tar xvf spot-$VERSION.tar.gz
|
||||||
- cd spot-$VERSION
|
- cd spot-$VERSION
|
||||||
- mkdir install_dir
|
- mkdir install_dir
|
||||||
|
|
@ -267,19 +214,17 @@ mingw-static:
|
||||||
|
|
||||||
debpkg-stable:
|
debpkg-stable:
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- /-deb$/
|
- /-deb$/
|
||||||
- master
|
- master
|
||||||
- next
|
- next
|
||||||
- stable
|
- stable
|
||||||
script:
|
script:
|
||||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian:stable
|
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian:stable
|
||||||
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
- vol=spot-stable-$CI_COMMIT_SHA
|
||||||
- docker volume create $vol
|
- docker volume create $vol
|
||||||
- exitcode=0
|
- exitcode=0
|
||||||
- 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 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 cp helper-$vol:/build/result _build_stable || exitcode=$?
|
- docker cp helper-$vol:/build/result _build_stable || exitcode=$?
|
||||||
- docker rm helper-$vol || exitcode=$?
|
- docker rm helper-$vol || exitcode=$?
|
||||||
- docker volume rm $vol || exitcode=$?
|
- docker volume rm $vol || exitcode=$?
|
||||||
|
|
@ -293,8 +238,6 @@ debpkg-stable:
|
||||||
|
|
||||||
debpkg-stable-i386:
|
debpkg-stable-i386:
|
||||||
stage: build2
|
stage: build2
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- /-deb$/
|
- /-deb$/
|
||||||
- master
|
- master
|
||||||
|
|
@ -303,11 +246,11 @@ debpkg-stable-i386:
|
||||||
tags: ["x86"]
|
tags: ["x86"]
|
||||||
needs: ["debpkg-stable"]
|
needs: ["debpkg-stable"]
|
||||||
script:
|
script:
|
||||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386:stable
|
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386:stable
|
||||||
- vol=spot-stable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
- vol=spot-stable-$CI_COMMIT_SHA
|
||||||
- docker volume create $vol
|
- docker volume create $vol
|
||||||
- exitcode=0
|
- exitcode=0
|
||||||
- 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 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 cp _build_stable/. helper-$vol:/build/result || exitcode=$?
|
- docker cp _build_stable/. helper-$vol:/build/result || exitcode=$?
|
||||||
- rm -rf _build_stable
|
- rm -rf _build_stable
|
||||||
- docker start -a helper-$vol || exitcode=$?
|
- docker start -a helper-$vol || exitcode=$?
|
||||||
|
|
@ -324,17 +267,15 @@ debpkg-stable-i386:
|
||||||
|
|
||||||
debpkg-unstable:
|
debpkg-unstable:
|
||||||
stage: build
|
stage: build
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- /-deb$/
|
- /-deb$/
|
||||||
- next
|
- next
|
||||||
script:
|
script:
|
||||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian
|
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian
|
||||||
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
- vol=spot-unstable-$CI_COMMIT_SHA
|
||||||
- docker volume create $vol
|
- docker volume create $vol
|
||||||
- exitcode=0
|
- exitcode=0
|
||||||
- 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 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 cp helper-$vol:/build/result _build_unstable || exitcode=$?
|
- docker cp helper-$vol:/build/result _build_unstable || exitcode=$?
|
||||||
- docker rm helper-$vol || exitcode=$?
|
- docker rm helper-$vol || exitcode=$?
|
||||||
- docker volume rm $vol || exitcode=$?
|
- docker volume rm $vol || exitcode=$?
|
||||||
|
|
@ -348,19 +289,17 @@ debpkg-unstable:
|
||||||
|
|
||||||
debpkg-unstable-i386:
|
debpkg-unstable-i386:
|
||||||
stage: build2
|
stage: build2
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- /-deb$/
|
- /-deb$/
|
||||||
- next
|
- next
|
||||||
tags: ["x86"]
|
tags: ["x86"]
|
||||||
needs: ["debpkg-unstable"]
|
needs: ["debpkg-unstable"]
|
||||||
script:
|
script:
|
||||||
- docker pull gitlab-registry.lre.epita.fr/spot/buildenv/debian-i386
|
- docker pull gitlab-registry.lrde.epita.fr/spot/buildenv/debian-i386
|
||||||
- vol=spot-unstable-$CI_COMMIT_SHA-$CI_PIPELINE_ID
|
- vol=spot-unstable-$CI_COMMIT_SHA
|
||||||
- docker volume create $vol
|
- docker volume create $vol
|
||||||
- exitcode=0
|
- exitcode=0
|
||||||
- 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 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 cp _build_unstable/. helper-$vol:/build/result || exitcode=$?
|
- docker cp _build_unstable/. helper-$vol:/build/result || exitcode=$?
|
||||||
- rm -rf _build_unstable
|
- rm -rf _build_unstable
|
||||||
- docker start -a helper-$vol || exitcode=$?
|
- docker start -a helper-$vol || exitcode=$?
|
||||||
|
|
@ -382,7 +321,7 @@ rpm-pkg:
|
||||||
- master
|
- master
|
||||||
- next
|
- next
|
||||||
- stable
|
- stable
|
||||||
image: gitlab-registry.lre.epita.fr/spot/buildenv/fedora
|
image: gitlab-registry.lrde.epita.fr/spot/buildenv/fedora
|
||||||
script:
|
script:
|
||||||
- autoreconf -vfi
|
- autoreconf -vfi
|
||||||
- ./configure
|
- ./configure
|
||||||
|
|
@ -401,8 +340,6 @@ rpm-pkg:
|
||||||
|
|
||||||
publish-rpm:
|
publish-rpm:
|
||||||
stage: publish
|
stage: publish
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
only:
|
only:
|
||||||
- /-rpm$/
|
- /-rpm$/
|
||||||
- next
|
- next
|
||||||
|
|
@ -413,7 +350,6 @@ publish-rpm:
|
||||||
- rpm-pkg
|
- rpm-pkg
|
||||||
script:
|
script:
|
||||||
- case $CI_COMMIT_REF_NAME in stable) rput fedora stable *.rpm;; next) rput fedora unstable *.rpm;; esac
|
- case $CI_COMMIT_REF_NAME in stable) rput fedora stable *.rpm;; next) rput fedora unstable *.rpm;; esac
|
||||||
- rm -rf ./*
|
|
||||||
|
|
||||||
publish-stable:
|
publish-stable:
|
||||||
only:
|
only:
|
||||||
|
|
@ -421,23 +357,15 @@ publish-stable:
|
||||||
tags:
|
tags:
|
||||||
- dput
|
- dput
|
||||||
stage: publish
|
stage: publish
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- debpkg-stable-i386
|
- debpkg-stable-i386
|
||||||
- make-dist
|
|
||||||
script:
|
script:
|
||||||
- cd _build_stable
|
- cd _build_stable
|
||||||
- ls -l
|
- ls -l
|
||||||
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
|
- dput lrde *.changes
|
||||||
- cd ..
|
|
||||||
- ls -l
|
|
||||||
- tgz=`ls spot-*.tar.* | head -n 1`
|
- tgz=`ls spot-*.tar.* | head -n 1`
|
||||||
- case $tgz in *[0-9].tar.*) scp $tgz doc@perso:/var/www/dload/spot/;; esac
|
- case $tgz in *[0-9].tar.*) scp $tgz doc@perso:/var/www/dload/spot/;; esac
|
||||||
- rm -rf ./*
|
- 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
|
||||||
- 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:
|
publish-unstable:
|
||||||
only:
|
only:
|
||||||
|
|
@ -445,18 +373,14 @@ publish-unstable:
|
||||||
tags:
|
tags:
|
||||||
- dput
|
- dput
|
||||||
stage: publish
|
stage: publish
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- debpkg-unstable-i386
|
- debpkg-unstable-i386
|
||||||
script:
|
script:
|
||||||
- cd _build_unstable
|
- cd _build_unstable
|
||||||
- ls -l
|
- ls -l
|
||||||
- dput lrde `ls -t *amd64.changes | head -1` `ls -t *i386.changes | head -1`
|
- dput lrde *.changes
|
||||||
- cd ..
|
- 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
|
||||||
- rm -rf _build_unstable
|
- curl -X POST -F ref=master -F token=$TRIGGER_SANDBOX https://gitlab.lrde.epita.fr/api/v4/projects/181/trigger/pipeline
|
||||||
- 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:
|
raspbian:
|
||||||
stage: build
|
stage: build
|
||||||
|
|
|
||||||
20
.mailmap
20
.mailmap
|
|
@ -1,20 +0,0 @@
|
||||||
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
|
Spot's gitlab page is at
|
||||||
|
|
||||||
https://gitlab.lre.epita.fr/spot/spot
|
https://gitlab.lrde.epita.fr/spot/spot
|
||||||
|
|
||||||
The GIT repository can be cloned with
|
The GIT repository can be cloned with
|
||||||
|
|
||||||
git clone https://gitlab.lre.epita.fr/spot/spot.git
|
git clone https://gitlab.lrde.epita.fr/spot/spot.git
|
||||||
|
|
||||||
Some files in SPOT's source tree are generated. They are distributed
|
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
|
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 Automake >= 1.11
|
||||||
GNU Libtool >= 2.4
|
GNU Libtool >= 2.4
|
||||||
GNU Flex >= 2.6
|
GNU Flex >= 2.6
|
||||||
GNU Bison >= 3.3
|
GNU Bison >= 3.0
|
||||||
GNU Emacs (preferably >= 24 but it may work with older versions)
|
GNU Emacs (preferably >= 24 but it may work with older versions)
|
||||||
org-mode >= 9.1 (the version that comes bundled with your emacs
|
org-mode >= 9.1 (the version that comes bundled with your emacs
|
||||||
version is likely out-of-date; but distribution often have
|
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
|
make check LOG_DRIVER=$PWD/tools/test-driver-teamcity
|
||||||
|
|
||||||
|
|
||||||
C++ Coding conventions
|
Coding conventions
|
||||||
======================
|
==================
|
||||||
|
|
||||||
Here some of the conventions we follow in Spot, so that the code looks
|
Here some of the conventions we follow in Spot, so that the code looks
|
||||||
homogeneous. Please follow these strictly. Since this is free
|
homogeneous. Please follow these strictly. Since this is free
|
||||||
|
|
@ -682,43 +682,3 @@ Other style recommandations
|
||||||
|
|
||||||
* Always code as if the person who ends up maintaining your code is
|
* Always code as if the person who ends up maintaining your code is
|
||||||
a violent psychopath who knows where you live.
|
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 -*-
|
## -*- coding: utf-8 -*-
|
||||||
## Copyright (C) 2011-2017, 2020, 2022 Laboratoire de Recherche et Développement
|
## Copyright (C) 2011-2017, 2020 Laboratoire de Recherche et Développement
|
||||||
## de l'Epita (LRDE).
|
## de l'Epita (LRDE).
|
||||||
## Copyright (C) 2003, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
## Copyright (C) 2003, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -36,9 +36,8 @@ DOC_SUBDIR = doc
|
||||||
SUBDIRS = picosat buddy lib ltdl spot bin tests $(PYTHON_SUBDIR) $(DOC_SUBDIR) \
|
SUBDIRS = picosat buddy lib ltdl spot bin tests $(PYTHON_SUBDIR) $(DOC_SUBDIR) \
|
||||||
$(NEVER_SUBDIRS)
|
$(NEVER_SUBDIRS)
|
||||||
|
|
||||||
UTF8 = utf8/README.md utf8/LICENSE utf8/utf8.h \
|
UTF8 = utf8/README.md utf8/utf8.h \
|
||||||
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h \
|
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
|
||||||
utf8/utf8/cpp11.h utf8/utf8/cpp17.h
|
|
||||||
|
|
||||||
DEBIAN = \
|
DEBIAN = \
|
||||||
debian/changelog \
|
debian/changelog \
|
||||||
|
|
@ -69,8 +68,7 @@ EXTRA_DIST = HACKING ChangeLog.1 tools/gitlog-to-changelog \
|
||||||
tools/help2man tools/man2html.pl \
|
tools/help2man tools/man2html.pl \
|
||||||
tools/test-driver-teamcity $(UTF8) $(DEBIAN) \
|
tools/test-driver-teamcity $(UTF8) $(DEBIAN) \
|
||||||
m4/gnulib-cache.m4 .dir-locals.el \
|
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
|
dist-hook: gen-ChangeLog
|
||||||
|
|
||||||
|
|
@ -116,6 +114,3 @@ deb: dist
|
||||||
|
|
||||||
spot.spec: configure.ac spot.spec.in
|
spot.spec: configure.ac spot.spec.in
|
||||||
sed 's/[@]VERSION[@]/$(VERSION)/;s/[@]GITPATCH[@]/@@@$(GITPATCH)/;s/@@@\.//' spot.spec.in > $@.tmp && mv $@.tmp $@
|
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 $@
|
|
||||||
|
|
|
||||||
329
NEWS
329
NEWS
|
|
@ -1,155 +1,9 @@
|
||||||
New in spot 2.11.5.dev (not yet released)
|
New in spot 2.10.4.dev (net 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:
|
Command-line tools:
|
||||||
|
|
||||||
- autfilt has a new options --aliases=drop|keep to specify
|
- autfilt has a new options --aliases=drop|keep to specify
|
||||||
if the HOA printer should attempt to preserve aliases
|
if the output code should attempt to preserve aliases
|
||||||
present in the HOA input. This defaults to "keep".
|
present in the HOA input. This defaults to "keep".
|
||||||
|
|
||||||
- autfilt has a new --to-finite option, illustrated on
|
- autfilt has a new --to-finite option, illustrated on
|
||||||
|
|
@ -160,38 +14,6 @@ New in spot 2.11 (2022-10-08)
|
||||||
associated option --sonf-aps allows listing the newly introduced
|
associated option --sonf-aps allows listing the newly introduced
|
||||||
atomic propositions.
|
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:
|
Library:
|
||||||
|
|
||||||
- The new function suffix_operator_normal_form() implements
|
- The new function suffix_operator_normal_form() implements
|
||||||
|
|
@ -208,20 +30,16 @@ New in spot 2.11 (2022-10-08)
|
||||||
- tgba_determinize() learned to fill the "original-classes" property.
|
- tgba_determinize() learned to fill the "original-classes" property.
|
||||||
States of the determinized automaton that correspond to the same
|
States of the determinized automaton that correspond to the same
|
||||||
subset of states of the original automaton belong to the same
|
subset of states of the original automaton belong to the same
|
||||||
class. Filling this property is only done on demand as it inccurs
|
class. Filling this property is only done on demand has it inccurs
|
||||||
a small overhead.
|
on small overhead.
|
||||||
|
|
||||||
- sbacc() learned to take the "original-classes" property into
|
- sbacc() learned to take the "original-classes" property into
|
||||||
account and to preserve it.
|
account and preserve it.
|
||||||
|
|
||||||
- The HOA parser and printer learned to map the synthesis-outputs
|
- The HOA parser and printer learned to map the synthesis-outputs
|
||||||
property of Spot to the controllable-AP header for the Extended
|
property of Spot to the controllable-AP header for the Extended
|
||||||
HOA format used in SyntComp. https://arxiv.org/abs/1912.05793
|
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
|
- "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
|
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
|
by the HOA printer on a best-effort basis. Aliases can be used to
|
||||||
|
|
@ -248,147 +66,14 @@ New in spot 2.11 (2022-10-08)
|
||||||
- purge_dead_states() will now also remove edges labeled by false
|
- purge_dead_states() will now also remove edges labeled by false
|
||||||
(except self-loops).
|
(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:
|
Bugs fixed:
|
||||||
|
|
||||||
- reduce_parity() produced incorrect results when applied to
|
- reduce_parity() produced incorrect results when applied to
|
||||||
automata with deleted edges.
|
automata with deleted edges.
|
||||||
|
|
||||||
- An optimization of Zielonka could result in incorrect results
|
- work around a portability issue in Flex 2.6.4 preventing
|
||||||
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.
|
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)
|
New in spot 2.10.4 (2022-02-01)
|
||||||
|
|
||||||
Bug fixed:
|
Bug fixed:
|
||||||
|
|
@ -1748,7 +1433,7 @@ New in spot 2.6.2 (2018-09-28)
|
||||||
|
|
||||||
- We no longer distribute the Python-based CGI script + javascript
|
- We no longer distribute the Python-based CGI script + javascript
|
||||||
code for the online translator. Its replacement has its own
|
code for the online translator. Its replacement has its own
|
||||||
repository: https://gitlab.lre.epita.fr/spot/spot-web-app/
|
repository: https://gitlab.lrde.epita.fr/spot/spot-web-app/
|
||||||
|
|
||||||
Library:
|
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
|
make install' process. People unfamiliar with the GNU Build System
|
||||||
should read the file INSTALL for generic instructions.
|
should read the file INSTALL for generic instructions.
|
||||||
|
|
||||||
If you plan to use the Python bindings, we recommend you use the
|
If you plan to use the Python binding, we recommend you use one
|
||||||
following --prefix options when calling configure:
|
of the following --prefix options when calling configure:
|
||||||
|
|
||||||
--prefix ~/.local
|
--prefix /usr
|
||||||
|
--prefix /usr/local (the default)
|
||||||
|
--prefix ~/.local (if you do not have root permissions)
|
||||||
|
|
||||||
The reason is that ~/.local/lib/python3.X/site-packages, where Spot's
|
The reason is that all these locations are usually automatically
|
||||||
Python bindings will be installed, is automatically searched by
|
searched by Python. If you use a different prefix directory, you may
|
||||||
Python. If you use a different prefix directory, you may have to tune
|
have to tune the PYTHONPATH environment variable.
|
||||||
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
|
In addition to its usual options, ./configure will accept some
|
||||||
flags specific to Spot:
|
flags specific to Spot:
|
||||||
|
|
@ -173,12 +173,6 @@ flags specific to Spot:
|
||||||
client code should be compiled with -D_GLIBCXX_DEBUG as well. This
|
client code should be compiled with -D_GLIBCXX_DEBUG as well. This
|
||||||
options should normally only be useful to run Spot's test-suite.
|
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
|
--enable-c++20
|
||||||
Build everything in C++20 mode. We use that in our build farm to
|
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.
|
ensure that Spot can be used in C++20 projects as well.
|
||||||
|
|
@ -250,31 +244,17 @@ To test the Python bindings, try running
|
||||||
>>> import spot
|
>>> import spot
|
||||||
>>> print(spot.version())
|
>>> print(spot.version())
|
||||||
|
|
||||||
If you installed Spot with a prefix that is not searched by Python by
|
If you installed Spot with a prefix that is not one of those suggested
|
||||||
default it is likely that the above import statement will fail to
|
in the "Building and installing" section, it is likely that the above
|
||||||
locate the spot package. You can show the list of directories that
|
import statement will fail to locate the spot package. You can show
|
||||||
are searched by Python using:
|
the list of directories that are searched by Python using:
|
||||||
|
|
||||||
% python3
|
% python3
|
||||||
>>> import sys
|
>>> import sys
|
||||||
>>> print(sys.path)
|
>>> print(sys.path)
|
||||||
|
|
||||||
And you can modify that list of searched directories using the
|
And you can modify that list of searched directories using the
|
||||||
PYTHONPATH environment variable. Alternatively, you can instruct Spot
|
PYTHONPATH environment variable.
|
||||||
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:
|
To test if man pages can be found, simply try:
|
||||||
|
|
||||||
|
|
@ -339,13 +319,13 @@ bench/ Benchmarks for ...
|
||||||
wdba/ ... WDBA minimization (for obligation properties).
|
wdba/ ... WDBA minimization (for obligation properties).
|
||||||
python/ Python bindings for Spot and BuDDy
|
python/ Python bindings for Spot and BuDDy
|
||||||
|
|
||||||
Third-party software
|
Third party software
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
buddy/ A customized version of BuDDy 2.3 (a BDD library).
|
buddy/ A customized version of BuDDy 2.3 (a BDD library).
|
||||||
ltdl/ Libtool's portable dlopen() wrapper library.
|
ltdl/ Libtool's portable dlopen() wrapper library.
|
||||||
lib/ Gnulib's portability modules.
|
lib/ Gnulib's portability modules.
|
||||||
utf8/ Trifunovic's utf-8 routines. https://github.com/nemtrif/utfcpp
|
utf8/ Nemanja Trifunovic's utf-8 routines.
|
||||||
elisp/ Related emacs modes, used for building the documentation.
|
elisp/ Related emacs modes, used for building the documentation.
|
||||||
picosat/ A distribution of PicoSAT 965 (a satsolver library).
|
picosat/ A distribution of PicoSAT 965 (a satsolver library).
|
||||||
spot/bricks/ A collection of useful C++ code provided by DiVinE
|
spot/bricks/ A collection of useful C++ code provided by DiVinE
|
||||||
|
|
|
||||||
12
THANKS
12
THANKS
|
|
@ -11,12 +11,9 @@ Christian Dax
|
||||||
Christopher Ziegler
|
Christopher Ziegler
|
||||||
Clément Tamines
|
Clément Tamines
|
||||||
David Müller
|
David Müller
|
||||||
Dávid Smolka
|
|
||||||
Edmond Irani Liu
|
|
||||||
Ernesto Posse
|
Ernesto Posse
|
||||||
Étienne Renault
|
Étienne Renault
|
||||||
Fabrice Kordon
|
Fabrice Kordon
|
||||||
Fangyi Zhou
|
|
||||||
Felix Klaedtke
|
Felix Klaedtke
|
||||||
Florian Perlié-Long
|
Florian Perlié-Long
|
||||||
František Blahoudek
|
František Blahoudek
|
||||||
|
|
@ -24,7 +21,6 @@ Gerard J. Holzmann
|
||||||
Hashim Ali
|
Hashim Ali
|
||||||
Heikki Tauriainen
|
Heikki Tauriainen
|
||||||
Henrich Lauko
|
Henrich Lauko
|
||||||
Jacopo Binchi
|
|
||||||
Jan Strejček
|
Jan Strejček
|
||||||
Jean-Michel Couvreur
|
Jean-Michel Couvreur
|
||||||
Jean-Michel Ilié
|
Jean-Michel Ilié
|
||||||
|
|
@ -45,18 +41,14 @@ Michael Weber
|
||||||
Mikuláš Klokočka
|
Mikuláš Klokočka
|
||||||
Ming-Hsien Tsai
|
Ming-Hsien Tsai
|
||||||
Nikos Gorogiannis
|
Nikos Gorogiannis
|
||||||
Ondřej Lengál
|
|
||||||
Paul Guénézan
|
Paul Guénézan
|
||||||
Pierre Ganty
|
|
||||||
Raven Beutner
|
|
||||||
Reuben Rowe
|
Reuben Rowe
|
||||||
Roei Nahum
|
Roei Nahum
|
||||||
Rüdiger Ehlers
|
Rüdiger Ehlers
|
||||||
Shachar Itzhaky
|
|
||||||
Shengping Shaw
|
|
||||||
Shufang Zhu
|
|
||||||
Silien Hong
|
Silien Hong
|
||||||
Simon Jantsch
|
Simon Jantsch
|
||||||
|
Shengping Shaw
|
||||||
|
Shufang Zhu
|
||||||
Sonali Dutta
|
Sonali Dutta
|
||||||
Tereza Šťastná
|
Tereza Šťastná
|
||||||
Tobias Meggendorfer.
|
Tobias Meggendorfer.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# Copyright (C) 2016-2018, 2023 Laboratoire de Recherche et Développement de
|
# Copyright (C) 2016-2018 Laboratoire de Recherche et Développement de
|
||||||
# l'Epita (LRDE).
|
# l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
|
|
@ -55,12 +55,12 @@ class BenchConfig(object):
|
||||||
if line[0] == '#' or line.isspace():
|
if line[0] == '#' or line.isspace():
|
||||||
continue
|
continue
|
||||||
elif line[0:2] == "sh":
|
elif line[0:2] == "sh":
|
||||||
sh = re.search('sh (.+)$', line).group(1)
|
sh = re.search('sh (.+?)$', line).group(1)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
name = re.search('(.+?):', line).group(1)
|
name = re.search('(.+?):', line).group(1)
|
||||||
code = 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)
|
b = Bench(name=name, code=code, xoptions=xoptions)
|
||||||
self.l.append(b)
|
self.l.append(b)
|
||||||
self.sh.append(sh)
|
self.sh.append(sh)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014, 2015, 2016, 2017, 2022 Laboratoire de Recherche
|
// Copyright (C) 2014, 2015, 2016, 2017 Laboratoire de Recherche et
|
||||||
// et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
#include <spot/misc/timer.hh>
|
#include <spot/misc/timer.hh>
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "";
|
const char argp_program_doc[] ="";
|
||||||
|
|
||||||
const struct argp_child children[] =
|
const struct argp_child children[] =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2020, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2017-2020 Laboratoire de Recherche et Développement de
|
||||||
// Développement de l'Epita (LRDE).
|
// l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
#include <spot/misc/escape.hh>
|
#include <spot/misc/escape.hh>
|
||||||
#include <spot/misc/timer.hh>
|
#include <spot/misc/timer.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Call several tools that process automata and cross-compare their output \
|
Call several tools that process automata and cross-compare their output \
|
||||||
to detect bugs, or to gather statistics. The list of automata to use \
|
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\
|
should be supplied on standard input, or using the -F option.\v\
|
||||||
|
|
@ -64,7 +64,6 @@ Exit status:\n\
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_BOGUS = 256,
|
OPT_BOGUS = 256,
|
||||||
OPT_COMPLEMENTED,
|
|
||||||
OPT_CSV,
|
OPT_CSV,
|
||||||
OPT_HIGH,
|
OPT_HIGH,
|
||||||
OPT_FAIL_ON_TIMEOUT,
|
OPT_FAIL_ON_TIMEOUT,
|
||||||
|
|
@ -95,8 +94,6 @@ static const argp_option options[] =
|
||||||
"consider timeouts as errors", 0 },
|
"consider timeouts as errors", 0 },
|
||||||
{ "language-preserved", OPT_LANG, nullptr, 0,
|
{ "language-preserved", OPT_LANG, nullptr, 0,
|
||||||
"expect that each tool preserves the input language", 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,
|
{ "no-checks", OPT_NOCHECKS, nullptr, 0,
|
||||||
"do not perform any sanity checks", 0 },
|
"do not perform any sanity checks", 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
|
|
@ -147,7 +144,6 @@ static bool fail_on_timeout = false;
|
||||||
static bool stop_on_error = false;
|
static bool stop_on_error = false;
|
||||||
static bool no_checks = false;
|
static bool no_checks = false;
|
||||||
static bool opt_language_preserved = false;
|
static bool opt_language_preserved = false;
|
||||||
static bool opt_language_complemented = false;
|
|
||||||
static bool opt_omit = false;
|
static bool opt_omit = false;
|
||||||
static const char* csv_output = nullptr;
|
static const char* csv_output = nullptr;
|
||||||
static unsigned round_num = 0;
|
static unsigned round_num = 0;
|
||||||
|
|
@ -162,7 +158,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case 'F':
|
case 'F':
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
quiet = true;
|
quiet = true;
|
||||||
|
|
@ -174,9 +170,6 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
bogus_output_filename = arg;
|
bogus_output_filename = arg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_COMPLEMENTED:
|
|
||||||
opt_language_complemented = true;
|
|
||||||
break;
|
|
||||||
case OPT_CSV:
|
case OPT_CSV:
|
||||||
csv_output = arg ? arg : "-";
|
csv_output = arg ? arg : "-";
|
||||||
break;
|
break;
|
||||||
|
|
@ -216,7 +209,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (arg[0] == '-' && !arg[1])
|
if (arg[0] == '-' && !arg[1])
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
else
|
else
|
||||||
tools_push_autproc(arg);
|
tools_push_autproc(arg);
|
||||||
break;
|
break;
|
||||||
|
|
@ -345,6 +338,7 @@ struct in_statistics
|
||||||
|
|
||||||
struct out_statistics
|
struct out_statistics
|
||||||
{
|
{
|
||||||
|
|
||||||
// If OK is false, output statistics are not available.
|
// If OK is false, output statistics are not available.
|
||||||
bool ok;
|
bool ok;
|
||||||
const char* status_str;
|
const char* status_str;
|
||||||
|
|
@ -352,7 +346,7 @@ struct out_statistics
|
||||||
double time;
|
double time;
|
||||||
aut_statistics output;
|
aut_statistics output;
|
||||||
|
|
||||||
out_statistics() noexcept
|
out_statistics()
|
||||||
: ok(false),
|
: ok(false),
|
||||||
status_str(nullptr),
|
status_str(nullptr),
|
||||||
status_code(0),
|
status_code(0),
|
||||||
|
|
@ -539,32 +533,25 @@ namespace
|
||||||
const spot::const_twa_graph_ptr& aut_j,
|
const spot::const_twa_graph_ptr& aut_j,
|
||||||
size_t i, size_t 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() >
|
if (aut_i->num_sets() + aut_j->num_sets() >
|
||||||
spot::acc_cond::mark_t::max_accsets())
|
spot::acc_cond::mark_t::max_accsets())
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
std::cerr << "info: building " << autname(i, is_really_comp(i))
|
std::cerr << "info: building " << autname(i)
|
||||||
<< '*' << autname(j, !is_really_comp(j))
|
<< '*' << autname(j, true)
|
||||||
<< " requires more acceptance sets than supported\n";
|
<< " requires more acceptance sets than supported\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
std::cerr << "info: check_empty "
|
std::cerr << "info: check_empty "
|
||||||
<< autname(i, is_really_comp(i))
|
<< autname(i) << '*' << autname(j, true) << '\n';
|
||||||
<< '*' << autname(j, !is_really_comp(j)) << '\n';
|
|
||||||
|
|
||||||
auto w = aut_i->intersecting_word(aut_j);
|
auto w = aut_i->intersecting_word(aut_j);
|
||||||
if (w)
|
if (w)
|
||||||
{
|
{
|
||||||
std::ostream& err = global_error();
|
std::ostream& err = global_error();
|
||||||
err << "error: " << autname(i, is_really_comp(i))
|
err << "error: " << autname(i) << '*' << autname(j, true)
|
||||||
<< '*' << autname(j, !is_really_comp(j))
|
|
||||||
<< (" is nonempty; both automata accept the infinite word:\n"
|
<< (" is nonempty; both automata accept the infinite word:\n"
|
||||||
" ");
|
" ");
|
||||||
example() << *w << '\n';
|
example() << *w << '\n';
|
||||||
|
|
@ -613,7 +600,7 @@ namespace
|
||||||
return src.str();
|
return src.str();
|
||||||
}();
|
}();
|
||||||
|
|
||||||
input_statistics.emplace_back(in_statistics());
|
input_statistics.push_back(in_statistics());
|
||||||
|
|
||||||
input_statistics[round_num].input_source = std::move(source);
|
input_statistics[round_num].input_source = std::move(source);
|
||||||
if (auto name = input->get_named_prop<std::string>("automaton-name"))
|
if (auto name = input->get_named_prop<std::string>("automaton-name"))
|
||||||
|
|
@ -634,15 +621,12 @@ namespace
|
||||||
|
|
||||||
int problems = 0;
|
int problems = 0;
|
||||||
size_t m = tools.size();
|
size_t m = tools.size();
|
||||||
size_t mi = m + opt_language_preserved + opt_language_complemented;
|
size_t mi = m + opt_language_preserved;
|
||||||
std::vector<spot::twa_graph_ptr> pos(mi);
|
std::vector<spot::twa_graph_ptr> pos(mi);
|
||||||
std::vector<spot::twa_graph_ptr> neg(mi);
|
std::vector<spot::twa_graph_ptr> neg(mi);
|
||||||
vector_tool_statistics stats(m);
|
vector_tool_statistics stats(m);
|
||||||
|
|
||||||
// For --language-complemented, we store the input automata in
|
if (opt_language_preserved)
|
||||||
// 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;
|
pos[mi - 1] = input;
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
|
@ -658,7 +642,7 @@ namespace
|
||||||
problems += prob;
|
problems += prob;
|
||||||
}
|
}
|
||||||
spot::cleanup_tmpfiles();
|
spot::cleanup_tmpfiles();
|
||||||
output_statistics.emplace_back(std::move(stats));
|
output_statistics.push_back(std::move(stats));
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
|
|
@ -734,9 +718,6 @@ namespace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_language_complemented)
|
|
||||||
std::swap(pos[mi - 1], neg[mi - 1]);
|
|
||||||
|
|
||||||
// Just make a circular implication check
|
// Just make a circular implication check
|
||||||
// A0 <= A1, A1 <= A2, ..., AN <= A0
|
// A0 <= A1, A1 <= A2, ..., AN <= A0
|
||||||
unsigned ok = 0;
|
unsigned ok = 0;
|
||||||
|
|
@ -843,15 +824,10 @@ main(int argc, char** argv)
|
||||||
|
|
||||||
check_no_automaton();
|
check_no_automaton();
|
||||||
|
|
||||||
if (s == 1 && !no_checks
|
if (s == 1 && !opt_language_preserved && !no_checks)
|
||||||
&& !opt_language_preserved
|
error(2, 0, "Since --language-preserved is not used, you need "
|
||||||
&& !opt_language_complemented)
|
"at least two tools to compare.");
|
||||||
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_color();
|
||||||
setup_sig_handler();
|
setup_sig_handler();
|
||||||
|
|
|
||||||
130
bin/autfilt.cc
130
bin/autfilt.cc
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -448,7 +448,7 @@ struct canon_aut
|
||||||
std::vector<tr_t> edges;
|
std::vector<tr_t> edges;
|
||||||
std::string acc;
|
std::string acc;
|
||||||
|
|
||||||
explicit canon_aut(const spot::const_twa_graph_ptr& aut)
|
canon_aut(const spot::const_twa_graph_ptr& aut)
|
||||||
: num_states(aut->num_states())
|
: num_states(aut->num_states())
|
||||||
, edges(aut->edge_vector().begin() + 1,
|
, edges(aut->edge_vector().begin() + 1,
|
||||||
aut->edge_vector().end())
|
aut->edge_vector().end())
|
||||||
|
|
@ -713,12 +713,10 @@ ensure_deterministic(const spot::twa_graph_ptr& aut, bool nonalt = false)
|
||||||
return p.run(aut);
|
return p.run(aut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static spot::twa_graph_ptr
|
static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
|
||||||
ensure_tba(spot::twa_graph_ptr aut,
|
|
||||||
spot::postprocessor::output_type type = spot::postprocessor::Buchi)
|
|
||||||
{
|
{
|
||||||
spot::postprocessor p;
|
spot::postprocessor p;
|
||||||
p.set_type(type);
|
p.set_type(spot::postprocessor::Buchi);
|
||||||
p.set_pref(spot::postprocessor::Any);
|
p.set_pref(spot::postprocessor::Any);
|
||||||
p.set_level(spot::postprocessor::Low);
|
p.set_level(spot::postprocessor::Low);
|
||||||
return p.run(aut);
|
return p.run(aut);
|
||||||
|
|
@ -728,14 +726,12 @@ ensure_tba(spot::twa_graph_ptr aut,
|
||||||
static spot::twa_graph_ptr
|
static spot::twa_graph_ptr
|
||||||
product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
||||||
{
|
{
|
||||||
// Are we likely to fail because of too many colors?
|
if ((type == spot::postprocessor::Buchi)
|
||||||
if ((left->num_sets() + right->num_sets() >
|
&& (left->num_sets() + right->num_sets() >
|
||||||
spot::acc_cond::mark_t::max_accsets())
|
spot::acc_cond::mark_t::max_accsets()))
|
||||||
&& (type == spot::postprocessor::Buchi
|
|
||||||
|| type == spot::postprocessor::CoBuchi))
|
|
||||||
{
|
{
|
||||||
left = ensure_tba(left, type);
|
left = ensure_tba(left);
|
||||||
right = ensure_tba(right, type);
|
right = ensure_tba(right);
|
||||||
}
|
}
|
||||||
return spot::product(left, right);
|
return spot::product(left, right);
|
||||||
}
|
}
|
||||||
|
|
@ -743,34 +739,16 @@ product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
||||||
static spot::twa_graph_ptr
|
static spot::twa_graph_ptr
|
||||||
product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
|
||||||
{
|
{
|
||||||
// Are we likely to fail because of too many colors?
|
if ((type == spot::postprocessor::Buchi)
|
||||||
if ((left->num_sets() + right->num_sets() >
|
&& (left->num_sets() + right->num_sets() >
|
||||||
spot::acc_cond::mark_t::max_accsets())
|
spot::acc_cond::mark_t::max_accsets()))
|
||||||
&& (type == spot::postprocessor::Buchi
|
|
||||||
|| type == spot::postprocessor::CoBuchi))
|
|
||||||
{
|
{
|
||||||
left = ensure_tba(left, type);
|
left = ensure_tba(left);
|
||||||
right = ensure_tba(right, type);
|
right = ensure_tba(right);
|
||||||
}
|
}
|
||||||
return spot::product_or(left, right);
|
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
|
static int
|
||||||
parse_opt(int key, char* arg, struct argp_state*)
|
parse_opt(int key, char* arg, struct argp_state*)
|
||||||
{
|
{
|
||||||
|
|
@ -783,7 +761,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
automaton_format = Count;
|
automaton_format = Count;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
opt_max_count = to_pos_int(arg, "-n/--max-count");
|
opt_max_count = to_pos_int(arg, "-n/--max-count");
|
||||||
|
|
@ -792,14 +770,17 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_nth = parse_range(arg, 0, std::numeric_limits<int>::max());
|
opt_nth = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
opt->uniq = std::make_unique<unique_aut_t>();
|
opt->uniq = std::unique_ptr<unique_aut_t>(new std::set<canon_aut>());
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
opt_invert = true;
|
opt_invert = true;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
if (const char* opt = extra_options.parse_options(arg))
|
{
|
||||||
|
const char* opt = extra_options.parse_options(arg);
|
||||||
|
if (opt)
|
||||||
error(2, 0, "failed to parse --options near '%s'", opt);
|
error(2, 0, "failed to parse --options near '%s'", opt);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_ALIASES:
|
case OPT_ALIASES:
|
||||||
opt_aliases = XARGMATCH("--aliases", arg, aliases_args, aliases_types);
|
opt_aliases = XARGMATCH("--aliases", arg, aliases_args, aliases_types);
|
||||||
|
|
@ -815,7 +796,16 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_art_sccs_set = true;
|
opt_art_sccs_set = true;
|
||||||
break;
|
break;
|
||||||
case OPT_ACCEPT_WORD:
|
case OPT_ACCEPT_WORD:
|
||||||
opt->acc_words.emplace_back(word_to_aut(arg, "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());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_ACCEPTANCE_IS:
|
case OPT_ACCEPTANCE_IS:
|
||||||
{
|
{
|
||||||
|
|
@ -968,7 +958,16 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
"%d should be followed by a comma and WORD", res);
|
"%d should be followed by a comma and WORD", res);
|
||||||
arg = endptr + 1;
|
arg = endptr + 1;
|
||||||
}
|
}
|
||||||
opt->hl_words.emplace_back(word_to_aut(arg, "highlight-word"), res);
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_HIGHLIGHT_LANGUAGES:
|
case OPT_HIGHLIGHT_LANGUAGES:
|
||||||
|
|
@ -989,7 +988,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
if (!opt->included_in)
|
if (!opt->included_in)
|
||||||
opt->included_in = aut;
|
opt->included_in = aut;
|
||||||
else
|
else
|
||||||
opt->included_in = ::product_or(opt->included_in, aut);
|
opt->included_in = spot::product_or(opt->included_in, aut);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_INHERENTLY_WEAK_SCCS:
|
case OPT_INHERENTLY_WEAK_SCCS:
|
||||||
|
|
@ -1152,7 +1151,16 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_art_sccs_set = true;
|
opt_art_sccs_set = true;
|
||||||
break;
|
break;
|
||||||
case OPT_REJECT_WORD:
|
case OPT_REJECT_WORD:
|
||||||
opt->rej_words.emplace_back(word_to_aut(arg, "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());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OPT_REM_AP:
|
case OPT_REM_AP:
|
||||||
opt->rem_ap.add_ap(arg);
|
opt->rem_ap.add_ap(arg);
|
||||||
|
|
@ -1244,7 +1252,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
opt_art_sccs_set = true;
|
opt_art_sccs_set = true;
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1277,7 +1285,7 @@ namespace
|
||||||
static
|
static
|
||||||
bool match_acceptance(spot::twa_graph_ptr aut)
|
bool match_acceptance(spot::twa_graph_ptr aut)
|
||||||
{
|
{
|
||||||
const spot::acc_cond& acc = aut->acc();
|
auto& acc = aut->acc();
|
||||||
switch (opt_acceptance_is)
|
switch (opt_acceptance_is)
|
||||||
{
|
{
|
||||||
case ACC_Any:
|
case ACC_Any:
|
||||||
|
|
@ -1332,7 +1340,8 @@ namespace
|
||||||
{
|
{
|
||||||
bool max;
|
bool max;
|
||||||
bool odd;
|
bool odd;
|
||||||
if (!acc.is_parity(max, odd, true))
|
bool is_p = acc.is_parity(max, odd, true);
|
||||||
|
if (!is_p)
|
||||||
return false;
|
return false;
|
||||||
switch (opt_acceptance_is)
|
switch (opt_acceptance_is)
|
||||||
{
|
{
|
||||||
|
|
@ -1445,7 +1454,7 @@ namespace
|
||||||
if (matched && opt_acceptance_is)
|
if (matched && opt_acceptance_is)
|
||||||
matched = match_acceptance(aut);
|
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);
|
spot::scc_info si(aut);
|
||||||
unsigned n = si.scc_count();
|
unsigned n = si.scc_count();
|
||||||
|
|
@ -1525,14 +1534,14 @@ namespace
|
||||||
&& spot::contains(aut, opt->equivalent_pos);
|
&& spot::contains(aut, opt->equivalent_pos);
|
||||||
|
|
||||||
if (matched && !opt->acc_words.empty())
|
if (matched && !opt->acc_words.empty())
|
||||||
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
|
for (auto& word_aut: opt->acc_words)
|
||||||
if (spot::product(aut, word_aut)->is_empty())
|
if (spot::product(aut, word_aut)->is_empty())
|
||||||
{
|
{
|
||||||
matched = false;
|
matched = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (matched && !opt->rej_words.empty())
|
if (matched && !opt->rej_words.empty())
|
||||||
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
|
for (auto& word_aut: opt->rej_words)
|
||||||
if (!spot::product(aut, word_aut)->is_empty())
|
if (!spot::product(aut, word_aut)->is_empty())
|
||||||
{
|
{
|
||||||
matched = false;
|
matched = false;
|
||||||
|
|
@ -1666,9 +1675,14 @@ namespace
|
||||||
aut->accepting_run()->highlight(opt_highlight_accepting_run);
|
aut->accepting_run()->highlight(opt_highlight_accepting_run);
|
||||||
|
|
||||||
if (!opt->hl_words.empty())
|
if (!opt->hl_words.empty())
|
||||||
for (auto& [word_aut, color]: opt->hl_words)
|
for (auto& word_aut: opt->hl_words)
|
||||||
if (auto run = spot::product(aut, word_aut)->accepting_run())
|
{
|
||||||
run->project(aut)->highlight(color);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
if (opt->uniq)
|
if (opt->uniq)
|
||||||
|
|
@ -1743,17 +1757,15 @@ main(int argc, char** argv)
|
||||||
post.set_level(level);
|
post.set_level(level);
|
||||||
|
|
||||||
autfilt_processor processor(post, o.dict);
|
autfilt_processor processor(post, o.dict);
|
||||||
int err = processor.run();
|
if (processor.run())
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
// Diagnose unused -x options
|
||||||
|
extra_options.report_unused_options();
|
||||||
|
|
||||||
if (automaton_format == Count)
|
if (automaton_format == Count)
|
||||||
std::cout << match_count << std::endl;
|
std::cout << match_count << std::endl;
|
||||||
|
|
||||||
// Diagnose unused -x options
|
|
||||||
if (!err)
|
|
||||||
extra_options.report_unused_options();
|
|
||||||
else
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
check_cout();
|
check_cout();
|
||||||
return match_count ? 0 : 1;
|
return match_count ? 0 : 1;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#include <spot/twaalgos/isdet.hh>
|
#include <spot/twaalgos/isdet.hh>
|
||||||
|
|
||||||
automaton_format_t automaton_format = Hoa;
|
automaton_format_t automaton_format = Hoa;
|
||||||
const char* automaton_format_opt = nullptr;
|
static const char* automaton_format_opt = nullptr;
|
||||||
const char* opt_name = nullptr;
|
const char* opt_name = nullptr;
|
||||||
static const char* opt_output = nullptr;
|
static const char* opt_output = nullptr;
|
||||||
static const char* stats = "";
|
static const char* stats = "";
|
||||||
|
|
@ -203,18 +203,12 @@ static const argp_option io_options[] =
|
||||||
"to specify additional options as in --hoa=opt)", 0 },
|
"to specify additional options as in --hoa=opt)", 0 },
|
||||||
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%M, %m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"name of the automaton", 0 },
|
"name of the automaton", 0 },
|
||||||
{ "%S, %s, %[LETTER]S, %[LETTER]s",
|
{ "%S, %s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
"number of reachable states", 0 },
|
||||||
"number of states (add one LETTER to select (r) reachable [default], "
|
{ "%E, %e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"(u) unreachable, (a) all).", 0 },
|
"number of reachable edges", 0 },
|
||||||
{ "%E, %e, %[LETTER]E, %[LETTER]e",
|
{ "%T, %t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
"number of reachable transitions", 0 },
|
||||||
"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,
|
{ "%A, %a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"number of acceptance sets", 0 },
|
"number of acceptance sets", 0 },
|
||||||
{ "%G, %g, %[LETTERS]G, %[LETTERS]g", 0, nullptr,
|
{ "%G, %g, %[LETTERS]G, %[LETTERS]g", 0, nullptr,
|
||||||
|
|
@ -274,15 +268,12 @@ static const argp_option o_options[] =
|
||||||
"to specify additional options as in --hoa=opt)", 0 },
|
"to specify additional options as in --hoa=opt)", 0 },
|
||||||
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%m", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"name of the automaton", 0 },
|
"name of the automaton", 0 },
|
||||||
{ "%s, %[LETTER]s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%s", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"number of states (add one LETTER to select (r) reachable [default], "
|
"number of reachable states", 0 },
|
||||||
"(u) unreachable, (a) all).", 0 },
|
{ "%e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
{ "%e, %[LETTER]e", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
"number of reachable edges", 0 },
|
||||||
"number of edges (add one LETTER to select (r) reachable [default], "
|
{ "%t", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"(u) unreachable, (a) all).", 0 },
|
"number of reachable transitions", 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,
|
{ "%a", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"number of acceptance sets", 0 },
|
"number of acceptance sets", 0 },
|
||||||
{ "%g, %[LETTERS]g", 0, nullptr,
|
{ "%g, %[LETTERS]g", 0, nullptr,
|
||||||
|
|
@ -453,7 +444,7 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
|
||||||
const spot::const_twa_graph_ptr& aut,
|
const spot::const_twa_graph_ptr& aut,
|
||||||
spot::formula f,
|
spot::formula f,
|
||||||
const char* filename, int loc,
|
const char* filename, int loc,
|
||||||
const spot::process_timer& ptimer,
|
spot::process_timer& ptimer,
|
||||||
const char* csv_prefix, const char* csv_suffix)
|
const char* csv_prefix, const char* csv_suffix)
|
||||||
{
|
{
|
||||||
timer_ = ptimer;
|
timer_ = ptimer;
|
||||||
|
|
@ -481,15 +472,15 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
|
||||||
if (has('T'))
|
if (has('T'))
|
||||||
{
|
{
|
||||||
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
|
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
|
||||||
haut_states_.set(s.states, haut->aut->num_states());
|
haut_states_ = s.states;
|
||||||
haut_edges_.set(s.edges, haut->aut->num_edges());
|
haut_edges_ = s.edges;
|
||||||
haut_trans_.set(s.transitions, count_all_transitions(haut->aut));
|
haut_trans_ = s.transitions;
|
||||||
}
|
}
|
||||||
else if (has('E') || has('S'))
|
else if (has('E') || has('S'))
|
||||||
{
|
{
|
||||||
spot::twa_statistics s = stats_reachable(haut->aut);
|
spot::twa_statistics s = stats_reachable(haut->aut);
|
||||||
haut_states_.set(s.states, haut->aut->num_states());
|
haut_states_ = s.states;
|
||||||
haut_edges_.set(s.edges, haut->aut->num_edges());
|
haut_edges_ = s.edges;
|
||||||
}
|
}
|
||||||
if (has('M'))
|
if (has('M'))
|
||||||
{
|
{
|
||||||
|
|
@ -633,10 +624,10 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||||
outputnamer.print(haut, aut, f, filename, loc, ptimer,
|
outputnamer.print(haut, aut, f, filename, loc, ptimer,
|
||||||
csv_prefix, csv_suffix);
|
csv_prefix, csv_suffix);
|
||||||
std::string fname = outputname.str();
|
std::string fname = outputname.str();
|
||||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
auto p = outputfiles.emplace(fname, nullptr);
|
||||||
if (b)
|
if (p.second)
|
||||||
it->second.reset(new output_file(fname.c_str()));
|
p.first->second.reset(new output_file(fname.c_str()));
|
||||||
out = &it->second->ostream();
|
out = &p.first->second->ostream();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output it.
|
// Output it.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014-2018, 2020, 2022, 2023 Laboratoire de Recherche
|
// Copyright (C) 2014-2018, 2020 Laboratoire de Recherche et
|
||||||
// et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -47,7 +47,6 @@ enum automaton_format_t {
|
||||||
|
|
||||||
// The format to use in output_automaton()
|
// The format to use in output_automaton()
|
||||||
extern automaton_format_t automaton_format;
|
extern automaton_format_t automaton_format;
|
||||||
extern const char* automaton_format_opt;
|
|
||||||
// Set to the argument of --name, else nullptr.
|
// Set to the argument of --name, else nullptr.
|
||||||
extern const char* opt_name;
|
extern const char* opt_name;
|
||||||
// Output options
|
// Output options
|
||||||
|
|
@ -155,7 +154,7 @@ public:
|
||||||
print(const spot::const_parsed_aut_ptr& haut,
|
print(const spot::const_parsed_aut_ptr& haut,
|
||||||
const spot::const_twa_graph_ptr& aut,
|
const spot::const_twa_graph_ptr& aut,
|
||||||
spot::formula f,
|
spot::formula f,
|
||||||
const char* filename, int loc, const spot::process_timer& ptimer,
|
const char* filename, int loc, spot::process_timer& ptimer,
|
||||||
const char* csv_prefix, const char* csv_suffix);
|
const char* csv_prefix, const char* csv_suffix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -166,9 +165,9 @@ private:
|
||||||
spot::printable_value<std::string> aut_word_;
|
spot::printable_value<std::string> aut_word_;
|
||||||
spot::printable_value<std::string> haut_word_;
|
spot::printable_value<std::string> haut_word_;
|
||||||
spot::printable_acc_cond haut_gen_acc_;
|
spot::printable_acc_cond haut_gen_acc_;
|
||||||
spot::printable_size haut_states_;
|
spot::printable_value<unsigned> haut_states_;
|
||||||
spot::printable_size haut_edges_;
|
spot::printable_value<unsigned> haut_edges_;
|
||||||
spot::printable_long_size haut_trans_;
|
spot::printable_value<unsigned long long> haut_trans_;
|
||||||
spot::printable_value<unsigned> haut_acc_;
|
spot::printable_value<unsigned> haut_acc_;
|
||||||
printable_varset haut_ap_;
|
printable_varset haut_ap_;
|
||||||
printable_varset aut_ap_;
|
printable_varset aut_ap_;
|
||||||
|
|
@ -196,7 +195,7 @@ class automaton_printer
|
||||||
std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit automaton_printer(stat_style input = no_input);
|
automaton_printer(stat_style input = no_input);
|
||||||
~automaton_printer();
|
~automaton_printer();
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015, 2018, 2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2015, 2018 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -25,15 +25,10 @@ int
|
||||||
to_int(const char* s, const char* where)
|
to_int(const char* s, const char* where)
|
||||||
{
|
{
|
||||||
char* endptr;
|
char* endptr;
|
||||||
errno = 0;
|
int res = strtol(s, &endptr, 10);
|
||||||
long int lres = strtol(s, &endptr, 10);
|
|
||||||
if (*endptr)
|
if (*endptr)
|
||||||
error(2, 0, "failed to parse '%s' as an integer (in argument of %s).",
|
error(2, 0, "failed to parse '%s' as an integer (in argument of %s).",
|
||||||
s, where);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,17 +45,11 @@ unsigned
|
||||||
to_unsigned (const char *s, const char* where)
|
to_unsigned (const char *s, const char* where)
|
||||||
{
|
{
|
||||||
char* endptr;
|
char* endptr;
|
||||||
errno = 0;
|
unsigned res = strtoul(s, &endptr, 10);
|
||||||
unsigned long lres = strtoul(s, &endptr, 10);
|
|
||||||
if (*endptr)
|
if (*endptr)
|
||||||
error(2, 0,
|
error(2, 0,
|
||||||
"failed to parse '%s' as an unsigned integer (in argument of %s).",
|
"failed to parse '%s' as an unsigned integer (in argument of %s).",
|
||||||
s, where);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,9 +57,8 @@ float
|
||||||
to_float(const char* s, const char* where)
|
to_float(const char* s, const char* where)
|
||||||
{
|
{
|
||||||
char* endptr;
|
char* endptr;
|
||||||
errno = 0;
|
|
||||||
float res = strtof(s, &endptr);
|
float res = strtof(s, &endptr);
|
||||||
if (*endptr || errno == ERANGE)
|
if (*endptr)
|
||||||
error(2, 0, "failed to parse '%s' as a float (in argument of %s)",
|
error(2, 0, "failed to parse '%s' as a float (in argument of %s)",
|
||||||
s, where);
|
s, where);
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -92,9 +80,8 @@ to_longs(const char* arg)
|
||||||
while (*arg)
|
while (*arg)
|
||||||
{
|
{
|
||||||
char* endptr;
|
char* endptr;
|
||||||
errno = 0;
|
|
||||||
long value = strtol(arg, &endptr, 10);
|
long value = strtol(arg, &endptr, 10);
|
||||||
if (endptr == arg || errno)
|
if (endptr == arg)
|
||||||
error(2, 0, "failed to parse '%s' as an integer.", arg);
|
error(2, 0, "failed to parse '%s' as an integer.", arg);
|
||||||
res.push_back(value);
|
res.push_back(value);
|
||||||
while (*endptr == ' ' || *endptr == ',')
|
while (*endptr == ' ' || *endptr == ',')
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015, 2016, 2022, 2023 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
|
||||||
// Développement de l'Epita (LRDE).
|
// l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -21,27 +21,25 @@
|
||||||
#include <error.h>
|
#include <error.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
output_file::output_file(const char* name, bool force_append)
|
|
||||||
|
output_file::output_file(const char* name)
|
||||||
{
|
{
|
||||||
std::ios_base::openmode mode = std::ios_base::trunc;
|
std::ios_base::openmode mode = std::ios_base::trunc;
|
||||||
if (name[0] == '>' && name[1] == '>')
|
if (name[0] == '>' && name[1] == '>')
|
||||||
{
|
{
|
||||||
|
mode = std::ios_base::app;
|
||||||
append_ = true;
|
append_ = true;
|
||||||
name += 2;
|
name += 2;
|
||||||
}
|
}
|
||||||
if (force_append)
|
|
||||||
append_ = true;
|
|
||||||
if (append_)
|
|
||||||
mode = std::ios_base::app;
|
|
||||||
if (name[0] == '-' && name[1] == 0)
|
if (name[0] == '-' && name[1] == 0)
|
||||||
{
|
{
|
||||||
os_ = &std::cout;
|
os_ = &std::cout;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
of_ = std::make_unique<std::ofstream>(name, mode);
|
of_ = new std::ofstream(name, mode);
|
||||||
if (!*of_)
|
if (!*of_)
|
||||||
error(2, errno, "cannot open '%s'", name);
|
error(2, errno, "cannot open '%s'", name);
|
||||||
os_ = of_.get();
|
os_ = of_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2016, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
|
||||||
// Développement de l'Epita (LRDE).
|
// l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -21,22 +21,27 @@
|
||||||
|
|
||||||
#include "common_sys.hh"
|
#include "common_sys.hh"
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <memory>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <error.h>
|
||||||
|
|
||||||
class output_file
|
class output_file
|
||||||
{
|
{
|
||||||
std::ostream* os_;
|
std::ostream* os_;
|
||||||
std::unique_ptr<std::ofstream> of_;
|
std::ofstream* of_ = nullptr;
|
||||||
bool append_ = false;
|
bool append_ = false;
|
||||||
public:
|
public:
|
||||||
// Open a file for output. "-" is interpreted as stdout.
|
// Open a file for output. "-" is interpreted as stdout.
|
||||||
// Names that start with ">>" are opened for append.
|
// Names that start with ">>" are opened for append.
|
||||||
// The function calls error() on... error.
|
// The function calls error() on... error.
|
||||||
output_file(const char* name, bool force_append = false);
|
output_file(const char* name);
|
||||||
|
|
||||||
void close(const std::string& name);
|
void close(const std::string& name);
|
||||||
|
|
||||||
|
~output_file()
|
||||||
|
{
|
||||||
|
delete of_;
|
||||||
|
}
|
||||||
|
|
||||||
bool append() const
|
bool append() const
|
||||||
{
|
{
|
||||||
return append_;
|
return append_;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2017, 2019, 2021-2023 Laboratoire de Recherche
|
// Copyright (C) 2012-2017, 2019, 2021 Laboratoire de Recherche et
|
||||||
// et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// 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)
|
switch (key)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
jobs.emplace_back(arg, job_type::LTL_STRING);
|
jobs.emplace_back(arg, false);
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case OPT_LBT:
|
case OPT_LBT:
|
||||||
lbt_input = true;
|
lbt_input = true;
|
||||||
|
|
@ -96,6 +96,12 @@ parse_formula(const std::string& s)
|
||||||
(s, spot::default_environment::instance(), false, lenient);
|
(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()
|
job_processor::~job_processor()
|
||||||
{
|
{
|
||||||
if (real_filename)
|
if (real_filename)
|
||||||
|
|
@ -297,22 +303,8 @@ job_processor::process_stream(std::istream& is,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
job_processor::process_aut_file(const char*)
|
job_processor::process_file(const char* filename)
|
||||||
{
|
{
|
||||||
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.
|
// Special case for stdin.
|
||||||
if (filename[0] == '-' && filename[1] == 0)
|
if (filename[0] == '-' && filename[1] == 0)
|
||||||
return process_stream(std::cin, filename);
|
return process_stream(std::cin, filename);
|
||||||
|
|
@ -364,25 +356,12 @@ int
|
||||||
job_processor::run()
|
job_processor::run()
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
for (const auto& j: jobs)
|
for (auto& j: jobs)
|
||||||
{
|
{
|
||||||
switch (j.type)
|
if (!j.file_p)
|
||||||
{
|
|
||||||
case job_type::LTL_STRING:
|
|
||||||
error |= process_string(j.str);
|
error |= process_string(j.str);
|
||||||
break;
|
else
|
||||||
case job_type::LTL_FILENAME:
|
error |= process_file(j.str);
|
||||||
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)
|
if (abort_run)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -397,7 +376,7 @@ void check_no_formula()
|
||||||
error(2, 0, "No formula to translate? Run '%s --help' for help.\n"
|
error(2, 0, "No formula to translate? Run '%s --help' for help.\n"
|
||||||
"Use '%s -' to force reading formulas from the standard "
|
"Use '%s -' to force reading formulas from the standard "
|
||||||
"input.", program_name, program_name);
|
"input.", program_name, program_name);
|
||||||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
jobs.emplace_back("-", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_no_automaton()
|
void check_no_automaton()
|
||||||
|
|
@ -408,5 +387,5 @@ void check_no_automaton()
|
||||||
error(2, 0, "No automaton to process? Run '%s --help' for help.\n"
|
error(2, 0, "No automaton to process? Run '%s --help' for help.\n"
|
||||||
"Use '%s -' to force reading automata from the standard "
|
"Use '%s -' to force reading automata from the standard "
|
||||||
"input.", program_name, program_name);
|
"input.", program_name, program_name);
|
||||||
jobs.emplace_back("-", job_type::AUT_FILENAME);
|
jobs.emplace_back("-", true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2017, 2022, 2023 Laboratoire de Recherche et
|
// Copyright (C) 2012-2017 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -25,18 +25,13 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <spot/tl/parse.hh>
|
#include <spot/tl/parse.hh>
|
||||||
|
|
||||||
enum class job_type : char { LTL_STRING,
|
|
||||||
LTL_FILENAME,
|
|
||||||
AUT_FILENAME,
|
|
||||||
TLSF_FILENAME };
|
|
||||||
|
|
||||||
struct job
|
struct job
|
||||||
{
|
{
|
||||||
const char* str;
|
const char* str;
|
||||||
job_type type;
|
bool file_p; // true if str is a filename, false if it is a formula
|
||||||
|
|
||||||
job(const char* str, job_type type) noexcept
|
job(const char* str, bool file_p) noexcept
|
||||||
: str(str), type(type)
|
: str(str), file_p(file_p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -56,11 +51,9 @@ spot::parsed_formula parse_formula(const std::string& s);
|
||||||
class job_processor
|
class job_processor
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool abort_run = false; // Set to true in process_formula() to abort run().
|
bool abort_run; // Set to true in process_formula() to abort run().
|
||||||
public:
|
public:
|
||||||
job_processor() = default;
|
job_processor();
|
||||||
job_processor(const job_processor&) = delete;
|
|
||||||
job_processor& operator=(const job_processor&) = delete;
|
|
||||||
|
|
||||||
virtual ~job_processor();
|
virtual ~job_processor();
|
||||||
|
|
||||||
|
|
@ -75,21 +68,15 @@ public:
|
||||||
process_stream(std::istream& is, const char* filename);
|
process_stream(std::istream& is, const char* filename);
|
||||||
|
|
||||||
virtual int
|
virtual int
|
||||||
process_ltl_file(const char* filename);
|
process_file(const char* filename);
|
||||||
|
|
||||||
virtual int
|
|
||||||
process_aut_file(const char* filename);
|
|
||||||
|
|
||||||
virtual int
|
|
||||||
process_tlsf_file(const char* filename);
|
|
||||||
|
|
||||||
virtual int
|
virtual int
|
||||||
run();
|
run();
|
||||||
|
|
||||||
char* real_filename = nullptr;
|
char* real_filename;
|
||||||
long int col_to_read = 0;
|
long int col_to_read;
|
||||||
char* prefix = nullptr;
|
char* prefix;
|
||||||
char* suffix = nullptr;
|
char* suffix;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Report and error message or add a default job depending on whether
|
// Report and error message or add a default job depending on whether
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015, 2017, 2018, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2017, 2018 Laboratoire de Recherche et Développement de
|
||||||
// Développement de l'Epita (LRDE).
|
// l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -80,10 +80,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
process_aut_file(const char* filename) override
|
process_file(const char* filename) override
|
||||||
{
|
{
|
||||||
col_to_read = 0;
|
|
||||||
|
|
||||||
// If we have a filename like "foo/NN" such
|
// If we have a filename like "foo/NN" such
|
||||||
// that:
|
// that:
|
||||||
// ① foo/NN is not a file,
|
// ① foo/NN is not a file,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2019, 2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
|
||||||
#include <spot/tl/print.hh>
|
#include <spot/tl/print.hh>
|
||||||
#include <spot/tl/length.hh>
|
#include <spot/tl/length.hh>
|
||||||
#include <spot/tl/apcollect.hh>
|
#include <spot/tl/apcollect.hh>
|
||||||
|
|
@ -298,9 +297,9 @@ namespace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<formula_printer> format;
|
static formula_printer* format = nullptr;
|
||||||
static std::ostringstream outputname;
|
static std::ostringstream outputname;
|
||||||
static std::unique_ptr<formula_printer> outputnamer;
|
static formula_printer* outputnamer = nullptr;
|
||||||
static std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
static std::map<std::string, std::unique_ptr<output_file>> outputfiles;
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -321,7 +320,7 @@ parse_opt_output(int key, char* arg, struct argp_state*)
|
||||||
output_format = lbt_output;
|
output_format = lbt_output;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
outputnamer = std::make_unique<formula_printer>(outputname, arg);
|
outputnamer = new formula_printer(outputname, arg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
full_parenth = true;
|
full_parenth = true;
|
||||||
|
|
@ -342,7 +341,8 @@ parse_opt_output(int key, char* arg, struct argp_state*)
|
||||||
output_format = wring_output;
|
output_format = wring_output;
|
||||||
break;
|
break;
|
||||||
case OPT_FORMAT:
|
case OPT_FORMAT:
|
||||||
format = std::make_unique<formula_printer>(std::cout, arg);
|
delete format;
|
||||||
|
format = new formula_printer(std::cout, arg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ARGP_ERR_UNKNOWN;
|
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 };
|
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
||||||
outputnamer->print(fl, ptimer);
|
outputnamer->print(fl, ptimer);
|
||||||
std::string fname = outputname.str();
|
std::string fname = outputname.str();
|
||||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
auto p = outputfiles.emplace(fname, nullptr);
|
||||||
if (b)
|
if (p.second)
|
||||||
it->second.reset(new output_file(fname.c_str()));
|
p.first->second.reset(new output_file(fname.c_str()));
|
||||||
out = &it->second->ostream();
|
out = &p.first->second->ostream();
|
||||||
}
|
}
|
||||||
output_formula(*out, f, ptimer, filename, linenum, prefix, suffix);
|
output_formula(*out, f, ptimer, filename, linenum, prefix, suffix);
|
||||||
*out << output_terminator;
|
*out << output_terminator;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2014, 2016, 2023 Laboratoire de Recherche et
|
// Copyright (C) 2012, 2014, 2016 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -36,17 +36,13 @@ parse_range(const char* str, int missing_left, int missing_right)
|
||||||
{
|
{
|
||||||
range res;
|
range res;
|
||||||
char* end;
|
char* end;
|
||||||
errno = 0;
|
res.min = strtol(str, &end, 10);
|
||||||
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)
|
if (end == str)
|
||||||
{
|
{
|
||||||
// No leading number. It's OK as long as the string is not
|
// No leading number. It's OK as long as the string is not
|
||||||
// empty.
|
// empty.
|
||||||
if (!*end)
|
if (!*end)
|
||||||
error(2, 0, "invalid empty range");
|
error(1, 0, "invalid empty range");
|
||||||
res.min = missing_left;
|
res.min = missing_left;
|
||||||
}
|
}
|
||||||
if (!*end)
|
if (!*end)
|
||||||
|
|
@ -70,23 +66,19 @@ parse_range(const char* str, int missing_left, int missing_right)
|
||||||
{
|
{
|
||||||
// Parse the next integer.
|
// Parse the next integer.
|
||||||
char* end2;
|
char* end2;
|
||||||
errno = 0;
|
res.max = strtol(end, &end2, 10);
|
||||||
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)
|
if (str == end2)
|
||||||
error(2, 0, "invalid range '%s' "
|
error(1, 0, "invalid range '%s' "
|
||||||
"(should start with digits, dots, or colon)", str);
|
"(should start with digits, dots, or colon)", str);
|
||||||
if (end == end2)
|
if (end == end2)
|
||||||
error(2, 0, "invalid range '%s' (missing end?)", str);
|
error(1, 0, "invalid range '%s' (missing end?)", str);
|
||||||
if (*end2)
|
if (*end2)
|
||||||
error(2, 0, "invalid range '%s' (trailing garbage?)", str);
|
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.min < 0 || res.max < 0)
|
if (res.min < 0 || res.max < 0)
|
||||||
error(2, 0, "invalid range '%s': values must be positive", str);
|
error(1, 0, "invalid range '%s': values must be positive", str);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012-2022 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -20,14 +20,13 @@
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
#include "common_aoutput.hh"
|
#include "common_aoutput.hh"
|
||||||
|
|
||||||
#include <argp.h>
|
#include "argp.h"
|
||||||
#include <closeout.h>
|
#include "closeout.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <error.h>
|
|
||||||
#include <spot/misc/tmpfile.hh>
|
#include <spot/misc/tmpfile.hh>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -36,7 +35,7 @@ display_version(FILE *stream, struct argp_state*)
|
||||||
fputs(program_name, stream);
|
fputs(program_name, stream);
|
||||||
fputs(" (" PACKAGE_NAME ") " PACKAGE_VERSION "\n\
|
fputs(" (" PACKAGE_NAME ") " PACKAGE_VERSION "\n\
|
||||||
\n\
|
\n\
|
||||||
Copyright (C) 2023 Laboratoire de Recherche de l'Epita (LRE)\n\
|
Copyright (C) 2022 Laboratoire de Recherche et Développement de l'Epita.\n\
|
||||||
License GPLv3+: \
|
License GPLv3+: \
|
||||||
GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
|
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\
|
This is free software: you are free to change and redistribute it.\n\
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2013, 2018-2019, 2023 Laboratoire de Recherche
|
// Copyright (C) 2012, 2013, 2018, 2019 Laboratoire de Recherche et
|
||||||
// et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// 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.
|
// Diagnose exceptions.
|
||||||
[[noreturn]] void handle_any_exception();
|
[[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(); }
|
#define END_EXCEPTION_PROTECT } catch (...) { handle_any_exception(); }
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2015-2022 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
|
||||||
#if __has_include(<spawn.h>)
|
#if __has_include(<spawn.h>)
|
||||||
#define HAVE_SPAWN_H 1
|
#define HAVE_SPAWN_H 1
|
||||||
#include <spawn.h>
|
#include <spawn.h>
|
||||||
|
|
@ -53,7 +52,7 @@ struct shorthands_t
|
||||||
};
|
};
|
||||||
#define SHORTHAND(PRE, POST) { PRE, std::regex("^" PRE), POST }
|
#define SHORTHAND(PRE, POST) { PRE, std::regex("^" PRE), POST }
|
||||||
|
|
||||||
static const shorthands_t shorthands_ltl[] = {
|
static shorthands_t shorthands_ltl[] = {
|
||||||
SHORTHAND("delag", " %f>%O"),
|
SHORTHAND("delag", " %f>%O"),
|
||||||
SHORTHAND("lbt", " <%L>%O"),
|
SHORTHAND("lbt", " <%L>%O"),
|
||||||
SHORTHAND("ltl2ba", " -f %s>%O"),
|
SHORTHAND("ltl2ba", " -f %s>%O"),
|
||||||
|
|
@ -73,7 +72,7 @@ static const shorthands_t shorthands_ltl[] = {
|
||||||
SHORTHAND("owl.* ltl-utilities\\b", " -f %f"),
|
SHORTHAND("owl.* ltl-utilities\\b", " -f %f"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const shorthands_t shorthands_autproc[] = {
|
static shorthands_t shorthands_autproc[] = {
|
||||||
SHORTHAND("autfilt", " %H>%O"),
|
SHORTHAND("autfilt", " %H>%O"),
|
||||||
SHORTHAND("dra2dpa", " <%H>%O"),
|
SHORTHAND("dra2dpa", " <%H>%O"),
|
||||||
SHORTHAND("dstar2tgba", " %H>%O"),
|
SHORTHAND("dstar2tgba", " %H>%O"),
|
||||||
|
|
@ -85,7 +84,7 @@ static const shorthands_t shorthands_autproc[] = {
|
||||||
" <%H>%O"),
|
" <%H>%O"),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void show_shorthands(const shorthands_t* begin, const shorthands_t* end)
|
static void show_shorthands(shorthands_t* begin, shorthands_t* end)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
|
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
|
||||||
|
|
@ -100,8 +99,7 @@ static void show_shorthands(const shorthands_t* begin, const shorthands_t* end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tool_spec::tool_spec(const char* spec,
|
tool_spec::tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
||||||
const shorthands_t* begin, const shorthands_t* end,
|
|
||||||
bool is_ref) noexcept
|
bool is_ref) noexcept
|
||||||
: spec(spec), cmd(spec), name(spec), reference(is_ref)
|
: spec(spec), cmd(spec), name(spec), reference(is_ref)
|
||||||
{
|
{
|
||||||
|
|
@ -114,11 +112,11 @@ tool_spec::tool_spec(const char* spec,
|
||||||
{
|
{
|
||||||
if (*pos == '{')
|
if (*pos == '{')
|
||||||
++count;
|
++count;
|
||||||
else if (*pos == '}' && --count == 0)
|
else if (*pos == '}')
|
||||||
|
if (!--count)
|
||||||
{
|
{
|
||||||
name = strndup(cmd + 1, pos - cmd - 1);
|
name = strndup(cmd + 1, pos - cmd - 1);
|
||||||
cmd = pos + 1;
|
cmd = pos + 1;
|
||||||
// skip leading whitespace
|
|
||||||
while (*cmd == ' ' || *cmd == '\t')
|
while (*cmd == ' ' || *cmd == '\t')
|
||||||
++cmd;
|
++cmd;
|
||||||
break;
|
break;
|
||||||
|
|
@ -148,11 +146,11 @@ tool_spec::tool_spec(const char* spec,
|
||||||
auto& p = *begin++;
|
auto& p = *begin++;
|
||||||
if (std::regex_search(basename, p.rprefix))
|
if (std::regex_search(basename, p.rprefix))
|
||||||
{
|
{
|
||||||
size_t m = strlen(p.suffix);
|
int m = strlen(p.suffix);
|
||||||
size_t q = strlen(cmd);
|
int q = strlen(cmd);
|
||||||
char* tmp = static_cast<char*>(malloc(q + m + 1));
|
char* tmp = static_cast<char*>(malloc(q + m + 1));
|
||||||
memcpy(tmp, cmd, q);
|
strcpy(tmp, cmd);
|
||||||
memcpy(tmp + q, p.suffix, m + 1);
|
strcpy(tmp + q, p.suffix);
|
||||||
cmd = tmp;
|
cmd = tmp;
|
||||||
allocated = true;
|
allocated = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -463,92 +461,6 @@ autproc_runner::round_automaton(spot::const_twa_graph_ptr aut, unsigned serial)
|
||||||
filename_automaton.new_round(aut, 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};
|
std::atomic<bool> timed_out{false};
|
||||||
unsigned timeout_count = 0;
|
unsigned timeout_count = 0;
|
||||||
|
|
||||||
|
|
@ -612,7 +524,7 @@ get_arg(const char*& cmd)
|
||||||
{
|
{
|
||||||
const char* start = cmd;
|
const char* start = cmd;
|
||||||
std::string arg;
|
std::string arg;
|
||||||
while (char c = *cmd)
|
while (int c = *cmd)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
@ -642,14 +554,14 @@ get_arg(const char*& cmd)
|
||||||
goto end_loop;
|
goto end_loop;
|
||||||
case '\'':
|
case '\'':
|
||||||
{
|
{
|
||||||
char d = '\0';
|
int d = 0;
|
||||||
while ((d = *++cmd))
|
while ((d = *++cmd))
|
||||||
{
|
{
|
||||||
if (d == '\'')
|
if (d == '\'')
|
||||||
break;
|
break;
|
||||||
arg.push_back(d);
|
arg.push_back(d);
|
||||||
}
|
}
|
||||||
if (d == '\0')
|
if (d == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -794,7 +706,6 @@ parse_simple_command(const char* cmd)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_SPAWN_H
|
#ifndef HAVE_SPAWN_H
|
||||||
static void
|
static void
|
||||||
exec_command(const char* cmd)
|
exec_command(const char* cmd)
|
||||||
|
|
@ -840,6 +751,8 @@ exec_command(const char* cmd)
|
||||||
SPOT_UNREACHABLE();
|
SPOT_UNREACHABLE();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
extern char **environ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2018, 2020, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2015-2018, 2020 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -51,8 +51,7 @@ struct tool_spec
|
||||||
// Whether the tool is a reference.
|
// Whether the tool is a reference.
|
||||||
bool reference;
|
bool reference;
|
||||||
|
|
||||||
tool_spec(const char* spec,
|
tool_spec(const char* spec, shorthands_t* begin, shorthands_t* end,
|
||||||
const shorthands_t* begin, const shorthands_t* end,
|
|
||||||
bool is_ref) noexcept;
|
bool is_ref) noexcept;
|
||||||
tool_spec(const tool_spec& other) noexcept;
|
tool_spec(const tool_spec& other) noexcept;
|
||||||
tool_spec& operator=(const tool_spec& other);
|
tool_spec& operator=(const tool_spec& other);
|
||||||
|
|
@ -72,7 +71,7 @@ struct quoted_formula final: public spot::printable_value<spot::formula>
|
||||||
|
|
||||||
struct filed_formula final: public spot::printable
|
struct filed_formula final: public spot::printable
|
||||||
{
|
{
|
||||||
explicit filed_formula(const quoted_formula& ltl) : f_(ltl)
|
filed_formula(const quoted_formula& ltl) : f_(ltl)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +89,9 @@ struct filed_formula final: public spot::printable
|
||||||
|
|
||||||
struct filed_automaton final: public spot::printable
|
struct filed_automaton final: public spot::printable
|
||||||
{
|
{
|
||||||
filed_automaton() = default;
|
filed_automaton()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void print(std::ostream& os, const char* pos) const override;
|
void print(std::ostream& os, const char* pos) const override;
|
||||||
|
|
||||||
|
|
@ -111,7 +112,7 @@ struct printable_result_filename final:
|
||||||
unsigned translator_num;
|
unsigned translator_num;
|
||||||
|
|
||||||
printable_result_filename();
|
printable_result_filename();
|
||||||
~printable_result_filename() override;
|
~printable_result_filename();
|
||||||
void reset(unsigned n);
|
void reset(unsigned n);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
|
@ -125,7 +126,7 @@ protected:
|
||||||
spot::bdd_dict_ptr dict;
|
spot::bdd_dict_ptr dict;
|
||||||
// Round-specific variables
|
// Round-specific variables
|
||||||
quoted_formula ltl_formula;
|
quoted_formula ltl_formula;
|
||||||
filed_formula filename_formula{ltl_formula};
|
filed_formula filename_formula = ltl_formula;
|
||||||
// Run-specific variables
|
// Run-specific variables
|
||||||
printable_result_filename output;
|
printable_result_filename output;
|
||||||
public:
|
public:
|
||||||
|
|
@ -150,7 +151,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
using spot::formater::has;
|
using spot::formater::has;
|
||||||
|
|
||||||
explicit autproc_runner(// whether we accept the absence of output
|
autproc_runner(// whether we accept the absence of output
|
||||||
// specifier
|
// specifier
|
||||||
bool no_output_allowed = false);
|
bool no_output_allowed = false);
|
||||||
void round_automaton(spot::const_twa_graph_ptr aut, unsigned serial);
|
void round_automaton(spot::const_twa_graph_ptr aut, unsigned serial);
|
||||||
|
|
@ -174,9 +175,3 @@ int exec_with_timeout(const char* cmd);
|
||||||
#define exec_with_timeout(cmd) system(cmd)
|
#define exec_with_timeout(cmd) system(cmd)
|
||||||
#define setup_sig_handler() while (0);
|
#define setup_sig_handler() while (0);
|
||||||
#endif // !ENABLE_TIMEOUT
|
#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 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2019, 2022, 2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2019 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -89,7 +89,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case 'F':
|
case 'F':
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
{
|
{
|
||||||
|
|
@ -99,7 +99,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
jobs.emplace_back(arg, job_type::AUT_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ARGP_ERR_UNKNOWN;
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
|
@ -117,7 +117,7 @@ namespace
|
||||||
spot::postprocessor& post;
|
spot::postprocessor& post;
|
||||||
automaton_printer printer;
|
automaton_printer printer;
|
||||||
|
|
||||||
explicit dstar_processor(spot::postprocessor& post)
|
dstar_processor(spot::postprocessor& post)
|
||||||
: hoa_processor(spot::make_bdd_dict()), post(post), printer(aut_input)
|
: hoa_processor(spot::make_bdd_dict()), post(post), printer(aut_input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2019, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2017-2019 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -43,8 +43,7 @@
|
||||||
|
|
||||||
using namespace spot;
|
using namespace spot;
|
||||||
|
|
||||||
static const char argp_program_doc[] =
|
const char argp_program_doc[] ="Generate ω-automata from predefined patterns.";
|
||||||
"Generate ω-automata from predefined patterns.";
|
|
||||||
|
|
||||||
static const argp_option options[] =
|
static const argp_option options[] =
|
||||||
{
|
{
|
||||||
|
|
@ -63,11 +62,6 @@ static const argp_option options[] =
|
||||||
{ "m-nba", gen::AUT_M_NBA, "RANGE", 0,
|
{ "m-nba", gen::AUT_M_NBA, "RANGE", 0,
|
||||||
"An NBA with N+1 states whose determinization needs at least "
|
"An NBA with N+1 states whose determinization needs at least "
|
||||||
"N! states", 0},
|
"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,
|
RANGE_DOC,
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||||
|
|
@ -128,7 +122,7 @@ output_pattern(gen::aut_pattern_id pattern, int n)
|
||||||
static void
|
static void
|
||||||
run_jobs()
|
run_jobs()
|
||||||
{
|
{
|
||||||
for (const auto& j: jobs)
|
for (auto& j: jobs)
|
||||||
{
|
{
|
||||||
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
||||||
int n = j.range.min;
|
int n = j.range.min;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2013, 2015-2019, 2022-2023 Laboratoire de
|
// Copyright (C) 2012, 2013, 2015-2019 Laboratoire de Recherche et
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
using namespace spot;
|
using namespace spot;
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Generate temporal logic formulas from predefined patterns.";
|
Generate temporal logic formulas from predefined patterns.";
|
||||||
|
|
||||||
// We reuse the values from gen::ltl_pattern_id as option keys.
|
// We reuse the values from gen::ltl_pattern_id as option keys.
|
||||||
|
|
@ -84,8 +84,6 @@ static const argp_option options[] =
|
||||||
{ "eh-patterns", gen::LTL_EH_PATTERNS, "RANGE", OPTION_ARG_OPTIONAL,
|
{ "eh-patterns", gen::LTL_EH_PATTERNS, "RANGE", OPTION_ARG_OPTIONAL,
|
||||||
"Etessami and Holzmann [Concur'00] patterns "
|
"Etessami and Holzmann [Concur'00] patterns "
|
||||||
"(range should be included in 1..12)", 0 },
|
"(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,
|
{ "fxg-or", gen::LTL_FXG_OR, "RANGE", 0,
|
||||||
"F(p0 | XG(p1 | XG(p2 | ... XG(pn))))", 0},
|
"F(p0 | XG(p1 | XG(p2 | ... XG(pn))))", 0},
|
||||||
{ "gf-equiv", gen::LTL_GF_EQUIV, "RANGE", 0,
|
{ "gf-equiv", gen::LTL_GF_EQUIV, "RANGE", 0,
|
||||||
|
|
@ -317,7 +315,7 @@ output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
||||||
static void
|
static void
|
||||||
run_jobs()
|
run_jobs()
|
||||||
{
|
{
|
||||||
for (const auto& j: jobs)
|
for (auto& j: jobs)
|
||||||
{
|
{
|
||||||
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
int inc = (j.range.max < j.range.min) ? -1 : 1;
|
||||||
int n = j.range.min;
|
int n = j.range.min;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2019, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -105,9 +105,10 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
// FIXME: use stat() to distinguish filename from string?
|
// FIXME: use stat() to distinguish filename from string?
|
||||||
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
|
if (*arg == '-' && !arg[1])
|
||||||
? job_type::LTL_FILENAME
|
jobs.emplace_back(arg, true);
|
||||||
: job_type::LTL_STRING));
|
else
|
||||||
|
jobs.emplace_back(arg, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -124,10 +125,10 @@ namespace
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
spot::translator& trans;
|
spot::translator& trans;
|
||||||
automaton_printer printer{ltl_input};
|
automaton_printer printer;
|
||||||
|
|
||||||
explicit trans_processor(spot::translator& trans)
|
trans_processor(spot::translator& trans)
|
||||||
: trans(trans)
|
: trans(trans), printer(ltl_input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2020, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
#include <spot/taalgos/minimize.hh>
|
#include <spot/taalgos/minimize.hh>
|
||||||
#include <spot/misc/optionmap.hh>
|
#include <spot/misc/optionmap.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Translate linear-time formulas (LTL/PSL) into Testing Automata.\n\n\
|
Translate linear-time formulas (LTL/PSL) into Testing Automata.\n\n\
|
||||||
By default it outputs a transition-based generalized Testing Automaton \
|
By default it outputs a transition-based generalized Testing Automaton \
|
||||||
the smallest Transition-based Generalized Büchi Automata, \
|
the smallest Transition-based Generalized Büchi Automata, \
|
||||||
|
|
@ -148,9 +148,10 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
// FIXME: use stat() to distinguish filename from string?
|
// FIXME: use stat() to distinguish filename from string?
|
||||||
jobs.emplace_back(arg, ((*arg == '-' && !arg[1])
|
if (*arg == '-' && !arg[1])
|
||||||
? job_type::LTL_FILENAME
|
jobs.emplace_back(arg, true);
|
||||||
: job_type::LTL_STRING));
|
else
|
||||||
|
jobs.emplace_back(arg, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -168,7 +169,7 @@ namespace
|
||||||
public:
|
public:
|
||||||
spot::translator& trans;
|
spot::translator& trans;
|
||||||
|
|
||||||
explicit trans_processor(spot::translator& trans)
|
trans_processor(spot::translator& trans)
|
||||||
: trans(trans)
|
: trans(trans)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2020, 2022, 2023 Laboratoire de Recherche et
|
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
#include <spot/misc/tmpfile.hh>
|
#include <spot/misc/tmpfile.hh>
|
||||||
#include <spot/misc/timer.hh>
|
#include <spot/misc/timer.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Call several LTL/PSL translators and cross-compare their output to detect \
|
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 \
|
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\
|
supplied on standard input, or using the -f or -F options.\v\
|
||||||
|
|
@ -264,32 +264,55 @@ end_error()
|
||||||
|
|
||||||
struct statistics
|
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
|
// If OK is false, only the status_str, status_code, and time fields
|
||||||
// should be valid.
|
// should be valid.
|
||||||
bool ok = false;
|
bool ok;
|
||||||
bool alternating = false;
|
bool alternating;
|
||||||
const char* status_str = nullptr;
|
const char* status_str;
|
||||||
int status_code = 0;
|
int status_code;
|
||||||
double time = 0.0;
|
double time;
|
||||||
unsigned states = 0;
|
unsigned states;
|
||||||
unsigned edges = 0;
|
unsigned edges;
|
||||||
unsigned long long transitions = 0;
|
unsigned long long transitions;
|
||||||
unsigned acc = 0;
|
unsigned acc;
|
||||||
unsigned scc = 0;
|
unsigned scc;
|
||||||
unsigned nonacc_scc = 0;
|
unsigned nonacc_scc;
|
||||||
unsigned terminal_scc = 0;
|
unsigned terminal_scc;
|
||||||
unsigned weak_scc = 0;
|
unsigned weak_scc;
|
||||||
unsigned strong_scc = 0;
|
unsigned strong_scc;
|
||||||
unsigned nondetstates = 0;
|
unsigned nondetstates;
|
||||||
bool nondeterministic = false;
|
bool nondeterministic;
|
||||||
bool terminal_aut = false;
|
bool terminal_aut;
|
||||||
bool weak_aut = false;
|
bool weak_aut;
|
||||||
bool strong_aut = false;
|
bool strong_aut;
|
||||||
std::vector<double> product_states;
|
std::vector<double> product_states;
|
||||||
std::vector<double> product_transitions;
|
std::vector<double> product_transitions;
|
||||||
std::vector<double> product_scc;
|
std::vector<double> product_scc;
|
||||||
bool ambiguous = false;
|
bool ambiguous;
|
||||||
bool complete = false;
|
bool complete;
|
||||||
std::string hoa_str;
|
std::string hoa_str;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -461,7 +484,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (arg[0] == '-' && !arg[1])
|
if (arg[0] == '-' && !arg[1])
|
||||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
else
|
else
|
||||||
tools_push_trans(arg);
|
tools_push_trans(arg);
|
||||||
break;
|
break;
|
||||||
|
|
@ -558,7 +581,7 @@ namespace
|
||||||
class xtranslator_runner final: public translator_runner
|
class xtranslator_runner final: public translator_runner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
|
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||||
: translator_runner(dict)
|
: translator_runner(dict)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -1072,7 +1095,9 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we do not translate the same formula twice.
|
// Make sure we do not translate the same formula twice.
|
||||||
if (!allow_dups && !unique_set.insert(f).second)
|
if (!allow_dups)
|
||||||
|
{
|
||||||
|
if (!unique_set.insert(f).second)
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
std::cerr
|
std::cerr
|
||||||
|
|
@ -1081,6 +1106,7 @@ namespace
|
||||||
"should not be ignored.\n\n");
|
"should not be ignored.\n\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int problems = 0;
|
int problems = 0;
|
||||||
|
|
||||||
|
|
|
||||||
18
bin/ltldo.cc
18
bin/ltldo.cc
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2020, 2022-2023 Laboratoire de Recherche et
|
// Copyright (C) 2015-2020 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
#include <spot/twaalgos/totgba.hh>
|
#include <spot/twaalgos/totgba.hh>
|
||||||
#include <spot/parseaut/public.hh>
|
#include <spot/parseaut/public.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Run LTL/PSL formulas through another program, performing conversion\n\
|
Run LTL/PSL formulas through another program, performing conversion\n\
|
||||||
of input and output as required.";
|
of input and output as required.";
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (arg[0] == '-' && !arg[1])
|
if (arg[0] == '-' && !arg[1])
|
||||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
else
|
else
|
||||||
tools_push_trans(arg);
|
tools_push_trans(arg);
|
||||||
break;
|
break;
|
||||||
|
|
@ -209,7 +209,7 @@ namespace
|
||||||
class xtranslator_runner final: public translator_runner
|
class xtranslator_runner final: public translator_runner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit xtranslator_runner(spot::bdd_dict_ptr dict)
|
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||||
: translator_runner(dict, true)
|
: translator_runner(dict, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -224,6 +224,8 @@ namespace
|
||||||
format(command, tools[translator_num].cmd);
|
format(command, tools[translator_num].cmd);
|
||||||
|
|
||||||
std::string cmd = command.str();
|
std::string cmd = command.str();
|
||||||
|
//std::cerr << "Running [" << l << translator_num << "]: "
|
||||||
|
// << cmd << std::endl;
|
||||||
timer.start();
|
timer.start();
|
||||||
int es = exec_with_timeout(cmd.c_str());
|
int es = exec_with_timeout(cmd.c_str());
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
@ -310,7 +312,7 @@ namespace
|
||||||
spot::printable_value<std::string> inputf;
|
spot::printable_value<std::string> inputf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit processor(spot::postprocessor& post)
|
processor(spot::postprocessor& post)
|
||||||
: runner(dict), best_printer(best_stream, best_format), post(post)
|
: runner(dict), best_printer(best_stream, best_format), post(post)
|
||||||
{
|
{
|
||||||
printer.add_stat('T', &cmdname);
|
printer.add_stat('T', &cmdname);
|
||||||
|
|
@ -321,7 +323,9 @@ namespace
|
||||||
best_printer.declare('f', &inputf);
|
best_printer.declare('f', &inputf);
|
||||||
}
|
}
|
||||||
|
|
||||||
~processor() override = default;
|
~processor()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
process_string(const std::string& input,
|
process_string(const std::string& input,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
#include <spot/twaalgos/totgba.hh>
|
#include <spot/twaalgos/totgba.hh>
|
||||||
#include <spot/twaalgos/word.hh>
|
#include <spot/twaalgos/word.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Read a list of formulas and output them back after some optional processing.\v\
|
Read a list of formulas and output them back after some optional processing.\v\
|
||||||
Exit status:\n\
|
Exit status:\n\
|
||||||
0 if some formulas were output (skipped syntax errors do not count)\n\
|
0 if some formulas were output (skipped syntax errors do not count)\n\
|
||||||
|
|
@ -387,7 +387,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
// FIXME: use stat() to distinguish filename from string?
|
// FIXME: use stat() to distinguish filename from string?
|
||||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case OPT_ACCEPT_WORD:
|
case OPT_ACCEPT_WORD:
|
||||||
try
|
try
|
||||||
|
|
@ -586,7 +586,7 @@ namespace
|
||||||
fset_t unique_set;
|
fset_t unique_set;
|
||||||
spot::relabeling_map relmap;
|
spot::relabeling_map relmap;
|
||||||
|
|
||||||
explicit ltl_processor(spot::tl_simplifier& simpl)
|
ltl_processor(spot::tl_simplifier& simpl)
|
||||||
: simpl(simpl)
|
: simpl(simpl)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -722,7 +722,7 @@ namespace
|
||||||
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
|
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
|
||||||
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
|
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
|
||||||
{
|
{
|
||||||
spot::atomic_prop_set* s = atomic_prop_collect(f);
|
auto s = atomic_prop_collect(f);
|
||||||
int n = s->size();
|
int n = s->size();
|
||||||
delete s;
|
delete s;
|
||||||
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
|
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
|
||||||
|
|
@ -761,7 +761,7 @@ namespace
|
||||||
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
|
aut = ltl_to_tgba_fm(f, simpl.get_dict(), true);
|
||||||
|
|
||||||
if (matched && !opt->acc_words.empty())
|
if (matched && !opt->acc_words.empty())
|
||||||
for (const spot::twa_graph_ptr& word_aut: opt->acc_words)
|
for (auto& word_aut: opt->acc_words)
|
||||||
if (spot::product(aut, word_aut)->is_empty())
|
if (spot::product(aut, word_aut)->is_empty())
|
||||||
{
|
{
|
||||||
matched = false;
|
matched = false;
|
||||||
|
|
@ -769,7 +769,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched && !opt->rej_words.empty())
|
if (matched && !opt->rej_words.empty())
|
||||||
for (const spot::twa_graph_ptr& word_aut: opt->rej_words)
|
for (auto& word_aut: opt->rej_words)
|
||||||
if (!spot::product(aut, word_aut)->is_empty())
|
if (!spot::product(aut, word_aut)->is_empty())
|
||||||
{
|
{
|
||||||
matched = false;
|
matched = false;
|
||||||
|
|
@ -843,12 +843,12 @@ namespace
|
||||||
{
|
{
|
||||||
// Sort the formulas alphabetically.
|
// Sort the formulas alphabetically.
|
||||||
std::map<std::string, spot::formula> m;
|
std::map<std::string, spot::formula> m;
|
||||||
for (const auto& [newformula, oldname]: relmap)
|
for (auto& p: relmap)
|
||||||
m.emplace(str_psl(newformula), oldname);
|
m.emplace(str_psl(p.first), p.second);
|
||||||
for (const auto& [newname, oldname]: m)
|
for (auto& p: m)
|
||||||
stream_formula(opt->output_define->ostream()
|
stream_formula(opt->output_define->ostream()
|
||||||
<< "#define " << newname << " (",
|
<< "#define " << p.first << " (",
|
||||||
oldname, filename,
|
p.second, filename,
|
||||||
std::to_string(linenum).c_str()) << ")\n";
|
std::to_string(linenum).c_str()) << ")\n";
|
||||||
}
|
}
|
||||||
one_match = true;
|
one_match = true;
|
||||||
|
|
@ -876,7 +876,7 @@ main(int argc, char** argv)
|
||||||
exit(err);
|
exit(err);
|
||||||
|
|
||||||
if (jobs.empty())
|
if (jobs.empty())
|
||||||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
jobs.emplace_back("-", 1);
|
||||||
|
|
||||||
if (boolean_to_isop && simplification_level == 0)
|
if (boolean_to_isop && simplification_level == 0)
|
||||||
simplification_level = 1;
|
simplification_level = 1;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014-2019, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -143,7 +143,7 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
break;
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
// FIXME: use stat() to distinguish filename from string?
|
// FIXME: use stat() to distinguish filename from string?
|
||||||
jobs.emplace_back(arg, job_type::LTL_FILENAME);
|
jobs.emplace_back(arg, true);
|
||||||
break;
|
break;
|
||||||
case OPT_AP2CONST:
|
case OPT_AP2CONST:
|
||||||
opt_all = 0;
|
opt_all = 0;
|
||||||
|
|
|
||||||
531
bin/ltlsynt.cc
531
bin/ltlsynt.cc
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2017-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -23,10 +23,8 @@
|
||||||
|
|
||||||
#include "common_aoutput.hh"
|
#include "common_aoutput.hh"
|
||||||
#include "common_finput.hh"
|
#include "common_finput.hh"
|
||||||
#include "common_hoaread.hh"
|
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
#include "common_sys.hh"
|
#include "common_sys.hh"
|
||||||
#include "common_trans.hh"
|
|
||||||
|
|
||||||
#include <spot/misc/bddlt.hh>
|
#include <spot/misc/bddlt.hh>
|
||||||
#include <spot/misc/escape.hh>
|
#include <spot/misc/escape.hh>
|
||||||
|
|
@ -37,7 +35,6 @@
|
||||||
#include <spot/twaalgos/aiger.hh>
|
#include <spot/twaalgos/aiger.hh>
|
||||||
#include <spot/twaalgos/game.hh>
|
#include <spot/twaalgos/game.hh>
|
||||||
#include <spot/twaalgos/hoa.hh>
|
#include <spot/twaalgos/hoa.hh>
|
||||||
#include <spot/twaalgos/dot.hh>
|
|
||||||
#include <spot/twaalgos/minimize.hh>
|
#include <spot/twaalgos/minimize.hh>
|
||||||
#include <spot/twaalgos/mealy_machine.hh>
|
#include <spot/twaalgos/mealy_machine.hh>
|
||||||
#include <spot/twaalgos/product.hh>
|
#include <spot/twaalgos/product.hh>
|
||||||
|
|
@ -47,12 +44,8 @@
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OPT_ALGO = 256,
|
OPT_ALGO = 256,
|
||||||
OPT_BYPASS,
|
|
||||||
OPT_CSV,
|
OPT_CSV,
|
||||||
OPT_DECOMPOSE,
|
OPT_DECOMPOSE,
|
||||||
OPT_DOT,
|
|
||||||
OPT_FROM_PGAME,
|
|
||||||
OPT_HIDE,
|
|
||||||
OPT_INPUT,
|
OPT_INPUT,
|
||||||
OPT_OUTPUT,
|
OPT_OUTPUT,
|
||||||
OPT_PRINT,
|
OPT_PRINT,
|
||||||
|
|
@ -60,7 +53,6 @@ enum
|
||||||
OPT_PRINT_HOA,
|
OPT_PRINT_HOA,
|
||||||
OPT_REAL,
|
OPT_REAL,
|
||||||
OPT_SIMPLIFY,
|
OPT_SIMPLIFY,
|
||||||
OPT_TLSF,
|
|
||||||
OPT_VERBOSE,
|
OPT_VERBOSE,
|
||||||
OPT_VERIFY
|
OPT_VERIFY
|
||||||
};
|
};
|
||||||
|
|
@ -73,17 +65,11 @@ static const argp_option options[] =
|
||||||
"comma-separated list of controllable (a.k.a. output) atomic"
|
"comma-separated list of controllable (a.k.a. output) atomic"
|
||||||
" propositions", 0},
|
" propositions", 0},
|
||||||
{ "ins", OPT_INPUT, "PROPS", 0,
|
{ "ins", OPT_INPUT, "PROPS", 0,
|
||||||
"comma-separated list of uncontrollable (a.k.a. input) atomic"
|
"comma-separated list of controllable (a.k.a. output) atomic"
|
||||||
" propositions", 0},
|
" 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 },
|
{ nullptr, 0, nullptr, 0, "Fine tuning:", 10 },
|
||||||
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old|acd", 0,
|
{ "algo", OPT_ALGO, "sd|ds|ps|lar|lar.old", 0,
|
||||||
"choose the algorithm for synthesis:"
|
"choose the algorithm for synthesis:"
|
||||||
" \"sd\": translate to tgba, split, then determinize;"
|
" \"sd\": translate to tgba, split, then determinize;"
|
||||||
" \"ds\": translate to tgba, determinize, then split;"
|
" \"ds\": translate to tgba, determinize, then split;"
|
||||||
|
|
@ -91,19 +77,13 @@ static const argp_option options[] =
|
||||||
" \"lar\": translate to a deterministic automaton with arbitrary"
|
" \"lar\": translate to a deterministic automaton with arbitrary"
|
||||||
" acceptance condition, then use LAR to turn to parity,"
|
" acceptance condition, then use LAR to turn to parity,"
|
||||||
" then split (default);"
|
" then split (default);"
|
||||||
" \"lar.old\": old version of LAR, for benchmarking;"
|
" \"lar.old\": old version of LAR, for benchmarking.\n", 0 },
|
||||||
" \"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,
|
{ "decompose", OPT_DECOMPOSE, "yes|no", 0,
|
||||||
"whether to decompose the specification as multiple output-disjoint "
|
"whether to decompose the specification as multiple output-disjoint "
|
||||||
"problems to solve independently (enabled by default)", 0 },
|
"problems to solve independently (enabled by default)", 0 },
|
||||||
{ "simplify", OPT_SIMPLIFY, "no|bisim|bwoa|sat|bisim-sat|bwoa-sat", 0,
|
{ "simplify", OPT_SIMPLIFY, "no|bisim|bwoa|sat|bisim-sat|bwoa-sat", 0,
|
||||||
"simplification to apply to the controller (no) nothing, "
|
"simplification to apply to the controler (no) nothing, "
|
||||||
"(bisim) bisimulation-based reduction, (bwoa) bisimulation-based "
|
"(bisim) bisimulation-based reduction, (bwoa) bissimulation-based "
|
||||||
"reduction with output assignment, (sat) SAT-based minimization, "
|
"reduction with output assignment, (sat) SAT-based minimization, "
|
||||||
"(bisim-sat) SAT after bisim, (bwoa-sat) SAT after bwoa. Defaults "
|
"(bisim-sat) SAT after bisim, (bwoa-sat) SAT after bwoa. Defaults "
|
||||||
"to 'bwoa'.", 0 },
|
"to 'bwoa'.", 0 },
|
||||||
|
|
@ -117,34 +97,25 @@ static const argp_option options[] =
|
||||||
"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]"
|
{ "aiger", OPT_PRINT_AIGER, "ite|isop|both[+ud][+dc]"
|
||||||
"[+sub0|sub1|sub2]", OPTION_ARG_OPTIONAL,
|
"[+sub0|sub1|sub2]", OPTION_ARG_OPTIONAL,
|
||||||
"encode the winning strategy as an AIG circuit and print it in AIGER"
|
"prints a winning strategy as an AIGER circuit. The first, and only "
|
||||||
" format. The first word indicates the encoding to used: \"ite\" for "
|
"mandatory option defines the method to be used. \"ite\" for "
|
||||||
"If-Then-Else normal form; "
|
"If-then-else normal form; "
|
||||||
"\"isop\" for irreducible sum of products; "
|
"\"isop\" for irreducible sum of producs; "
|
||||||
"\"both\" tries both and keeps the smaller one. "
|
"\"both\" tries both encodings and keeps the smaller one. "
|
||||||
"Other options further "
|
"The other options further "
|
||||||
"refine the encoding, see aiger::encode_bdd. Defaults to \"ite\".", 0 },
|
"refine the encoding, see aiger::encode_bdd.", 0},
|
||||||
{ "dot", OPT_DOT, "options", OPTION_ARG_OPTIONAL,
|
{ "verbose", OPT_VERBOSE, nullptr, 0,
|
||||||
"Use dot format when printing the result (game, strategy, or "
|
"verbose mode", -1 },
|
||||||
"AIG circuit, depending on other options). The options that "
|
{ "verify", OPT_VERIFY, nullptr, 0,
|
||||||
"may be passed to --dot depend on the nature of what is printed. "
|
"verifies the strategy or (if demanded) aiger against the spec.", -1 },
|
||||||
"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,
|
{ "csv", OPT_CSV, "[>>]FILENAME", OPTION_ARG_OPTIONAL,
|
||||||
"output statistics as CSV in FILENAME or on standard output "
|
"output statistics as CSV in FILENAME or on standard output "
|
||||||
"(if '>>' is used to request append mode, the header line is "
|
"(if '>>' is used to request append mode, the header line is "
|
||||||
"not output)", 0 },
|
"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 },
|
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -1 },
|
||||||
{ "extra-options", 'x', "OPTS", 0,
|
{ "extra-options", 'x', "OPTS", 0,
|
||||||
"fine-tuning options (see spot-x (7))", 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 },
|
{ nullptr, 0, nullptr, 0, nullptr, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -152,19 +123,20 @@ static const struct argp_child children[] =
|
||||||
{
|
{
|
||||||
{ &finput_argp_headless, 0, nullptr, 0 },
|
{ &finput_argp_headless, 0, nullptr, 0 },
|
||||||
{ &aoutput_argp, 0, nullptr, 0 },
|
{ &aoutput_argp, 0, nullptr, 0 },
|
||||||
|
//{ &aoutput_o_format_argp, 0, nullptr, 0 },
|
||||||
{ &misc_argp, 0, nullptr, 0 },
|
{ &misc_argp, 0, nullptr, 0 },
|
||||||
{ nullptr, 0, nullptr, 0 }
|
{ nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] = "\
|
||||||
Synthesize a controller from its LTL specification.\v\
|
Synthesize a controller from its LTL specification.\v\
|
||||||
Exit status:\n\
|
Exit status:\n\
|
||||||
0 if all input problems were realizable\n\
|
0 if the input problem is realizable\n\
|
||||||
1 if at least one input problem was not realizable\n\
|
1 if the input problem is not realizable\n\
|
||||||
2 if any error has been reported";
|
2 if any error has been reported";
|
||||||
|
|
||||||
static std::optional<std::vector<std::string>> all_output_aps;
|
static std::vector<std::string> all_output_aps;
|
||||||
static std::optional<std::vector<std::string>> all_input_aps;
|
static std::vector<std::string> all_input_aps;
|
||||||
|
|
||||||
static const char* opt_csv = nullptr;
|
static const char* opt_csv = nullptr;
|
||||||
static bool opt_print_pg = false;
|
static bool opt_print_pg = false;
|
||||||
|
|
@ -173,10 +145,8 @@ static const char* opt_print_hoa_args = nullptr;
|
||||||
static bool opt_real = false;
|
static bool opt_real = false;
|
||||||
static bool opt_do_verify = false;
|
static bool opt_do_verify = false;
|
||||||
static const char* opt_print_aiger = nullptr;
|
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 spot::synthesis_info* gi;
|
||||||
static bool show_status = true;
|
|
||||||
|
|
||||||
static char const *const algo_names[] =
|
static char const *const algo_names[] =
|
||||||
{
|
{
|
||||||
|
|
@ -184,8 +154,7 @@ static char const *const algo_names[] =
|
||||||
"sd",
|
"sd",
|
||||||
"ps",
|
"ps",
|
||||||
"lar",
|
"lar",
|
||||||
"lar.old",
|
"lar.old"
|
||||||
"acd",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const *const algo_args[] =
|
static char const *const algo_args[] =
|
||||||
|
|
@ -195,7 +164,6 @@ static char const *const algo_args[] =
|
||||||
"dpasplit", "ps",
|
"dpasplit", "ps",
|
||||||
"lar",
|
"lar",
|
||||||
"lar.old",
|
"lar.old",
|
||||||
"acd",
|
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
static spot::synthesis_info::algo const algo_types[] =
|
static spot::synthesis_info::algo const algo_types[] =
|
||||||
|
|
@ -205,24 +173,9 @@ static spot::synthesis_info::algo const algo_types[] =
|
||||||
spot::synthesis_info::algo::DPA_SPLIT, spot::synthesis_info::algo::DPA_SPLIT,
|
spot::synthesis_info::algo::DPA_SPLIT, spot::synthesis_info::algo::DPA_SPLIT,
|
||||||
spot::synthesis_info::algo::LAR,
|
spot::synthesis_info::algo::LAR,
|
||||||
spot::synthesis_info::algo::LAR_OLD,
|
spot::synthesis_info::algo::LAR_OLD,
|
||||||
spot::synthesis_info::algo::ACD,
|
|
||||||
};
|
};
|
||||||
ARGMATCH_VERIFY(algo_args, algo_types);
|
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[] =
|
static const char* const decompose_args[] =
|
||||||
{
|
{
|
||||||
"yes", "true", "enabled", "1",
|
"yes", "true", "enabled", "1",
|
||||||
|
|
@ -268,22 +221,7 @@ namespace
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_print_hoa(const spot::const_twa_graph_ptr& game)
|
print_csv(const spot::formula& f)
|
||||||
{
|
|
||||||
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& vs = gi->verbose_stream;
|
||||||
auto& bv = gi->bv;
|
auto& bv = gi->bv;
|
||||||
|
|
@ -292,9 +230,7 @@ namespace
|
||||||
if (vs)
|
if (vs)
|
||||||
*vs << "writing CSV to " << opt_csv << '\n';
|
*vs << "writing CSV to " << opt_csv << '\n';
|
||||||
|
|
||||||
static bool not_first_time = false;
|
output_file outf(opt_csv);
|
||||||
output_file outf(opt_csv, not_first_time);
|
|
||||||
not_first_time = true; // force append on next print.
|
|
||||||
std::ostream& out = outf.ostream();
|
std::ostream& out = outf.ostream();
|
||||||
|
|
||||||
// Do not output the header line if we append to a file.
|
// Do not output the header line if we append to a file.
|
||||||
|
|
@ -319,15 +255,10 @@ namespace
|
||||||
out << '\n';
|
out << '\n';
|
||||||
}
|
}
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
if (filename)
|
|
||||||
os << filename;
|
|
||||||
else
|
|
||||||
os << f;
|
os << f;
|
||||||
spot::escape_rfc4180(out << '"', os.str()) << "\",";
|
spot::escape_rfc4180(out << '"', os.str());
|
||||||
// if a filename was given, assume the game has been read directly
|
out << "\",\"" << algo_names[(int) gi->s]
|
||||||
if (!filename)
|
<< "\"," << bv->total_time
|
||||||
out << '"' << algo_names[(int) gi->s] << '"';
|
|
||||||
out << ',' << bv->total_time
|
|
||||||
<< ',' << bv->trans_time
|
<< ',' << bv->trans_time
|
||||||
<< ',' << bv->split_time
|
<< ',' << bv->split_time
|
||||||
<< ',' << bv->paritize_time;
|
<< ',' << bv->paritize_time;
|
||||||
|
|
@ -354,13 +285,11 @@ namespace
|
||||||
outf.close(opt_csv);
|
outf.close(opt_csv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
solve_formula(const spot::formula& f,
|
solve_formula(const spot::formula& f,
|
||||||
const std::vector<std::string>& input_aps,
|
const std::vector<std::string>& input_aps,
|
||||||
const std::vector<std::string>& output_aps)
|
const std::vector<std::string>& output_aps)
|
||||||
{
|
{
|
||||||
if (opt_csv) // reset benchmark data
|
|
||||||
gi->bv = spot::synthesis_info::bench_var();
|
|
||||||
spot::stopwatch sw;
|
spot::stopwatch sw;
|
||||||
if (gi->bv)
|
if (gi->bv)
|
||||||
sw.start();
|
sw.start();
|
||||||
|
|
@ -376,12 +305,6 @@ namespace
|
||||||
if (opt_decompose_ltl)
|
if (opt_decompose_ltl)
|
||||||
{
|
{
|
||||||
auto subs = split_independant_formulas(f, output_aps);
|
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)
|
if (subs.first.size() > 1)
|
||||||
{
|
{
|
||||||
sub_form = subs.first;
|
sub_form = subs.first;
|
||||||
|
|
@ -424,6 +347,17 @@ namespace
|
||||||
auto sub_o = sub_outs_str.begin();
|
auto sub_o = sub_outs_str.begin();
|
||||||
std::vector<spot::mealy_like> mealy_machines;
|
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)
|
for (; sub_f != sub_form.end(); ++sub_f, ++sub_o)
|
||||||
{
|
{
|
||||||
spot::mealy_like m_like
|
spot::mealy_like m_like
|
||||||
|
|
@ -434,15 +368,14 @@ namespace
|
||||||
};
|
};
|
||||||
// If we want to print a game,
|
// If we want to print a game,
|
||||||
// we never use the direct approach
|
// we never use the direct approach
|
||||||
if (!want_game && opt_bypass)
|
if (!want_game)
|
||||||
m_like =
|
m_like =
|
||||||
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi, !opt_real);
|
spot::try_create_direct_strategy(*sub_f, *sub_o, *gi);
|
||||||
|
|
||||||
switch (m_like.success)
|
switch (m_like.success)
|
||||||
{
|
{
|
||||||
case spot::mealy_like::realizability_code::UNREALIZABLE:
|
case spot::mealy_like::realizability_code::UNREALIZABLE:
|
||||||
{
|
{
|
||||||
if (show_status)
|
|
||||||
std::cout << "UNREALIZABLE" << std::endl;
|
std::cout << "UNREALIZABLE" << std::endl;
|
||||||
safe_tot_time();
|
safe_tot_time();
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -461,20 +394,13 @@ namespace
|
||||||
assert((spptr->at(arena->get_init_state_number()) == false)
|
assert((spptr->at(arena->get_init_state_number()) == false)
|
||||||
&& "Env needs first turn");
|
&& "Env needs first turn");
|
||||||
}
|
}
|
||||||
if (want_game)
|
print_game(arena);
|
||||||
{
|
|
||||||
dispatch_print_hoa(arena);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!spot::solve_game(arena, *gi))
|
if (!spot::solve_game(arena, *gi))
|
||||||
{
|
{
|
||||||
if (show_status)
|
|
||||||
std::cout << "UNREALIZABLE" << std::endl;
|
std::cout << "UNREALIZABLE" << std::endl;
|
||||||
safe_tot_time();
|
safe_tot_time();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (gi->bv)
|
|
||||||
gi->bv->realizable = true;
|
|
||||||
// Create the (partial) strategy
|
// Create the (partial) strategy
|
||||||
// only if we need it
|
// only if we need it
|
||||||
if (!opt_real)
|
if (!opt_real)
|
||||||
|
|
@ -482,13 +408,14 @@ namespace
|
||||||
spot::mealy_like ml;
|
spot::mealy_like ml;
|
||||||
ml.success =
|
ml.success =
|
||||||
spot::mealy_like::realizability_code::REALIZABLE_REGULAR;
|
spot::mealy_like::realizability_code::REALIZABLE_REGULAR;
|
||||||
// By default this produces a split machine
|
if (opt_print_aiger)
|
||||||
|
// we do not care about the type,
|
||||||
|
// machine to aiger can handle it
|
||||||
ml.mealy_like =
|
ml.mealy_like =
|
||||||
spot::solved_game_to_mealy(arena, *gi);
|
spot::solved_game_to_mealy(arena, *gi);
|
||||||
// Keep the machine split for aiger
|
else
|
||||||
// else -> separated
|
ml.mealy_like =
|
||||||
spot::simplify_mealy_here(ml.mealy_like, *gi,
|
spot::solved_game_to_separated_mealy(arena, *gi);
|
||||||
opt_print_aiger);
|
|
||||||
ml.glob_cond = bddfalse;
|
ml.glob_cond = bddfalse;
|
||||||
mealy_machines.push_back(ml);
|
mealy_machines.push_back(ml);
|
||||||
}
|
}
|
||||||
|
|
@ -499,14 +426,54 @@ namespace
|
||||||
// the direct approach yielded a strategy
|
// the direct approach yielded a strategy
|
||||||
// which can now be minimized
|
// which can now be minimized
|
||||||
// We minimize only if we need it
|
// We minimize only if we need it
|
||||||
assert(opt_real ||
|
assert(m_like.mealy_like && "Expected success but found no mealy!");
|
||||||
(m_like.mealy_like && "Expected success but found no mealy!"));
|
|
||||||
if (!opt_real)
|
if (!opt_real)
|
||||||
{
|
{
|
||||||
// Keep the machine split for aiger
|
spot::stopwatch sw_direct;
|
||||||
// else -> separated
|
sw_direct.start();
|
||||||
spot::simplify_mealy_here(m_like.mealy_like, *gi,
|
|
||||||
opt_print_aiger);
|
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";
|
||||||
}
|
}
|
||||||
SPOT_FALLTHROUGH;
|
SPOT_FALLTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
@ -527,7 +494,6 @@ namespace
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_status)
|
|
||||||
std::cout << "REALIZABLE" << std::endl;
|
std::cout << "REALIZABLE" << std::endl;
|
||||||
if (opt_real)
|
if (opt_real)
|
||||||
{
|
{
|
||||||
|
|
@ -537,8 +503,8 @@ namespace
|
||||||
// If we reach this line
|
// If we reach this line
|
||||||
// a strategy was found for each subformula
|
// a strategy was found for each subformula
|
||||||
assert(mealy_machines.size() == sub_form.size()
|
assert(mealy_machines.size() == sub_form.size()
|
||||||
&& ("There are subformula for which no mealy like object"
|
&& "There are subformula for which no mealy like object"
|
||||||
" has been created."));
|
"has been created.");
|
||||||
|
|
||||||
spot::aig_ptr saig = nullptr;
|
spot::aig_ptr saig = nullptr;
|
||||||
spot::twa_graph_ptr tot_strat = nullptr;
|
spot::twa_graph_ptr tot_strat = nullptr;
|
||||||
|
|
@ -567,9 +533,6 @@ namespace
|
||||||
<< " latches and "
|
<< " latches and "
|
||||||
<< saig->num_gates() << " gates\n";
|
<< saig->num_gates() << " gates\n";
|
||||||
}
|
}
|
||||||
if (opt_dot)
|
|
||||||
spot::print_dot(std::cout, saig, opt_dot_arg);
|
|
||||||
else
|
|
||||||
spot::print_aiger(std::cout, saig) << '\n';
|
spot::print_aiger(std::cout, saig) << '\n';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -582,8 +545,7 @@ namespace
|
||||||
&& "ltlsynt: Cannot handle TGBA as strategy.");
|
&& "ltlsynt: Cannot handle TGBA as strategy.");
|
||||||
tot_strat = mealy_machines.front().mealy_like;
|
tot_strat = mealy_machines.front().mealy_like;
|
||||||
for (size_t i = 1; i < mealy_machines.size(); ++i)
|
for (size_t i = 1; i < mealy_machines.size(); ++i)
|
||||||
tot_strat = spot::mealy_product(tot_strat,
|
tot_strat = spot::product(tot_strat, mealy_machines[i].mealy_like);
|
||||||
mealy_machines[i].mealy_like);
|
|
||||||
printer.print(tot_strat, timer_printer_dummy);
|
printer.print(tot_strat, timer_printer_dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -621,27 +583,15 @@ namespace
|
||||||
return 0;
|
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
|
class ltl_processor final : public job_processor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::optional<std::vector<std::string>> input_aps_;
|
std::vector<std::string> input_aps_;
|
||||||
std::optional<std::vector<std::string>> output_aps_;
|
std::vector<std::string> output_aps_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ltl_processor(std::optional<std::vector<std::string>> input_aps_,
|
ltl_processor(std::vector<std::string> input_aps_,
|
||||||
std::optional<std::vector<std::string>> output_aps_)
|
std::vector<std::string> output_aps_)
|
||||||
: input_aps_(std::move(input_aps_)),
|
: input_aps_(std::move(input_aps_)),
|
||||||
output_aps_(std::move(output_aps_))
|
output_aps_(std::move(output_aps_))
|
||||||
{
|
{
|
||||||
|
|
@ -651,13 +601,11 @@ namespace
|
||||||
const char* filename, int linenum) override
|
const char* filename, int linenum) override
|
||||||
{
|
{
|
||||||
auto unknown_aps = [](spot::formula f,
|
auto unknown_aps = [](spot::formula f,
|
||||||
const std::optional<std::vector<std::string>>& known,
|
const std::vector<std::string>& known,
|
||||||
const std::optional<std::vector<std::string>>& known2 = {})
|
const std::vector<std::string>* known2 = nullptr)
|
||||||
{
|
{
|
||||||
std::vector<std::string> unknown;
|
std::vector<std::string> unknown;
|
||||||
std::set<spot::formula> seen;
|
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)
|
f.traverse([&](const spot::formula& s)
|
||||||
{
|
{
|
||||||
if (s.is(spot::op::ap))
|
if (s.is(spot::op::ap))
|
||||||
|
|
@ -665,11 +613,10 @@ namespace
|
||||||
if (!seen.insert(s).second)
|
if (!seen.insert(s).second)
|
||||||
return false;
|
return false;
|
||||||
const std::string& a = s.ap_name();
|
const std::string& a = s.ap_name();
|
||||||
if (!can_have_ap
|
if (std::find(known.begin(), known.end(), a) == known.end()
|
||||||
|| (std::find(known->begin(), known->end(), a) == known->end()
|
&& (!known2
|
||||||
&& (!known2.has_value()
|
|
||||||
|| std::find(known2->begin(),
|
|| std::find(known2->begin(),
|
||||||
known2->end(), a) == known2->end())))
|
known2->end(), a) == known2->end()))
|
||||||
unknown.push_back(a);
|
unknown.push_back(a);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -679,233 +626,36 @@ namespace
|
||||||
|
|
||||||
// Decide which atomic propositions are input or output.
|
// Decide which atomic propositions are input or output.
|
||||||
int res;
|
int res;
|
||||||
if (!input_aps_.has_value() && output_aps_.has_value())
|
if (input_aps_.empty() && !output_aps_.empty())
|
||||||
{
|
{
|
||||||
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_.has_value() && input_aps_.has_value())
|
else if (output_aps_.empty() && !input_aps_.empty())
|
||||||
{
|
{
|
||||||
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_.has_value() && !input_aps_.has_value())
|
else if (output_aps_.empty() && input_aps_.empty())
|
||||||
{
|
{
|
||||||
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,
|
error_at_line(2, 0, filename, linenum,
|
||||||
"one of --ins or --outs should list '%s'",
|
"one of --ins or --outs should list '%s'",
|
||||||
ap.c_str());
|
ap.c_str());
|
||||||
res = solve_formula(f, *input_aps_, *output_aps_);
|
res = solve_formula(f, input_aps_, output_aps_);
|
||||||
}
|
}
|
||||||
else
|
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,
|
error_at_line(2, 0, filename, linenum,
|
||||||
"both --ins and --outs are specified, "
|
"both --ins and --outs are specified, "
|
||||||
"but '%s' is unlisted",
|
"but '%s' is unlisted",
|
||||||
ap.c_str());
|
ap.c_str());
|
||||||
res = solve_formula(f, *input_aps_, *output_aps_);
|
res = solve_formula(f, input_aps_, output_aps_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_csv)
|
if (opt_csv)
|
||||||
print_csv(f);
|
print_csv(f);
|
||||||
return res;
|
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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -919,37 +669,35 @@ parse_opt(int key, char *arg, struct argp_state *)
|
||||||
case OPT_ALGO:
|
case OPT_ALGO:
|
||||||
gi->s = XARGMATCH("--algo", arg, algo_args, algo_types);
|
gi->s = XARGMATCH("--algo", arg, algo_args, algo_types);
|
||||||
break;
|
break;
|
||||||
case OPT_BYPASS:
|
|
||||||
opt_bypass = XARGMATCH("--bypass", arg, bypass_args, bypass_values);
|
|
||||||
break;
|
|
||||||
case OPT_CSV:
|
case OPT_CSV:
|
||||||
opt_csv = arg ? arg : "-";
|
opt_csv = arg ? arg : "-";
|
||||||
|
if (not gi->bv)
|
||||||
|
gi->bv = spot::synthesis_info::bench_var();
|
||||||
break;
|
break;
|
||||||
case OPT_DECOMPOSE:
|
case OPT_DECOMPOSE:
|
||||||
opt_decompose_ltl = XARGMATCH("--decompose", arg,
|
opt_decompose_ltl = XARGMATCH("--decompose", arg,
|
||||||
decompose_args, decompose_values);
|
decompose_args, decompose_values);
|
||||||
break;
|
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:
|
case OPT_INPUT:
|
||||||
{
|
{
|
||||||
all_input_aps.emplace(std::vector<std::string>{});
|
std::istringstream aps(arg);
|
||||||
split_aps(arg, *all_input_aps);
|
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));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_OUTPUT:
|
case OPT_OUTPUT:
|
||||||
{
|
{
|
||||||
all_output_aps.emplace(std::vector<std::string>{});
|
std::istringstream aps(arg);
|
||||||
split_aps(arg, *all_output_aps);
|
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));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPT_PRINT:
|
case OPT_PRINT:
|
||||||
|
|
@ -970,9 +718,6 @@ parse_opt(int key, char *arg, struct argp_state *)
|
||||||
gi->minimize_lvl = XARGMATCH("--simplify", arg,
|
gi->minimize_lvl = XARGMATCH("--simplify", arg,
|
||||||
simplify_args, simplify_values);
|
simplify_args, simplify_values);
|
||||||
break;
|
break;
|
||||||
case OPT_TLSF:
|
|
||||||
jobs.emplace_back(arg, job_type::TLSF_FILENAME);
|
|
||||||
break;
|
|
||||||
case OPT_VERBOSE:
|
case OPT_VERBOSE:
|
||||||
gi->verbose_stream = &std::cerr;
|
gi->verbose_stream = &std::cerr;
|
||||||
if (not gi->bv)
|
if (not gi->bv)
|
||||||
|
|
@ -1009,14 +754,12 @@ main(int argc, char **argv)
|
||||||
argp_program_doc, children, nullptr, nullptr };
|
argp_program_doc, children, nullptr, nullptr };
|
||||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
|
||||||
exit(err);
|
exit(err);
|
||||||
|
|
||||||
check_no_formula();
|
check_no_formula();
|
||||||
|
|
||||||
// Check if inputs and outputs are distinct
|
// Check if inputs and outputs are distinct
|
||||||
if (all_input_aps.has_value() && all_output_aps.has_value())
|
for (const std::string& ai : all_input_aps)
|
||||||
for (const std::string& ai : *all_input_aps)
|
if (std::find(all_output_aps.begin(), all_output_aps.end(), ai)
|
||||||
if (std::find(all_output_aps->begin(), all_output_aps->end(), ai)
|
!= all_output_aps.end())
|
||||||
!= all_output_aps->end())
|
|
||||||
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
|
error(2, 0, "'%s' appears both in --ins and --outs", ai.c_str());
|
||||||
|
|
||||||
ltl_processor processor(all_input_aps, all_output_aps);
|
ltl_processor processor(all_input_aps, all_output_aps);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2016, 2018-2020, 2022 Laboratoire de Recherche
|
// Copyright (C) 2012-2016, 2018-2020 Laboratoire de Recherche et
|
||||||
// et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
#include <spot/twaalgos/canonicalize.hh>
|
#include <spot/twaalgos/canonicalize.hh>
|
||||||
|
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] = "\
|
||||||
Generate random connected automata.\n\n\
|
Generate random connected automata.\n\n\
|
||||||
The automata are built over the atomic propositions named by PROPS...\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\
|
or, if N is a nonnegative number, using N arbitrary names.\n\
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2016, 2018-2019, 2022, 2023 Laboratoire de
|
// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// et Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
#include <spot/misc/random.hh>
|
#include <spot/misc/random.hh>
|
||||||
#include <spot/misc/optionmap.hh>
|
#include <spot/misc/optionmap.hh>
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Generate random temporal logic formulas.\n\n\
|
Generate random temporal logic formulas.\n\n\
|
||||||
The formulas are built over the atomic propositions named by PROPS...\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\
|
or, if N is a nonnegative number, using N arbitrary names.\v\
|
||||||
|
|
@ -65,6 +65,7 @@ enum {
|
||||||
OPT_DUMP_PRIORITIES,
|
OPT_DUMP_PRIORITIES,
|
||||||
OPT_DUPS,
|
OPT_DUPS,
|
||||||
OPT_LTL_PRIORITIES,
|
OPT_LTL_PRIORITIES,
|
||||||
|
OPT_PSL_PRIORITIES,
|
||||||
OPT_SEED,
|
OPT_SEED,
|
||||||
OPT_SERE_PRIORITIES,
|
OPT_SERE_PRIORITIES,
|
||||||
OPT_TREE_SIZE,
|
OPT_TREE_SIZE,
|
||||||
|
|
@ -193,6 +194,7 @@ parse_opt(int key, char* arg, struct argp_state* as)
|
||||||
case OPT_DUMP_PRIORITIES:
|
case OPT_DUMP_PRIORITIES:
|
||||||
opt_dump_priorities = true;
|
opt_dump_priorities = true;
|
||||||
break;
|
break;
|
||||||
|
// case OPT_PSL_PRIORITIES: break;
|
||||||
case OPT_SERE_PRIORITIES:
|
case OPT_SERE_PRIORITIES:
|
||||||
opt_pS = arg;
|
opt_pS = arg;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
|
|
||||||
static const char argp_program_doc[] = "\
|
const char argp_program_doc[] ="\
|
||||||
Common fine-tuning options for programs installed with Spot.\n\
|
Common fine-tuning options for programs installed with Spot.\n\
|
||||||
\n\
|
\n\
|
||||||
The argument of -x or --extra-options is a comma-separated list of KEY=INT \
|
The argument of -x or --extra-options is a comma-separated list of KEY=INT \
|
||||||
|
|
@ -47,17 +47,9 @@ depends on the --low, --medium, or --high settings.") },
|
||||||
{ DOC("tls-max-states",
|
{ DOC("tls-max-states",
|
||||||
"Maximum number of states of automata involved in automata-based \
|
"Maximum number of states of automata involved in automata-based \
|
||||||
implication checks for formula simplifications. Defaults to 64.") },
|
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 },
|
{ nullptr, 0, nullptr, 0, "Translation options:", 0 },
|
||||||
{ DOC("ltl-split", "Set to 0 to disable the translation of automata \
|
{ DOC("ltl-split", "Set to 0 to disable the translation of automata \
|
||||||
as product or sum of subformulas.") },
|
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, \
|
{ DOC("comp-susp", "Set to 1 to enable compositional suspension, \
|
||||||
as described in our SPIN'13 paper (see Bibliography below). Set to 2, \
|
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 \
|
to build only the skeleton TGBA without composing it. Set to 0 (the \
|
||||||
|
|
@ -83,9 +75,6 @@ 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 \
|
used when comp-susp=1 and default to 1 or 2 depending on whether --small \
|
||||||
or --deterministic is specified.") },
|
or --deterministic is specified.") },
|
||||||
{ nullptr, 0, nullptr, 0, "Postprocessing options:", 0 },
|
{ 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 \
|
{ DOC("scc-filter", "Set to 1 (the default) to enable \
|
||||||
SCC-pruning and acceptance simplification at the beginning of \
|
SCC-pruning and acceptance simplification at the beginning of \
|
||||||
post-processing. Transitions that are outside of accepting SCC are \
|
post-processing. Transitions that are outside of accepting SCC are \
|
||||||
|
|
@ -175,10 +164,6 @@ 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. \
|
simulation. Set to 3 to iterate both direct and reverse simulations. \
|
||||||
The default is the value of parameter \"simul\" in --high mode, and 0 \
|
The default is the value of parameter \"simul\" in --high mode, and 0 \
|
||||||
therwise.") },
|
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 \
|
{ DOC("simul-max", "Number of states above which simulation-based \
|
||||||
reductions are skipped. Defaults to 4096. Set to 0 to disable. This \
|
reductions are skipped. Defaults to 4096. Set to 0 to disable. This \
|
||||||
applies to all simulation-based optimization, including thoses of the \
|
applies to all simulation-based optimization, including thoses of the \
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2018, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2013-2018 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -24,8 +24,7 @@
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
#include "common_setup.hh"
|
#include "common_setup.hh"
|
||||||
|
|
||||||
static const char argp_program_doc[] =
|
const char argp_program_doc[] ="Command-line tools installed by Spot.";
|
||||||
"Command-line tools installed by Spot.";
|
|
||||||
|
|
||||||
#define DOC(NAME, TXT) NAME, 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, TXT, 0
|
#define DOC(NAME, TXT) NAME, 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, TXT, 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,6 @@ BUDDY_API_VAR const BDD bddtrue;
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
#ifdef CPLUSPLUS
|
#ifdef CPLUSPLUS
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
/*=== User BDD class ===================================================*/
|
/*=== User BDD class ===================================================*/
|
||||||
|
|
||||||
|
|
@ -1093,11 +1092,6 @@ inline bddxfalse bdd_false(void)
|
||||||
{ return bddxfalse(); }
|
{ return bddxfalse(); }
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct std::default_delete<bddPair> {
|
|
||||||
void operator()(bddPair *p) const { bdd_freepair(p); };
|
|
||||||
};
|
|
||||||
|
|
||||||
/*=== Iostream printing ================================================*/
|
/*=== Iostream printing ================================================*/
|
||||||
|
|
||||||
class BUDDY_API bdd_ioformat
|
class BUDDY_API bdd_ioformat
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ static BddTree *reorder_win2ite(BddTree *t)
|
||||||
{
|
{
|
||||||
BddTree *this, *first=t;
|
BddTree *this, *first=t;
|
||||||
int lastsize;
|
int lastsize;
|
||||||
|
int c=1;
|
||||||
|
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return t;
|
return t;
|
||||||
|
|
@ -245,6 +246,7 @@ static BddTree *reorder_win2ite(BddTree *t)
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf(" %d nodes\n", reorder_nodenum());
|
printf(" %d nodes\n", reorder_nodenum());
|
||||||
|
c++;
|
||||||
}
|
}
|
||||||
while (reorder_nodenum() != lastsize);
|
while (reorder_nodenum() != lastsize);
|
||||||
|
|
||||||
|
|
|
||||||
43
configure.ac
43
configure.ac
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2008-2023, Laboratoire de Recherche et Développement
|
# Copyright (C) 2008-2022, Laboratoire de Recherche et Développement
|
||||||
# de l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
# Copyright (C) 2003-2007 Laboratoire d'Informatique de Paris 6
|
# Copyright (C) 2003-2007 Laboratoire d'Informatique de Paris 6
|
||||||
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
# (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/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
AC_INIT([spot], [2.11.5.dev], [spot@lrde.epita.fr])
|
AC_INIT([spot], [2.10.4.dev], [spot@lrde.epita.fr])
|
||||||
AC_CONFIG_AUX_DIR([tools])
|
AC_CONFIG_AUX_DIR([tools])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests])
|
AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests])
|
||||||
|
|
@ -53,15 +53,6 @@ AC_ARG_ENABLE([c++20],
|
||||||
[Compile in C++20 mode.])],
|
[Compile in C++20 mode.])],
|
||||||
[enable_20=$enableval], [enable_20=no])
|
[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],
|
AC_ARG_ENABLE([doxygen],
|
||||||
[AS_HELP_STRING([--enable-doxygen],
|
[AS_HELP_STRING([--enable-doxygen],
|
||||||
[enable generation of Doxygen documentation (requires Doxygen)])],
|
[enable generation of Doxygen documentation (requires Doxygen)])],
|
||||||
|
|
@ -79,7 +70,6 @@ if test 0 -eq `expr $enable_max_accsets % $default_max_accsets`
|
||||||
then
|
then
|
||||||
AC_DEFINE_UNQUOTED([MAX_ACCSETS], [$enable_max_accsets],
|
AC_DEFINE_UNQUOTED([MAX_ACCSETS], [$enable_max_accsets],
|
||||||
[The maximal number of acceptance sets supported (also known as acceptance marks)])
|
[The maximal number of acceptance sets supported (also known as acceptance marks)])
|
||||||
AC_SUBST([MAX_ACCSETS], [$enable_max_accsets])
|
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([The argument of --enable-max-accsets must be a multiple of $default_max_accsets])
|
AC_MSG_ERROR([The argument of --enable-max-accsets must be a multiple of $default_max_accsets])
|
||||||
fi
|
fi
|
||||||
|
|
@ -160,7 +150,7 @@ AX_CHECK_BUDDY
|
||||||
AC_CHECK_FUNCS([times kill alarm sigaction sched_getcpu])
|
AC_CHECK_FUNCS([times kill alarm sigaction sched_getcpu])
|
||||||
|
|
||||||
oLIBS=$LIBS
|
oLIBS=$LIBS
|
||||||
LIBS="$LIBS -pthread"
|
LIBS="$LIBS -lpthread"
|
||||||
AC_CHECK_FUNCS([pthread_setaffinity_np])
|
AC_CHECK_FUNCS([pthread_setaffinity_np])
|
||||||
LIBS=$oLIBS
|
LIBS=$oLIBS
|
||||||
|
|
||||||
|
|
@ -189,14 +179,9 @@ if test "x${enable_python:-yes}" = xyes; then
|
||||||
AC_MSG_NOTICE([You may configure with --disable-python ]dnl
|
AC_MSG_NOTICE([You may configure with --disable-python ]dnl
|
||||||
[if you do not need Python bindings.])
|
[if you do not need Python bindings.])
|
||||||
adl_CHECK_PYTHON
|
adl_CHECK_PYTHON
|
||||||
|
|
||||||
AC_ARG_WITH([pythondir],
|
|
||||||
[AS_HELP_STRING([--with-pythondir], [override the computed pythondir])],
|
|
||||||
[pythondir=$withval pyexecdir=$withval], [])
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
adl_ENABLE_DEBUG
|
adl_ENABLE_DEBUG
|
||||||
ad_GCC_OPTIM
|
ad_GCC_OPTIM
|
||||||
adl_NDEBUG
|
adl_NDEBUG
|
||||||
|
|
@ -217,7 +202,7 @@ AC_CHECK_PROG([LTL3BA], [ltl3ba], [ltl3ba])
|
||||||
AC_CHECK_PROG([PERL], [perl], [perl])
|
AC_CHECK_PROG([PERL], [perl], [perl])
|
||||||
AC_CHECK_PROG([SPIN], [spin], [spin])
|
AC_CHECK_PROG([SPIN], [spin], [spin])
|
||||||
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
|
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
|
||||||
AM_MISSING_PROG([EMACS], [emacs])
|
AC_CHECK_PROG([EMACS], [emacs], [emacs])
|
||||||
AC_CHECK_PROGS([IPYTHON], [ipython3 ipython], [ipython])
|
AC_CHECK_PROGS([IPYTHON], [ipython3 ipython], [ipython])
|
||||||
AC_CHECK_PROGS([JUPYTER], [jupyter], [jupyter])
|
AC_CHECK_PROGS([JUPYTER], [jupyter], [jupyter])
|
||||||
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
|
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
|
||||||
|
|
@ -295,23 +280,3 @@ case $VERSION:$enable_devel in
|
||||||
echo '==================================================================='
|
echo '==================================================================='
|
||||||
;;
|
;;
|
||||||
esac
|
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
|
Section: science
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
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, graphviz, jupyter-nbconvert, doxygen
|
Build-Depends: debhelper (>= 12), python3-all-dev, ipython3-notebook | python3-ipykernel, ipython3-notebook | python3-nbconvert, libltdl-dev, dh-python
|
||||||
Standards-Version: 4.5.1
|
Standards-Version: 4.5.1
|
||||||
Homepage: http://spot.lrde.epita.fr/
|
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/
|
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Upstream-Name: spot
|
Upstream-Name: spot
|
||||||
Source: http://www.lrde.epita.fr/dload/spot/
|
Source: http://spot.lrde.epita.fr/dload/spot/
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2003-2007 Laboratoire d'Informatique de Paris 6 (LIP6)
|
Copyright: 2003-2007 Laboratoire d'Informatique de Paris 6 (LIP6)
|
||||||
|
|
|
||||||
18
debian/rules
vendored
18
debian/rules
vendored
|
|
@ -20,16 +20,20 @@ include /usr/share/dpkg/default.mk
|
||||||
%:
|
%:
|
||||||
dh $@ --with=python3
|
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
|
# ARFLAGS is for Automake
|
||||||
# AR_FLAGS is for Libtool, (but libtool 2.4.7 will now use ARFLAGS as well)
|
# AR_FLAGS is for Libtool
|
||||||
# The gcc-tools activate the LTO plugin.
|
# These activate the LTO pluggin, but also remove the 'u' option
|
||||||
|
# from ar, since its now ignored with Debian's default to 'D'.
|
||||||
LTOSETUP = \
|
LTOSETUP = \
|
||||||
LDFLAGS='-fuse-linker-plugin' \
|
LDFLAGS='-fuse-linker-plugin' \
|
||||||
NM='gcc-nm' \
|
NM='nm --plugin $(LTOPLUG)' \
|
||||||
AR='gcc-ar' \
|
ARFLAGS='cr --plugin $(LTOPLUG)' \
|
||||||
ARFLAGS='cr' \
|
AR_FLAGS='cr --plugin $(LTOPLUG)' \
|
||||||
AR_FLAGS='cr' \
|
RANLIB='ranlib --plugin $(LTOPLUG)' \
|
||||||
RANLIB='gcc-ranlib' \
|
|
||||||
VALGRIND=false
|
VALGRIND=false
|
||||||
GCDADIR := $(shell pwd)/gcda
|
GCDADIR := $(shell pwd)/gcda
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
# -*- 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,9 +27,6 @@
|
||||||
(setenv "SPOT_DOTEXTRA" "node[fontsize=12] fontsize=12 stylesheet=\"spot.css\" edge[arrowhead=vee, arrowsize=.7, fontsize=12]")
|
(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")
|
(setq org-babel-temporary-directory "@abs_top_builddir@/doc/org/tmp")
|
||||||
(make-directory org-babel-temporary-directory t)
|
(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
|
(org-babel-do-load-languages 'org-babel-load-languages
|
||||||
`((,(if (version< org-version "8.3") 'sh 'shell) . t)
|
`((,(if (version< org-version "8.3") 'sh 'shell) . t)
|
||||||
(python . t)
|
(python . t)
|
||||||
|
|
@ -42,6 +39,7 @@
|
||||||
(org-babel-python-command . "@PYTHON@")
|
(org-babel-python-command . "@PYTHON@")
|
||||||
(org-babel-C++-compiler . "./g++wrap")
|
(org-babel-C++-compiler . "./g++wrap")
|
||||||
(shell-file-name . "@SHELL@")
|
(shell-file-name . "@SHELL@")
|
||||||
|
(ess-ask-for-ess-directory . nil)
|
||||||
(org-export-html-postamble . nil)
|
(org-export-html-postamble . nil)
|
||||||
(org-html-table-header-tags
|
(org-html-table-header-tags
|
||||||
"<th scope=\"%s\"%s><div><span>" . "</span></div></th>")
|
"<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 | 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 |
|
| -: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 |
|
||||||
|
|
||||||
* Transformation that preserve or complement languages
|
* Language preserving transformation
|
||||||
|
|
||||||
By default =autcross= assumes that for a given input the automata
|
By default =autcross= assumes that for a given input the automata
|
||||||
produced by all tools should be equivalent. However it does not
|
produced by all tools should be equivalent. However it does not
|
||||||
|
|
@ -261,13 +261,6 @@ 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
|
=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.
|
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
|
* Detecting problems
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: checks
|
:CUSTOM_ID: checks
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,7 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
||||||
(iw) inherently weak. Use uppercase letters to
|
(iw) inherently weak. Use uppercase letters to
|
||||||
negate them.
|
negate them.
|
||||||
%d 1 if the output is deterministic, 0 otherwise
|
%d 1 if the output is deterministic, 0 otherwise
|
||||||
%e, %[LETTER]e number of edges (add one LETTER to select (r)
|
%e number of reachable edges
|
||||||
reachable [default], (u) unreachable, (a) all).
|
|
||||||
%f the formula, in Spot's syntax
|
%f the formula, in Spot's syntax
|
||||||
%F name of the input file
|
%F name of the input file
|
||||||
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
|
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
|
||||||
|
|
@ -171,11 +170,8 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
||||||
LETTERS to restrict to(u) user time, (s) system
|
LETTERS to restrict to(u) user time, (s) system
|
||||||
time, (p) parent process, or (c) children
|
time, (p) parent process, or (c) children
|
||||||
processes.
|
processes.
|
||||||
%s, %[LETTER]s number of states (add one LETTER to select (r)
|
%s number of reachable states
|
||||||
reachable [default], (u) unreachable, (a) all).
|
%t number of reachable transitions
|
||||||
%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
|
%u, %[e]u number of states (or [e]dges) with universal
|
||||||
branching
|
branching
|
||||||
%u, %[LETTER]u 1 if the automaton contains some universal
|
%u, %[LETTER]u 1 if the automaton contains some universal
|
||||||
|
|
|
||||||
|
|
@ -6,22 +6,18 @@
|
||||||
|
|
||||||
* Generic reference
|
* Generic reference
|
||||||
|
|
||||||
If you need to cite the Spot project, the latest tool paper about
|
If you need to cite the Spot project in some academic paper, please
|
||||||
it is the following reference:
|
use the following reference:
|
||||||
|
|
||||||
- *From Spot 2.0 to Spot 2.10: What's new?*, /Alexandre Duret-Lutz/,
|
- *Spot 2.0 — a framework for LTL and ω-automata manipulation*,
|
||||||
/Etienne Renault/, /Maximilien Colange/, /Florian Renkin/,
|
/Alexandre Duret-Lutz/, /Alexandre Lewkowicz/, /Amaury Fauchille/,
|
||||||
/Alexandre Gbaguidi Aisse/, /Philipp Schlehuber-Caissier/, /Thomas
|
/Thibaud Michaud/, /Etienne Renault/, and /Laurent Xu/. In Proc.
|
||||||
Medioni/, /Antoine Martin/, /Jérôme Dubois/, /Clément Gillard/, and
|
of ATVA'16, LNCS 9938, pp. 122--129. Chiba, Japan, Oct. 2016.
|
||||||
Henrich Lauko/. In Proc. of CAV'22, LNCS 13372, pp. 174--187.
|
([[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]])
|
||||||
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]])
|
|
||||||
|
|
||||||
#+begin_note
|
This provides a quick overview of the entire project (the features
|
||||||
Tools evolve while published papers don't. Please always specify
|
of the library, [[file:tools.org][the tools]], the Python bindings), and provides many
|
||||||
the version of Spot (or any other tool) you are using when citing it
|
references detailing more specific aspects.
|
||||||
in a paper. Future versions might have different behaviors.
|
|
||||||
#+end_note
|
|
||||||
|
|
||||||
* Other, more specific, references
|
* Other, more specific, references
|
||||||
|
|
||||||
|
|
@ -80,28 +76,12 @@ be more specific about a particular aspect of Spot.
|
||||||
- *Generic Emptiness Check for Fun and Profit*,
|
- *Generic Emptiness Check for Fun and Profit*,
|
||||||
/Christel Baier/, /František Blahoudek/, /Alexandre Duret-Lutz/,
|
/Christel Baier/, /František Blahoudek/, /Alexandre Duret-Lutz/,
|
||||||
/Joachim Klein/, /David Müller/, and /Jan Strejček/.
|
/Joachim Klein/, /David Müller/, and /Jan Strejček/.
|
||||||
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]] |
|
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]] |
|
||||||
[[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]])
|
[[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.
|
Presents the generic emptiness-check implemented in Spot.
|
||||||
|
|
||||||
- *Practical Applications of the Alternating Cycle Decomposition*,
|
* Obsolete reference
|
||||||
/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
|
- *Spot: an extensible model checking library using transition-based
|
||||||
generalized Büchi automata*, /Alexandre Duret-Lutz/ and /Denis
|
generalized Büchi automata*, /Alexandre Duret-Lutz/ and /Denis
|
||||||
|
|
|
||||||
|
|
@ -210,14 +210,11 @@ one library requiring another, you will need to link with the =bddx=
|
||||||
library. This should be as simple as adding =-lbddx= after =-lspot=
|
library. This should be as simple as adding =-lbddx= after =-lspot=
|
||||||
in the first three cases.
|
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
|
In the fourth case where =libtool= is used to link against
|
||||||
=libspot.la= linking against =libbddx.la= should not be necessary because
|
=libspot.la= linking against =libbddx.la= should not be necessary because
|
||||||
Libtool already handles such dependencies. However the version of =libtool=
|
Libtool already handles such dependencies. However the version of =libtool=
|
||||||
distributed with Debian is patched to ignore those dependencies, so in this
|
distributed with Debian is patched to ignore those dependencies, so in this
|
||||||
case you have to list all dependencies.
|
case you 2
|
||||||
|
|
||||||
* Additional suggestions
|
* Additional suggestions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -381,14 +381,13 @@ When /transition-based acceptance/ is used, acceptance sets are now
|
||||||
sets of /edges/ (or set of /transitions/ if you prefer), and runs are
|
sets of /edges/ (or set of /transitions/ if you prefer), and runs are
|
||||||
accepting if the edges they visit satisfy the acceptance condition.
|
accepting if the edges they visit satisfy the acceptance condition.
|
||||||
|
|
||||||
Here is an example of Transition-based Büchi Automaton
|
Here is an example of Transition-based Generalized Büchi Automaton
|
||||||
(TBA).
|
(TGBA).
|
||||||
|
|
||||||
#+NAME: tgba-example1
|
#+NAME: tgba-example1
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
ltl2tgba 'GF(a & X(a U b))' -d
|
ltl2tgba 'GF(a & X(a U b))' -d
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results
|
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results
|
||||||
$txt
|
$txt
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
@ -400,13 +399,27 @@ This automaton accept all ω-words that infinitely often match the
|
||||||
pattern $a^+;b$ (that is: a positive number of letters where $a$ is
|
pattern $a^+;b$ (that is: a positive number of letters where $a$ is
|
||||||
true are followed by one letter where $b$ is true).
|
true are followed by one letter where $b$ is true).
|
||||||
|
|
||||||
Using transition-based acceptance often allows for more compact automata.
|
Using transition-based acceptance allows for more compact automata.
|
||||||
For instance the above automaton would need at least 3 states with
|
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
|
||||||
state-based acceptance:
|
state-based acceptance:
|
||||||
|
|
||||||
#+NAME: tgba-example3
|
#+NAME: tgba-example3
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
ltl2tgba 'GF(a & X(a U b))' -B -d
|
ltl2tgba 'GFa' -B -d
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results
|
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results
|
||||||
$txt
|
$txt
|
||||||
|
|
@ -1022,7 +1035,7 @@ layers.
|
||||||
dynamic libraries that [[http://fmt.cs.utwente.nl/tools/ltsmin/][LTSmin]] uses to represent state-spaces. It
|
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
|
currently supports libraries generated from Promela models using
|
||||||
SpinS or a patched version of DiVinE, but you have to install
|
SpinS or a patched version of DiVinE, but you have to install
|
||||||
those third-party tools first. See [[https://gitlab.lre.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
|
those third-party tools first. See [[https://gitlab.lrde.epita.fr/spot/spot/blob/next/tests/ltsmin/README][=tests/ltsmin/README=]]
|
||||||
for details.
|
for details.
|
||||||
- In addition to the C++17 API, we also provide Python bindings for
|
- In addition to the C++17 API, we also provide Python bindings for
|
||||||
=libspotgen=, =libspotltsmin=, =libbddx=, and most of =libspot=.
|
=libspotgen=, =libspotltsmin=, =libbddx=, and most of =libspot=.
|
||||||
|
|
@ -1034,8 +1047,8 @@ layers.
|
||||||
distributed with the rest of Spot, their source-code is publicly
|
distributed with the rest of Spot, their source-code is publicly
|
||||||
available (in case you want to contribute or run a local version).
|
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
|
The [[https://spot-sandbox.lrde.epita.fr/][=spot-sandbox=]] website runs from a Docker container whose
|
||||||
configuration can be found in [[https://gitlab.lre.epita.fr/spot/sandbox/tree/master=][this repository]]. The client and
|
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.lre.epita.fr/spot/spot-web-app/][this
|
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
|
||||||
repository]].
|
repository]].
|
||||||
|
|
||||||
* Automaton property flags
|
* Automaton property flags
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# This is a wrapper around the compiler, to ensure that the code
|
# This is a wrapper around the compiler, to ensure that the code
|
||||||
# examples run from org-mode files are all linked with Spot.
|
# example run from the org-mode file are all linked with Spot.
|
||||||
#
|
#
|
||||||
# Also we save errors to org.errors, so that we can detect issues
|
# Also we save errors to org.errors, so that we can detect issues
|
||||||
# after org-mode has exported everything. Otherwise these errors
|
# after org-mode has exported everything. Otherwise these errors
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
@top_builddir@/libtool link @CXX@ @CXXFLAGS@ @CPPFLAGS@ -Wall -Werror \
|
@top_builddir@/libtool link @CXX@ @CXXFLAGS@ @CPPFLAGS@ -Wall -Werror \
|
||||||
-I@abs_top_builddir@ -I@abs_top_srcdir@ -I@abs_top_srcdir@/buddy/src \
|
-I@abs_top_builddir@ -I@abs_top_srcdir@ -I@abs_top_srcdir@/buddy/src \
|
||||||
"$@" @abs_top_builddir@/spot/libspot.la \
|
"$@" @abs_top_builddir@/spot/libspot.la \
|
||||||
@abs_top_builddir@/buddy/src/libbddx.la @LIBSPOT_PTHREAD@ 2> errors.$$
|
@abs_top_builddir@/buddy/src/libbddx.la 2> errors.$$
|
||||||
code=$?
|
code=$?
|
||||||
if test $code -ne 0 && test -s errors.$$; then
|
if test $code -ne 0 && test -s errors.$$; then
|
||||||
cat errors.$$ >>org.errors
|
cat errors.$$ >>org.errors
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ the HOA format, the output may not be exactly the same as the input.
|
||||||
sets.
|
sets.
|
||||||
|
|
||||||
This hard-coded limit can be augmented at configure time
|
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.
|
more memory and time.
|
||||||
|
|
||||||
- Multiple (or missing) initial states are emulated.
|
- Multiple (or missing) initial states are emulated.
|
||||||
|
|
@ -76,8 +76,7 @@ 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
|
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
|
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
|
original initial states (if one of those has no incoming edge) or a
|
||||||
new state introduced for that purpose. This "conversion" may change
|
new state introduced for that purpose.
|
||||||
the completeness property of the automaton.
|
|
||||||
|
|
||||||
Similarly, when an automaton with no initial state is loaded (this
|
Similarly, when an automaton with no initial state is loaded (this
|
||||||
includes the case where the automaton has no state), a disconnected
|
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
|
weak-DBA, removal of useless SCCs, acceptance-condition
|
||||||
transformations, determinization, [[file:satmin.org][SAT-based minimization of
|
transformations, determinization, [[file:satmin.org][SAT-based minimization of
|
||||||
deterministic automata]], [[https://spot.lrde.epita.fr/ipynb/zlktree.html][Alternating Cycle Decomposition]], etc.
|
deterministic automata]], [[https://spot.lrde.epita.fr/ipynb/zlktree.html][Alternating Cycle Decomposition]], etc.
|
||||||
- Support for [[file:tut40.org][Safety]] and [[https://spot.lrde.epita.fr/ipynb/games.html][parity games]].
|
- Support for [[file:tut40.org][Safety]] and [[https://spot-dev.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]].
|
- 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
|
- 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]].
|
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
|
* Latest version
|
||||||
|
|
||||||
The latest version is *call_SPOT_VERSION()* and was released on
|
The latest version is *{{{LASTRELEASE}}}* and was released on
|
||||||
*{{{LASTDATE}}}*. Please see the [[file:install.org][download and installation instructions]].
|
*{{{LASTDATE}}}*. Please see the [[file:install.org][download and installation instructions]].
|
||||||
|
|
||||||
* Documentation
|
* Documentation
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
(package-install ess)))))
|
(package-install ess)))))
|
||||||
|
|
||||||
(require 'ox-publish)
|
(require 'ox-publish)
|
||||||
|
(require 'org-install)
|
||||||
(require 'hoa-mode)
|
(require 'hoa-mode)
|
||||||
|
|
||||||
; See https://github.com/emacs-ess/ESS/issues/1052
|
; See https://github.com/emacs-ess/ESS/issues/1052
|
||||||
|
|
@ -88,9 +89,7 @@
|
||||||
(setq org-babel-C++-compiler "./g++wrap")
|
(setq org-babel-C++-compiler "./g++wrap")
|
||||||
(setq shell-file-name "@SHELL@")
|
(setq shell-file-name "@SHELL@")
|
||||||
(setq ess-ask-for-ess-directory nil)
|
(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
|
(setq org-babel-default-header-args:plantuml
|
||||||
'((:results . "file")
|
'((:results . "file")
|
||||||
(:exports . "results")
|
(:exports . "results")
|
||||||
|
|
@ -160,7 +159,7 @@ up.html points to index.html, then the result is:
|
||||||
(setq body res)
|
(setq body res)
|
||||||
(not cmp)))
|
(not cmp)))
|
||||||
(concat "#+TITLE: " title
|
(concat "#+TITLE: " title
|
||||||
"\n#+INCLUDE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
|
"\n#+SETUPFILE: setup.org\n#+HTML_LINK_UP: index.html\n\n"
|
||||||
body)))
|
body)))
|
||||||
|
|
||||||
(setq org-publish-project-alist
|
(setq org-publish-project-alist
|
||||||
|
|
@ -185,49 +184,6 @@ up.html points to index.html, then the result is:
|
||||||
:publishing-function org-publish-attachment)
|
:publishing-function org-publish-attachment)
|
||||||
("spot-all" :components ("spot-html" "spot-static"))))
|
("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-publish-all t)
|
||||||
;;; org-babel-remove-temporary-directory does not correctly remove
|
;;; org-babel-remove-temporary-directory does not correctly remove
|
||||||
;;; nested directories and we have some files in tmp/.libs/ because of
|
;;; nested directories and we have some files in tmp/.libs/ because of
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@
|
||||||
:CUSTOM_ID: tar
|
:CUSTOM_ID: tar
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
The latest release of Spot is version call_SPOT_VERSION() and was released on {{{LASTDATE}}}:
|
The latest release of Spot is version {{{LASTRELEASE}}}:
|
||||||
|
|
||||||
- call_TARBALL_LINK() (see also the call_NEWS_LINK())
|
- {{{LASTTARBALL}}} (see also the {{{LASTNEWS}}})
|
||||||
|
|
||||||
Past releases can be found [[https://www.lrde.epita.fr/dload/spot/][in the same directory]]. If you are
|
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.lre.epita.fr/spot/spot/-/jobs/artifacts/next/browse?job=make-dist][last
|
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
|
||||||
successful development build]].
|
successful development build]].
|
||||||
|
|
||||||
** Requirements
|
** Requirements
|
||||||
|
|
@ -52,13 +52,10 @@ make
|
||||||
make install
|
make install
|
||||||
#+END_SRC
|
#+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
|
Files =INSTALL= and =README= included in the tarball contains more
|
||||||
explanations about the various options you can use during the
|
explanations about the various options you can use during this
|
||||||
compilation process. Also note that =README= has a section about
|
process. Also note that =README= has a section about troubleshooting
|
||||||
troubleshooting installations.
|
installations.
|
||||||
|
|
||||||
* Installing the Debian packages
|
* Installing the Debian packages
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
|
|
@ -91,9 +88,7 @@ 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
|
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
|
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
|
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. If you have an old copy of
|
9E74 44F2 A84A=, if you want to verify it.
|
||||||
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=
|
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
|
contains the header files if you plan to use Spot in a C++17
|
||||||
|
|
@ -167,11 +162,11 @@ the (working) code that should be part of the next major release.
|
||||||
To clone the git repository, use
|
To clone the git repository, use
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
#+BEGIN_SRC sh
|
||||||
git clone https://gitlab.lre.epita.fr/spot/spot.git
|
git clone https://gitlab.lrde.epita.fr/spot/spot.git
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
This should put you on the =next= branch by default. From there, read
|
This should put you on the =next= branch by default. From there, read
|
||||||
the [[https://gitlab.lre.epita.fr/spot/spot/blob/next/HACKING][HACKING]] file that should be at the top of your cloned repository:
|
the [[https://gitlab.lrde.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
|
it lists all the tools you should install before attempting to compile
|
||||||
the source tree.
|
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
|
=ltl2tgba= for each formula, we just need to plot column
|
||||||
=dt2$state.small= against =dt2$state.deter=.
|
=dt2$state.small= against =dt2$state.deter=.
|
||||||
|
|
||||||
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r.svg
|
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r.svg
|
||||||
library(ggplot2)
|
library(ggplot2)
|
||||||
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
||||||
geom_abline(colour='white') + geom_point()
|
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
|
We should probably print the formulas for the cases where the two
|
||||||
sizes differ.
|
sizes differ.
|
||||||
|
|
||||||
#+BEGIN_SRC R :results output graphics file :width 5 :height 5 :file ltlcross-r2.svg
|
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r2.svg
|
||||||
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
ggplot(dt2, aes(x=states.small, y=states.deter)) +
|
||||||
geom_abline(colour='white') + geom_point() +
|
geom_abline(colour='white') + geom_point() +
|
||||||
geom_text(data=subset(dt2, states.small != states.deter),
|
geom_text(data=subset(dt2, states.small != states.deter),
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,19 @@
|
||||||
|
|
||||||
* Basic usage
|
* Basic usage
|
||||||
|
|
||||||
This tool synthesizes reactive controllers from LTL/PSL formulas.
|
This tool synthesizes controllers from LTL/PSL formulas.
|
||||||
|
|
||||||
Consider a set $I$ of /input/ atomic propositions, a set $O$ of output atomic
|
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
|
propositions, and a PSL formula \phi over the propositions in $I \cup O$. A
|
||||||
*reactive controller* realizing \phi is a function $c: (2^{I})^\star \times 2^I \mapsto
|
=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
|
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
|
the input propositions, the word $(u_i \cup c(u_0 \dots u_{i-1}, u_i))_{i \in
|
||||||
N}$ satisfies \phi.
|
N}$ satisfies \phi.
|
||||||
|
|
||||||
If a reactive controller exists, then one with finite memory
|
If a controller exists, then one with finite memory exists. Such controllers
|
||||||
exists. Such controllers are easily represented as automata (or more
|
are easily represented as automata (or more specifically as I/O automata or
|
||||||
specifically as Mealy machines). In the automaton representing the
|
transducers). In the automaton representing the controller, the acceptance
|
||||||
controller, the acceptance condition is irrelevant and trivially true.
|
condition is irrelevant and trivially true.
|
||||||
|
|
||||||
=ltlsynt= has three mandatory options:
|
=ltlsynt= has three mandatory options:
|
||||||
- =--ins=: a comma-separated list of input atomic propositions;
|
- =--ins=: a comma-separated list of input atomic propositions;
|
||||||
|
|
@ -27,52 +27,45 @@ controller, the acceptance condition is irrelevant and trivially true.
|
||||||
- =--formula= or =--file=: a specification in LTL or PSL.
|
- =--formula= or =--file=: a specification in LTL or PSL.
|
||||||
|
|
||||||
One of =--ins= or =--outs= may be omitted, as any atomic proposition not listed
|
One of =--ins= or =--outs= may be omitted, as any atomic proposition not listed
|
||||||
as input can be assumed to be output and vice-versa.
|
as input can be assumed to be an output and vice-versa.
|
||||||
|
|
||||||
The following example illustrates the synthesis of a controller
|
The following example illustrates the synthesis of a controller acting as an
|
||||||
ensuring that input =i1= and =i2= are both true initially if and only
|
=AND= gate. We have two inputs =a= and =b= and one output =c=, and we want =c=
|
||||||
if eventually output =o1= will go from true to false at some point.
|
to always be the =AND= of the two inputs:
|
||||||
Note that this is an equivalence, not an implication.
|
|
||||||
|
|
||||||
#+NAME: example
|
#+NAME: example
|
||||||
#+BEGIN_SRC sh :exports both
|
#+BEGIN_SRC sh :exports both
|
||||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))'
|
ltlsynt --ins=a,b -f 'G (a & b <=> c)'
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+RESULTS: example
|
#+RESULTS: example
|
||||||
#+begin_example
|
#+begin_example
|
||||||
REALIZABLE
|
REALIZABLE
|
||||||
HOA: v1
|
HOA: v1
|
||||||
States: 3
|
States: 1
|
||||||
Start: 0
|
Start: 0
|
||||||
AP: 3 "i1" "i2" "o1"
|
AP: 3 "a" "b" "c"
|
||||||
acc-name: all
|
acc-name: all
|
||||||
Acceptance: 0 t
|
Acceptance: 0 t
|
||||||
properties: trans-labels explicit-labels state-acc deterministic
|
properties: trans-labels explicit-labels state-acc deterministic
|
||||||
controllable-AP: 2
|
|
||||||
--BODY--
|
--BODY--
|
||||||
State: 0
|
State: 0
|
||||||
[0&1&2] 1
|
[!0&!2 | !1&!2] 0
|
||||||
[!0&2 | !1&2] 2
|
[0&1&2] 0
|
||||||
State: 1
|
|
||||||
[!2] 0
|
|
||||||
State: 2
|
|
||||||
[2] 2
|
|
||||||
--END--
|
--END--
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
The output is composed of two parts:
|
The output is composed of two parts:
|
||||||
- The first one is a single line =REALIZABLE= or =UNREALIZABLE=; the presence of this
|
- the first one is a single line =REALIZABLE= or =UNREALIZABLE;=
|
||||||
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 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 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
|
#+NAME: exampledot
|
||||||
#+BEGIN_SRC sh :exports code
|
#+BEGIN_SRC sh :exports none :noweb yes
|
||||||
ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --dot
|
sed 1d <<EOF | autfilt --dot=.A
|
||||||
|
<<example()>>
|
||||||
|
EOF
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC dot :file ltlsyntex.svg :var txt=exampledot :exports results
|
#+BEGIN_SRC dot :file ltlsyntex.svg :var txt=exampledot :exports results
|
||||||
|
|
@ -82,6 +75,9 @@ ltlsynt --ins=i1,i2 -f '(i1 & i2) <-> F(o1 & X(!o1))' --hide-status --dot
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:ltlsyntex.svg]]
|
[[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
|
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
|
=a= is an input proposition, there is no way to guarantee that it will
|
||||||
eventually hold.
|
eventually hold.
|
||||||
|
|
@ -94,68 +90,11 @@ ltlsynt --ins=a -f 'F a'
|
||||||
: UNREALIZABLE
|
: UNREALIZABLE
|
||||||
|
|
||||||
By default, the controller is output in HOA format, but it can be
|
By default, the controller is output in HOA format, but it can be
|
||||||
output as an And-Inverter-Graph in [[http://fmv.jku.at/aiger/][AIGER format]] using the =--aiger=
|
output as an [[http://fmv.jku.at/aiger/][AIGER]] circuit thanks to the =--aiger= flag. This is the
|
||||||
flag. This is the output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
|
output format required for the [[http://syntcomp.org/][SYNTCOMP]] competition.
|
||||||
|
|
||||||
#+NAME: exampleaig
|
The generation of a controller can be disabled with the flag =--realizability=.
|
||||||
#+BEGIN_SRC sh :exports both
|
In this case, =ltlsynt= output is limited to =REALIZABLE= or =UNREALIZABLE=.
|
||||||
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
|
* TLSF
|
||||||
|
|
||||||
|
|
@ -165,20 +104,14 @@ specification language created for the purpose of this competition.
|
||||||
Fortunately, the SYNTCOMP organizers also provide a tool called
|
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.
|
[[https://github.com/reactive-systems/syfco][=syfco=]] which can translate a TLSF specification to an LTL formula.
|
||||||
|
|
||||||
The following line shows how a TLSF specification called =FILE= can
|
The following four steps show you how a TLSF specification called =FILE= can
|
||||||
be synthesized using =syfco= and =ltlsynt=:
|
be synthesized using =syfco= and =ltlsynt=:
|
||||||
|
|
||||||
#+BEGIN_SRC sh :export code
|
#+BEGIN_SRC sh :export code
|
||||||
ltlsynt --tlsf FILE
|
LTL=$(syfco FILE -f ltlxba -m fully)
|
||||||
#+END_SRC
|
IN=$(syfco FILE --print-input-signals)
|
||||||
|
OUT=$(syfco FILE --print-output-signals)
|
||||||
The above =--tlsf= option will call =syfco= to perform the conversion
|
ltlsynt --formula="$LTL" --ins="$IN" --outs="$OUT"
|
||||||
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
|
#+END_SRC
|
||||||
|
|
||||||
* Internal details
|
* Internal details
|
||||||
|
|
@ -238,18 +171,7 @@ be tried by separating them using commas. For instance
|
||||||
You can also ask =ltlsynt= to print to obtained parity game into
|
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,
|
[[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
|
using =--print-game-hoa=. These flag deactivate the resolution of the
|
||||||
parity game. Note that if any of those flag is used with =--dot=, the game
|
parity 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
|
For benchmarking purpose, the =--csv= option can be used to record
|
||||||
intermediate statistics about the resolution.
|
intermediate statistics about the resolution.
|
||||||
|
|
@ -272,11 +194,6 @@ Further improvements are described in the following paper:
|
||||||
/Alexandre Duret-Lutz/, and /Adrien Pommellet/. Presented at the
|
/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]])
|
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: utf ltlsynt AIGER html args mapsto SRC acc aiger TLSF
|
||||||
# LocalWords: UNREALIZABLE unrealizable SYNTCOMP realizability Proc
|
# LocalWords: UNREALIZABLE unrealizable SYNTCOMP realizability Proc
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,11 @@
|
||||||
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil
|
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil
|
||||||
#+EMAIL: spot@lrde.epita.fr
|
#+EMAIL: spot@lrde.epita.fr
|
||||||
#+HTML_LINK_HOME: index.html
|
#+HTML_LINK_HOME: index.html
|
||||||
#+MACRO: LASTDATE 2023-04-20
|
#+MACRO: SPOTVERSION 2.10.4
|
||||||
|
#+MACRO: LASTRELEASE 2.10.4
|
||||||
#+NAME: SPOT_VERSION
|
#+MACRO: LASTTARBALL [[http://www.lrde.epita.fr/dload/spot/spot-2.10.4.tar.gz][=spot-2.10.4.tar.gz=]]
|
||||||
#+BEGIN_SRC python :exports none :results value :wrap org
|
#+MACRO: LASTNEWS [[https://gitlab.lrde.epita.fr/spot/spot/blob/spot-2-10-4/NEWS][summary of the changes]]
|
||||||
return "2.11.5"
|
#+MACRO: LASTDATE 2022-02-01
|
||||||
#+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
|
#+ATTR_HTML: :id spotlogo
|
||||||
[[file:spot2.svg]]
|
[[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}
|
#table-of-contents #text-table-of-contents{text-align:left}
|
||||||
#org-div-home-and-up{text-align:center;font-size:100%}
|
#org-div-home-and-up{text-align:center;font-size:100%}
|
||||||
.outline-2 h2{display:block;width:100%;position:relative}
|
.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: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-color:#ffe35e;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{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: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-color:#ffe35e;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}
|
.outline-2 h2:hover::before,.outline-3 h3:hover::before{background-color:#ffe35e}
|
||||||
pre{margin:1.2ex}
|
pre{margin:1.2ex}
|
||||||
pre.src{padding-top:8px;border-left-style:solid;border-color:#00adad;overflow:auto;margin-top:0;margin-bottom:0}
|
pre.src{padding-top:8px;border-left-style:solid;border-color:#00adad;overflow:auto;margin-top:0;margin-bottom:0}
|
||||||
|
|
@ -77,13 +77,11 @@ thead tr{background:#ffe35e}
|
||||||
.org-hoa-ap-number{color:#d70079}
|
.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{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}
|
.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{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}
|
.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}
|
.spotlogo{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogo}
|
||||||
g.spotlogobg{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogobg}
|
g.spotlogobg{transform-origin:50% 50%;animation-duration:2s;animation-name:animspotlogobg}
|
||||||
g.spotlogover{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
|
g#version{transform-origin:50% 50%;animation-duration:3s;animation-name:animspotlogover}
|
||||||
@keyframes animspotlogo{
|
@keyframes animspotlogo{
|
||||||
0%{transform:rotateY(90deg)}
|
0%{transform:rotateY(90deg)}
|
||||||
80%{transform:rotateY(0deg)}
|
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=" 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)"/>
|
<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>
|
||||||
<g class="spotlogover">
|
<g id="version">
|
||||||
<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=" 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: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)"/>
|
<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 -*-
|
# -*- 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
|
#+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
|
#+HTML_LINK_UP: index.html
|
||||||
#+PROPERTY: header-args:sh :results verbatim :exports both
|
#+PROPERTY: header-args:sh :results verbatim :exports both
|
||||||
|
|
||||||
This document introduces command-line tools that are installed with
|
This document introduces command-line tools that are installed with
|
||||||
Spot call_SPOT_VERSION(). We give some examples to highlight possible
|
the Spot library. We give some examples to highlight possible
|
||||||
use-cases but shall not attempt to cover all features exhaustively
|
use-cases but shall not attempt to cover all features exhaustively
|
||||||
(please check the man pages for further inspiration).
|
(please check the man pages for further inspiration).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,6 @@ real notebooks instead.
|
||||||
automata.
|
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-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/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/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/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]].
|
- [[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
|
=formula::F(formula::X(formula::tt()))= will return the same formula
|
||||||
as =formula::tt()=. These simplifications are those that involve the
|
as =formula::tt()=. These simplifications are those that involve the
|
||||||
true and false constants, impotence (=F(F(e))=F(e)=), involutions
|
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
|
(=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/.
|
these /trivial identities/.
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ detail of the top-level operator in the formula.
|
||||||
|
|
||||||
std::cout << f << '\n';
|
std::cout << f << '\n';
|
||||||
|
|
||||||
// kindstr() prints the name of the operator
|
// kindstar() prints the name of the operator
|
||||||
// size() return the number of operands of the operators
|
// size() return the number of operands of the operators
|
||||||
std::cout << f.kindstr() << ", " << f.size() << " children\n";
|
std::cout << f.kindstr() << ", " << f.size() << " children\n";
|
||||||
// operator[] accesses each operand
|
// operator[] accesses each operand
|
||||||
|
|
@ -157,7 +157,7 @@ The Python equivalent is similar:
|
||||||
|
|
||||||
print(f)
|
print(f)
|
||||||
|
|
||||||
# kindstr() prints the name of the operator
|
# kindstar() prints the name of the operator
|
||||||
# size() return the number of operands of the operators
|
# size() return the number of operands of the operators
|
||||||
print("{}, {} children".format(f.kindstr(), f.size()))
|
print("{}, {} children".format(f.kindstr(), f.size()))
|
||||||
# [] accesses each operand
|
# [] accesses each operand
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ automaton. Finally, the output as a never claim is done via the
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
spot::parsed_formula pf = spot::parse_infix_psl("GFa -> GFb");
|
spot::parsed_formula pf = spot::parse_infix_psl("[]<>a || <>[]b");
|
||||||
if (pf.format_errors(std::cerr))
|
if (pf.format_errors(std::cerr))
|
||||||
return 1;
|
return 1;
|
||||||
spot::translator trans;
|
spot::translator trans;
|
||||||
|
|
@ -158,22 +158,22 @@ never {
|
||||||
T0_init:
|
T0_init:
|
||||||
if
|
if
|
||||||
:: (true) -> goto T0_init
|
:: (true) -> goto T0_init
|
||||||
:: (b) -> goto accept_S1
|
:: (a) -> goto accept_S1
|
||||||
:: (!(a)) -> goto accept_S2
|
:: (b) -> goto accept_S2
|
||||||
fi;
|
fi;
|
||||||
accept_S1:
|
accept_S1:
|
||||||
if
|
if
|
||||||
:: (b) -> goto accept_S1
|
:: (a) -> goto accept_S1
|
||||||
:: (!(b)) -> goto T0_S3
|
:: (!(a)) -> goto T0_S3
|
||||||
fi;
|
fi;
|
||||||
accept_S2:
|
accept_S2:
|
||||||
if
|
if
|
||||||
:: (!(a)) -> goto accept_S2
|
:: (b) -> goto accept_S2
|
||||||
fi;
|
fi;
|
||||||
T0_S3:
|
T0_S3:
|
||||||
if
|
if
|
||||||
:: (b) -> goto accept_S1
|
:: (a) -> goto accept_S1
|
||||||
:: (!(b)) -> goto T0_S3
|
:: (!(a)) -> goto T0_S3
|
||||||
fi;
|
fi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,9 @@ states.
|
||||||
|
|
||||||
We now look at how to create such a game in Python.
|
We now look at how to create such a game in Python.
|
||||||
|
|
||||||
Essentially, a game in Spot is just an automaton equiped with a [[file:concepts.org::#named-properties][named
|
Essentially, a game in Spot is just an automaton equiped with a
|
||||||
property "state-player"]] that hold a Boolean vector indicating the
|
special property to indicate the owner of each states. So it can be
|
||||||
owner of each state. The game can be created using the usual
|
created using the usual interface:
|
||||||
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
|
#+NAME: build_game
|
||||||
#+BEGIN_SRC python :exports code
|
#+BEGIN_SRC python :exports code
|
||||||
|
|
@ -175,7 +173,7 @@ automaton interface, and the owners are set by calling
|
||||||
todo = []
|
todo = []
|
||||||
|
|
||||||
# Create the state (i, j) for a player if it does not exist yet and
|
# Create the state (i, j) for a player if it does not exist yet and
|
||||||
# return the state's number in the game.
|
# returns the state's number in the game.
|
||||||
def get_game_state(player, i, j):
|
def get_game_state(player, i, j):
|
||||||
orig_state = s_orig_states if player else d_orig_states
|
orig_state = s_orig_states if player else d_orig_states
|
||||||
if (i, j) in orig_state:
|
if (i, j) in orig_state:
|
||||||
|
|
|
||||||
90
doc/spot.bib
90
doc/spot.bib
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
@InProceedings{ babiak.12.tacas,
|
@InProceedings{ babiak.12.tacas,
|
||||||
author = {Tom{\'a}{\v{s}} Babiak and Mojm{\'i}r
|
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
|
K{\v{r}}et{\'i}nsk{\'y} and Vojt{\v{e}}ch {\v{R}}eh{\'a}k
|
||||||
|
|
@ -172,22 +173,6 @@
|
||||||
doi = {10.4230/LIPIcs.ICALP.2021.123}
|
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,
|
@InProceedings{ cerna.03.mfcs,
|
||||||
author = {Ivana {\v{C}}ern{\'a} and Radek Pel{\'a}nek},
|
author = {Ivana {\v{C}}ern{\'a} and Radek Pel{\'a}nek},
|
||||||
title = {Relating Hierarchy of Temporal Properties to Model
|
title = {Relating Hierarchy of Temporal Properties to Model
|
||||||
|
|
@ -230,11 +215,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@InProceedings{ cimatti.06.fmcad,
|
@InProceedings{ cimatti.06.fmcad,
|
||||||
author = {Cimatti, Alessandro and Roveri, Marco and Semprini, Simone
|
author = {Cimatti, Alessandro and Roveri, Marco and Semprini, Simone and
|
||||||
and Tonetta, Stefano},
|
Tonetta, Stefano},
|
||||||
title = {From {PSL} to {NBA}: a Modular Symbolic Encoding},
|
title = {From {PSL} to {NBA}: a Modular Symbolic Encoding},
|
||||||
booktitle = {Proceedings of the 6th conference on Formal Methods in
|
booktitle = {Proceedings of the 6th conference on Formal Methods in Computer
|
||||||
Computer Aided Design (FMCAD'06)},
|
Aided Design (FMCAD'06)},
|
||||||
pages = {125--133},
|
pages = {125--133},
|
||||||
year = {2006},
|
year = {2006},
|
||||||
publisher = {IEEE Computer Society},
|
publisher = {IEEE Computer Society},
|
||||||
|
|
@ -368,41 +353,6 @@
|
||||||
doi = {10.1504/IJCCBS.2014.059594}
|
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,
|
@InProceedings{ dwyer.98.fmsp,
|
||||||
author = {Matthew B. Dwyer and George S. Avrunin and James C.
|
author = {Matthew B. Dwyer and George S. Avrunin and James C.
|
||||||
Corbett},
|
Corbett},
|
||||||
|
|
@ -908,22 +858,6 @@
|
||||||
doi = {10.1007/978-3-030-59152-6_7}
|
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,
|
@InProceedings{ rozier.07.spin,
|
||||||
author = {Kristin Y. Rozier and Moshe Y. Vardi},
|
author = {Kristin Y. Rozier and Moshe Y. Vardi},
|
||||||
title = {LTL Satisfiability Checking},
|
title = {LTL Satisfiability Checking},
|
||||||
|
|
@ -1086,19 +1020,7 @@
|
||||||
publisher = {Elsevier},
|
publisher = {Elsevier},
|
||||||
editor = {Rance Cleaveland and Hubert Garavel},
|
editor = {Rance Cleaveland and Hubert Garavel},
|
||||||
year = {2002},
|
year = {2002},
|
||||||
month = jul, pdf = {adl/duret.16.atva.pdf},
|
month = jul,
|
||||||
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},
|
address = {M{\'a}laga, Spain},
|
||||||
doi = {10.1016/S1571-0661(04)80409-2}
|
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
|
(allowing better compatibility with Wring and VIS) may only used in
|
||||||
temporal formulas. Boolean expressions that occur inside SERE (see
|
temporal formulas. Boolean expressions that occur inside SERE (see
|
||||||
Section~\ref{sec:sere}) may not use this form because the $\STARALT$
|
Section~\ref{sec:sere}) may not use this form because the $\STARALT$
|
||||||
symbol is used as the Kleene star.}
|
symbol is used as the Kleen star.}
|
||||||
|
|
||||||
Additionally, an atomic proposition $a$ can be negated using the
|
Additionally, an atomic proposition $a$ can be negated using the
|
||||||
syntax \samp{$a$=0}, which is equivalent to \samp{$\NOT a$}. Also
|
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}.
|
``\textit{Semi-Extended Regular Expression}''~\citep{eisner.08.hvc}.
|
||||||
In any case, the intent is the same: regular expressions with
|
In any case, the intent is the same: regular expressions with
|
||||||
traditional operations (union `$\OR$', concatenation `$\CONCAT$',
|
traditional operations (union `$\OR$', concatenation `$\CONCAT$',
|
||||||
Kleene star `$\STAR{}$') are extended with operators such as
|
Kleen star `$\STAR{}$') are extended with operators such as
|
||||||
intersection `$\ANDALT$', and fusion `$\FUSION$'.
|
intersection `$\ANDALT$', and fusion `$\FUSION$'.
|
||||||
|
|
||||||
Any Boolean formula (section~\ref{def:boolform}) is a SERE. SERE can
|
Any Boolean formula (section~\ref{def:boolform}) is a SERE. SERE can
|
||||||
|
|
@ -638,7 +638,7 @@ denote arbitrary SERE.
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
\footnotetext{\emph{Non-Length-Matching} intersection.}
|
\footnotetext{\emph{Non-Length-Matching} interesction.}
|
||||||
|
|
||||||
The character \samp{\$} or the string \samp{inf} can also be used as
|
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
|
value for $\mvar{j}$ in the above operators to denote an unbounded
|
||||||
|
|
@ -668,17 +668,20 @@ $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\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
|
\sigma\VDash f\STAR{\mvar{i}..\mvar{j}}& \iff
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
\text{either} & \mvar{i}=0 \land\mvar{j}=0\land \sigma=\varepsilon \\
|
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
|
||||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma = \varepsilon) \lor (\sigma
|
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
\VDash f\STAR{\mvar{1}..\mvar{j}})\bigr)\\
|
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||||
|
\VDash f\STAR{\mvar{0}..\mvar{j-1}}))\\
|
||||||
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||||
\VDash f\STAR{\mvar{i-1}..\mvar{j-1}}))\\
|
\VDash f\STAR{\mvar{i-1}..\mvar{j-1}}))\\
|
||||||
\end{cases}\\
|
\end{cases}\\
|
||||||
\sigma\VDash f\STAR{\mvar{i}..} & \iff
|
\sigma\VDash f\STAR{\mvar{i}..} & \iff
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
\text{either} & \mvar{i}=0 \land \bigl((\sigma=\varepsilon)\lor(\sigma
|
\text{either} & \mvar{i}=0 \land \sigma=\varepsilon \\
|
||||||
\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{0}..}))\\
|
||||||
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||||
\VDash f\STAR{\mvar{i-1}..}))\\
|
\VDash f\STAR{\mvar{i-1}..}))\\
|
||||||
|
|
@ -686,22 +689,25 @@ $a$ is an atomic proposition.
|
||||||
\sigma\VDash f\FSTAR{\mvar{i}..\mvar{j}}& \iff
|
\sigma\VDash f\FSTAR{\mvar{i}..\mvar{j}}& \iff
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
\text{either} & \mvar{i}=0 \land \mvar{j}=0 \land \sigma\VDash\1 \\
|
\text{either} & \mvar{i}=0 \land \mvar{j}=0 \land \sigma\VDash\1 \\
|
||||||
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land \bigl((\sigma\VDash\1)\lor(\sigma
|
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
\VDash f\FSTAR{\mvar{1}..\mvar{j}})\bigr)\\
|
(\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 (\exists k\in\N,\,
|
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
\VDash f\FSTAR{\mvar{i-1}..\mvar{j-1}}))\\
|
\VDash f\FSTAR{\mvar{i-1}..\mvar{j-1}}))\\
|
||||||
\end{cases}\\
|
\end{cases}\\
|
||||||
\sigma\VDash f\FSTAR{\mvar{i}..} & \iff
|
\sigma\VDash f\FSTAR{\mvar{i}..} & \iff
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
\text{either} & \mvar{i}=0 \land \bigl((\sigma\VDash\1)
|
\text{either} & \mvar{i}=0 \land \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{0}..}))\\
|
||||||
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||||
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
\VDash f\FSTAR{\mvar{i-1}..}))\\
|
\VDash f\FSTAR{\mvar{i-1}..}))\\
|
||||||
\end{cases}\\
|
\end{cases}\\
|
||||||
\sigma\VDash \FIRSTMATCH\code(f\code) & \iff
|
\sigma\VDash \FIRSTMATCH\code(f\code) & \iff
|
||||||
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k-1}\nVDash f)
|
(\sigma\VDash f)\land (\forall k<|\sigma|,\,\sigma^{0..k}\nVDash f)
|
||||||
\end{align*}}
|
\end{align*}}
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
@ -853,18 +859,10 @@ The following rules are all valid with the two arguments swapped.
|
||||||
\1\OR b &\equiv \1 &
|
\1\OR b &\equiv \1 &
|
||||||
\1 \FUSION f & \equiv f\mathrlap{\text{~if~}\varepsilon\nVDash f}\\
|
\1 \FUSION f & \equiv f\mathrlap{\text{~if~}\varepsilon\nVDash f}\\
|
||||||
&&
|
&&
|
||||||
\STAR{} \ANDALT f &\equiv f &
|
\STAR{} \AND f &\equiv f &
|
||||||
\STAR{} \OR f &\equiv \mathrlap{\STAR{}} &
|
\STAR{} \OR f &\equiv \1\mathrlap{\STAR{}} &
|
||||||
&&
|
&&
|
||||||
\STAR{} \CONCAT f &\equiv \STAR{}\text{~if~}\varepsilon\VDash f& \\
|
\STAR{} \CONCAT f &\equiv \STAR{}\mathrlap{\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\AND f &\equiv f &
|
||||||
\eword\ANDALT f &\equiv
|
\eword\ANDALT f &\equiv
|
||||||
\begin{cases}
|
\begin{cases}
|
||||||
|
|
@ -888,9 +886,7 @@ 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&\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\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&\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*}
|
\end{align*}
|
||||||
\section{SERE-LTL Binding Operators}
|
\section{SERE-LTL Binding Operators}
|
||||||
|
|
||||||
|
|
@ -1073,7 +1069,7 @@ psl2ba, Modella, and NuSMV all have $\U$ and $\R$ as left-associative,
|
||||||
while Goal (hence Büchi store), LTL2AUT, and LTL2Büchi (from
|
while Goal (hence Büchi store), LTL2AUT, and LTL2Büchi (from
|
||||||
JavaPathFinder) have $\U$ and $\R$ as right-associative. Vis and LBTT
|
JavaPathFinder) have $\U$ and $\R$ as right-associative. Vis and LBTT
|
||||||
have these two operators as non-associative (parentheses required).
|
have these two operators as non-associative (parentheses required).
|
||||||
Similarly the tools do not agree on the associativity of $\IMPLIES$
|
Similarly the tools do not aggree on the associativity of $\IMPLIES$
|
||||||
and $\EQUIV$: some tools handle both operators as left-associative, or
|
and $\EQUIV$: some tools handle both operators as left-associative, or
|
||||||
both right-associative, other have only $\IMPLIES$ as right-associative.
|
both right-associative, other have only $\IMPLIES$ as right-associative.
|
||||||
|
|
||||||
|
|
@ -1433,7 +1429,7 @@ $\NOT$ operator.
|
||||||
\end{align*}
|
\end{align*}
|
||||||
|
|
||||||
Note that the above rules include the ``unabbreviation'' of operators
|
Note that the above rules include the ``unabbreviation'' of operators
|
||||||
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', corresponding to the
|
``$\EQUIV$'', ``$\IMPLIES$'', and ``$\XOR$'', correspondings to the
|
||||||
rules \texttt{"ei\^"} of function `\verb=unabbreviate()= as described
|
rules \texttt{"ei\^"} of function `\verb=unabbreviate()= as described
|
||||||
in Section~\ref{sec:unabbrev}. Therefore it is never necessary to
|
in Section~\ref{sec:unabbrev}. Therefore it is never necessary to
|
||||||
apply these abbreviations before or after
|
apply these abbreviations before or after
|
||||||
|
|
@ -1930,12 +1926,6 @@ Many of the above rules were collected from the
|
||||||
literature~\cite{somenzi.00.cav,tauriainen.03.tr,babiak.12.tacas} and
|
literature~\cite{somenzi.00.cav,tauriainen.03.tr,babiak.12.tacas} and
|
||||||
sometimes generalized to support operators such as $\M$ and $\W$.
|
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
|
The following rules mix implication-based checks with formulas that
|
||||||
are pure eventualities ($e$) or that are purely universal ($u$).
|
are pure eventualities ($e$) or that are purely universal ($u$).
|
||||||
|
|
||||||
|
|
@ -2107,14 +2097,3 @@ $f_1\AND f_2$ & \bor{f_1}{g}{f_2}{g} & & &
|
||||||
%%% TeX-master: t
|
%%% TeX-master: t
|
||||||
%%% coding: utf-8
|
%%% coding: utf-8
|
||||||
%%% End:
|
%%% 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 -*-
|
## -*- coding: utf-8 -*-
|
||||||
## Copyright (C) 2015-2018, 2022 Laboratoire de Recherche et
|
## Copyright (C) 2015, 2016, 2017, 2018 Laboratoire de Recherche et Développement
|
||||||
## Développement de l'Epita (LRDE).
|
## de l'Epita (LRDE).
|
||||||
##
|
##
|
||||||
## This file is part of Spot, a model checking library.
|
## This file is part of Spot, a model checking library.
|
||||||
##
|
##
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
EXTRA_DIST = hoa-mode.el
|
EXTRA_DIST = hoa-mode.el
|
||||||
|
|
||||||
GIT = https://gitlab.lre.epita.fr/spot/emacs-modes/raw/master/
|
GIT = https://gitlab.lrde.epita.fr/spot/emacs-modes/raw/master/
|
||||||
|
|
||||||
.PHONY: update-el
|
.PHONY: update-el
|
||||||
update-el:
|
update-el:
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
;;; hoa-mode.el --- Major mode for the HOA format -*- lexical-binding: t -*-
|
;;; hoa-mode.el --- Major mode for the HOA format -*- lexical-binding: t -*-
|
||||||
|
|
||||||
;; Copyright (C) 2015, 2017, 2019, 2022 Alexandre Duret-Lutz
|
;; Copyright (C) 2015, 2017, 2019 Alexandre Duret-Lutz
|
||||||
|
|
||||||
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
;; Author: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
;; Maintainer: Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
;; URL: https://gitlab.lre.epita.fr/spot/emacs-modes
|
;; URL: https://gitlab.lrde.epita.fr/spot/emacs-modes
|
||||||
;; Keywords: major-mode, automata, convenience
|
;; Keywords: major-mode, automata, convenience
|
||||||
;; Created: 2015-11-13
|
;; Created: 2015-11-13
|
||||||
|
|
||||||
|
|
|
||||||
43
flake.lock
generated
43
flake.lock
generated
|
|
@ -1,43 +0,0 @@
|
||||||
{
|
|
||||||
"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
211
flake.nix
|
|
@ -1,211 +0,0 @@
|
||||||
{
|
|
||||||
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
|
|
||||||
]))
|
|
||||||
];
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
# 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,14 +21,6 @@ AC_DEFUN([CF_GXX_WARNINGS],
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line __oline__ "configure"
|
#line __oline__ "configure"
|
||||||
#include <string>
|
#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[[]])
|
int main(int argc, char *argv[[]])
|
||||||
{
|
{
|
||||||
// This string comparison is here to detect superfluous
|
// This string comparison is here to detect superfluous
|
||||||
|
|
@ -41,26 +33,19 @@ int main(int argc, char *argv[[]])
|
||||||
std::string a{"foo"}, b{"bar"};
|
std::string a{"foo"}, b{"bar"};
|
||||||
if (b < a)
|
if (b < a)
|
||||||
return 1;
|
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;
|
return argv[[argc-1]] == nullptr;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
cf_save_CXXFLAGS="$CXXFLAGS"
|
cf_save_CXXFLAGS="$CXXFLAGS"
|
||||||
ac_cv_prog_gxx_warn_flags="-W -Werror"
|
ac_cv_prog_gxx_warn_flags="-W -Wall"
|
||||||
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 \
|
for cf_opt in \
|
||||||
Wall:Wno-maybe-uninitialized:\
|
Werror \
|
||||||
Wint-to-void-pointer-cast \
|
Wint-to-void-pointer-cast \
|
||||||
Wzero-as-null-pointer-constant \
|
Wzero-as-null-pointer-constant \
|
||||||
Wcast-align \
|
Wcast-align \
|
||||||
Wpointer-arith \
|
Wpointer-arith \
|
||||||
Wwrite-strings \
|
Wwrite-strings \
|
||||||
Wcast-qual::DXTSTRINGDEFINES \
|
Wcast-qual \
|
||||||
Wdocumentation \
|
Wdocumentation \
|
||||||
Wmissing-declarations \
|
Wmissing-declarations \
|
||||||
Wnoexcept \
|
Wnoexcept \
|
||||||
|
|
@ -73,25 +58,10 @@ dnl if -OPT fails we try -OPT -BAD. If -OPT succeeds we add -GOOD.
|
||||||
Wsuggest-override \
|
Wsuggest-override \
|
||||||
Wpedantic
|
Wpedantic
|
||||||
do
|
do
|
||||||
fopt=${cf_opt%%:*}
|
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$cf_opt"
|
||||||
CXXFLAGS="$cf_save_CXXFLAGS $ac_cv_prog_gxx_warn_flags -$fopt"
|
|
||||||
if AC_TRY_EVAL(ac_compile); then
|
if AC_TRY_EVAL(ac_compile); then
|
||||||
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$fopt"
|
ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -$cf_opt"
|
||||||
case $cf_opt in
|
test "$cf_opt" = Wcast-qual && ac_cv_prog_gxx_warn_flags="$ac_cv_prog_gxx_warn_flags -DXTSTRINGDEFINES"
|
||||||
*:*:);;
|
|
||||||
*:*:*)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
|
fi
|
||||||
done
|
done
|
||||||
rm -f conftest*
|
rm -f conftest*
|
||||||
|
|
|
||||||
12
m4/getopt.m4
12
m4/getopt.m4
|
|
@ -1,5 +1,5 @@
|
||||||
# getopt.m4 serial 47
|
# getopt.m4 serial 47
|
||||||
dnl Copyright (C) 2002-2006, 2008-2020, 2022 Free Software Foundation, Inc.
|
dnl Copyright (C) 2002-2006, 2008-2020 Free Software Foundation, Inc.
|
||||||
dnl This file is free software; the Free Software Foundation
|
dnl This file is free software; the Free Software Foundation
|
||||||
dnl gives unlimited permission to copy and/or distribute it,
|
dnl gives unlimited permission to copy and/or distribute it,
|
||||||
dnl with or without modifications, as long as this notice is preserved.
|
dnl with or without modifications, as long as this notice is preserved.
|
||||||
|
|
@ -363,9 +363,13 @@ dnl is ambiguous with environment values that contain newlines.
|
||||||
|
|
||||||
AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
|
AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
|
||||||
[
|
[
|
||||||
# pretend HAVE_SYS_CDEFS_H is always 0 including <sys/defs.h> isn't
|
AC_CHECK_HEADERS_ONCE([sys/cdefs.h])
|
||||||
# really necessary and causes warning on Alpine Linux.
|
if test $ac_cv_header_sys_cdefs_h = yes; then
|
||||||
AC_SUBST([HAVE_SYS_CDEFS_H], [0])
|
HAVE_SYS_CDEFS_H=1
|
||||||
|
else
|
||||||
|
HAVE_SYS_CDEFS_H=0
|
||||||
|
fi
|
||||||
|
AC_SUBST([HAVE_SYS_CDEFS_H])
|
||||||
|
|
||||||
AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
|
AC_DEFINE([__GETOPT_PREFIX], [[rpl_]],
|
||||||
[Define to rpl_ if the getopt replacement functions and variables
|
[Define to rpl_ if the getopt replacement functions and variables
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
|
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -57,7 +57,6 @@ gl_MODULES([
|
||||||
argmatch
|
argmatch
|
||||||
argp
|
argp
|
||||||
closeout
|
closeout
|
||||||
environ
|
|
||||||
error
|
error
|
||||||
isatty
|
isatty
|
||||||
mkstemp
|
mkstemp
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# DO NOT EDIT! GENERATED AUTOMATICALLY!
|
# DO NOT EDIT! GENERATED AUTOMATICALLY!
|
||||||
# Copyright (C) 2002-2020, 2022 Free Software Foundation, Inc.
|
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -246,8 +246,6 @@ AC_SUBST([LTALLOCA])
|
||||||
AC_LIBOBJ([lstat])
|
AC_LIBOBJ([lstat])
|
||||||
gl_PREREQ_LSTAT
|
gl_PREREQ_LSTAT
|
||||||
fi
|
fi
|
||||||
gl_ENVIRON
|
|
||||||
gl_UNISTD_MODULE_INDICATOR([environ])
|
|
||||||
gl_SYS_STAT_MODULE_INDICATOR([lstat])
|
gl_SYS_STAT_MODULE_INDICATOR([lstat])
|
||||||
gl_FUNC_MALLOC_GNU
|
gl_FUNC_MALLOC_GNU
|
||||||
if test $REPLACE_MALLOC = 1; then
|
if test $REPLACE_MALLOC = 1; then
|
||||||
|
|
|
||||||
74
m4/ltargz.m4
Normal file
74
m4/ltargz.m4
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
# 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 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2014-2023 Laboratoire de Recherche et Développement de
|
# Copyright (C) 2014-2021 Laboratoire de
|
||||||
# l'Epita (LRDE).
|
# Recherche et Développement de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
#
|
#
|
||||||
|
|
@ -104,22 +104,19 @@ def setup(**kwargs):
|
||||||
os.environ['SPOT_DOTDEFAULT'] = d
|
os.environ['SPOT_DOTDEFAULT'] = d
|
||||||
|
|
||||||
|
|
||||||
# Swig versions prior to 4.1.0 export formula.X as formula_X as well,
|
# In version 3.0.2, Swig puts strongly typed enum in the main
|
||||||
# for all operators. Swig 4.1.0 stops doing this, breaking some
|
# namespace without prefixing them. Latter versions fix this. So we
|
||||||
# existing code.
|
# can remove for following hack once 3.0.2 is no longer used in our
|
||||||
if 'formula_ff' not in globals():
|
# build farm.
|
||||||
|
if 'op_ff' not in globals():
|
||||||
for i in ('ff', 'tt', 'eword', 'ap', 'Not', 'X', 'F', 'G',
|
for i in ('ff', 'tt', 'eword', 'ap', 'Not', 'X', 'F', 'G',
|
||||||
'Closure', 'NegClosure', 'NegClosureMarked',
|
'Closure', 'NegClosure', 'NegClosureMarked',
|
||||||
'Xor', 'Implies', 'Equiv', 'U', 'R', 'W', 'M',
|
'Xor', 'Implies', 'Equiv', 'U', 'R', 'W', 'M',
|
||||||
'EConcat', 'EConcatMarked', 'UConcat', 'Or',
|
'EConcat', 'EConcatMarked', 'UConcat', 'Or',
|
||||||
'OrRat', 'And', 'AndRat', 'AndNLM', 'Concat',
|
'OrRat', 'And', 'AndRat', 'AndNLM', 'Concat',
|
||||||
'Fusion', 'Star', 'FStar', 'nested_unop_range',
|
'Fusion', 'Star', 'FStar'):
|
||||||
'sugar_goto', 'sugar_equal', 'sugar_delay', 'unop',
|
globals()['op_' + i] = globals()[i]
|
||||||
'binop', 'bunop', 'multop', 'first_match', 'unbounded'):
|
del globals()[i]
|
||||||
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.
|
# Global BDD dict so that we do not have to create one in user code.
|
||||||
|
|
@ -264,12 +261,6 @@ class twa:
|
||||||
ostr = ostringstream()
|
ostr = ostringstream()
|
||||||
print_lbtt(ostr, a, opt)
|
print_lbtt(ostr, a, opt)
|
||||||
return ostr.str()
|
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)
|
raise ValueError("unknown string format: " + format)
|
||||||
|
|
||||||
def save(a, filename, format='hoa', opt=None, append=False):
|
def save(a, filename, format='hoa', opt=None, append=False):
|
||||||
|
|
@ -502,57 +493,51 @@ class acd:
|
||||||
.acdacc polygon{fill:green;}
|
.acdacc polygon{fill:green;}
|
||||||
'''
|
'''
|
||||||
js = '''
|
js = '''
|
||||||
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(){{
|
function acd{num}_clear(){{
|
||||||
acdremclasses("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge",
|
$("#acd{num} .node,#acdaut{num} .node,#acdaut{num} .edge")
|
||||||
["acdhigh", "acdbold", "acdacc", "acdrej"]);
|
.removeClass("acdhigh acdbold acdacc acdrej");
|
||||||
}};
|
}};
|
||||||
function acd{num}_state(state){{
|
function acd{num}_state(state){{
|
||||||
acd{num}_clear();
|
acd{num}_clear();
|
||||||
acdaddclasses("#acd{num} .acdS" + state, ["acdhigh", "acdbold"]);
|
$("#acd{num} .acdS" + state).addClass("acdhigh acdbold");
|
||||||
acdaddclasses("#acdaut{num} #S" + state, ["acdbold"]);
|
$("#acdaut{num} #S" + state).addClass("acdbold");
|
||||||
}};
|
}};
|
||||||
function acd{num}_edge(edge){{
|
function acd{num}_edge(edge){{
|
||||||
acd{num}_clear();
|
acd{num}_clear();
|
||||||
var theedge = document.querySelector('#acdaut{num} #E' + edge);
|
var theedge = $('#acdaut{num} #E' + edge)
|
||||||
theedge.classList.forEach(function(item, index) {{
|
var classList = theedge.attr('class').split(/\s+/);
|
||||||
|
$.each(classList, function(index, item) {{
|
||||||
if (item.startsWith('acdN')) {{
|
if (item.startsWith('acdN')) {{
|
||||||
acdaddclasses("#acd{num} #" + item.substring(3), ["acdhigh", "acdbold"]);
|
$("#acd{num} #" + item.substring(3)).addClass("acdhigh acdbold");
|
||||||
}}
|
}}
|
||||||
}});
|
}});
|
||||||
theedge.classList.add("acdbold");
|
theedge.addClass("acdbold");
|
||||||
}};
|
}};
|
||||||
function acd{num}_node(node, acc){{
|
function acd{num}_node(node, acc){{
|
||||||
acd{num}_clear();
|
acd{num}_clear();
|
||||||
acdaddclasses("#acdaut{num} .acdN" + node,
|
$("#acdaut{num} .acdN" + node).addClass(acc
|
||||||
[acc ? "acdacc" : "acdrej", "acdbold"]);
|
? "acdacc acdbold"
|
||||||
acdaddclasses("#acd{num} #N" + node, ["acdbold", "acdhigh"]);
|
: "acdrej acdbold");
|
||||||
|
$("#acd{num} #N" + node).addClass("acdbold acdhigh");
|
||||||
}};'''.format(num=num)
|
}};'''.format(num=num)
|
||||||
me = 0
|
me = 0
|
||||||
for n in range(self.node_count()):
|
for n in range(self.node_count()):
|
||||||
for e in self.edges_of_node(n):
|
for e in self.edges_of_node(n):
|
||||||
me = max(e, me)
|
me = max(e, me)
|
||||||
js += 'acdaddclasses("#acdaut{num} #E{e}", ["acdN{n}"]);\n'\
|
js += '$("#acdaut{num} #E{e}").addClass("acdN{n}");'\
|
||||||
.format(num=num, e=e, n=n)
|
.format(num=num, e=e, n=n)
|
||||||
for e in range(1, me + 1):
|
for e in range(1, me + 1):
|
||||||
js += 'acdonclick("#acdaut{num} #E{e}",'\
|
js += '$("#acdaut{num} #E{e}")'\
|
||||||
'function(){{acd{num}_edge({e});}});\n'\
|
'.click(function(){{acd{num}_edge({e});}});'\
|
||||||
.format(num=num, e=e)
|
.format(num=num, e=e)
|
||||||
for s in range(self.get_aut().num_states()):
|
for s in range(self.get_aut().num_states()):
|
||||||
js += 'acdonclick("#acdaut{num} #S{s}",'\
|
js += '$("#acdaut{num} #S{s}")'\
|
||||||
'function(){{acd{num}_state({s});}});\n'\
|
'.click(function(){{acd{num}_state({s});}});'\
|
||||||
.format(num=num, s=s)
|
.format(num=num, s=s)
|
||||||
for n in range(self.node_count()):
|
for n in range(self.node_count()):
|
||||||
v = int(self.node_acceptance(n))
|
v = int(self.node_acceptance(n))
|
||||||
js += 'acdonclick("#acd{num} #N{n}",'\
|
js += '$("#acd{num} #N{n}")'\
|
||||||
'function(){{acd{num}_node({n}, {v});}});\n'\
|
'.click(function(){{acd{num}_node({n}, {v});}});'\
|
||||||
.format(num=num, n=n, v=v)
|
.format(num=num, n=n, v=v)
|
||||||
html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\
|
html = '<style>{}</style><div>{}</div><div>{}</div><script>{}</script>'\
|
||||||
.format(style,
|
.format(style,
|
||||||
|
|
@ -1307,36 +1292,6 @@ def sat_minimize(aut, acc=None, colored=False,
|
||||||
else:
|
else:
|
||||||
return sm(aut, args, state_based)
|
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):
|
def parse_word(word, dic=_bdd_dict):
|
||||||
from spot.impl import parse_word as pw
|
from spot.impl import parse_word as pw
|
||||||
|
|
@ -1347,10 +1302,6 @@ def bdd_to_formula(b, dic=_bdd_dict):
|
||||||
from spot.impl import bdd_to_formula as bf
|
from spot.impl import bdd_to_formula as bf
|
||||||
return bf(b, dic)
|
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):
|
def language_containment_checker(dic=_bdd_dict):
|
||||||
from spot.impl import language_containment_checker as c
|
from spot.impl import language_containment_checker as c
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009-2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2009-2022 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
// Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
|
// Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
|
||||||
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||||
|
|
@ -90,9 +90,7 @@
|
||||||
|
|
||||||
#include <spot/tl/apcollect.hh>
|
#include <spot/tl/apcollect.hh>
|
||||||
#include <spot/tl/contain.hh>
|
#include <spot/tl/contain.hh>
|
||||||
#include <spot/tl/derive.hh>
|
|
||||||
#include <spot/tl/dot.hh>
|
#include <spot/tl/dot.hh>
|
||||||
#include <spot/tl/expansions.hh>
|
|
||||||
#include <spot/tl/nenoform.hh>
|
#include <spot/tl/nenoform.hh>
|
||||||
#include <spot/tl/print.hh>
|
#include <spot/tl/print.hh>
|
||||||
#include <spot/tl/simplify.hh>
|
#include <spot/tl/simplify.hh>
|
||||||
|
|
@ -116,14 +114,13 @@
|
||||||
#include <spot/twaalgos/aiger.hh>
|
#include <spot/twaalgos/aiger.hh>
|
||||||
#include <spot/twaalgos/alternation.hh>
|
#include <spot/twaalgos/alternation.hh>
|
||||||
#include <spot/twaalgos/cleanacc.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/cobuchi.hh>
|
||||||
#include <spot/twaalgos/copy.hh>
|
#include <spot/twaalgos/copy.hh>
|
||||||
#include <spot/twaalgos/complete.hh>
|
#include <spot/twaalgos/complete.hh>
|
||||||
#include <spot/twaalgos/complement.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/emptiness.hh>
|
||||||
#include <spot/twaalgos/gtec/gtec.hh>
|
#include <spot/twaalgos/gtec/gtec.hh>
|
||||||
#include <spot/twaalgos/genem.hh>
|
#include <spot/twaalgos/genem.hh>
|
||||||
|
|
@ -163,7 +160,6 @@
|
||||||
#include <spot/twaalgos/stutter.hh>
|
#include <spot/twaalgos/stutter.hh>
|
||||||
#include <spot/twaalgos/synthesis.hh>
|
#include <spot/twaalgos/synthesis.hh>
|
||||||
#include <spot/twaalgos/translate.hh>
|
#include <spot/twaalgos/translate.hh>
|
||||||
#include <spot/twaalgos/translate_aa.hh>
|
|
||||||
#include <spot/twaalgos/toweak.hh>
|
#include <spot/twaalgos/toweak.hh>
|
||||||
#include <spot/twaalgos/hoa.hh>
|
#include <spot/twaalgos/hoa.hh>
|
||||||
#include <spot/twaalgos/dtwasat.hh>
|
#include <spot/twaalgos/dtwasat.hh>
|
||||||
|
|
@ -490,7 +486,6 @@ static void handle_any_exception()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%implicitconv spot::parallel_policy;
|
|
||||||
%include <spot/misc/common.hh>
|
%include <spot/misc/common.hh>
|
||||||
%include <spot/misc/version.hh>
|
%include <spot/misc/version.hh>
|
||||||
%include <spot/misc/minato.hh>
|
%include <spot/misc/minato.hh>
|
||||||
|
|
@ -523,12 +518,9 @@ namespace std {
|
||||||
%template(vectorbdd) vector<bdd>;
|
%template(vectorbdd) vector<bdd>;
|
||||||
%template(aliasvector) vector<pair<string, bdd>>;
|
%template(aliasvector) vector<pair<string, bdd>>;
|
||||||
%template(vectorstring) vector<string>;
|
%template(vectorstring) vector<string>;
|
||||||
%template(vectorint) vector<int>;
|
|
||||||
%template(pair_formula_vectorstring) pair<spot::formula, vector<string>>;
|
%template(pair_formula_vectorstring) pair<spot::formula, vector<string>>;
|
||||||
%template(atomic_prop_set) set<spot::formula>;
|
%template(atomic_prop_set) set<spot::formula>;
|
||||||
%template(relabeling_map) map<spot::formula, 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>
|
%include <spot/tl/environment.hh>
|
||||||
|
|
@ -541,8 +533,6 @@ namespace std {
|
||||||
%include <spot/twa/bdddict.hh>
|
%include <spot/twa/bdddict.hh>
|
||||||
%include <spot/twa/bddprint.hh>
|
%include <spot/twa/bddprint.hh>
|
||||||
%include <spot/twa/formula2bdd.hh>
|
%include <spot/twa/formula2bdd.hh>
|
||||||
%template(formula_to_bdd) spot::formula_to_bdd<spot::twa_graph>;
|
|
||||||
|
|
||||||
%include <spot/twa/fwd.hh>
|
%include <spot/twa/fwd.hh>
|
||||||
/* These operators may raise exceptions, and we do not
|
/* These operators may raise exceptions, and we do not
|
||||||
want Swig4 to convert those exceptions to NotImplemented. */
|
want Swig4 to convert those exceptions to NotImplemented. */
|
||||||
|
|
@ -559,27 +549,6 @@ namespace std {
|
||||||
}
|
}
|
||||||
%apply std::vector<unsigned> &OUTPUT {std::vector<unsigned>& pairs}
|
%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}
|
%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>
|
%include <spot/twa/acc.hh>
|
||||||
%template(pair_bool_mark) std::pair<bool, spot::acc_cond::mark_t>;
|
%template(pair_bool_mark) std::pair<bool, spot::acc_cond::mark_t>;
|
||||||
|
|
||||||
|
|
@ -608,8 +577,6 @@ namespace std {
|
||||||
|
|
||||||
%include <spot/tl/apcollect.hh>
|
%include <spot/tl/apcollect.hh>
|
||||||
%include <spot/tl/contain.hh>
|
%include <spot/tl/contain.hh>
|
||||||
%include <spot/tl/derive.hh>
|
|
||||||
%include <spot/tl/expansions.hh>
|
|
||||||
%include <spot/tl/dot.hh>
|
%include <spot/tl/dot.hh>
|
||||||
%include <spot/tl/nenoform.hh>
|
%include <spot/tl/nenoform.hh>
|
||||||
%include <spot/tl/sonf.hh>
|
%include <spot/tl/sonf.hh>
|
||||||
|
|
@ -697,14 +664,11 @@ def state_is_accepting(self, src) -> "bool":
|
||||||
%include <spot/twaalgos/aiger.hh>
|
%include <spot/twaalgos/aiger.hh>
|
||||||
%include <spot/twaalgos/alternation.hh>
|
%include <spot/twaalgos/alternation.hh>
|
||||||
%include <spot/twaalgos/cleanacc.hh>
|
%include <spot/twaalgos/cleanacc.hh>
|
||||||
|
%include <spot/twaalgos/degen.hh>
|
||||||
|
%include <spot/twaalgos/dot.hh>
|
||||||
%include <spot/twaalgos/cobuchi.hh>
|
%include <spot/twaalgos/cobuchi.hh>
|
||||||
%include <spot/twaalgos/copy.hh>
|
%include <spot/twaalgos/copy.hh>
|
||||||
%include <spot/twaalgos/complete.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;
|
%feature("flatnested") spot::twa_run::step;
|
||||||
%include <spot/twaalgos/emptiness.hh>
|
%include <spot/twaalgos/emptiness.hh>
|
||||||
%template(list_step) std::list<spot::twa_run::step>;
|
%template(list_step) std::list<spot::twa_run::step>;
|
||||||
|
|
@ -716,6 +680,8 @@ def state_is_accepting(self, src) -> "bool":
|
||||||
%include <spot/twaalgos/gfguarantee.hh>
|
%include <spot/twaalgos/gfguarantee.hh>
|
||||||
%include <spot/twaalgos/compsusp.hh>
|
%include <spot/twaalgos/compsusp.hh>
|
||||||
%include <spot/twaalgos/contains.hh>
|
%include <spot/twaalgos/contains.hh>
|
||||||
|
%include <spot/twaalgos/determinize.hh>
|
||||||
|
%include <spot/twaalgos/dualize.hh>
|
||||||
%include <spot/twaalgos/langmap.hh>
|
%include <spot/twaalgos/langmap.hh>
|
||||||
%include <spot/twaalgos/magic.hh>
|
%include <spot/twaalgos/magic.hh>
|
||||||
%include <spot/twaalgos/minimize.hh>
|
%include <spot/twaalgos/minimize.hh>
|
||||||
|
|
@ -762,7 +728,6 @@ def state_is_accepting(self, src) -> "bool":
|
||||||
%include <spot/twaalgos/stutter.hh>
|
%include <spot/twaalgos/stutter.hh>
|
||||||
%include <spot/twaalgos/synthesis.hh>
|
%include <spot/twaalgos/synthesis.hh>
|
||||||
%include <spot/twaalgos/translate.hh>
|
%include <spot/twaalgos/translate.hh>
|
||||||
%include <spot/twaalgos/translate_aa.hh>
|
|
||||||
%include <spot/twaalgos/toweak.hh>
|
%include <spot/twaalgos/toweak.hh>
|
||||||
%include <spot/twaalgos/hoa.hh>
|
%include <spot/twaalgos/hoa.hh>
|
||||||
%include <spot/twaalgos/dtwasat.hh>
|
%include <spot/twaalgos/dtwasat.hh>
|
||||||
|
|
|
||||||
10
spot.spec.in
10
spot.spec.in
|
|
@ -71,16 +71,16 @@ logic (LTL & PSL).
|
||||||
|
|
||||||
%files -n libspot
|
%files -n libspot
|
||||||
%{_libdir}/libbddx.a
|
%{_libdir}/libbddx.a
|
||||||
%exclude %{_libdir}/libbddx.la
|
%{_libdir}/libbddx.la
|
||||||
%{_libdir}/libbddx.so*
|
%{_libdir}/libbddx.so*
|
||||||
%{_libdir}/libspot.a
|
%{_libdir}/libspot.a
|
||||||
%exclude %{_libdir}/libspot.la
|
%{_libdir}/libspot.la
|
||||||
%{_libdir}/libspot.so*
|
%{_libdir}/libspot.so*
|
||||||
%{_libdir}/libspotgen.a
|
%{_libdir}/libspotgen.a
|
||||||
%exclude %{_libdir}/libspotgen.la
|
%{_libdir}/libspotgen.la
|
||||||
%{_libdir}/libspotgen.so*
|
%{_libdir}/libspotgen.so*
|
||||||
%{_libdir}/libspotltsmin.a
|
%{_libdir}/libspotltsmin.a
|
||||||
%exclude %{_libdir}/libspotltsmin.la
|
%{_libdir}/libspotltsmin.la
|
||||||
%{_libdir}/libspotltsmin.so*
|
%{_libdir}/libspotltsmin.so*
|
||||||
%license COPYING
|
%license COPYING
|
||||||
%doc AUTHORS COPYING NEWS README THANKS
|
%doc AUTHORS COPYING NEWS README THANKS
|
||||||
|
|
@ -121,7 +121,7 @@ temporal logic (LTL & PSL).
|
||||||
%dir %{python3_sitearch}/spot
|
%dir %{python3_sitearch}/spot
|
||||||
%{python3_sitearch}/spot/*
|
%{python3_sitearch}/spot/*
|
||||||
%{python3_sitearch}/_buddy.*.a
|
%{python3_sitearch}/_buddy.*.a
|
||||||
%exclude %{python3_sitearch}/_buddy.*.la
|
%{python3_sitearch}/_buddy.*.la
|
||||||
%{python3_sitearch}/_buddy.*.so
|
%{python3_sitearch}/_buddy.*.so
|
||||||
%license COPYING
|
%license COPYING
|
||||||
%doc AUTHORS COPYING NEWS README THANKS
|
%doc AUTHORS COPYING NEWS README THANKS
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
## -*- coding: utf-8 -*-
|
## -*- coding: utf-8 -*-
|
||||||
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020, 2022
|
## Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2016, 2017, 2020
|
||||||
## Laboratoire de Recherche et Développement de l'Epita (LRDE).
|
## Laboratoire de Recherche et Développement de l'Epita (LRDE).
|
||||||
## Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
## Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
## 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
|
lib_LTLIBRARIES = libspot.la
|
||||||
libspot_la_SOURCES =
|
libspot_la_SOURCES =
|
||||||
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined @LIBSPOT_PTHREAD@ $(SYMBOLIC_LDFLAGS)
|
libspot_la_LDFLAGS = $(BUDDY_LDFLAGS) -no-undefined $(SYMBOLIC_LDFLAGS)
|
||||||
libspot_la_LIBADD = \
|
libspot_la_LIBADD = \
|
||||||
kripke/libkripke.la \
|
kripke/libkripke.la \
|
||||||
misc/libmisc.la \
|
misc/libmisc.la \
|
||||||
|
|
@ -68,7 +68,6 @@ libspot.pc: $(srcdir)/libspot.pc.in Makefile
|
||||||
-e 's![@]includedir[@]!$(includedir)!g' \
|
-e 's![@]includedir[@]!$(includedir)!g' \
|
||||||
-e 's![@]libdir[@]!$(libdir)!g' \
|
-e 's![@]libdir[@]!$(libdir)!g' \
|
||||||
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
|
-e 's![@]PACKAGE_VERSION[@]!$(PACKAGE_VERSION)!g' \
|
||||||
-e 's![@]LIBSPOT_PTHREAD[@]!$(LIBSPOT_PTHREAD)!g' \
|
|
||||||
$(srcdir)/libspot.pc.in > $@.tmp && mv $@.tmp $@
|
$(srcdir)/libspot.pc.in > $@.tmp && mv $@.tmp $@
|
||||||
|
|
||||||
CLEANFILES = libspot.pc
|
CLEANFILES = libspot.pc
|
||||||
|
|
|
||||||
|
|
@ -583,7 +583,7 @@ struct _ConcurrentHashSet : HashSetBase< Cell >
|
||||||
return begin() + size();
|
return begin() + size();
|
||||||
}
|
}
|
||||||
|
|
||||||
Row() noexcept : _data( nullptr ), _size( 0 ) {}
|
Row() : _data( nullptr ), _size( 0 ) {}
|
||||||
~Row() { free(); }
|
~Row() { free(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2019, 2021-2022 Laboratoire de Recherche et
|
// Copyright (C) 2017-2019, 2021 Laboratoire de Recherche et
|
||||||
// Developpement de l'EPITA (LRDE).
|
// Developpement de l'EPITA (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -220,48 +220,13 @@ namespace spot
|
||||||
return aut;
|
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)
|
twa_graph_ptr aut_pattern(aut_pattern_id pattern, int n, bdd_dict_ptr dict)
|
||||||
{
|
{
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
{
|
{
|
||||||
std::ostringstream err;
|
std::ostringstream err;
|
||||||
err << "pattern argument for " << aut_pattern_name(pattern)
|
err << "pattern argument for " << aut_pattern_name(pattern)
|
||||||
<< " should be non-negative";
|
<< " should be positive";
|
||||||
throw std::runtime_error(err.str());
|
throw std::runtime_error(err.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -276,10 +241,6 @@ namespace spot
|
||||||
return l_dsa(n, dict);
|
return l_dsa(n, dict);
|
||||||
case AUT_M_NBA:
|
case AUT_M_NBA:
|
||||||
return m_nba(n, dict);
|
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:
|
case AUT_END:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -294,8 +255,6 @@ namespace spot
|
||||||
"l-nba",
|
"l-nba",
|
||||||
"l-dsa",
|
"l-dsa",
|
||||||
"m-nba",
|
"m-nba",
|
||||||
"cyclist-trace-nba",
|
|
||||||
"cyclist-proof-dba",
|
|
||||||
};
|
};
|
||||||
// Make sure we do not forget to update the above table every
|
// Make sure we do not forget to update the above table every
|
||||||
// time a new pattern is added.
|
// time a new pattern is added.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017, 2019, 2022 Laboratoire de Recherche et Developpement de
|
// Copyright (C) 2017, 2019 Laboratoire de Recherche et Developpement de
|
||||||
// l'EPITA (LRDE).
|
// l'EPITA (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -79,24 +79,6 @@ namespace spot
|
||||||
/// propositions to encode the $n+1$ letters used in the
|
/// propositions to encode the $n+1$ letters used in the
|
||||||
/// original alphabet.
|
/// original alphabet.
|
||||||
AUT_M_NBA,
|
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
|
AUT_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2019, 2022 Laboratoire de Recherche et Developpement
|
// Copyright (C) 2012-2019 Laboratoire de Recherche et Developpement
|
||||||
// de l'EPITA (LRDE).
|
// de l'EPITA (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -1198,13 +1198,13 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
static formula
|
static formula
|
||||||
pps_arbiter(std::string r_, std::string g_, unsigned n, bool strict_)
|
pps_arbiter(std::string r_, std::string g_, int n, bool strict_)
|
||||||
{
|
{
|
||||||
formula* r = new formula[n];
|
formula* r = new formula[n];
|
||||||
formula* g = new formula[n];
|
formula* g = new formula[n];
|
||||||
std::vector<formula> res;
|
std::vector<formula> res;
|
||||||
|
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
r[i] = formula::ap(r_ + std::to_string(i + 1));
|
r[i] = formula::ap(r_ + std::to_string(i + 1));
|
||||||
g[i] = formula::ap(g_ + std::to_string(i + 1));
|
g[i] = formula::ap(g_ + std::to_string(i + 1));
|
||||||
|
|
@ -1218,17 +1218,17 @@ namespace spot
|
||||||
formula phi_s;
|
formula phi_s;
|
||||||
{
|
{
|
||||||
std::vector<formula> res;
|
std::vector<formula> res;
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
res.push_back(formula::Not(r[i]));
|
res.push_back(formula::Not(r[i]));
|
||||||
theta_e = formula::And(res);
|
theta_e = formula::And(res);
|
||||||
|
|
||||||
res.clear();
|
res.clear();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
res.push_back(formula::Not(g[i]));
|
res.push_back(formula::Not(g[i]));
|
||||||
theta_s = formula::And(res);
|
theta_s = formula::And(res);
|
||||||
|
|
||||||
res.clear();
|
res.clear();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
formula left = formula::Xor(r[i], g[i]);
|
formula left = formula::Xor(r[i], g[i]);
|
||||||
formula right = formula::Equiv(r[i], formula::X(r[i]));
|
formula right = formula::Equiv(r[i], formula::X(r[i]));
|
||||||
|
|
@ -1237,9 +1237,9 @@ namespace spot
|
||||||
psi_e = formula::And(res);
|
psi_e = formula::And(res);
|
||||||
|
|
||||||
res.clear();
|
res.clear();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
for (unsigned j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j)
|
||||||
res.push_back(formula::Not(formula::And({g[i], g[j]})));
|
res.push_back(formula::Not(formula::And({g[i], g[j]})));
|
||||||
formula left = formula::Equiv(r[i], g[i]);
|
formula left = formula::Equiv(r[i], g[i]);
|
||||||
formula right = formula::Equiv(g[i], formula::X(g[i]));
|
formula right = formula::Equiv(g[i], formula::X(g[i]));
|
||||||
|
|
@ -1248,7 +1248,7 @@ namespace spot
|
||||||
psi_s = formula::And(res);
|
psi_s = formula::And(res);
|
||||||
|
|
||||||
res.clear();
|
res.clear();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
formula f = formula::Not(formula::And({r[i], g[i]}));
|
formula f = formula::Not(formula::And({r[i], g[i]}));
|
||||||
res.push_back(formula::G(formula::F(f)));
|
res.push_back(formula::G(formula::F(f)));
|
||||||
|
|
@ -1256,7 +1256,7 @@ namespace spot
|
||||||
phi_e = formula::And(res);
|
phi_e = formula::And(res);
|
||||||
|
|
||||||
res.clear();
|
res.clear();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
res.push_back(formula::G(formula::F(formula::Equiv(r[i], g[i]))));
|
res.push_back(formula::G(formula::F(formula::Equiv(r[i], g[i]))));
|
||||||
}
|
}
|
||||||
|
|
@ -1267,9 +1267,9 @@ namespace spot
|
||||||
|
|
||||||
if (!strict_)
|
if (!strict_)
|
||||||
{
|
{
|
||||||
formula left = formula::And({formula::G(psi_e), phi_e});
|
|
||||||
formula imp =
|
formula imp =
|
||||||
formula::Implies(left, formula::And({formula::G(psi_s), phi_s}));
|
formula::Implies(formula::And({formula::G(psi_e), phi_e}),
|
||||||
|
formula::And({formula::G(psi_s), phi_s}));
|
||||||
return formula::Implies(theta_e, formula::And({theta_s, imp}));
|
return formula::Implies(theta_e, formula::And({theta_s, imp}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1281,21 +1281,6 @@ 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)
|
formula ltl_pattern(ltl_pattern_id pattern, int n, int m)
|
||||||
{
|
{
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
|
|
@ -1332,8 +1317,6 @@ namespace spot
|
||||||
return dac_pattern(n);
|
return dac_pattern(n);
|
||||||
case LTL_EH_PATTERNS:
|
case LTL_EH_PATTERNS:
|
||||||
return eh_pattern(n);
|
return eh_pattern(n);
|
||||||
case LTL_EIL_GSI:
|
|
||||||
return eil_gsi(n, "a", "b", "c");
|
|
||||||
case LTL_FXG_OR:
|
case LTL_FXG_OR:
|
||||||
return FXG_or_n("p", n);
|
return FXG_or_n("p", n);
|
||||||
case LTL_GF_EQUIV:
|
case LTL_GF_EQUIV:
|
||||||
|
|
@ -1435,7 +1418,6 @@ namespace spot
|
||||||
"ccj-beta-prime",
|
"ccj-beta-prime",
|
||||||
"dac-patterns",
|
"dac-patterns",
|
||||||
"eh-patterns",
|
"eh-patterns",
|
||||||
"eil-gsi",
|
|
||||||
"fxg-or",
|
"fxg-or",
|
||||||
"gf-equiv",
|
"gf-equiv",
|
||||||
"gf-equiv-xn",
|
"gf-equiv-xn",
|
||||||
|
|
@ -1503,7 +1485,6 @@ namespace spot
|
||||||
return 55;
|
return 55;
|
||||||
case LTL_EH_PATTERNS:
|
case LTL_EH_PATTERNS:
|
||||||
return 12;
|
return 12;
|
||||||
case LTL_EIL_GSI:
|
|
||||||
case LTL_FXG_OR:
|
case LTL_FXG_OR:
|
||||||
case LTL_GF_EQUIV:
|
case LTL_GF_EQUIV:
|
||||||
case LTL_GF_EQUIV_XN:
|
case LTL_GF_EQUIV_XN:
|
||||||
|
|
@ -1573,7 +1554,6 @@ namespace spot
|
||||||
case LTL_CCJ_BETA_PRIME:
|
case LTL_CCJ_BETA_PRIME:
|
||||||
case LTL_DAC_PATTERNS:
|
case LTL_DAC_PATTERNS:
|
||||||
case LTL_EH_PATTERNS:
|
case LTL_EH_PATTERNS:
|
||||||
case LTL_EIL_GSI:
|
|
||||||
case LTL_FXG_OR:
|
case LTL_FXG_OR:
|
||||||
case LTL_GF_EQUIV:
|
case LTL_GF_EQUIV:
|
||||||
case LTL_GF_EQUIV_XN:
|
case LTL_GF_EQUIV_XN:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2019, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2017, 2018, 2019 Laboratoire de Recherche et Developpement de
|
||||||
// Developpement de l'EPITA (LRDE).
|
// l'EPITA (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -56,8 +56,6 @@ namespace spot
|
||||||
/// 12 formulas from Etessami and Holzmann.
|
/// 12 formulas from Etessami and Holzmann.
|
||||||
/// \cite etessami.00.concur
|
/// \cite etessami.00.concur
|
||||||
LTL_EH_PATTERNS,
|
LTL_EH_PATTERNS,
|
||||||
/// Familly sent by Edmond Irani Liu
|
|
||||||
LTL_EIL_GSI,
|
|
||||||
/// `F(p0 | XG(p1 | XG(p2 | ... XG(pn))))`
|
/// `F(p0 | XG(p1 | XG(p2 | ... XG(pn))))`
|
||||||
LTL_FXG_OR,
|
LTL_FXG_OR,
|
||||||
/// `(GFa1 & GFa2 & ... & GFan) <-> GFz`
|
/// `(GFa1 & GFa2 & ... & GFan) <-> GFz`
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014-2018, 2020-2022 Laboratoire de Recherche et
|
// Copyright (C) 2014-2018, 2020, 2021 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita.
|
// Développement de l'Epita.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <spot/misc/common.hh>
|
#include <spot/misc/common.hh>
|
||||||
#include <spot/misc/_config.h>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
@ -29,9 +28,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#ifdef SPOT_ENABLE_PTHREAD
|
|
||||||
# include <thread>
|
|
||||||
#endif // SPOT_ENABLE_PTHREAD
|
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
|
@ -557,11 +553,10 @@ namespace spot
|
||||||
{
|
{
|
||||||
std::map<std::vector<unsigned>, unsigned> uniq_;
|
std::map<std::vector<unsigned>, unsigned> uniq_;
|
||||||
G& g_;
|
G& g_;
|
||||||
unsigned acc_sink_;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
univ_dest_mapper(G& graph, unsigned sink = -1u)
|
univ_dest_mapper(G& graph)
|
||||||
: g_(graph), acc_sink_(sink)
|
: g_(graph)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,9 +566,6 @@ namespace spot
|
||||||
std::vector<unsigned> tmp(begin, end);
|
std::vector<unsigned> tmp(begin, end);
|
||||||
std::sort(tmp.begin(), tmp.end());
|
std::sort(tmp.begin(), tmp.end());
|
||||||
tmp.erase(std::unique(tmp.begin(), tmp.end()), 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);
|
auto p = uniq_.emplace(tmp, 0);
|
||||||
if (p.second)
|
if (p.second)
|
||||||
p.first->second = g_.new_univ_dests(tmp.begin(), tmp.end());
|
p.first->second = g_.new_univ_dests(tmp.begin(), tmp.end());
|
||||||
|
|
@ -808,23 +800,8 @@ namespace spot
|
||||||
return *dst_begin;
|
return *dst_begin;
|
||||||
SPOT_ASSERT(sz > 1);
|
SPOT_ASSERT(sz > 1);
|
||||||
unsigned d = dests_.size();
|
unsigned d = dests_.size();
|
||||||
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_.emplace_back(sz);
|
||||||
dests_.insert(dests_.end(), dst_begin, dst_end);
|
dests_.insert(dests_.end(), dst_begin, dst_end);
|
||||||
}
|
|
||||||
return ~d;
|
return ~d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1249,78 +1226,6 @@ namespace spot
|
||||||
std::stable_sort(edges_.begin() + 1, edges_.end(), p);
|
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
|
/// \brief Sort edges of the given states
|
||||||
///
|
///
|
||||||
/// \tparam Predicate : Comparison type
|
/// \tparam Predicate : Comparison type
|
||||||
|
|
@ -1338,19 +1243,14 @@ namespace spot
|
||||||
//dump_storage(std::cerr);
|
//dump_storage(std::cerr);
|
||||||
auto pi = [&](unsigned t1, unsigned t2)
|
auto pi = [&](unsigned t1, unsigned t2)
|
||||||
{return p(edges_[t1], edges_[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_;
|
std::vector<unsigned> sort_idx_;
|
||||||
unsigned ns = num_states();
|
for (unsigned i = 0; i < num_states(); ++i)
|
||||||
for (unsigned i = 0; i < ns; ++i)
|
|
||||||
{
|
{
|
||||||
if (to_sort_ptr && !(*to_sort_ptr)[i])
|
if (to_sort_ptr && !(*to_sort_ptr)[i])
|
||||||
continue;
|
continue;
|
||||||
unsigned t = states_[i].succ;
|
|
||||||
if (t == 0)
|
|
||||||
continue;
|
|
||||||
sort_idx_.clear();
|
sort_idx_.clear();
|
||||||
|
unsigned t = states_[i].succ;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sort_idx_.push_back(t);
|
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/
|
URL: https://spot.lrde.epita.fr/
|
||||||
Version: @PACKAGE_VERSION@
|
Version: @PACKAGE_VERSION@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
Libs: -L${libdir} -lspot @LIBSPOT_PTHREAD@
|
Libs: -L${libdir} -lspot
|
||||||
Requires: libbddx
|
Requires: libbddx
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017, 2018, 2020, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2017, 2018, 2020 Laboratoire de Recherche et Développement de
|
||||||
// Développement de l'Epita (LRDE)
|
// l'Epita (LRDE)
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -400,10 +400,10 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: I think we only need visible aps. E.g., if the system has
|
// FIXME I think we only need visbles aps, i.e. if the system has
|
||||||
// variables P_0.var1 and P_0.var2 but the property automaton only
|
// following variables, i.e. P_0.var1 and P_0.var2 but the property
|
||||||
// mentions P_0.var2, we do not need to capture (in the resulting
|
// automaton only mention P_0.var2, we do not need to capture (in
|
||||||
// cube) any atomic proposition for P_0.var1
|
// the resulting cube) any atomic proposition for P_0.var1
|
||||||
void
|
void
|
||||||
kripkecube<cspins_state,
|
kripkecube<cspins_state,
|
||||||
cspins_iterator>::match_aps(std::vector<std::string>& aps,
|
cspins_iterator>::match_aps(std::vector<std::string>& aps,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||||
// Developpement de l'Epita
|
// Developpement de l'Epita
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -127,7 +127,7 @@ namespace spot
|
||||||
bool b = it.isnew();
|
bool b = it.isnew();
|
||||||
|
|
||||||
// Insertion failed, delete element
|
// 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)
|
if (!b)
|
||||||
p_.deallocate(v);
|
p_.deallocate(v);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||||
// Developpement de l'Epita
|
// Developpement de l'Epita
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -251,7 +251,7 @@ namespace spot
|
||||||
uf_element* q;
|
uf_element* q;
|
||||||
uf_element* r;
|
uf_element* r;
|
||||||
|
|
||||||
do
|
while (true)
|
||||||
{
|
{
|
||||||
a_root = find(a);
|
a_root = find(a);
|
||||||
b_root = find(b);
|
b_root = find(b);
|
||||||
|
|
@ -261,24 +261,28 @@ namespace spot
|
||||||
// Update acceptance condition
|
// Update acceptance condition
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
||||||
|
a_root->acc |= acc;
|
||||||
acc |= a_root->acc;
|
acc |= a_root->acc;
|
||||||
a_root->acc = acc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (a_root->parent.load() != a_root)
|
while (a_root->parent.load() != a_root)
|
||||||
{
|
{
|
||||||
a_root = find(a_root);
|
a_root = find(a_root);
|
||||||
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
std::lock_guard<std::mutex> rlock(a_root->acc_mutex_);
|
||||||
|
a_root->acc |= acc;
|
||||||
acc |= a_root->acc;
|
acc |= a_root->acc;
|
||||||
a_root->acc = acc;
|
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = std::max(a_root, b_root);
|
r = std::max(a_root, b_root);
|
||||||
q = std::min(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);
|
uf_element* a_list = lock_list(a);
|
||||||
if (a_list == nullptr)
|
if (a_list == nullptr)
|
||||||
|
|
@ -325,8 +329,9 @@ namespace spot
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
||||||
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
||||||
acc |= r->acc | q->acc;
|
q->acc |= acc;
|
||||||
r->acc = q->acc = acc;
|
r->acc |= q->acc;
|
||||||
|
acc |= r->acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (r->parent.load() != r)
|
while (r->parent.load() != r)
|
||||||
|
|
@ -334,8 +339,8 @@ namespace spot
|
||||||
r = find(r);
|
r = find(r);
|
||||||
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
std::lock_guard<std::mutex> rlock(r->acc_mutex_);
|
||||||
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
std::lock_guard<std::mutex> qlock(q->acc_mutex_);
|
||||||
acc |= r->acc | q->acc;
|
r->acc |= q->acc;
|
||||||
r->acc = acc;
|
acc |= r->acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_list(a_list);
|
unlock_list(a_list);
|
||||||
|
|
@ -355,7 +360,9 @@ namespace spot
|
||||||
a_status = a->list_status_.load();
|
a_status = a->list_status_.load();
|
||||||
|
|
||||||
if (a_status == list_status::BUSY)
|
if (a_status == list_status::BUSY)
|
||||||
|
{
|
||||||
return a;
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
if (a_status == list_status::DONE)
|
if (a_status == list_status::DONE)
|
||||||
break;
|
break;
|
||||||
|
|
@ -400,7 +407,9 @@ namespace spot
|
||||||
b_status = b->list_status_.load();
|
b_status = b->list_status_.load();
|
||||||
|
|
||||||
if (b_status == list_status::BUSY)
|
if (b_status == list_status::BUSY)
|
||||||
|
{
|
||||||
return b;
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
if (b_status == list_status::DONE)
|
if (b_status == list_status::DONE)
|
||||||
break;
|
break;
|
||||||
|
|
@ -547,8 +556,8 @@ namespace spot
|
||||||
|
|
||||||
{
|
{
|
||||||
auto root = uf_.find(w.second);
|
auto root = uf_.find(w.second);
|
||||||
std::lock_guard<std::mutex> lock(root->acc_mutex_);
|
std::lock_guard<std::mutex> lock(w.second->acc_mutex_);
|
||||||
scc_acc = root->acc;
|
scc_acc = w.second->acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cycle found in SCC and it contains acceptance condition
|
// cycle found in SCC and it contains acceptance condition
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2020, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2015, 2016, 2017, 2018, 2019, 2020 Laboratoire de Recherche et
|
||||||
// Developpement de l'Epita
|
// Developpement de l'Epita
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -191,7 +191,9 @@ namespace spot
|
||||||
{
|
{
|
||||||
// Try to insert the new state in the shared map.
|
// Try to insert the new state in the shared map.
|
||||||
auto it = map_.insert(s);
|
auto it = map_.insert(s);
|
||||||
SPOT_ASSERT(!it.isnew()); // should never be new in a red DFS
|
bool b = it.isnew();
|
||||||
|
|
||||||
|
SPOT_ASSERT(!b); // should never be new in a red DFS
|
||||||
bool red = ((*it)).colors->red.load();
|
bool red = ((*it)).colors->red.load();
|
||||||
bool cyan = ((*it)).colors->l[tid_].cyan;
|
bool cyan = ((*it)).colors->l[tid_].cyan;
|
||||||
bool in_Rp = ((*it)).colors->l[tid_].is_in_Rp;
|
bool in_Rp = ((*it)).colors->l[tid_].is_in_Rp;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015-2016, 2018-, 20222022 Laboratoire de Recherche et
|
// Copyright (C) 2015-2016, 2018-2021 Laboratoire de Recherche et
|
||||||
// Developpement de l'Epita
|
// Developpement de l'Epita
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// 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
|
/// \brief This class implements the sequential emptiness check as
|
||||||
/// presented in "Three SCC-based Emptiness Checks for Generalized
|
/// presented in "Three SCC-based Emptiness Checks for Generalized
|
||||||
/// Büchi Automata" (Renault et al, LPAR 2013). Among the three
|
/// B\¨uchi Automata" (Renault et al, LPAR 2013). Among the three
|
||||||
/// emptiness checks that have been proposed, we opted to implement
|
/// emptiness check that has been proposed we opted to implement
|
||||||
/// yGabow's one.
|
/// the Gabow's one.
|
||||||
template<typename State, typename SuccIterator,
|
template<typename State, typename SuccIterator,
|
||||||
typename StateHash, typename StateEqual>
|
typename StateHash, typename StateEqual>
|
||||||
class SPOT_API lpar13
|
class SPOT_API lpar13
|
||||||
|
|
@ -62,8 +62,8 @@ namespace spot
|
||||||
size_t
|
size_t
|
||||||
operator()(const product_state that) const noexcept
|
operator()(const product_state that) const noexcept
|
||||||
{
|
{
|
||||||
// FIXME: wang32_hash(that.st_prop) could have been
|
// FIXME! wang32_hash(that.st_prop) could have
|
||||||
// pre-calculated!
|
// been pre-calculated!
|
||||||
StateHash hasher;
|
StateHash hasher;
|
||||||
return wang32_hash(that.st_prop) ^ hasher(that.st_kripke);
|
return wang32_hash(that.st_prop) ^ hasher(that.st_kripke);
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +135,7 @@ namespace spot
|
||||||
map[newtop])))
|
map[newtop])))
|
||||||
{
|
{
|
||||||
sys_.recycle(todo.back().it_kripke, tid_);
|
sys_.recycle(todo.back().it_kripke, tid_);
|
||||||
// FIXME: a local storage for twacube iterator?
|
// FIXME a local storage for twacube iterator?
|
||||||
todo.pop_back();
|
todo.pop_back();
|
||||||
if (SPOT_UNLIKELY(found_))
|
if (SPOT_UNLIKELY(found_))
|
||||||
{
|
{
|
||||||
|
|
@ -346,7 +346,7 @@ namespace spot
|
||||||
ctrx_element* current = front;
|
ctrx_element* current = front;
|
||||||
while (current != nullptr)
|
while (current != nullptr)
|
||||||
{
|
{
|
||||||
// FIXME: also display acc?
|
// FIXME also display acc?
|
||||||
res = res + " " +
|
res = res + " " +
|
||||||
std::to_string(current->prod_st->st_prop) +
|
std::to_string(current->prod_st->st_prop) +
|
||||||
+ "*" +
|
+ "*" +
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
## -*- coding: utf-8 -*-
|
## -*- coding: utf-8 -*-
|
||||||
## Copyright (C) 2011-2014, 2016-2018, 2020-2022 Laboratoire de
|
## Copyright (C) 2011-2014, 2016-2018, 2020-2021 Laboratoire de
|
||||||
## Recherche et Développement de l'Epita (LRDE).
|
## Recherche et Développement de l'Epita (LRDE).
|
||||||
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
||||||
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2021, 2023 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -111,22 +111,22 @@ namespace spot
|
||||||
return;
|
return;
|
||||||
if (storage_ == &local_storage_)
|
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)));
|
(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)
|
for (size_t i = 0; i < block_count_; ++i)
|
||||||
new_storage[i] = storage_[i];
|
new_storage_[i] = storage_[i];
|
||||||
storage_ = new_storage;
|
storage_ = new_storage_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
block_t* new_storage = static_cast<block_t*>
|
auto old = storage_;
|
||||||
(realloc(storage_, new_block_count * sizeof(block_t)));
|
storage_ = static_cast<block_t*>
|
||||||
if (SPOT_UNLIKELY(!new_storage))
|
(realloc(old, new_block_count * sizeof(block_t)));
|
||||||
// storage_, untouched, will be freed by the destructor.
|
if (!storage_)
|
||||||
|
{
|
||||||
|
free(old);
|
||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
storage_ = new_storage;
|
}
|
||||||
}
|
}
|
||||||
block_count_ = new_block_count;
|
block_count_ = new_block_count;
|
||||||
}
|
}
|
||||||
|
|
@ -134,8 +134,8 @@ namespace spot
|
||||||
private:
|
private:
|
||||||
void grow()
|
void grow()
|
||||||
{
|
{
|
||||||
size_t new_block_count = (block_count_ + 1) * 7 / 5;
|
size_t new_block_count_ = (block_count_ + 1) * 7 / 5;
|
||||||
reserve_blocks(new_block_count);
|
reserve_blocks(new_block_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013-2022 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013-2021 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -145,27 +145,6 @@ 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.
|
// 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