diff --git a/.gitignore b/.gitignore index 3c761969d..13689e55f 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,5 @@ nbproject/ *.out resources/3rdparty/cudd-3.0.0/Makefile.in resources/3rdparty/cudd-3.0.0/aclocal.m4 -# Python config -stormpy/setup.cfg # Travis helpers travis/mtime_cache/cache.json diff --git a/.travis.yml b/.travis.yml index 7b8de9321..1074ba368 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -# This file was inspired from https://github.com/google/fruit - # # General config # @@ -27,7 +25,7 @@ notifications: on_failure: always on_success: change recipients: - secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w=" + secure: "BoMQTBWnkh4ZLIHEaKu0tAKDohhVmOQ2pz/fjc+ScKG8mtvXqtpx0TiyePOUV1MuYNZiAP7x4mwABcoid55SwZ4+LPjd8uxXNfOji9B9GW5YqbqRvAeh7Es7dx48MyLYPIezjoryHH9R3Q2zZ9gmxgtw5eirjURcLNTXpKAwq/oOsKvh+vhOx4Qierw98wEXjMV7ipBzE4cfkgUbbX7oxGh1nsAsCew+rRmNLijfmE9tctYdH5W0wE+zC9ik+12Xyk3FwsDIABirPHfeCcEl+b9I0h1a2vZSZIA+sCDkIGKTiv9pCnsthn5LJc9pMLX7B/Wf6xLGMzpSiw3P1ZzjXpOE026WuyhTMVXqZYvbl7cJoNZiLCfTYg3MQVq5NHkq0h0jInIH7QlZYd0hZPOGONwdy17O1QmnX2Weq6G+Ps9siLVKFba37+y5PfRYkiUatJvDf2f7Jdxye6TWrUmlxQkAvs65ioyr8doad7IT1/yaGr/rBpXeQqZp6zNoMYr/cCRAYX6nOrnSszgiIWEc8QMMx+G31v77Uvd++9VG4MG9gbdpexpfYRNzKAxDarSaYEOuaWm2Z6R87bpNcjA+tW0hnBHBzRx0NFYYqXyW0tpVO9+035A9CHrLDLz77r4jJttcRvrP2rTbTBiwuhpmiufRyk3BuWlgzU3yaSuQV3M=" # # Configurations @@ -35,35 +33,123 @@ notifications: jobs: include: + ### + # Stage: Build Carl + ### + + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build Carl + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build_carl.sh + after_success: + - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; + - docker commit carl movesrwth/carl:travis-debug; + - docker push movesrwth/carl:travis-debug; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build Carl + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build_carl.sh + after_success: + - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; + - docker commit carl movesrwth/carl:travis; + - docker push movesrwth/carl:travis; + ### # Stage: Build (1st run) ### - # ubuntu-16.10 + # debian-9 - DefaultDebug + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build1 + - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis - stage: Build (1st run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - rm -rf build - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build1 + - travis/build.sh Build1 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (1st run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - rm -rf build + - travis/install_linux.sh + script: + - travis/build.sh Build1 + before_cache: + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -71,29 +157,82 @@ jobs: # Stage: Build (2nd run) ### - # ubuntu-16.10 + # debian-9 - DefaultDebug + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build2 + - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis - stage: Build (2nd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build2 + - travis/build.sh Build2 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (2nd run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build2 + before_cache: + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -101,29 +240,82 @@ jobs: # Stage: Build (3rd run) ### - # ubuntu-16.10 + # debian-9 - DefaultDebug - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build3 + - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease - stage: Build (3rd run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh Build3 + - travis/build.sh Build3 before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Build (3rd run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh Build3 + before_cache: + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -131,29 +323,82 @@ jobs: # Stage: Build (4th run) ### - # ubuntu-16.10 + # debian-9 - DefaultDebug + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultReleaseTravis + - stage: Build (4th run) + os: linux + compiler: gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh BuildLast + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultDebug - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh BuildLast + - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease - stage: Build (4th run) os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh BuildLast + - travis/build.sh BuildLast before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; @@ -161,37 +406,106 @@ jobs: # Stage: Test all ### - # ubuntu-16.10 + # debian-9 - DefaultDebug - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultDebug LINUX=debian-9 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh TestAll + - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # debian-9 - DefaultRelease + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=debian-9 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-17.10 - DefaultDebugTravis + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit storm mvolk/storm-debug:travis; - - docker push mvolk/storm-debug:travis; + - docker commit storm movesrwth/storm:travis-debug; + - docker push movesrwth/storm:travis-debug; + # ubuntu-17.10 - DefaultReleaseTravis - stage: Test all os: linux compiler: gcc - env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc install: - travis/install_linux.sh script: - - travis_wait 60 travis/build.sh TestAll + - travis/build.sh TestAll before_cache: - - docker cp storm:/storm/. . + - docker cp storm:/opt/storm/. . after_failure: - find build -iname '*err*.log' -type f -print -exec cat {} \; after_success: - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD"; - - docker commit storm mvolk/storm:travis; - - docker push mvolk/storm:travis; + - docker commit storm movesrwth/storm:travis; + - docker push movesrwth/storm:travis; + # ubuntu-18.04 - DefaultDebug + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultDebug LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + # ubuntu-18.04 - DefaultRelease + - stage: Test all + os: linux + compiler: gcc + env: CONFIG=DefaultRelease LINUX=ubuntu-18.04 COMPILER=gcc + install: + - travis/install_linux.sh + script: + - travis/build.sh TestAll + before_cache: + - docker cp storm:/opt/storm/. . + after_failure: + - find build -iname '*err*.log' -type f -print -exec cat {} \; + allow_failures: + - stage: Build (1st run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (2nd run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (3rd run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Build (4th run) + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc + - stage: Test all + os: linux + env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc diff --git a/CHANGELOG.md b/CHANGELOG.md index 5832b1e35..54be35d3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,17 @@ The releases of major and minor versions contain an overview of changes since th Version 1.2.x ------------- -### Version 1.2.1 (to be released) +### Version 1.2.2 (to be released) +- `storm-dft`: improvements in Galileo parser +- `storm-dft`: test cases for DFT analysis +- Sound value iteration (SVI) for DTMCs and MDPs +- Topological solver for linear equation systems and MinMax equation systems. + + +### Version 1.2.1 (2018/02) - Multi-dimensional reward bounded reachability properties for DTMCs. +- `storm-dft`: transformation of DFTs to GSPNs +- Several bug fixes ### Version 1.2.0 (2017/12) - C++ api changes: Building model takes `BuilderOptions` instead of extended list of Booleans, does not depend on settings anymore. diff --git a/CMakeLists.txt b/CMakeLists.txt index 0edec97d7..8ca3b9b7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,14 @@ set(BIN_INSTALL_DIR lib/ CACHE PATH "Installation directory for executables") set(DEF_INSTALL_CMAKE_DIR "lib/CMake/storm") set(CMAKE_INSTALL_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") +# Add CMake install prefix +foreach(p LIB BIN INCLUDE CMAKE) + set(var ${p}_INSTALL_DIR) + if(NOT IS_ABSOLUTE "${${var}}") + set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif() +endforeach() + message("CMAKE_INSTALL_DIR: ${CMAKE_INSTALL_DIR}") # If the STORM_DEVELOPER option was turned on, by default we target a debug version, otherwise a release version. @@ -179,8 +187,9 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(STORM_COMPILER_APPLECLANG ON) set(CLANG ON) set(STORM_COMPILER_ID "AppleClang") - set(CMAKE_MACOSX_RPATH ON) + set(CMAKE_MACOSX_RPATH ON) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(GCC ON) # using GCC if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) message(FATAL_ERROR "gcc version must be at least 5.0.") @@ -222,16 +231,16 @@ if (STORM_COMPILER_CLANG OR STORM_COMPILER_APPLECLANG) if(FORCE_COLOR) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics") endif() - + if (LINUX) set(CLANG_STDLIB libstdc++) else() set(CLANG_STDLIB libc++) endif() - + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=${CLANG_STDLIB} -ftemplate-depth=1024") - set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -fno-finite-math-only") - + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + if(LINUX) set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") @@ -241,20 +250,20 @@ if (STORM_COMPILER_CLANG OR STORM_COMPILER_APPLECLANG) endif() elseif (STORM_COMPILER_GCC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprefetch-loop-arrays -ffast-math -fno-finite-math-only") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fprefetch-loop-arrays") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rdynamic") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic") endif () if (STORM_USE_LTO) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto") - + # Fix for problems that occurred when using LTO on gcc. This should be removed when it # is not needed anymore as it makes the the already long link-step potentially longer. if (STORM_COMPILER_GCC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto-partition=none") endif() - + message(STATUS "Storm - Enabling link-time optimizations.") else() message(STATUS "Storm - Disabling link-time optimizations.") @@ -402,25 +411,25 @@ endif(DOXYGEN_FOUND) # try to obtain the current version from git. include(GetGitRevisionDescription) get_git_head_revision(STORM_VERSION_REFSPEC STORM_VERSION_GIT_HASH) -git_describe_checkout(STORM_GIT_VERSION_STRING) +git_describe(STORM_GIT_VERSION_STRING) # parse the git tag into variables -string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" STORM_VERSION_MAJOR "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" STORM_VERSION_MINOR "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" STORM_VERSION_PATCH "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+)\\-.*" "\\1" STORM_VERSION_COMMITS_AHEAD "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-[0-9]+\\-([a-z0-9]+).*" "\\1" STORM_VERSION_TAG_HASH "${STORM_GIT_VERSION_STRING}") -string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+\\-[0-9]+\\-[a-z0-9]+\\-(.*)" "\\1" STORM_VERSION_APPENDIX "${STORM_GIT_VERSION_STRING}") - -# now check whether the git version lookup failed -if (STORM_VERSION_MAJOR MATCHES "NOTFOUND") - include(version.cmake) - set(STORM_VERSION_GIT_HASH "") - set(STORM_VERSION_COMMITS_AHEAD 0) - set(STORM_VERSION_DIRTY boost::none) - - message(WARNING "Storm - git version information not available, statically assuming version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}.") -else() +# start with major.minor.patch +string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)$" STORM_VERSION_MATCH "${STORM_GIT_VERSION_STRING}") +set(STORM_VERSION_MAJOR "${CMAKE_MATCH_1}") +set(STORM_VERSION_MINOR "${CMAKE_MATCH_2}") +set(STORM_VERSION_PATCH "${CMAKE_MATCH_3}") +set(STORM_GIT_VERSION_REST "${CMAKE_MATCH_4}") +# parse rest of the form (-label)-commitsahead-hash-appendix +string(REGEX MATCH "^(\\-([a-z][a-z0-9\\.]+))?\\-([0-9]+)\\-([a-z0-9]+)(\\-.*)?$" STORM_VERSION_REST_MATCH "${STORM_GIT_VERSION_REST}") +set(STORM_VERSION_LABEL "${CMAKE_MATCH_2}") # might be empty +set(STORM_VERSION_COMMITS_AHEAD "${CMAKE_MATCH_3}") +set(STORM_VERSION_TAG_HASH "${CMAKE_MATCH_4}") +set(STORM_VERSION_APPENDIX "${CMAKE_MATCH_5}") # might be empty + + +set(STORM_VERSION_DIRTY boost::none) +if (NOT "${STORM_GIT_VERSION_STRING}" STREQUAL "") if ("${STORM_VERSION_APPENDIX}" MATCHES "^.*dirty.*$") set(STORM_VERSION_DIRTY "true") else() @@ -428,20 +437,43 @@ else() endif() endif() +# now check whether the git version lookup failed +set(STORM_VERSION_SOURCE "VersionSource::Git") +if (STORM_GIT_VERSION_STRING MATCHES "NOTFOUND") + set(STORM_VERSION_SOURCE "VersionSource::Static") + set(STORM_VERSION_COMMITS_AHEAD "boost::none") + include(version.cmake) + message(WARNING "Storm - git version information not available, statically assuming version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}.") +endif() + +# check whether there is a label ('alpha', 'pre', etc.) +if ("${STORM_VERSION_LABEL}" STREQUAL "") + set(STORM_VERSION_LABEL_STRING "") +else() + set(STORM_VERSION_LABEL_STRING "-${STORM_VERSION_LABEL}") +endif() + +# check for development version with commits ahead of latest tag set(STORM_VERSION_DEV "false") set(STORM_VERSION_DEV_STRING "") if(STORM_VERSION_COMMITS_AHEAD) - MATH(EXPR STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}+1") + if ("${STORM_VERSION_LABEL}" STREQUAL "") + # increase patch number to indicate newer version + MATH(EXPR STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}+1") + else() + set(STORM_VERSION_DEV_PATCH "${STORM_VERSION_PATCH}") + endif() set(STORM_VERSION_DEV "true") set(STORM_VERSION_DEV_STRING " (dev)") else() set(STORM_VERSION_DEV_PATCH ${STORM_VERSION_PATCH}) endif() +# set final Storm version set(STORM_VERSION "${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_DEV_PATCH}") -set(STORM_VERSION_STRING "${STORM_VERSION}${STORM_VERSION_DEV_STRING}") +set(STORM_VERSION_STRING "${STORM_VERSION}${STORM_VERSION_LABEL_STRING}${STORM_VERSION_DEV_STRING}") -message(STATUS "Storm - version is ${STORM_VERSION_STRING} (version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH} + ${STORM_VERSION_COMMITS_AHEAD} commits), building from git: ${STORM_VERSION_GIT_HASH} (dirty: ${STORM_VERSION_DIRTY}).") +message(STATUS "Storm - version is ${STORM_VERSION_STRING} (version ${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_PATCH}${STORM_VERSION_LABEL_STRING} + ${STORM_VERSION_COMMITS_AHEAD} commits), building from git: ${STORM_VERSION_GIT_HASH} (dirty: ${STORM_VERSION_DIRTY}).") # Configure a header file to pass some of the CMake settings to the source code @@ -476,4 +508,8 @@ add_subdirectory(src) include(export) +install(FILES ${CMAKE_BINARY_DIR}/stormConfig.install.cmake DESTINATION ${CMAKE_INSTALL_DIR} RENAME stormConfig.cmake) +install(FILES ${CMAKE_BINARY_DIR}/stormConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_DIR}) +install(EXPORT storm_Targets FILE stormTargets.cmake DESTINATION ${CMAKE_INSTALL_DIR}) + include(StormCPackConfig.cmake) diff --git a/README.md b/README.md index a415b376e..6dcf702a0 100644 --- a/README.md +++ b/README.md @@ -30,15 +30,15 @@ Authors Storm has been developed at RWTH Aachen University. ###### Principal developers -* Christian Dehnert +* Christian Hensel * Sebastian Junges * Joost-Pieter Katoen +* Tim Quatmann * Matthias Volk ###### Developers (lexicographical order) * Philipp Berger * David Korzeniewski -* Tim Quatmann ###### Contributors (lexicographical order) * Dimitri Bohlender diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index 979c5cbe8..5957f3b51 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -157,9 +157,9 @@ if(Z3_FOUND) endif() if(STORM_HAVE_Z3_OPTIMIZE) - message (STATUS "Storm - Linking with Z3. (Z3 version supports optimization)") + message (STATUS "Storm - Linking with Z3 (version ${Z3_VERSION}). (Z3 version supports optimization)") else() - message (STATUS "Storm - Linking with Z3. (Z3 version does not support optimization)") + message (STATUS "Storm - Linking with Z3 (version ${Z3_VERSION}). (Z3 version does not support optimization)") endif() add_imported_library(z3 SHARED ${Z3_LIBRARIES} ${Z3_INCLUDE_DIRS}) diff --git a/resources/3rdparty/cudd-3.0.0/Makefile.in b/resources/3rdparty/cudd-3.0.0/Makefile.in deleted file mode 100644 index 7bfa478ae..000000000 --- a/resources/3rdparty/cudd-3.0.0/Makefile.in +++ /dev/null @@ -1,3190 +0,0 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2017 Free Software Foundation, Inc. - -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@DDDMP_TRUE@am__append_1 = dddmp/dddmp.h -@OBJ_TRUE@am__append_2 = cplusplus/cuddObj.hh -check_PROGRAMS = cudd/testcudd$(EXEEXT) cudd/testextra$(EXEEXT) \ - st/testst$(EXEEXT) mtr/testmtr$(EXEEXT) \ - dddmp/testdddmp$(EXEEXT) cplusplus/testobj$(EXEEXT) \ - cplusplus/testmulti$(EXEEXT) nanotrav/nanotrav$(EXEEXT) -@CROSS_COMPILING_FALSE@am__append_3 = cudd/test_cudd.test \ -@CROSS_COMPILING_FALSE@ st/test_st.test mtr/test_mtr.test \ -@CROSS_COMPILING_FALSE@ dddmp/test_dddmp.test \ -@CROSS_COMPILING_FALSE@ cplusplus/test_obj.test \ -@CROSS_COMPILING_FALSE@ nanotrav/test_ntrv.test -@DDDMP_TRUE@am__append_4 = $(dddmp_sources) -@DDDMP_FALSE@am__append_5 = dddmp/libdddmp.la -@OBJ_TRUE@am__append_6 = $(cplusplus_sources) -@OBJ_FALSE@am__append_7 = cplusplus/libobj.la -@HAVE_PDFLATEX_TRUE@am__append_8 = doc/cudd.pdf doc/cudd.aux doc/cudd.idx doc/cudd.ilg doc/cudd.ind \ -@HAVE_PDFLATEX_TRUE@ doc/cudd.log doc/cudd.out doc/cudd.toc - -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/modern_cxx.m4 $(top_srcdir)/m4/w32.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(dist_check_DATA) \ - $(am__include_HEADERS_DIST) $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = Doxyfile doc/cudd.tex dddmp/exp/test1.sh \ - dddmp/exp/test2.sh dddmp/exp/test3.sh dddmp/exp/test4.sh \ - dddmp/exp/test5.sh dddmp/exp/test6.sh dddmp/exp/test7.sh -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) -cplusplus_libobj_la_LIBADD = -am__cplusplus_libobj_la_SOURCES_DIST = cplusplus/cuddObj.hh \ - cplusplus/cuddObj.cc -am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = cplusplus/cplusplus_libobj_la-cuddObj.lo -@OBJ_FALSE@am_cplusplus_libobj_la_OBJECTS = $(am__objects_1) -cplusplus_libobj_la_OBJECTS = $(am_cplusplus_libobj_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@OBJ_FALSE@am_cplusplus_libobj_la_rpath = -cudd_libcudd_la_DEPENDENCIES = -am__cudd_libcudd_la_SOURCES_DIST = cudd/cudd.h cudd/cuddInt.h \ - cudd/cuddAddAbs.c cudd/cuddAddApply.c cudd/cuddAddFind.c \ - cudd/cuddAddInv.c cudd/cuddAddIte.c cudd/cuddAddNeg.c \ - cudd/cuddAddWalsh.c cudd/cuddAndAbs.c cudd/cuddAnneal.c \ - cudd/cuddApa.c cudd/cuddAPI.c cudd/cuddApprox.c \ - cudd/cuddBddAbs.c cudd/cuddBddCorr.c cudd/cuddBddIte.c \ - cudd/cuddBridge.c cudd/cuddCache.c cudd/cuddCheck.c \ - cudd/cuddClip.c cudd/cuddCof.c cudd/cuddCompose.c \ - cudd/cuddDecomp.c cudd/cuddEssent.c cudd/cuddExact.c \ - cudd/cuddExport.c cudd/cuddGenCof.c cudd/cuddGenetic.c \ - cudd/cuddGroup.c cudd/cuddHarwell.c cudd/cuddInit.c \ - cudd/cuddInteract.c cudd/cuddLCache.c cudd/cuddLevelQ.c \ - cudd/cuddLinear.c cudd/cuddLiteral.c cudd/cuddMatMult.c \ - cudd/cuddPriority.c cudd/cuddRead.c cudd/cuddRef.c \ - cudd/cuddReorder.c cudd/cuddSat.c cudd/cuddSign.c \ - cudd/cuddSolve.c cudd/cuddSplit.c cudd/cuddSubsetHB.c \ - cudd/cuddSubsetSP.c cudd/cuddSymmetry.c cudd/cuddTable.c \ - cudd/cuddUtil.c cudd/cuddWindow.c cudd/cuddZddCount.c \ - cudd/cuddZddFuncs.c cudd/cuddZddGroup.c cudd/cuddZddIsop.c \ - cudd/cuddZddLin.c cudd/cuddZddMisc.c cudd/cuddZddPort.c \ - cudd/cuddZddReord.c cudd/cuddZddSetop.c cudd/cuddZddSymm.c \ - cudd/cuddZddUtil.c util/util.h util/cstringstream.h \ - util/cpu_stats.c util/cpu_time.c util/cstringstream.c \ - util/datalimit.c util/pathsearch.c util/pipefork.c \ - util/prtime.c util/safe_mem.c util/strsav.c util/texpand.c \ - util/ucbqsort.c st/st.h st/st.c epd/epd.c epd/epdInt.h \ - epd/epd.h mtr/mtr.h mtr/mtrInt.h mtr/mtrBasic.c mtr/mtrGroup.c \ - dddmp/dddmp.h dddmp/dddmpInt.h dddmp/dddmpBinary.c \ - dddmp/dddmpConvert.c dddmp/dddmpDbg.c dddmp/dddmpLoad.c \ - dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c dddmp/dddmpNodeBdd.c \ - dddmp/dddmpNodeCnf.c dddmp/dddmpStoreAdd.c \ - dddmp/dddmpStoreBdd.c dddmp/dddmpStoreCnf.c \ - dddmp/dddmpStoreMisc.c dddmp/dddmpUtil.c cplusplus/cuddObj.hh \ - cplusplus/cuddObj.cc -am__objects_2 = dddmp/cudd_libcudd_la-dddmpBinary.lo \ - dddmp/cudd_libcudd_la-dddmpConvert.lo \ - dddmp/cudd_libcudd_la-dddmpDbg.lo \ - dddmp/cudd_libcudd_la-dddmpLoad.lo \ - dddmp/cudd_libcudd_la-dddmpLoadCnf.lo \ - dddmp/cudd_libcudd_la-dddmpNodeAdd.lo \ - dddmp/cudd_libcudd_la-dddmpNodeBdd.lo \ - dddmp/cudd_libcudd_la-dddmpNodeCnf.lo \ - dddmp/cudd_libcudd_la-dddmpStoreAdd.lo \ - dddmp/cudd_libcudd_la-dddmpStoreBdd.lo \ - dddmp/cudd_libcudd_la-dddmpStoreCnf.lo \ - dddmp/cudd_libcudd_la-dddmpStoreMisc.lo \ - dddmp/cudd_libcudd_la-dddmpUtil.lo -@DDDMP_TRUE@am__objects_3 = $(am__objects_2) -am__objects_4 = cplusplus/cudd_libcudd_la-cuddObj.lo -@OBJ_TRUE@am__objects_5 = $(am__objects_4) -am_cudd_libcudd_la_OBJECTS = cudd/cudd_libcudd_la-cuddAddAbs.lo \ - cudd/cudd_libcudd_la-cuddAddApply.lo \ - cudd/cudd_libcudd_la-cuddAddFind.lo \ - cudd/cudd_libcudd_la-cuddAddInv.lo \ - cudd/cudd_libcudd_la-cuddAddIte.lo \ - cudd/cudd_libcudd_la-cuddAddNeg.lo \ - cudd/cudd_libcudd_la-cuddAddWalsh.lo \ - cudd/cudd_libcudd_la-cuddAndAbs.lo \ - cudd/cudd_libcudd_la-cuddAnneal.lo \ - cudd/cudd_libcudd_la-cuddApa.lo \ - cudd/cudd_libcudd_la-cuddAPI.lo \ - cudd/cudd_libcudd_la-cuddApprox.lo \ - cudd/cudd_libcudd_la-cuddBddAbs.lo \ - cudd/cudd_libcudd_la-cuddBddCorr.lo \ - cudd/cudd_libcudd_la-cuddBddIte.lo \ - cudd/cudd_libcudd_la-cuddBridge.lo \ - cudd/cudd_libcudd_la-cuddCache.lo \ - cudd/cudd_libcudd_la-cuddCheck.lo \ - cudd/cudd_libcudd_la-cuddClip.lo \ - cudd/cudd_libcudd_la-cuddCof.lo \ - cudd/cudd_libcudd_la-cuddCompose.lo \ - cudd/cudd_libcudd_la-cuddDecomp.lo \ - cudd/cudd_libcudd_la-cuddEssent.lo \ - cudd/cudd_libcudd_la-cuddExact.lo \ - cudd/cudd_libcudd_la-cuddExport.lo \ - cudd/cudd_libcudd_la-cuddGenCof.lo \ - cudd/cudd_libcudd_la-cuddGenetic.lo \ - cudd/cudd_libcudd_la-cuddGroup.lo \ - cudd/cudd_libcudd_la-cuddHarwell.lo \ - cudd/cudd_libcudd_la-cuddInit.lo \ - cudd/cudd_libcudd_la-cuddInteract.lo \ - cudd/cudd_libcudd_la-cuddLCache.lo \ - cudd/cudd_libcudd_la-cuddLevelQ.lo \ - cudd/cudd_libcudd_la-cuddLinear.lo \ - cudd/cudd_libcudd_la-cuddLiteral.lo \ - cudd/cudd_libcudd_la-cuddMatMult.lo \ - cudd/cudd_libcudd_la-cuddPriority.lo \ - cudd/cudd_libcudd_la-cuddRead.lo \ - cudd/cudd_libcudd_la-cuddRef.lo \ - cudd/cudd_libcudd_la-cuddReorder.lo \ - cudd/cudd_libcudd_la-cuddSat.lo \ - cudd/cudd_libcudd_la-cuddSign.lo \ - cudd/cudd_libcudd_la-cuddSolve.lo \ - cudd/cudd_libcudd_la-cuddSplit.lo \ - cudd/cudd_libcudd_la-cuddSubsetHB.lo \ - cudd/cudd_libcudd_la-cuddSubsetSP.lo \ - cudd/cudd_libcudd_la-cuddSymmetry.lo \ - cudd/cudd_libcudd_la-cuddTable.lo \ - cudd/cudd_libcudd_la-cuddUtil.lo \ - cudd/cudd_libcudd_la-cuddWindow.lo \ - cudd/cudd_libcudd_la-cuddZddCount.lo \ - cudd/cudd_libcudd_la-cuddZddFuncs.lo \ - cudd/cudd_libcudd_la-cuddZddGroup.lo \ - cudd/cudd_libcudd_la-cuddZddIsop.lo \ - cudd/cudd_libcudd_la-cuddZddLin.lo \ - cudd/cudd_libcudd_la-cuddZddMisc.lo \ - cudd/cudd_libcudd_la-cuddZddPort.lo \ - cudd/cudd_libcudd_la-cuddZddReord.lo \ - cudd/cudd_libcudd_la-cuddZddSetop.lo \ - cudd/cudd_libcudd_la-cuddZddSymm.lo \ - cudd/cudd_libcudd_la-cuddZddUtil.lo \ - util/cudd_libcudd_la-cpu_stats.lo \ - util/cudd_libcudd_la-cpu_time.lo \ - util/cudd_libcudd_la-cstringstream.lo \ - util/cudd_libcudd_la-datalimit.lo \ - util/cudd_libcudd_la-pathsearch.lo \ - util/cudd_libcudd_la-pipefork.lo \ - util/cudd_libcudd_la-prtime.lo \ - util/cudd_libcudd_la-safe_mem.lo \ - util/cudd_libcudd_la-strsav.lo util/cudd_libcudd_la-texpand.lo \ - util/cudd_libcudd_la-ucbqsort.lo st/cudd_libcudd_la-st.lo \ - epd/cudd_libcudd_la-epd.lo mtr/cudd_libcudd_la-mtrBasic.lo \ - mtr/cudd_libcudd_la-mtrGroup.lo $(am__objects_3) \ - $(am__objects_5) -cudd_libcudd_la_OBJECTS = $(am_cudd_libcudd_la_OBJECTS) -cudd_libcudd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(cudd_libcudd_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -dddmp_libdddmp_la_LIBADD = -am__dddmp_libdddmp_la_SOURCES_DIST = dddmp/dddmp.h dddmp/dddmpInt.h \ - dddmp/dddmpBinary.c dddmp/dddmpConvert.c dddmp/dddmpDbg.c \ - dddmp/dddmpLoad.c dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c \ - dddmp/dddmpNodeBdd.c dddmp/dddmpNodeCnf.c \ - dddmp/dddmpStoreAdd.c dddmp/dddmpStoreBdd.c \ - dddmp/dddmpStoreCnf.c dddmp/dddmpStoreMisc.c dddmp/dddmpUtil.c -am__objects_6 = dddmp/dddmp_libdddmp_la-dddmpBinary.lo \ - dddmp/dddmp_libdddmp_la-dddmpConvert.lo \ - dddmp/dddmp_libdddmp_la-dddmpDbg.lo \ - dddmp/dddmp_libdddmp_la-dddmpLoad.lo \ - dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo \ - dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo \ - dddmp/dddmp_libdddmp_la-dddmpUtil.lo -@DDDMP_FALSE@am_dddmp_libdddmp_la_OBJECTS = $(am__objects_6) -dddmp_libdddmp_la_OBJECTS = $(am_dddmp_libdddmp_la_OBJECTS) -@DDDMP_FALSE@am_dddmp_libdddmp_la_rpath = -am_cplusplus_testmulti_OBJECTS = \ - cplusplus/cplusplus_testmulti-testmulti.$(OBJEXT) -cplusplus_testmulti_OBJECTS = $(am_cplusplus_testmulti_OBJECTS) -@OBJ_FALSE@cplusplus_testmulti_DEPENDENCIES = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testmulti_DEPENDENCIES = cudd/libcudd.la -cplusplus_testmulti_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(cplusplus_testmulti_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_cplusplus_testobj_OBJECTS = \ - cplusplus/cplusplus_testobj-testobj.$(OBJEXT) -cplusplus_testobj_OBJECTS = $(am_cplusplus_testobj_OBJECTS) -@OBJ_FALSE@cplusplus_testobj_DEPENDENCIES = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testobj_DEPENDENCIES = cudd/libcudd.la -am_cudd_testcudd_OBJECTS = cudd/cudd_testcudd-testcudd.$(OBJEXT) -cudd_testcudd_OBJECTS = $(am_cudd_testcudd_OBJECTS) -cudd_testcudd_DEPENDENCIES = cudd/libcudd.la -am_cudd_testextra_OBJECTS = cudd/cudd_testextra-testextra.$(OBJEXT) -cudd_testextra_OBJECTS = $(am_cudd_testextra_OBJECTS) -cudd_testextra_DEPENDENCIES = cudd/libcudd.la -am_dddmp_testdddmp_OBJECTS = \ - dddmp/dddmp_testdddmp-testdddmp.$(OBJEXT) -dddmp_testdddmp_OBJECTS = $(am_dddmp_testdddmp_OBJECTS) -@DDDMP_FALSE@dddmp_testdddmp_DEPENDENCIES = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@dddmp_testdddmp_DEPENDENCIES = cudd/libcudd.la -am_mtr_testmtr_OBJECTS = mtr/mtr_testmtr-testmtr.$(OBJEXT) -mtr_testmtr_OBJECTS = $(am_mtr_testmtr_OBJECTS) -mtr_testmtr_DEPENDENCIES = cudd/libcudd.la -am_nanotrav_nanotrav_OBJECTS = \ - nanotrav/nanotrav_nanotrav-bnet.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-chkMterm.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-main.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrBddTest.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntr.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrHeap.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrMflow.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrShort.$(OBJEXT) \ - nanotrav/nanotrav_nanotrav-ntrZddTest.$(OBJEXT) -nanotrav_nanotrav_OBJECTS = $(am_nanotrav_nanotrav_OBJECTS) -@DDDMP_FALSE@nanotrav_nanotrav_DEPENDENCIES = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@nanotrav_nanotrav_DEPENDENCIES = cudd/libcudd.la -am_st_testst_OBJECTS = st/st_testst-testst.$(OBJEXT) -st_testst_OBJECTS = $(am_st_testst_OBJECTS) -st_testst_DEPENDENCIES = cudd/libcudd.la -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(cplusplus_libobj_la_SOURCES) $(cudd_libcudd_la_SOURCES) \ - $(dddmp_libdddmp_la_SOURCES) $(cplusplus_testmulti_SOURCES) \ - $(cplusplus_testobj_SOURCES) $(cudd_testcudd_SOURCES) \ - $(cudd_testextra_SOURCES) $(dddmp_testdddmp_SOURCES) \ - $(mtr_testmtr_SOURCES) $(nanotrav_nanotrav_SOURCES) \ - $(st_testst_SOURCES) -DIST_SOURCES = $(am__cplusplus_libobj_la_SOURCES_DIST) \ - $(am__cudd_libcudd_la_SOURCES_DIST) \ - $(am__dddmp_libdddmp_la_SOURCES_DIST) \ - $(cplusplus_testmulti_SOURCES) $(cplusplus_testobj_SOURCES) \ - $(cudd_testcudd_SOURCES) $(cudd_testextra_SOURCES) \ - $(dddmp_testdddmp_SOURCES) $(mtr_testmtr_SOURCES) \ - $(nanotrav_nanotrav_SOURCES) $(st_testst_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__include_HEADERS_DIST = cudd/cudd.h mtr/mtr.h dddmp/dddmp.h \ - cplusplus/cuddObj.hh -HEADERS = $(include_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -AM_RECURSIVE_TARGETS = cscope check recheck -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(top_srcdir)/build-aux/ar-lib \ - $(top_srcdir)/build-aux/compile \ - $(top_srcdir)/build-aux/config.guess \ - $(top_srcdir)/build-aux/config.sub \ - $(top_srcdir)/build-aux/depcomp \ - $(top_srcdir)/build-aux/install-sh \ - $(top_srcdir)/build-aux/ltmain.sh \ - $(top_srcdir)/build-aux/missing \ - $(top_srcdir)/build-aux/tap-driver.sh \ - $(top_srcdir)/cplusplus/Included.am \ - $(top_srcdir)/cudd/Included.am $(top_srcdir)/dddmp/Included.am \ - $(top_srcdir)/dddmp/exp/test1.sh.in \ - $(top_srcdir)/dddmp/exp/test2.sh.in \ - $(top_srcdir)/dddmp/exp/test3.sh.in \ - $(top_srcdir)/dddmp/exp/test4.sh.in \ - $(top_srcdir)/dddmp/exp/test5.sh.in \ - $(top_srcdir)/dddmp/exp/test6.sh.in \ - $(top_srcdir)/dddmp/exp/test7.sh.in \ - $(top_srcdir)/doc/Included.am $(top_srcdir)/doc/cudd.tex.in \ - $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am \ - $(top_srcdir)/nanotrav/Included.am \ - $(top_srcdir)/st/Included.am $(top_srcdir)/util/Included.am \ - README build-aux/ar-lib build-aux/compile \ - build-aux/config.guess build-aux/config.sub build-aux/depcomp \ - build-aux/install-sh build-aux/ltmain.sh build-aux/missing -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DOXYGEN = @DOXYGEN@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINDEX = @MAKEINDEX@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PDFLATEX = @PDFLATEX@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -ACLOCAL_AMFLAGS = -I m4 -include_HEADERS = cudd/cudd.h mtr/mtr.h $(am__append_1) \ - $(am__append_2) -check_SCRIPTS = cudd/test_cudd.test st/test_st.test mtr/test_mtr.test \ - dddmp/test_dddmp.test cplusplus/test_obj.test \ - nanotrav/test_ntrv.test -dist_check_DATA = cudd/r7x8.1.mat cudd/r7x8.1.out cudd/extra.out \ - mtr/test.groups mtr/test.out cplusplus/test.out \ - cplusplus/multi.out nanotrav/adj49.blif nanotrav/adj49.out \ - nanotrav/C17.blif nanotrav/C17.out nanotrav/C880.blif \ - nanotrav/C880.out nanotrav/closest.blif nanotrav/closest.out \ - nanotrav/ham01.blif nanotrav/ham01.out nanotrav/mult32a.blif \ - nanotrav/mult32a.out nanotrav/rcn25.blif nanotrav/rcn25.out \ - nanotrav/s27.blif nanotrav/s27.out nanotrav/s27b.blif \ - nanotrav/s27b.out nanotrav/s27c.blif nanotrav/s27c.out \ - nanotrav/s382.blif nanotrav/s382.out nanotrav/s641.blif \ - nanotrav/s641.out nanotrav/miniFirst.blif \ - nanotrav/miniSecond.blif nanotrav/miniFirst.out -EXTRA_DIST = README RELEASE.NOTES LICENSE groups.dox \ - cudd/test_cudd.test.in st/test_st.test.in mtr/test_mtr.test.in \ - dddmp/README.dddmp dddmp/README.testdddmp dddmp/RELEASE_NOTES \ - dddmp/doc dddmp/test_dddmp.test.in dddmp/exp/test1.sh.in \ - dddmp/exp/test2.sh.in dddmp/exp/test3.sh.in \ - dddmp/exp/test4.sh.in dddmp/exp/test5.sh.in \ - dddmp/exp/test6.sh.in dddmp/exp/test7.sh.in dddmp/exp/0.add \ - dddmp/exp/0.bdd dddmp/exp/0or1.bdd dddmp/exp/1.add \ - dddmp/exp/1.bdd dddmp/exp/2and3.bdd dddmp/exp/2.bdd \ - dddmp/exp/3.bdd dddmp/exp/4.bdd dddmp/exp/4.bdd.bis1 \ - dddmp/exp/4.bdd.bis2 dddmp/exp/4.bdd.bis3 dddmp/exp/4.bdd.bis4 \ - dddmp/exp/4bis.bdd dddmp/exp/4.cnf dddmp/exp/4.cnf.bis \ - dddmp/exp/4.max1 dddmp/exp/4.max2 dddmp/exp/4xor5.bdd \ - dddmp/exp/5.bdd dddmp/exp/composeids.txt dddmp/exp/one.bdd \ - dddmp/exp/s27deltaDddmp1.bdd dddmp/exp/s27deltaDddmp1.bdd.bis \ - dddmp/exp/s27deltaDddmp2.bdd dddmp/exp/s27RP1.bdd \ - dddmp/exp/varauxids.ord dddmp/exp/varnames.ord \ - dddmp/exp/zero.bdd cplusplus/test_obj.test.in nanotrav/README \ - nanotrav/nanotrav.1 nanotrav/test_ntrv.test.in doc/phase.pdf -TESTS = $(am__append_3) - -#endif -CLEANFILES = cudd/r7x8.1.tst cudd/extra.tst mtr/test.tst \ - dddmp/exp/test1.sh dddmp/exp/test2.sh dddmp/exp/test3.sh \ - dddmp/exp/test4.sh dddmp/exp/test5.sh dddmp/exp/test6.sh \ - dddmp/exp/test7.sh cplusplus/test.tst cplusplus/multi.tst \ - nanotrav/adj49.tst nanotrav/C17.tst nanotrav/C880.tst \ - nanotrav/closest.tst nanotrav/ham01.tst nanotrav/mult32a.tst \ - nanotrav/rcn25.tst nanotrav/s27.tst nanotrav/s27b.tst \ - nanotrav/s27c.tst nanotrav/s382.tst nanotrav/s641.tst \ - nanotrav/miniFirst.tst $(am__append_8) $(check_SCRIPTS) -noinst_LTLIBRARIES = $(am__append_5) $(am__append_7) -TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ - $(top_srcdir)/build-aux/tap-driver.sh - -do_subst = sed \ - -e 's,[@]EXEEXT[@],$(EXEEXT),g' \ - -e 's,[@]srcdir[@],$(srcdir),g' - -lib_LTLIBRARIES = cudd/libcudd.la -cudd_libcudd_la_SOURCES = cudd/cudd.h cudd/cuddInt.h cudd/cuddAddAbs.c \ - cudd/cuddAddApply.c cudd/cuddAddFind.c cudd/cuddAddInv.c \ - cudd/cuddAddIte.c cudd/cuddAddNeg.c cudd/cuddAddWalsh.c \ - cudd/cuddAndAbs.c cudd/cuddAnneal.c cudd/cuddApa.c \ - cudd/cuddAPI.c cudd/cuddApprox.c cudd/cuddBddAbs.c \ - cudd/cuddBddCorr.c cudd/cuddBddIte.c cudd/cuddBridge.c \ - cudd/cuddCache.c cudd/cuddCheck.c cudd/cuddClip.c \ - cudd/cuddCof.c cudd/cuddCompose.c cudd/cuddDecomp.c \ - cudd/cuddEssent.c cudd/cuddExact.c cudd/cuddExport.c \ - cudd/cuddGenCof.c cudd/cuddGenetic.c cudd/cuddGroup.c \ - cudd/cuddHarwell.c cudd/cuddInit.c cudd/cuddInteract.c \ - cudd/cuddLCache.c cudd/cuddLevelQ.c cudd/cuddLinear.c \ - cudd/cuddLiteral.c cudd/cuddMatMult.c cudd/cuddPriority.c \ - cudd/cuddRead.c cudd/cuddRef.c cudd/cuddReorder.c \ - cudd/cuddSat.c cudd/cuddSign.c cudd/cuddSolve.c \ - cudd/cuddSplit.c cudd/cuddSubsetHB.c cudd/cuddSubsetSP.c \ - cudd/cuddSymmetry.c cudd/cuddTable.c cudd/cuddUtil.c \ - cudd/cuddWindow.c cudd/cuddZddCount.c cudd/cuddZddFuncs.c \ - cudd/cuddZddGroup.c cudd/cuddZddIsop.c cudd/cuddZddLin.c \ - cudd/cuddZddMisc.c cudd/cuddZddPort.c cudd/cuddZddReord.c \ - cudd/cuddZddSetop.c cudd/cuddZddSymm.c cudd/cuddZddUtil.c \ - util/util.h util/cstringstream.h util/cpu_stats.c \ - util/cpu_time.c util/cstringstream.c util/datalimit.c \ - util/pathsearch.c util/pipefork.c util/prtime.c \ - util/safe_mem.c util/strsav.c util/texpand.c util/ucbqsort.c \ - st/st.h st/st.c epd/epd.c epd/epdInt.h epd/epd.h mtr/mtr.h \ - mtr/mtrInt.h mtr/mtrBasic.c mtr/mtrGroup.c $(am__append_4) \ - $(am__append_6) -cudd_libcudd_la_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/st \ - -I$(top_srcdir)/epd -I$(top_srcdir)/mtr -I$(top_srcdir)/util - -@OBJ_TRUE@cudd_libcudd_la_LIBTOOLFLAGS = --tag=CXX -cudd_libcudd_la_LDFLAGS = -release @PACKAGE_VERSION@ -version-info 0:0:0 \ - -no-undefined - -cudd_testcudd_SOURCES = cudd/testcudd.c -cudd_testcudd_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -cudd_testcudd_LDADD = cudd/libcudd.la -cudd_testextra_SOURCES = cudd/testextra.c -cudd_testextra_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -cudd_testextra_LDADD = cudd/libcudd.la -@CROSS_COMPILING_TRUE@@MINGW64_TRUE@cudd_libcudd_la_LIBADD = -lws2_32 -lpsapi -st_testst_SOURCES = st/testst.c -st_testst_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -st_testst_LDADD = cudd/libcudd.la -mtr_testmtr_SOURCES = mtr/testmtr.c -mtr_testmtr_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -mtr_testmtr_LDADD = cudd/libcudd.la -dddmp_sources = dddmp/dddmp.h dddmp/dddmpInt.h \ - dddmp/dddmpBinary.c dddmp/dddmpConvert.c dddmp/dddmpDbg.c \ - dddmp/dddmpLoad.c dddmp/dddmpLoadCnf.c dddmp/dddmpNodeAdd.c \ - dddmp/dddmpNodeBdd.c dddmp/dddmpNodeCnf.c dddmp/dddmpStoreAdd.c \ - dddmp/dddmpStoreBdd.c dddmp/dddmpStoreCnf.c dddmp/dddmpStoreMisc.c \ - dddmp/dddmpUtil.c - -@DDDMP_FALSE@dddmp_libdddmp_la_SOURCES = $(dddmp_sources) -@DDDMP_FALSE@dddmp_libdddmp_la_CPPFLAGS = -I$(top_srcdir)/util -I$(top_srcdir)/mtr \ -@DDDMP_FALSE@ -I$(top_srcdir)/epd -I$(top_srcdir)/cudd -I$(top_srcdir)/st - -dddmp_testdddmp_SOURCES = dddmp/testdddmp.c -@DDDMP_FALSE@dddmp_testdddmp_CPPFLAGS = $(dddmp_libdddmp_la_CPPFLAGS) -@DDDMP_TRUE@dddmp_testdddmp_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@DDDMP_FALSE@dddmp_testdddmp_LDADD = dddmp/libdddmp.la cudd/libcudd.la -@DDDMP_TRUE@dddmp_testdddmp_LDADD = cudd/libcudd.la -cplusplus_sources = cplusplus/cuddObj.hh cplusplus/cuddObj.cc -@OBJ_FALSE@cplusplus_libobj_la_SOURCES = $(cplusplus_sources) -@OBJ_FALSE@cplusplus_libobj_la_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/mtr \ -@OBJ_FALSE@ -I$(top_srcdir)/epd -I$(top_srcdir)/st - -cplusplus_testobj_SOURCES = cplusplus/testobj.cc -@OBJ_FALSE@cplusplus_testobj_CPPFLAGS = $(cplusplus_libobj_la_CPPFLAGS) -@OBJ_TRUE@cplusplus_testobj_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@OBJ_FALSE@cplusplus_testobj_LDADD = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testobj_LDADD = cudd/libcudd.la -cplusplus_testmulti_SOURCES = cplusplus/testmulti.cc -@OBJ_FALSE@cplusplus_testmulti_CPPFLAGS = $(cplusplus_libobj_la_CPPFLAGS) -@OBJ_TRUE@cplusplus_testmulti_CPPFLAGS = $(cudd_libcudd_la_CPPFLAGS) -@OBJ_FALSE@cplusplus_testmulti_LDADD = cplusplus/libobj.la \ -@OBJ_FALSE@ cudd/libcudd.la -@OBJ_TRUE@cplusplus_testmulti_LDADD = cudd/libcudd.la -@HAVE_PTHREADS_TRUE@cplusplus_testmulti_LDFLAGS = -pthread -nanotrav_nanotrav_SOURCES = nanotrav/bnet.h nanotrav/ntr.h \ - nanotrav/bnet.c nanotrav/chkMterm.c nanotrav/main.c nanotrav/ntrBddTest.c \ - nanotrav/ntr.c nanotrav/ntrHeap.c nanotrav/ntrMflow.c nanotrav/ntrShort.c \ - nanotrav/ntrZddTest.c - -nanotrav_nanotrav_CPPFLAGS = -I$(top_srcdir)/cudd -I$(top_srcdir)/mtr \ - -I$(top_srcdir)/epd -I$(top_srcdir)/st -I$(top_srcdir)/dddmp \ - -I$(top_srcdir)/util - -@DDDMP_FALSE@nanotrav_nanotrav_LDADD = dddmp/libdddmp.la \ -@DDDMP_FALSE@ cudd/libcudd.la -@DDDMP_TRUE@nanotrav_nanotrav_LDADD = cudd/libcudd.la -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/cudd/Included.am $(top_srcdir)/util/Included.am $(top_srcdir)/st/Included.am $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am $(top_srcdir)/dddmp/Included.am $(top_srcdir)/cplusplus/Included.am $(top_srcdir)/nanotrav/Included.am $(top_srcdir)/doc/Included.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/cudd/Included.am $(top_srcdir)/util/Included.am $(top_srcdir)/st/Included.am $(top_srcdir)/epd/Included.am $(top_srcdir)/mtr/Included.am $(top_srcdir)/dddmp/Included.am $(top_srcdir)/cplusplus/Included.am $(top_srcdir)/nanotrav/Included.am $(top_srcdir)/doc/Included.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -@HAVE_DOXYGEN_TRUE@Doxyfile: $(top_builddir)/config.status $(srcdir)/Doxyfile.in -@HAVE_DOXYGEN_TRUE@ cd $(top_builddir) && $(SHELL) ./config.status $@ -@HAVE_PDFLATEX_TRUE@doc/cudd.tex: $(top_builddir)/config.status $(top_srcdir)/doc/cudd.tex.in -@HAVE_PDFLATEX_TRUE@ cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test1.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test1.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test2.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test2.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test3.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test3.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test4.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test4.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test5.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test5.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test6.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test6.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -dddmp/exp/test7.sh: $(top_builddir)/config.status $(top_srcdir)/dddmp/exp/test7.sh.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } -cplusplus/$(am__dirstamp): - @$(MKDIR_P) cplusplus - @: > cplusplus/$(am__dirstamp) -cplusplus/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cplusplus/$(DEPDIR) - @: > cplusplus/$(DEPDIR)/$(am__dirstamp) -cplusplus/cplusplus_libobj_la-cuddObj.lo: cplusplus/$(am__dirstamp) \ - cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/libobj.la: $(cplusplus_libobj_la_OBJECTS) $(cplusplus_libobj_la_DEPENDENCIES) $(EXTRA_cplusplus_libobj_la_DEPENDENCIES) cplusplus/$(am__dirstamp) - $(AM_V_CXXLD)$(CXXLINK) $(am_cplusplus_libobj_la_rpath) $(cplusplus_libobj_la_OBJECTS) $(cplusplus_libobj_la_LIBADD) $(LIBS) -cudd/$(am__dirstamp): - @$(MKDIR_P) cudd - @: > cudd/$(am__dirstamp) -cudd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) cudd/$(DEPDIR) - @: > cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddApply.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddFind.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddInv.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddIte.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddNeg.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAddWalsh.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAndAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAnneal.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddApa.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddAPI.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddApprox.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddAbs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddCorr.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBddIte.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddBridge.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCache.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCheck.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddClip.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCof.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddCompose.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddDecomp.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddEssent.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddExact.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddExport.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGenCof.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGenetic.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddGroup.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddHarwell.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddInit.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddInteract.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLCache.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLevelQ.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLinear.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddLiteral.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddMatMult.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddPriority.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddRead.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddRef.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddReorder.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSat.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSign.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSolve.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSplit.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSubsetHB.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSubsetSP.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddSymmetry.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddTable.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddUtil.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddWindow.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddCount.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddFuncs.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddGroup.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddIsop.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddLin.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddMisc.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddPort.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddReord.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddSetop.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddSymm.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -cudd/cudd_libcudd_la-cuddZddUtil.lo: cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) -util/$(am__dirstamp): - @$(MKDIR_P) util - @: > util/$(am__dirstamp) -util/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) util/$(DEPDIR) - @: > util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cpu_stats.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cpu_time.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-cstringstream.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-datalimit.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-pathsearch.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-pipefork.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-prtime.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-safe_mem.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-strsav.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-texpand.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -util/cudd_libcudd_la-ucbqsort.lo: util/$(am__dirstamp) \ - util/$(DEPDIR)/$(am__dirstamp) -st/$(am__dirstamp): - @$(MKDIR_P) st - @: > st/$(am__dirstamp) -st/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) st/$(DEPDIR) - @: > st/$(DEPDIR)/$(am__dirstamp) -st/cudd_libcudd_la-st.lo: st/$(am__dirstamp) \ - st/$(DEPDIR)/$(am__dirstamp) -epd/$(am__dirstamp): - @$(MKDIR_P) epd - @: > epd/$(am__dirstamp) -epd/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) epd/$(DEPDIR) - @: > epd/$(DEPDIR)/$(am__dirstamp) -epd/cudd_libcudd_la-epd.lo: epd/$(am__dirstamp) \ - epd/$(DEPDIR)/$(am__dirstamp) -mtr/$(am__dirstamp): - @$(MKDIR_P) mtr - @: > mtr/$(am__dirstamp) -mtr/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) mtr/$(DEPDIR) - @: > mtr/$(DEPDIR)/$(am__dirstamp) -mtr/cudd_libcudd_la-mtrBasic.lo: mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) -mtr/cudd_libcudd_la-mtrGroup.lo: mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) -dddmp/$(am__dirstamp): - @$(MKDIR_P) dddmp - @: > dddmp/$(am__dirstamp) -dddmp/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) dddmp/$(DEPDIR) - @: > dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpBinary.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpConvert.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpDbg.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpLoad.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpLoadCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpNodeCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpStoreMisc.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/cudd_libcudd_la-dddmpUtil.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -cplusplus/cudd_libcudd_la-cuddObj.lo: cplusplus/$(am__dirstamp) \ - cplusplus/$(DEPDIR)/$(am__dirstamp) - -cudd/libcudd.la: $(cudd_libcudd_la_OBJECTS) $(cudd_libcudd_la_DEPENDENCIES) $(EXTRA_cudd_libcudd_la_DEPENDENCIES) cudd/$(am__dirstamp) - $(AM_V_CXXLD)$(cudd_libcudd_la_LINK) -rpath $(libdir) $(cudd_libcudd_la_OBJECTS) $(cudd_libcudd_la_LIBADD) $(LIBS) -dddmp/dddmp_libdddmp_la-dddmpBinary.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpConvert.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpDbg.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpLoad.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) -dddmp/dddmp_libdddmp_la-dddmpUtil.lo: dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) - -dddmp/libdddmp.la: $(dddmp_libdddmp_la_OBJECTS) $(dddmp_libdddmp_la_DEPENDENCIES) $(EXTRA_dddmp_libdddmp_la_DEPENDENCIES) dddmp/$(am__dirstamp) - $(AM_V_CCLD)$(LINK) $(am_dddmp_libdddmp_la_rpath) $(dddmp_libdddmp_la_OBJECTS) $(dddmp_libdddmp_la_LIBADD) $(LIBS) - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -cplusplus/cplusplus_testmulti-testmulti.$(OBJEXT): \ - cplusplus/$(am__dirstamp) cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/testmulti$(EXEEXT): $(cplusplus_testmulti_OBJECTS) $(cplusplus_testmulti_DEPENDENCIES) $(EXTRA_cplusplus_testmulti_DEPENDENCIES) cplusplus/$(am__dirstamp) - @rm -f cplusplus/testmulti$(EXEEXT) - $(AM_V_CXXLD)$(cplusplus_testmulti_LINK) $(cplusplus_testmulti_OBJECTS) $(cplusplus_testmulti_LDADD) $(LIBS) -cplusplus/cplusplus_testobj-testobj.$(OBJEXT): \ - cplusplus/$(am__dirstamp) cplusplus/$(DEPDIR)/$(am__dirstamp) - -cplusplus/testobj$(EXEEXT): $(cplusplus_testobj_OBJECTS) $(cplusplus_testobj_DEPENDENCIES) $(EXTRA_cplusplus_testobj_DEPENDENCIES) cplusplus/$(am__dirstamp) - @rm -f cplusplus/testobj$(EXEEXT) - $(AM_V_CXXLD)$(CXXLINK) $(cplusplus_testobj_OBJECTS) $(cplusplus_testobj_LDADD) $(LIBS) -cudd/cudd_testcudd-testcudd.$(OBJEXT): cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) - -cudd/testcudd$(EXEEXT): $(cudd_testcudd_OBJECTS) $(cudd_testcudd_DEPENDENCIES) $(EXTRA_cudd_testcudd_DEPENDENCIES) cudd/$(am__dirstamp) - @rm -f cudd/testcudd$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(cudd_testcudd_OBJECTS) $(cudd_testcudd_LDADD) $(LIBS) -cudd/cudd_testextra-testextra.$(OBJEXT): cudd/$(am__dirstamp) \ - cudd/$(DEPDIR)/$(am__dirstamp) - -cudd/testextra$(EXEEXT): $(cudd_testextra_OBJECTS) $(cudd_testextra_DEPENDENCIES) $(EXTRA_cudd_testextra_DEPENDENCIES) cudd/$(am__dirstamp) - @rm -f cudd/testextra$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(cudd_testextra_OBJECTS) $(cudd_testextra_LDADD) $(LIBS) -dddmp/dddmp_testdddmp-testdddmp.$(OBJEXT): dddmp/$(am__dirstamp) \ - dddmp/$(DEPDIR)/$(am__dirstamp) - -dddmp/testdddmp$(EXEEXT): $(dddmp_testdddmp_OBJECTS) $(dddmp_testdddmp_DEPENDENCIES) $(EXTRA_dddmp_testdddmp_DEPENDENCIES) dddmp/$(am__dirstamp) - @rm -f dddmp/testdddmp$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(dddmp_testdddmp_OBJECTS) $(dddmp_testdddmp_LDADD) $(LIBS) -mtr/mtr_testmtr-testmtr.$(OBJEXT): mtr/$(am__dirstamp) \ - mtr/$(DEPDIR)/$(am__dirstamp) - -mtr/testmtr$(EXEEXT): $(mtr_testmtr_OBJECTS) $(mtr_testmtr_DEPENDENCIES) $(EXTRA_mtr_testmtr_DEPENDENCIES) mtr/$(am__dirstamp) - @rm -f mtr/testmtr$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(mtr_testmtr_OBJECTS) $(mtr_testmtr_LDADD) $(LIBS) -nanotrav/$(am__dirstamp): - @$(MKDIR_P) nanotrav - @: > nanotrav/$(am__dirstamp) -nanotrav/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) nanotrav/$(DEPDIR) - @: > nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-bnet.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-chkMterm.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-main.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrBddTest.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntr.$(OBJEXT): nanotrav/$(am__dirstamp) \ - nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrHeap.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrMflow.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrShort.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) -nanotrav/nanotrav_nanotrav-ntrZddTest.$(OBJEXT): \ - nanotrav/$(am__dirstamp) nanotrav/$(DEPDIR)/$(am__dirstamp) - -nanotrav/nanotrav$(EXEEXT): $(nanotrav_nanotrav_OBJECTS) $(nanotrav_nanotrav_DEPENDENCIES) $(EXTRA_nanotrav_nanotrav_DEPENDENCIES) nanotrav/$(am__dirstamp) - @rm -f nanotrav/nanotrav$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(nanotrav_nanotrav_OBJECTS) $(nanotrav_nanotrav_LDADD) $(LIBS) -st/st_testst-testst.$(OBJEXT): st/$(am__dirstamp) \ - st/$(DEPDIR)/$(am__dirstamp) - -st/testst$(EXEEXT): $(st_testst_OBJECTS) $(st_testst_DEPENDENCIES) $(EXTRA_st_testst_DEPENDENCIES) st/$(am__dirstamp) - @rm -f st/testst$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(st_testst_OBJECTS) $(st_testst_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f cplusplus/*.$(OBJEXT) - -rm -f cplusplus/*.lo - -rm -f cudd/*.$(OBJEXT) - -rm -f cudd/*.lo - -rm -f dddmp/*.$(OBJEXT) - -rm -f dddmp/*.lo - -rm -f epd/*.$(OBJEXT) - -rm -f epd/*.lo - -rm -f mtr/*.$(OBJEXT) - -rm -f mtr/*.lo - -rm -f nanotrav/*.$(OBJEXT) - -rm -f st/*.$(OBJEXT) - -rm -f st/*.lo - -rm -f util/*.$(OBJEXT) - -rm -f util/*.lo - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@cudd/$(DEPDIR)/cudd_testextra-testextra.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@epd/$(DEPDIR)/cudd_libcudd_la-epd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@st/$(DEPDIR)/cudd_libcudd_la-st.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@st/$(DEPDIR)/st_testst-testst.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-datalimit.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-pipefork.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-prtime.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-strsav.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-texpand.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -cudd/cudd_libcudd_la-cuddAddAbs.lo: cudd/cuddAddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddAddAbs.lo `test -f 'cudd/cuddAddAbs.c' || echo '$(srcdir)/'`cudd/cuddAddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddAbs.c' object='cudd/cudd_libcudd_la-cuddAddAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddAbs.lo `test -f 'cudd/cuddAddAbs.c' || echo '$(srcdir)/'`cudd/cuddAddAbs.c - -cudd/cudd_libcudd_la-cuddAddApply.lo: cudd/cuddAddApply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddApply.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Tpo -c -o cudd/cudd_libcudd_la-cuddAddApply.lo `test -f 'cudd/cuddAddApply.c' || echo '$(srcdir)/'`cudd/cuddAddApply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddApply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddApply.c' object='cudd/cudd_libcudd_la-cuddAddApply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddApply.lo `test -f 'cudd/cuddAddApply.c' || echo '$(srcdir)/'`cudd/cuddAddApply.c - -cudd/cudd_libcudd_la-cuddAddFind.lo: cudd/cuddAddFind.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddFind.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Tpo -c -o cudd/cudd_libcudd_la-cuddAddFind.lo `test -f 'cudd/cuddAddFind.c' || echo '$(srcdir)/'`cudd/cuddAddFind.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddFind.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddFind.c' object='cudd/cudd_libcudd_la-cuddAddFind.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddFind.lo `test -f 'cudd/cuddAddFind.c' || echo '$(srcdir)/'`cudd/cuddAddFind.c - -cudd/cudd_libcudd_la-cuddAddInv.lo: cudd/cuddAddInv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddInv.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Tpo -c -o cudd/cudd_libcudd_la-cuddAddInv.lo `test -f 'cudd/cuddAddInv.c' || echo '$(srcdir)/'`cudd/cuddAddInv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddInv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddInv.c' object='cudd/cudd_libcudd_la-cuddAddInv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddInv.lo `test -f 'cudd/cuddAddInv.c' || echo '$(srcdir)/'`cudd/cuddAddInv.c - -cudd/cudd_libcudd_la-cuddAddIte.lo: cudd/cuddAddIte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddIte.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Tpo -c -o cudd/cudd_libcudd_la-cuddAddIte.lo `test -f 'cudd/cuddAddIte.c' || echo '$(srcdir)/'`cudd/cuddAddIte.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddIte.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddIte.c' object='cudd/cudd_libcudd_la-cuddAddIte.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddIte.lo `test -f 'cudd/cuddAddIte.c' || echo '$(srcdir)/'`cudd/cuddAddIte.c - -cudd/cudd_libcudd_la-cuddAddNeg.lo: cudd/cuddAddNeg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddNeg.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Tpo -c -o cudd/cudd_libcudd_la-cuddAddNeg.lo `test -f 'cudd/cuddAddNeg.c' || echo '$(srcdir)/'`cudd/cuddAddNeg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddNeg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddNeg.c' object='cudd/cudd_libcudd_la-cuddAddNeg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddNeg.lo `test -f 'cudd/cuddAddNeg.c' || echo '$(srcdir)/'`cudd/cuddAddNeg.c - -cudd/cudd_libcudd_la-cuddAddWalsh.lo: cudd/cuddAddWalsh.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAddWalsh.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Tpo -c -o cudd/cudd_libcudd_la-cuddAddWalsh.lo `test -f 'cudd/cuddAddWalsh.c' || echo '$(srcdir)/'`cudd/cuddAddWalsh.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAddWalsh.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAddWalsh.c' object='cudd/cudd_libcudd_la-cuddAddWalsh.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAddWalsh.lo `test -f 'cudd/cuddAddWalsh.c' || echo '$(srcdir)/'`cudd/cuddAddWalsh.c - -cudd/cudd_libcudd_la-cuddAndAbs.lo: cudd/cuddAndAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAndAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddAndAbs.lo `test -f 'cudd/cuddAndAbs.c' || echo '$(srcdir)/'`cudd/cuddAndAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAndAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAndAbs.c' object='cudd/cudd_libcudd_la-cuddAndAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAndAbs.lo `test -f 'cudd/cuddAndAbs.c' || echo '$(srcdir)/'`cudd/cuddAndAbs.c - -cudd/cudd_libcudd_la-cuddAnneal.lo: cudd/cuddAnneal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAnneal.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Tpo -c -o cudd/cudd_libcudd_la-cuddAnneal.lo `test -f 'cudd/cuddAnneal.c' || echo '$(srcdir)/'`cudd/cuddAnneal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAnneal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAnneal.c' object='cudd/cudd_libcudd_la-cuddAnneal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAnneal.lo `test -f 'cudd/cuddAnneal.c' || echo '$(srcdir)/'`cudd/cuddAnneal.c - -cudd/cudd_libcudd_la-cuddApa.lo: cudd/cuddApa.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddApa.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Tpo -c -o cudd/cudd_libcudd_la-cuddApa.lo `test -f 'cudd/cuddApa.c' || echo '$(srcdir)/'`cudd/cuddApa.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddApa.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddApa.c' object='cudd/cudd_libcudd_la-cuddApa.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddApa.lo `test -f 'cudd/cuddApa.c' || echo '$(srcdir)/'`cudd/cuddApa.c - -cudd/cudd_libcudd_la-cuddAPI.lo: cudd/cuddAPI.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddAPI.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Tpo -c -o cudd/cudd_libcudd_la-cuddAPI.lo `test -f 'cudd/cuddAPI.c' || echo '$(srcdir)/'`cudd/cuddAPI.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddAPI.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddAPI.c' object='cudd/cudd_libcudd_la-cuddAPI.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddAPI.lo `test -f 'cudd/cuddAPI.c' || echo '$(srcdir)/'`cudd/cuddAPI.c - -cudd/cudd_libcudd_la-cuddApprox.lo: cudd/cuddApprox.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddApprox.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Tpo -c -o cudd/cudd_libcudd_la-cuddApprox.lo `test -f 'cudd/cuddApprox.c' || echo '$(srcdir)/'`cudd/cuddApprox.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddApprox.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddApprox.c' object='cudd/cudd_libcudd_la-cuddApprox.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddApprox.lo `test -f 'cudd/cuddApprox.c' || echo '$(srcdir)/'`cudd/cuddApprox.c - -cudd/cudd_libcudd_la-cuddBddAbs.lo: cudd/cuddBddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddAbs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Tpo -c -o cudd/cudd_libcudd_la-cuddBddAbs.lo `test -f 'cudd/cuddBddAbs.c' || echo '$(srcdir)/'`cudd/cuddBddAbs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddAbs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddAbs.c' object='cudd/cudd_libcudd_la-cuddBddAbs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddAbs.lo `test -f 'cudd/cuddBddAbs.c' || echo '$(srcdir)/'`cudd/cuddBddAbs.c - -cudd/cudd_libcudd_la-cuddBddCorr.lo: cudd/cuddBddCorr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddCorr.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Tpo -c -o cudd/cudd_libcudd_la-cuddBddCorr.lo `test -f 'cudd/cuddBddCorr.c' || echo '$(srcdir)/'`cudd/cuddBddCorr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddCorr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddCorr.c' object='cudd/cudd_libcudd_la-cuddBddCorr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddCorr.lo `test -f 'cudd/cuddBddCorr.c' || echo '$(srcdir)/'`cudd/cuddBddCorr.c - -cudd/cudd_libcudd_la-cuddBddIte.lo: cudd/cuddBddIte.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBddIte.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Tpo -c -o cudd/cudd_libcudd_la-cuddBddIte.lo `test -f 'cudd/cuddBddIte.c' || echo '$(srcdir)/'`cudd/cuddBddIte.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBddIte.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBddIte.c' object='cudd/cudd_libcudd_la-cuddBddIte.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBddIte.lo `test -f 'cudd/cuddBddIte.c' || echo '$(srcdir)/'`cudd/cuddBddIte.c - -cudd/cudd_libcudd_la-cuddBridge.lo: cudd/cuddBridge.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddBridge.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Tpo -c -o cudd/cudd_libcudd_la-cuddBridge.lo `test -f 'cudd/cuddBridge.c' || echo '$(srcdir)/'`cudd/cuddBridge.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddBridge.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddBridge.c' object='cudd/cudd_libcudd_la-cuddBridge.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddBridge.lo `test -f 'cudd/cuddBridge.c' || echo '$(srcdir)/'`cudd/cuddBridge.c - -cudd/cudd_libcudd_la-cuddCache.lo: cudd/cuddCache.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCache.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Tpo -c -o cudd/cudd_libcudd_la-cuddCache.lo `test -f 'cudd/cuddCache.c' || echo '$(srcdir)/'`cudd/cuddCache.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCache.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCache.c' object='cudd/cudd_libcudd_la-cuddCache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCache.lo `test -f 'cudd/cuddCache.c' || echo '$(srcdir)/'`cudd/cuddCache.c - -cudd/cudd_libcudd_la-cuddCheck.lo: cudd/cuddCheck.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCheck.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Tpo -c -o cudd/cudd_libcudd_la-cuddCheck.lo `test -f 'cudd/cuddCheck.c' || echo '$(srcdir)/'`cudd/cuddCheck.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCheck.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCheck.c' object='cudd/cudd_libcudd_la-cuddCheck.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCheck.lo `test -f 'cudd/cuddCheck.c' || echo '$(srcdir)/'`cudd/cuddCheck.c - -cudd/cudd_libcudd_la-cuddClip.lo: cudd/cuddClip.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddClip.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Tpo -c -o cudd/cudd_libcudd_la-cuddClip.lo `test -f 'cudd/cuddClip.c' || echo '$(srcdir)/'`cudd/cuddClip.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddClip.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddClip.c' object='cudd/cudd_libcudd_la-cuddClip.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddClip.lo `test -f 'cudd/cuddClip.c' || echo '$(srcdir)/'`cudd/cuddClip.c - -cudd/cudd_libcudd_la-cuddCof.lo: cudd/cuddCof.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCof.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Tpo -c -o cudd/cudd_libcudd_la-cuddCof.lo `test -f 'cudd/cuddCof.c' || echo '$(srcdir)/'`cudd/cuddCof.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCof.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCof.c' object='cudd/cudd_libcudd_la-cuddCof.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCof.lo `test -f 'cudd/cuddCof.c' || echo '$(srcdir)/'`cudd/cuddCof.c - -cudd/cudd_libcudd_la-cuddCompose.lo: cudd/cuddCompose.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddCompose.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Tpo -c -o cudd/cudd_libcudd_la-cuddCompose.lo `test -f 'cudd/cuddCompose.c' || echo '$(srcdir)/'`cudd/cuddCompose.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddCompose.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddCompose.c' object='cudd/cudd_libcudd_la-cuddCompose.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddCompose.lo `test -f 'cudd/cuddCompose.c' || echo '$(srcdir)/'`cudd/cuddCompose.c - -cudd/cudd_libcudd_la-cuddDecomp.lo: cudd/cuddDecomp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddDecomp.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Tpo -c -o cudd/cudd_libcudd_la-cuddDecomp.lo `test -f 'cudd/cuddDecomp.c' || echo '$(srcdir)/'`cudd/cuddDecomp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddDecomp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddDecomp.c' object='cudd/cudd_libcudd_la-cuddDecomp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddDecomp.lo `test -f 'cudd/cuddDecomp.c' || echo '$(srcdir)/'`cudd/cuddDecomp.c - -cudd/cudd_libcudd_la-cuddEssent.lo: cudd/cuddEssent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddEssent.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Tpo -c -o cudd/cudd_libcudd_la-cuddEssent.lo `test -f 'cudd/cuddEssent.c' || echo '$(srcdir)/'`cudd/cuddEssent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddEssent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddEssent.c' object='cudd/cudd_libcudd_la-cuddEssent.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddEssent.lo `test -f 'cudd/cuddEssent.c' || echo '$(srcdir)/'`cudd/cuddEssent.c - -cudd/cudd_libcudd_la-cuddExact.lo: cudd/cuddExact.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddExact.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Tpo -c -o cudd/cudd_libcudd_la-cuddExact.lo `test -f 'cudd/cuddExact.c' || echo '$(srcdir)/'`cudd/cuddExact.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddExact.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddExact.c' object='cudd/cudd_libcudd_la-cuddExact.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddExact.lo `test -f 'cudd/cuddExact.c' || echo '$(srcdir)/'`cudd/cuddExact.c - -cudd/cudd_libcudd_la-cuddExport.lo: cudd/cuddExport.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddExport.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Tpo -c -o cudd/cudd_libcudd_la-cuddExport.lo `test -f 'cudd/cuddExport.c' || echo '$(srcdir)/'`cudd/cuddExport.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddExport.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddExport.c' object='cudd/cudd_libcudd_la-cuddExport.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddExport.lo `test -f 'cudd/cuddExport.c' || echo '$(srcdir)/'`cudd/cuddExport.c - -cudd/cudd_libcudd_la-cuddGenCof.lo: cudd/cuddGenCof.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGenCof.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Tpo -c -o cudd/cudd_libcudd_la-cuddGenCof.lo `test -f 'cudd/cuddGenCof.c' || echo '$(srcdir)/'`cudd/cuddGenCof.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenCof.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGenCof.c' object='cudd/cudd_libcudd_la-cuddGenCof.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGenCof.lo `test -f 'cudd/cuddGenCof.c' || echo '$(srcdir)/'`cudd/cuddGenCof.c - -cudd/cudd_libcudd_la-cuddGenetic.lo: cudd/cuddGenetic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGenetic.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Tpo -c -o cudd/cudd_libcudd_la-cuddGenetic.lo `test -f 'cudd/cuddGenetic.c' || echo '$(srcdir)/'`cudd/cuddGenetic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGenetic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGenetic.c' object='cudd/cudd_libcudd_la-cuddGenetic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGenetic.lo `test -f 'cudd/cuddGenetic.c' || echo '$(srcdir)/'`cudd/cuddGenetic.c - -cudd/cudd_libcudd_la-cuddGroup.lo: cudd/cuddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddGroup.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Tpo -c -o cudd/cudd_libcudd_la-cuddGroup.lo `test -f 'cudd/cuddGroup.c' || echo '$(srcdir)/'`cudd/cuddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddGroup.c' object='cudd/cudd_libcudd_la-cuddGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddGroup.lo `test -f 'cudd/cuddGroup.c' || echo '$(srcdir)/'`cudd/cuddGroup.c - -cudd/cudd_libcudd_la-cuddHarwell.lo: cudd/cuddHarwell.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddHarwell.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Tpo -c -o cudd/cudd_libcudd_la-cuddHarwell.lo `test -f 'cudd/cuddHarwell.c' || echo '$(srcdir)/'`cudd/cuddHarwell.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddHarwell.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddHarwell.c' object='cudd/cudd_libcudd_la-cuddHarwell.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddHarwell.lo `test -f 'cudd/cuddHarwell.c' || echo '$(srcdir)/'`cudd/cuddHarwell.c - -cudd/cudd_libcudd_la-cuddInit.lo: cudd/cuddInit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddInit.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Tpo -c -o cudd/cudd_libcudd_la-cuddInit.lo `test -f 'cudd/cuddInit.c' || echo '$(srcdir)/'`cudd/cuddInit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddInit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddInit.c' object='cudd/cudd_libcudd_la-cuddInit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddInit.lo `test -f 'cudd/cuddInit.c' || echo '$(srcdir)/'`cudd/cuddInit.c - -cudd/cudd_libcudd_la-cuddInteract.lo: cudd/cuddInteract.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddInteract.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Tpo -c -o cudd/cudd_libcudd_la-cuddInteract.lo `test -f 'cudd/cuddInteract.c' || echo '$(srcdir)/'`cudd/cuddInteract.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddInteract.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddInteract.c' object='cudd/cudd_libcudd_la-cuddInteract.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddInteract.lo `test -f 'cudd/cuddInteract.c' || echo '$(srcdir)/'`cudd/cuddInteract.c - -cudd/cudd_libcudd_la-cuddLCache.lo: cudd/cuddLCache.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLCache.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Tpo -c -o cudd/cudd_libcudd_la-cuddLCache.lo `test -f 'cudd/cuddLCache.c' || echo '$(srcdir)/'`cudd/cuddLCache.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLCache.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLCache.c' object='cudd/cudd_libcudd_la-cuddLCache.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLCache.lo `test -f 'cudd/cuddLCache.c' || echo '$(srcdir)/'`cudd/cuddLCache.c - -cudd/cudd_libcudd_la-cuddLevelQ.lo: cudd/cuddLevelQ.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLevelQ.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Tpo -c -o cudd/cudd_libcudd_la-cuddLevelQ.lo `test -f 'cudd/cuddLevelQ.c' || echo '$(srcdir)/'`cudd/cuddLevelQ.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLevelQ.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLevelQ.c' object='cudd/cudd_libcudd_la-cuddLevelQ.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLevelQ.lo `test -f 'cudd/cuddLevelQ.c' || echo '$(srcdir)/'`cudd/cuddLevelQ.c - -cudd/cudd_libcudd_la-cuddLinear.lo: cudd/cuddLinear.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLinear.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Tpo -c -o cudd/cudd_libcudd_la-cuddLinear.lo `test -f 'cudd/cuddLinear.c' || echo '$(srcdir)/'`cudd/cuddLinear.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLinear.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLinear.c' object='cudd/cudd_libcudd_la-cuddLinear.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLinear.lo `test -f 'cudd/cuddLinear.c' || echo '$(srcdir)/'`cudd/cuddLinear.c - -cudd/cudd_libcudd_la-cuddLiteral.lo: cudd/cuddLiteral.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddLiteral.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Tpo -c -o cudd/cudd_libcudd_la-cuddLiteral.lo `test -f 'cudd/cuddLiteral.c' || echo '$(srcdir)/'`cudd/cuddLiteral.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddLiteral.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddLiteral.c' object='cudd/cudd_libcudd_la-cuddLiteral.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddLiteral.lo `test -f 'cudd/cuddLiteral.c' || echo '$(srcdir)/'`cudd/cuddLiteral.c - -cudd/cudd_libcudd_la-cuddMatMult.lo: cudd/cuddMatMult.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddMatMult.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Tpo -c -o cudd/cudd_libcudd_la-cuddMatMult.lo `test -f 'cudd/cuddMatMult.c' || echo '$(srcdir)/'`cudd/cuddMatMult.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddMatMult.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddMatMult.c' object='cudd/cudd_libcudd_la-cuddMatMult.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddMatMult.lo `test -f 'cudd/cuddMatMult.c' || echo '$(srcdir)/'`cudd/cuddMatMult.c - -cudd/cudd_libcudd_la-cuddPriority.lo: cudd/cuddPriority.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddPriority.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Tpo -c -o cudd/cudd_libcudd_la-cuddPriority.lo `test -f 'cudd/cuddPriority.c' || echo '$(srcdir)/'`cudd/cuddPriority.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddPriority.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddPriority.c' object='cudd/cudd_libcudd_la-cuddPriority.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddPriority.lo `test -f 'cudd/cuddPriority.c' || echo '$(srcdir)/'`cudd/cuddPriority.c - -cudd/cudd_libcudd_la-cuddRead.lo: cudd/cuddRead.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddRead.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Tpo -c -o cudd/cudd_libcudd_la-cuddRead.lo `test -f 'cudd/cuddRead.c' || echo '$(srcdir)/'`cudd/cuddRead.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddRead.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddRead.c' object='cudd/cudd_libcudd_la-cuddRead.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddRead.lo `test -f 'cudd/cuddRead.c' || echo '$(srcdir)/'`cudd/cuddRead.c - -cudd/cudd_libcudd_la-cuddRef.lo: cudd/cuddRef.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddRef.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Tpo -c -o cudd/cudd_libcudd_la-cuddRef.lo `test -f 'cudd/cuddRef.c' || echo '$(srcdir)/'`cudd/cuddRef.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddRef.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddRef.c' object='cudd/cudd_libcudd_la-cuddRef.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddRef.lo `test -f 'cudd/cuddRef.c' || echo '$(srcdir)/'`cudd/cuddRef.c - -cudd/cudd_libcudd_la-cuddReorder.lo: cudd/cuddReorder.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddReorder.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Tpo -c -o cudd/cudd_libcudd_la-cuddReorder.lo `test -f 'cudd/cuddReorder.c' || echo '$(srcdir)/'`cudd/cuddReorder.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddReorder.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddReorder.c' object='cudd/cudd_libcudd_la-cuddReorder.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddReorder.lo `test -f 'cudd/cuddReorder.c' || echo '$(srcdir)/'`cudd/cuddReorder.c - -cudd/cudd_libcudd_la-cuddSat.lo: cudd/cuddSat.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSat.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Tpo -c -o cudd/cudd_libcudd_la-cuddSat.lo `test -f 'cudd/cuddSat.c' || echo '$(srcdir)/'`cudd/cuddSat.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSat.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSat.c' object='cudd/cudd_libcudd_la-cuddSat.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSat.lo `test -f 'cudd/cuddSat.c' || echo '$(srcdir)/'`cudd/cuddSat.c - -cudd/cudd_libcudd_la-cuddSign.lo: cudd/cuddSign.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSign.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Tpo -c -o cudd/cudd_libcudd_la-cuddSign.lo `test -f 'cudd/cuddSign.c' || echo '$(srcdir)/'`cudd/cuddSign.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSign.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSign.c' object='cudd/cudd_libcudd_la-cuddSign.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSign.lo `test -f 'cudd/cuddSign.c' || echo '$(srcdir)/'`cudd/cuddSign.c - -cudd/cudd_libcudd_la-cuddSolve.lo: cudd/cuddSolve.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSolve.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Tpo -c -o cudd/cudd_libcudd_la-cuddSolve.lo `test -f 'cudd/cuddSolve.c' || echo '$(srcdir)/'`cudd/cuddSolve.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSolve.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSolve.c' object='cudd/cudd_libcudd_la-cuddSolve.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSolve.lo `test -f 'cudd/cuddSolve.c' || echo '$(srcdir)/'`cudd/cuddSolve.c - -cudd/cudd_libcudd_la-cuddSplit.lo: cudd/cuddSplit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSplit.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Tpo -c -o cudd/cudd_libcudd_la-cuddSplit.lo `test -f 'cudd/cuddSplit.c' || echo '$(srcdir)/'`cudd/cuddSplit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSplit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSplit.c' object='cudd/cudd_libcudd_la-cuddSplit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSplit.lo `test -f 'cudd/cuddSplit.c' || echo '$(srcdir)/'`cudd/cuddSplit.c - -cudd/cudd_libcudd_la-cuddSubsetHB.lo: cudd/cuddSubsetHB.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSubsetHB.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Tpo -c -o cudd/cudd_libcudd_la-cuddSubsetHB.lo `test -f 'cudd/cuddSubsetHB.c' || echo '$(srcdir)/'`cudd/cuddSubsetHB.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetHB.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSubsetHB.c' object='cudd/cudd_libcudd_la-cuddSubsetHB.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSubsetHB.lo `test -f 'cudd/cuddSubsetHB.c' || echo '$(srcdir)/'`cudd/cuddSubsetHB.c - -cudd/cudd_libcudd_la-cuddSubsetSP.lo: cudd/cuddSubsetSP.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSubsetSP.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Tpo -c -o cudd/cudd_libcudd_la-cuddSubsetSP.lo `test -f 'cudd/cuddSubsetSP.c' || echo '$(srcdir)/'`cudd/cuddSubsetSP.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSubsetSP.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSubsetSP.c' object='cudd/cudd_libcudd_la-cuddSubsetSP.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSubsetSP.lo `test -f 'cudd/cuddSubsetSP.c' || echo '$(srcdir)/'`cudd/cuddSubsetSP.c - -cudd/cudd_libcudd_la-cuddSymmetry.lo: cudd/cuddSymmetry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddSymmetry.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Tpo -c -o cudd/cudd_libcudd_la-cuddSymmetry.lo `test -f 'cudd/cuddSymmetry.c' || echo '$(srcdir)/'`cudd/cuddSymmetry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddSymmetry.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddSymmetry.c' object='cudd/cudd_libcudd_la-cuddSymmetry.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddSymmetry.lo `test -f 'cudd/cuddSymmetry.c' || echo '$(srcdir)/'`cudd/cuddSymmetry.c - -cudd/cudd_libcudd_la-cuddTable.lo: cudd/cuddTable.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddTable.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Tpo -c -o cudd/cudd_libcudd_la-cuddTable.lo `test -f 'cudd/cuddTable.c' || echo '$(srcdir)/'`cudd/cuddTable.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddTable.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddTable.c' object='cudd/cudd_libcudd_la-cuddTable.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddTable.lo `test -f 'cudd/cuddTable.c' || echo '$(srcdir)/'`cudd/cuddTable.c - -cudd/cudd_libcudd_la-cuddUtil.lo: cudd/cuddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddUtil.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Tpo -c -o cudd/cudd_libcudd_la-cuddUtil.lo `test -f 'cudd/cuddUtil.c' || echo '$(srcdir)/'`cudd/cuddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddUtil.c' object='cudd/cudd_libcudd_la-cuddUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddUtil.lo `test -f 'cudd/cuddUtil.c' || echo '$(srcdir)/'`cudd/cuddUtil.c - -cudd/cudd_libcudd_la-cuddWindow.lo: cudd/cuddWindow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddWindow.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Tpo -c -o cudd/cudd_libcudd_la-cuddWindow.lo `test -f 'cudd/cuddWindow.c' || echo '$(srcdir)/'`cudd/cuddWindow.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddWindow.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddWindow.c' object='cudd/cudd_libcudd_la-cuddWindow.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddWindow.lo `test -f 'cudd/cuddWindow.c' || echo '$(srcdir)/'`cudd/cuddWindow.c - -cudd/cudd_libcudd_la-cuddZddCount.lo: cudd/cuddZddCount.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddCount.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Tpo -c -o cudd/cudd_libcudd_la-cuddZddCount.lo `test -f 'cudd/cuddZddCount.c' || echo '$(srcdir)/'`cudd/cuddZddCount.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddCount.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddCount.c' object='cudd/cudd_libcudd_la-cuddZddCount.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddCount.lo `test -f 'cudd/cuddZddCount.c' || echo '$(srcdir)/'`cudd/cuddZddCount.c - -cudd/cudd_libcudd_la-cuddZddFuncs.lo: cudd/cuddZddFuncs.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddFuncs.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Tpo -c -o cudd/cudd_libcudd_la-cuddZddFuncs.lo `test -f 'cudd/cuddZddFuncs.c' || echo '$(srcdir)/'`cudd/cuddZddFuncs.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddFuncs.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddFuncs.c' object='cudd/cudd_libcudd_la-cuddZddFuncs.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddFuncs.lo `test -f 'cudd/cuddZddFuncs.c' || echo '$(srcdir)/'`cudd/cuddZddFuncs.c - -cudd/cudd_libcudd_la-cuddZddGroup.lo: cudd/cuddZddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddGroup.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Tpo -c -o cudd/cudd_libcudd_la-cuddZddGroup.lo `test -f 'cudd/cuddZddGroup.c' || echo '$(srcdir)/'`cudd/cuddZddGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddGroup.c' object='cudd/cudd_libcudd_la-cuddZddGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddGroup.lo `test -f 'cudd/cuddZddGroup.c' || echo '$(srcdir)/'`cudd/cuddZddGroup.c - -cudd/cudd_libcudd_la-cuddZddIsop.lo: cudd/cuddZddIsop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddIsop.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Tpo -c -o cudd/cudd_libcudd_la-cuddZddIsop.lo `test -f 'cudd/cuddZddIsop.c' || echo '$(srcdir)/'`cudd/cuddZddIsop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddIsop.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddIsop.c' object='cudd/cudd_libcudd_la-cuddZddIsop.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddIsop.lo `test -f 'cudd/cuddZddIsop.c' || echo '$(srcdir)/'`cudd/cuddZddIsop.c - -cudd/cudd_libcudd_la-cuddZddLin.lo: cudd/cuddZddLin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddLin.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Tpo -c -o cudd/cudd_libcudd_la-cuddZddLin.lo `test -f 'cudd/cuddZddLin.c' || echo '$(srcdir)/'`cudd/cuddZddLin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddLin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddLin.c' object='cudd/cudd_libcudd_la-cuddZddLin.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddLin.lo `test -f 'cudd/cuddZddLin.c' || echo '$(srcdir)/'`cudd/cuddZddLin.c - -cudd/cudd_libcudd_la-cuddZddMisc.lo: cudd/cuddZddMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddMisc.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Tpo -c -o cudd/cudd_libcudd_la-cuddZddMisc.lo `test -f 'cudd/cuddZddMisc.c' || echo '$(srcdir)/'`cudd/cuddZddMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddMisc.c' object='cudd/cudd_libcudd_la-cuddZddMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddMisc.lo `test -f 'cudd/cuddZddMisc.c' || echo '$(srcdir)/'`cudd/cuddZddMisc.c - -cudd/cudd_libcudd_la-cuddZddPort.lo: cudd/cuddZddPort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddPort.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Tpo -c -o cudd/cudd_libcudd_la-cuddZddPort.lo `test -f 'cudd/cuddZddPort.c' || echo '$(srcdir)/'`cudd/cuddZddPort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddPort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddPort.c' object='cudd/cudd_libcudd_la-cuddZddPort.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddPort.lo `test -f 'cudd/cuddZddPort.c' || echo '$(srcdir)/'`cudd/cuddZddPort.c - -cudd/cudd_libcudd_la-cuddZddReord.lo: cudd/cuddZddReord.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddReord.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Tpo -c -o cudd/cudd_libcudd_la-cuddZddReord.lo `test -f 'cudd/cuddZddReord.c' || echo '$(srcdir)/'`cudd/cuddZddReord.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddReord.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddReord.c' object='cudd/cudd_libcudd_la-cuddZddReord.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddReord.lo `test -f 'cudd/cuddZddReord.c' || echo '$(srcdir)/'`cudd/cuddZddReord.c - -cudd/cudd_libcudd_la-cuddZddSetop.lo: cudd/cuddZddSetop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddSetop.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Tpo -c -o cudd/cudd_libcudd_la-cuddZddSetop.lo `test -f 'cudd/cuddZddSetop.c' || echo '$(srcdir)/'`cudd/cuddZddSetop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSetop.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddSetop.c' object='cudd/cudd_libcudd_la-cuddZddSetop.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddSetop.lo `test -f 'cudd/cuddZddSetop.c' || echo '$(srcdir)/'`cudd/cuddZddSetop.c - -cudd/cudd_libcudd_la-cuddZddSymm.lo: cudd/cuddZddSymm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddSymm.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Tpo -c -o cudd/cudd_libcudd_la-cuddZddSymm.lo `test -f 'cudd/cuddZddSymm.c' || echo '$(srcdir)/'`cudd/cuddZddSymm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddSymm.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddSymm.c' object='cudd/cudd_libcudd_la-cuddZddSymm.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddSymm.lo `test -f 'cudd/cuddZddSymm.c' || echo '$(srcdir)/'`cudd/cuddZddSymm.c - -cudd/cudd_libcudd_la-cuddZddUtil.lo: cudd/cuddZddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_libcudd_la-cuddZddUtil.lo -MD -MP -MF cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Tpo -c -o cudd/cudd_libcudd_la-cuddZddUtil.lo `test -f 'cudd/cuddZddUtil.c' || echo '$(srcdir)/'`cudd/cuddZddUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Tpo cudd/$(DEPDIR)/cudd_libcudd_la-cuddZddUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/cuddZddUtil.c' object='cudd/cudd_libcudd_la-cuddZddUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_libcudd_la-cuddZddUtil.lo `test -f 'cudd/cuddZddUtil.c' || echo '$(srcdir)/'`cudd/cuddZddUtil.c - -util/cudd_libcudd_la-cpu_stats.lo: util/cpu_stats.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cpu_stats.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Tpo -c -o util/cudd_libcudd_la-cpu_stats.lo `test -f 'util/cpu_stats.c' || echo '$(srcdir)/'`util/cpu_stats.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Tpo util/$(DEPDIR)/cudd_libcudd_la-cpu_stats.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cpu_stats.c' object='util/cudd_libcudd_la-cpu_stats.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cpu_stats.lo `test -f 'util/cpu_stats.c' || echo '$(srcdir)/'`util/cpu_stats.c - -util/cudd_libcudd_la-cpu_time.lo: util/cpu_time.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cpu_time.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Tpo -c -o util/cudd_libcudd_la-cpu_time.lo `test -f 'util/cpu_time.c' || echo '$(srcdir)/'`util/cpu_time.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Tpo util/$(DEPDIR)/cudd_libcudd_la-cpu_time.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cpu_time.c' object='util/cudd_libcudd_la-cpu_time.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cpu_time.lo `test -f 'util/cpu_time.c' || echo '$(srcdir)/'`util/cpu_time.c - -util/cudd_libcudd_la-cstringstream.lo: util/cstringstream.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-cstringstream.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Tpo -c -o util/cudd_libcudd_la-cstringstream.lo `test -f 'util/cstringstream.c' || echo '$(srcdir)/'`util/cstringstream.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Tpo util/$(DEPDIR)/cudd_libcudd_la-cstringstream.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/cstringstream.c' object='util/cudd_libcudd_la-cstringstream.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-cstringstream.lo `test -f 'util/cstringstream.c' || echo '$(srcdir)/'`util/cstringstream.c - -util/cudd_libcudd_la-datalimit.lo: util/datalimit.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-datalimit.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-datalimit.Tpo -c -o util/cudd_libcudd_la-datalimit.lo `test -f 'util/datalimit.c' || echo '$(srcdir)/'`util/datalimit.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-datalimit.Tpo util/$(DEPDIR)/cudd_libcudd_la-datalimit.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/datalimit.c' object='util/cudd_libcudd_la-datalimit.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-datalimit.lo `test -f 'util/datalimit.c' || echo '$(srcdir)/'`util/datalimit.c - -util/cudd_libcudd_la-pathsearch.lo: util/pathsearch.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-pathsearch.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Tpo -c -o util/cudd_libcudd_la-pathsearch.lo `test -f 'util/pathsearch.c' || echo '$(srcdir)/'`util/pathsearch.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Tpo util/$(DEPDIR)/cudd_libcudd_la-pathsearch.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/pathsearch.c' object='util/cudd_libcudd_la-pathsearch.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-pathsearch.lo `test -f 'util/pathsearch.c' || echo '$(srcdir)/'`util/pathsearch.c - -util/cudd_libcudd_la-pipefork.lo: util/pipefork.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-pipefork.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-pipefork.Tpo -c -o util/cudd_libcudd_la-pipefork.lo `test -f 'util/pipefork.c' || echo '$(srcdir)/'`util/pipefork.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-pipefork.Tpo util/$(DEPDIR)/cudd_libcudd_la-pipefork.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/pipefork.c' object='util/cudd_libcudd_la-pipefork.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-pipefork.lo `test -f 'util/pipefork.c' || echo '$(srcdir)/'`util/pipefork.c - -util/cudd_libcudd_la-prtime.lo: util/prtime.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-prtime.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-prtime.Tpo -c -o util/cudd_libcudd_la-prtime.lo `test -f 'util/prtime.c' || echo '$(srcdir)/'`util/prtime.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-prtime.Tpo util/$(DEPDIR)/cudd_libcudd_la-prtime.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/prtime.c' object='util/cudd_libcudd_la-prtime.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-prtime.lo `test -f 'util/prtime.c' || echo '$(srcdir)/'`util/prtime.c - -util/cudd_libcudd_la-safe_mem.lo: util/safe_mem.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-safe_mem.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Tpo -c -o util/cudd_libcudd_la-safe_mem.lo `test -f 'util/safe_mem.c' || echo '$(srcdir)/'`util/safe_mem.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Tpo util/$(DEPDIR)/cudd_libcudd_la-safe_mem.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/safe_mem.c' object='util/cudd_libcudd_la-safe_mem.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-safe_mem.lo `test -f 'util/safe_mem.c' || echo '$(srcdir)/'`util/safe_mem.c - -util/cudd_libcudd_la-strsav.lo: util/strsav.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-strsav.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-strsav.Tpo -c -o util/cudd_libcudd_la-strsav.lo `test -f 'util/strsav.c' || echo '$(srcdir)/'`util/strsav.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-strsav.Tpo util/$(DEPDIR)/cudd_libcudd_la-strsav.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/strsav.c' object='util/cudd_libcudd_la-strsav.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-strsav.lo `test -f 'util/strsav.c' || echo '$(srcdir)/'`util/strsav.c - -util/cudd_libcudd_la-texpand.lo: util/texpand.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-texpand.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-texpand.Tpo -c -o util/cudd_libcudd_la-texpand.lo `test -f 'util/texpand.c' || echo '$(srcdir)/'`util/texpand.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-texpand.Tpo util/$(DEPDIR)/cudd_libcudd_la-texpand.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/texpand.c' object='util/cudd_libcudd_la-texpand.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-texpand.lo `test -f 'util/texpand.c' || echo '$(srcdir)/'`util/texpand.c - -util/cudd_libcudd_la-ucbqsort.lo: util/ucbqsort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/cudd_libcudd_la-ucbqsort.lo -MD -MP -MF util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Tpo -c -o util/cudd_libcudd_la-ucbqsort.lo `test -f 'util/ucbqsort.c' || echo '$(srcdir)/'`util/ucbqsort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Tpo util/$(DEPDIR)/cudd_libcudd_la-ucbqsort.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='util/ucbqsort.c' object='util/cudd_libcudd_la-ucbqsort.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/cudd_libcudd_la-ucbqsort.lo `test -f 'util/ucbqsort.c' || echo '$(srcdir)/'`util/ucbqsort.c - -st/cudd_libcudd_la-st.lo: st/st.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/cudd_libcudd_la-st.lo -MD -MP -MF st/$(DEPDIR)/cudd_libcudd_la-st.Tpo -c -o st/cudd_libcudd_la-st.lo `test -f 'st/st.c' || echo '$(srcdir)/'`st/st.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/cudd_libcudd_la-st.Tpo st/$(DEPDIR)/cudd_libcudd_la-st.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/st.c' object='st/cudd_libcudd_la-st.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/cudd_libcudd_la-st.lo `test -f 'st/st.c' || echo '$(srcdir)/'`st/st.c - -epd/cudd_libcudd_la-epd.lo: epd/epd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epd/cudd_libcudd_la-epd.lo -MD -MP -MF epd/$(DEPDIR)/cudd_libcudd_la-epd.Tpo -c -o epd/cudd_libcudd_la-epd.lo `test -f 'epd/epd.c' || echo '$(srcdir)/'`epd/epd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) epd/$(DEPDIR)/cudd_libcudd_la-epd.Tpo epd/$(DEPDIR)/cudd_libcudd_la-epd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='epd/epd.c' object='epd/cudd_libcudd_la-epd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epd/cudd_libcudd_la-epd.lo `test -f 'epd/epd.c' || echo '$(srcdir)/'`epd/epd.c - -mtr/cudd_libcudd_la-mtrBasic.lo: mtr/mtrBasic.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/cudd_libcudd_la-mtrBasic.lo -MD -MP -MF mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Tpo -c -o mtr/cudd_libcudd_la-mtrBasic.lo `test -f 'mtr/mtrBasic.c' || echo '$(srcdir)/'`mtr/mtrBasic.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Tpo mtr/$(DEPDIR)/cudd_libcudd_la-mtrBasic.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/mtrBasic.c' object='mtr/cudd_libcudd_la-mtrBasic.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/cudd_libcudd_la-mtrBasic.lo `test -f 'mtr/mtrBasic.c' || echo '$(srcdir)/'`mtr/mtrBasic.c - -mtr/cudd_libcudd_la-mtrGroup.lo: mtr/mtrGroup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/cudd_libcudd_la-mtrGroup.lo -MD -MP -MF mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Tpo -c -o mtr/cudd_libcudd_la-mtrGroup.lo `test -f 'mtr/mtrGroup.c' || echo '$(srcdir)/'`mtr/mtrGroup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Tpo mtr/$(DEPDIR)/cudd_libcudd_la-mtrGroup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/mtrGroup.c' object='mtr/cudd_libcudd_la-mtrGroup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/cudd_libcudd_la-mtrGroup.lo `test -f 'mtr/mtrGroup.c' || echo '$(srcdir)/'`mtr/mtrGroup.c - -dddmp/cudd_libcudd_la-dddmpBinary.lo: dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpBinary.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Tpo -c -o dddmp/cudd_libcudd_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpBinary.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpBinary.c' object='dddmp/cudd_libcudd_la-dddmpBinary.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c - -dddmp/cudd_libcudd_la-dddmpConvert.lo: dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpConvert.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Tpo -c -o dddmp/cudd_libcudd_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpConvert.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpConvert.c' object='dddmp/cudd_libcudd_la-dddmpConvert.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c - -dddmp/cudd_libcudd_la-dddmpDbg.lo: dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpDbg.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Tpo -c -o dddmp/cudd_libcudd_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpDbg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpDbg.c' object='dddmp/cudd_libcudd_la-dddmpDbg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c - -dddmp/cudd_libcudd_la-dddmpLoad.lo: dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpLoad.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Tpo -c -o dddmp/cudd_libcudd_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoad.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoad.c' object='dddmp/cudd_libcudd_la-dddmpLoad.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c - -dddmp/cudd_libcudd_la-dddmpLoadCnf.lo: dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpLoadCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpLoadCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoadCnf.c' object='dddmp/cudd_libcudd_la-dddmpLoadCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c - -dddmp/cudd_libcudd_la-dddmpNodeAdd.lo: dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeAdd.c' object='dddmp/cudd_libcudd_la-dddmpNodeAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c - -dddmp/cudd_libcudd_la-dddmpNodeBdd.lo: dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeBdd.c' object='dddmp/cudd_libcudd_la-dddmpNodeBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c - -dddmp/cudd_libcudd_la-dddmpNodeCnf.lo: dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpNodeCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpNodeCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeCnf.c' object='dddmp/cudd_libcudd_la-dddmpNodeCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c - -dddmp/cudd_libcudd_la-dddmpStoreAdd.lo: dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreAdd.c' object='dddmp/cudd_libcudd_la-dddmpStoreAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c - -dddmp/cudd_libcudd_la-dddmpStoreBdd.lo: dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreBdd.c' object='dddmp/cudd_libcudd_la-dddmpStoreBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c - -dddmp/cudd_libcudd_la-dddmpStoreCnf.lo: dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreCnf.c' object='dddmp/cudd_libcudd_la-dddmpStoreCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c - -dddmp/cudd_libcudd_la-dddmpStoreMisc.lo: dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpStoreMisc.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Tpo -c -o dddmp/cudd_libcudd_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpStoreMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreMisc.c' object='dddmp/cudd_libcudd_la-dddmpStoreMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c - -dddmp/cudd_libcudd_la-dddmpUtil.lo: dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/cudd_libcudd_la-dddmpUtil.lo -MD -MP -MF dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Tpo -c -o dddmp/cudd_libcudd_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Tpo dddmp/$(DEPDIR)/cudd_libcudd_la-dddmpUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpUtil.c' object='dddmp/cudd_libcudd_la-dddmpUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/cudd_libcudd_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c - -dddmp/dddmp_libdddmp_la-dddmpBinary.lo: dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpBinary.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpBinary.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpBinary.c' object='dddmp/dddmp_libdddmp_la-dddmpBinary.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpBinary.lo `test -f 'dddmp/dddmpBinary.c' || echo '$(srcdir)/'`dddmp/dddmpBinary.c - -dddmp/dddmp_libdddmp_la-dddmpConvert.lo: dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpConvert.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpConvert.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpConvert.c' object='dddmp/dddmp_libdddmp_la-dddmpConvert.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpConvert.lo `test -f 'dddmp/dddmpConvert.c' || echo '$(srcdir)/'`dddmp/dddmpConvert.c - -dddmp/dddmp_libdddmp_la-dddmpDbg.lo: dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpDbg.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpDbg.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpDbg.c' object='dddmp/dddmp_libdddmp_la-dddmpDbg.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpDbg.lo `test -f 'dddmp/dddmpDbg.c' || echo '$(srcdir)/'`dddmp/dddmpDbg.c - -dddmp/dddmp_libdddmp_la-dddmpLoad.lo: dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpLoad.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoad.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoad.c' object='dddmp/dddmp_libdddmp_la-dddmpLoad.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpLoad.lo `test -f 'dddmp/dddmpLoad.c' || echo '$(srcdir)/'`dddmp/dddmpLoad.c - -dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo: dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpLoadCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpLoadCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpLoadCnf.lo `test -f 'dddmp/dddmpLoadCnf.c' || echo '$(srcdir)/'`dddmp/dddmpLoadCnf.c - -dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo: dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeAdd.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeAdd.lo `test -f 'dddmp/dddmpNodeAdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeAdd.c - -dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo: dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeBdd.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeBdd.lo `test -f 'dddmp/dddmpNodeBdd.c' || echo '$(srcdir)/'`dddmp/dddmpNodeBdd.c - -dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo: dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpNodeCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpNodeCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpNodeCnf.lo `test -f 'dddmp/dddmpNodeCnf.c' || echo '$(srcdir)/'`dddmp/dddmpNodeCnf.c - -dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo: dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreAdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreAdd.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreAdd.lo `test -f 'dddmp/dddmpStoreAdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreAdd.c - -dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo: dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreBdd.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreBdd.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreBdd.lo `test -f 'dddmp/dddmpStoreBdd.c' || echo '$(srcdir)/'`dddmp/dddmpStoreBdd.c - -dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo: dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreCnf.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreCnf.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreCnf.lo `test -f 'dddmp/dddmpStoreCnf.c' || echo '$(srcdir)/'`dddmp/dddmpStoreCnf.c - -dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo: dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpStoreMisc.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpStoreMisc.c' object='dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpStoreMisc.lo `test -f 'dddmp/dddmpStoreMisc.c' || echo '$(srcdir)/'`dddmp/dddmpStoreMisc.c - -dddmp/dddmp_libdddmp_la-dddmpUtil.lo: dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_libdddmp_la-dddmpUtil.lo -MD -MP -MF dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Tpo -c -o dddmp/dddmp_libdddmp_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Tpo dddmp/$(DEPDIR)/dddmp_libdddmp_la-dddmpUtil.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/dddmpUtil.c' object='dddmp/dddmp_libdddmp_la-dddmpUtil.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_libdddmp_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_libdddmp_la-dddmpUtil.lo `test -f 'dddmp/dddmpUtil.c' || echo '$(srcdir)/'`dddmp/dddmpUtil.c - -cudd/cudd_testcudd-testcudd.o: cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testcudd-testcudd.o -MD -MP -MF cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo -c -o cudd/cudd_testcudd-testcudd.o `test -f 'cudd/testcudd.c' || echo '$(srcdir)/'`cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testcudd.c' object='cudd/cudd_testcudd-testcudd.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testcudd-testcudd.o `test -f 'cudd/testcudd.c' || echo '$(srcdir)/'`cudd/testcudd.c - -cudd/cudd_testcudd-testcudd.obj: cudd/testcudd.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testcudd-testcudd.obj -MD -MP -MF cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo -c -o cudd/cudd_testcudd-testcudd.obj `if test -f 'cudd/testcudd.c'; then $(CYGPATH_W) 'cudd/testcudd.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testcudd.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testcudd-testcudd.Tpo cudd/$(DEPDIR)/cudd_testcudd-testcudd.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testcudd.c' object='cudd/cudd_testcudd-testcudd.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testcudd_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testcudd-testcudd.obj `if test -f 'cudd/testcudd.c'; then $(CYGPATH_W) 'cudd/testcudd.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testcudd.c'; fi` - -cudd/cudd_testextra-testextra.o: cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testextra-testextra.o -MD -MP -MF cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo -c -o cudd/cudd_testextra-testextra.o `test -f 'cudd/testextra.c' || echo '$(srcdir)/'`cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo cudd/$(DEPDIR)/cudd_testextra-testextra.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testextra.c' object='cudd/cudd_testextra-testextra.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testextra-testextra.o `test -f 'cudd/testextra.c' || echo '$(srcdir)/'`cudd/testextra.c - -cudd/cudd_testextra-testextra.obj: cudd/testextra.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cudd/cudd_testextra-testextra.obj -MD -MP -MF cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo -c -o cudd/cudd_testextra-testextra.obj `if test -f 'cudd/testextra.c'; then $(CYGPATH_W) 'cudd/testextra.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testextra.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cudd/$(DEPDIR)/cudd_testextra-testextra.Tpo cudd/$(DEPDIR)/cudd_testextra-testextra.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cudd/testextra.c' object='cudd/cudd_testextra-testextra.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_testextra_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cudd/cudd_testextra-testextra.obj `if test -f 'cudd/testextra.c'; then $(CYGPATH_W) 'cudd/testextra.c'; else $(CYGPATH_W) '$(srcdir)/cudd/testextra.c'; fi` - -dddmp/dddmp_testdddmp-testdddmp.o: dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_testdddmp-testdddmp.o -MD -MP -MF dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo -c -o dddmp/dddmp_testdddmp-testdddmp.o `test -f 'dddmp/testdddmp.c' || echo '$(srcdir)/'`dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/testdddmp.c' object='dddmp/dddmp_testdddmp-testdddmp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_testdddmp-testdddmp.o `test -f 'dddmp/testdddmp.c' || echo '$(srcdir)/'`dddmp/testdddmp.c - -dddmp/dddmp_testdddmp-testdddmp.obj: dddmp/testdddmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dddmp/dddmp_testdddmp-testdddmp.obj -MD -MP -MF dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo -c -o dddmp/dddmp_testdddmp-testdddmp.obj `if test -f 'dddmp/testdddmp.c'; then $(CYGPATH_W) 'dddmp/testdddmp.c'; else $(CYGPATH_W) '$(srcdir)/dddmp/testdddmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Tpo dddmp/$(DEPDIR)/dddmp_testdddmp-testdddmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dddmp/testdddmp.c' object='dddmp/dddmp_testdddmp-testdddmp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(dddmp_testdddmp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dddmp/dddmp_testdddmp-testdddmp.obj `if test -f 'dddmp/testdddmp.c'; then $(CYGPATH_W) 'dddmp/testdddmp.c'; else $(CYGPATH_W) '$(srcdir)/dddmp/testdddmp.c'; fi` - -mtr/mtr_testmtr-testmtr.o: mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/mtr_testmtr-testmtr.o -MD -MP -MF mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo -c -o mtr/mtr_testmtr-testmtr.o `test -f 'mtr/testmtr.c' || echo '$(srcdir)/'`mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/testmtr.c' object='mtr/mtr_testmtr-testmtr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/mtr_testmtr-testmtr.o `test -f 'mtr/testmtr.c' || echo '$(srcdir)/'`mtr/testmtr.c - -mtr/mtr_testmtr-testmtr.obj: mtr/testmtr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mtr/mtr_testmtr-testmtr.obj -MD -MP -MF mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo -c -o mtr/mtr_testmtr-testmtr.obj `if test -f 'mtr/testmtr.c'; then $(CYGPATH_W) 'mtr/testmtr.c'; else $(CYGPATH_W) '$(srcdir)/mtr/testmtr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) mtr/$(DEPDIR)/mtr_testmtr-testmtr.Tpo mtr/$(DEPDIR)/mtr_testmtr-testmtr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mtr/testmtr.c' object='mtr/mtr_testmtr-testmtr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mtr_testmtr_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mtr/mtr_testmtr-testmtr.obj `if test -f 'mtr/testmtr.c'; then $(CYGPATH_W) 'mtr/testmtr.c'; else $(CYGPATH_W) '$(srcdir)/mtr/testmtr.c'; fi` - -nanotrav/nanotrav_nanotrav-bnet.o: nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-bnet.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo -c -o nanotrav/nanotrav_nanotrav-bnet.o `test -f 'nanotrav/bnet.c' || echo '$(srcdir)/'`nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/bnet.c' object='nanotrav/nanotrav_nanotrav-bnet.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-bnet.o `test -f 'nanotrav/bnet.c' || echo '$(srcdir)/'`nanotrav/bnet.c - -nanotrav/nanotrav_nanotrav-bnet.obj: nanotrav/bnet.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-bnet.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo -c -o nanotrav/nanotrav_nanotrav-bnet.obj `if test -f 'nanotrav/bnet.c'; then $(CYGPATH_W) 'nanotrav/bnet.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/bnet.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-bnet.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/bnet.c' object='nanotrav/nanotrav_nanotrav-bnet.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-bnet.obj `if test -f 'nanotrav/bnet.c'; then $(CYGPATH_W) 'nanotrav/bnet.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/bnet.c'; fi` - -nanotrav/nanotrav_nanotrav-chkMterm.o: nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-chkMterm.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo -c -o nanotrav/nanotrav_nanotrav-chkMterm.o `test -f 'nanotrav/chkMterm.c' || echo '$(srcdir)/'`nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/chkMterm.c' object='nanotrav/nanotrav_nanotrav-chkMterm.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-chkMterm.o `test -f 'nanotrav/chkMterm.c' || echo '$(srcdir)/'`nanotrav/chkMterm.c - -nanotrav/nanotrav_nanotrav-chkMterm.obj: nanotrav/chkMterm.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-chkMterm.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo -c -o nanotrav/nanotrav_nanotrav-chkMterm.obj `if test -f 'nanotrav/chkMterm.c'; then $(CYGPATH_W) 'nanotrav/chkMterm.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/chkMterm.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-chkMterm.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/chkMterm.c' object='nanotrav/nanotrav_nanotrav-chkMterm.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-chkMterm.obj `if test -f 'nanotrav/chkMterm.c'; then $(CYGPATH_W) 'nanotrav/chkMterm.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/chkMterm.c'; fi` - -nanotrav/nanotrav_nanotrav-main.o: nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-main.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo -c -o nanotrav/nanotrav_nanotrav-main.o `test -f 'nanotrav/main.c' || echo '$(srcdir)/'`nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/main.c' object='nanotrav/nanotrav_nanotrav-main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-main.o `test -f 'nanotrav/main.c' || echo '$(srcdir)/'`nanotrav/main.c - -nanotrav/nanotrav_nanotrav-main.obj: nanotrav/main.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-main.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo -c -o nanotrav/nanotrav_nanotrav-main.obj `if test -f 'nanotrav/main.c'; then $(CYGPATH_W) 'nanotrav/main.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/main.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/main.c' object='nanotrav/nanotrav_nanotrav-main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-main.obj `if test -f 'nanotrav/main.c'; then $(CYGPATH_W) 'nanotrav/main.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/main.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrBddTest.o: nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrBddTest.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.o `test -f 'nanotrav/ntrBddTest.c' || echo '$(srcdir)/'`nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrBddTest.c' object='nanotrav/nanotrav_nanotrav-ntrBddTest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.o `test -f 'nanotrav/ntrBddTest.c' || echo '$(srcdir)/'`nanotrav/ntrBddTest.c - -nanotrav/nanotrav_nanotrav-ntrBddTest.obj: nanotrav/ntrBddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrBddTest.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.obj `if test -f 'nanotrav/ntrBddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrBddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrBddTest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrBddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrBddTest.c' object='nanotrav/nanotrav_nanotrav-ntrBddTest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrBddTest.obj `if test -f 'nanotrav/ntrBddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrBddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrBddTest.c'; fi` - -nanotrav/nanotrav_nanotrav-ntr.o: nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntr.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo -c -o nanotrav/nanotrav_nanotrav-ntr.o `test -f 'nanotrav/ntr.c' || echo '$(srcdir)/'`nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntr.c' object='nanotrav/nanotrav_nanotrav-ntr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntr.o `test -f 'nanotrav/ntr.c' || echo '$(srcdir)/'`nanotrav/ntr.c - -nanotrav/nanotrav_nanotrav-ntr.obj: nanotrav/ntr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntr.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo -c -o nanotrav/nanotrav_nanotrav-ntr.obj `if test -f 'nanotrav/ntr.c'; then $(CYGPATH_W) 'nanotrav/ntr.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntr.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntr.c' object='nanotrav/nanotrav_nanotrav-ntr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntr.obj `if test -f 'nanotrav/ntr.c'; then $(CYGPATH_W) 'nanotrav/ntr.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntr.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrHeap.o: nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrHeap.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrHeap.o `test -f 'nanotrav/ntrHeap.c' || echo '$(srcdir)/'`nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrHeap.c' object='nanotrav/nanotrav_nanotrav-ntrHeap.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrHeap.o `test -f 'nanotrav/ntrHeap.c' || echo '$(srcdir)/'`nanotrav/ntrHeap.c - -nanotrav/nanotrav_nanotrav-ntrHeap.obj: nanotrav/ntrHeap.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrHeap.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrHeap.obj `if test -f 'nanotrav/ntrHeap.c'; then $(CYGPATH_W) 'nanotrav/ntrHeap.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrHeap.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrHeap.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrHeap.c' object='nanotrav/nanotrav_nanotrav-ntrHeap.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrHeap.obj `if test -f 'nanotrav/ntrHeap.c'; then $(CYGPATH_W) 'nanotrav/ntrHeap.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrHeap.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrMflow.o: nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrMflow.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrMflow.o `test -f 'nanotrav/ntrMflow.c' || echo '$(srcdir)/'`nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrMflow.c' object='nanotrav/nanotrav_nanotrav-ntrMflow.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrMflow.o `test -f 'nanotrav/ntrMflow.c' || echo '$(srcdir)/'`nanotrav/ntrMflow.c - -nanotrav/nanotrav_nanotrav-ntrMflow.obj: nanotrav/ntrMflow.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrMflow.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrMflow.obj `if test -f 'nanotrav/ntrMflow.c'; then $(CYGPATH_W) 'nanotrav/ntrMflow.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrMflow.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrMflow.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrMflow.c' object='nanotrav/nanotrav_nanotrav-ntrMflow.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrMflow.obj `if test -f 'nanotrav/ntrMflow.c'; then $(CYGPATH_W) 'nanotrav/ntrMflow.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrMflow.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrShort.o: nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrShort.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrShort.o `test -f 'nanotrav/ntrShort.c' || echo '$(srcdir)/'`nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrShort.c' object='nanotrav/nanotrav_nanotrav-ntrShort.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrShort.o `test -f 'nanotrav/ntrShort.c' || echo '$(srcdir)/'`nanotrav/ntrShort.c - -nanotrav/nanotrav_nanotrav-ntrShort.obj: nanotrav/ntrShort.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrShort.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrShort.obj `if test -f 'nanotrav/ntrShort.c'; then $(CYGPATH_W) 'nanotrav/ntrShort.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrShort.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrShort.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrShort.c' object='nanotrav/nanotrav_nanotrav-ntrShort.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrShort.obj `if test -f 'nanotrav/ntrShort.c'; then $(CYGPATH_W) 'nanotrav/ntrShort.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrShort.c'; fi` - -nanotrav/nanotrav_nanotrav-ntrZddTest.o: nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrZddTest.o -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.o `test -f 'nanotrav/ntrZddTest.c' || echo '$(srcdir)/'`nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrZddTest.c' object='nanotrav/nanotrav_nanotrav-ntrZddTest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.o `test -f 'nanotrav/ntrZddTest.c' || echo '$(srcdir)/'`nanotrav/ntrZddTest.c - -nanotrav/nanotrav_nanotrav-ntrZddTest.obj: nanotrav/ntrZddTest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nanotrav/nanotrav_nanotrav-ntrZddTest.obj -MD -MP -MF nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.obj `if test -f 'nanotrav/ntrZddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrZddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrZddTest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Tpo nanotrav/$(DEPDIR)/nanotrav_nanotrav-ntrZddTest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nanotrav/ntrZddTest.c' object='nanotrav/nanotrav_nanotrav-ntrZddTest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nanotrav_nanotrav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nanotrav/nanotrav_nanotrav-ntrZddTest.obj `if test -f 'nanotrav/ntrZddTest.c'; then $(CYGPATH_W) 'nanotrav/ntrZddTest.c'; else $(CYGPATH_W) '$(srcdir)/nanotrav/ntrZddTest.c'; fi` - -st/st_testst-testst.o: st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/st_testst-testst.o -MD -MP -MF st/$(DEPDIR)/st_testst-testst.Tpo -c -o st/st_testst-testst.o `test -f 'st/testst.c' || echo '$(srcdir)/'`st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/st_testst-testst.Tpo st/$(DEPDIR)/st_testst-testst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/testst.c' object='st/st_testst-testst.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/st_testst-testst.o `test -f 'st/testst.c' || echo '$(srcdir)/'`st/testst.c - -st/st_testst-testst.obj: st/testst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT st/st_testst-testst.obj -MD -MP -MF st/$(DEPDIR)/st_testst-testst.Tpo -c -o st/st_testst-testst.obj `if test -f 'st/testst.c'; then $(CYGPATH_W) 'st/testst.c'; else $(CYGPATH_W) '$(srcdir)/st/testst.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) st/$(DEPDIR)/st_testst-testst.Tpo st/$(DEPDIR)/st_testst-testst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='st/testst.c' object='st/st_testst-testst.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(st_testst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o st/st_testst-testst.obj `if test -f 'st/testst.c'; then $(CYGPATH_W) 'st/testst.c'; else $(CYGPATH_W) '$(srcdir)/st/testst.c'; fi` - -.cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cc.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< - -cplusplus/cplusplus_libobj_la-cuddObj.lo: cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_libobj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_libobj_la-cuddObj.lo -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Tpo -c -o cplusplus/cplusplus_libobj_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Tpo cplusplus/$(DEPDIR)/cplusplus_libobj_la-cuddObj.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/cuddObj.cc' object='cplusplus/cplusplus_libobj_la-cuddObj.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_libobj_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_libobj_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc - -cplusplus/cudd_libcudd_la-cuddObj.lo: cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cudd_libcudd_la-cuddObj.lo -MD -MP -MF cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Tpo -c -o cplusplus/cudd_libcudd_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Tpo cplusplus/$(DEPDIR)/cudd_libcudd_la-cuddObj.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/cuddObj.cc' object='cplusplus/cudd_libcudd_la-cuddObj.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(cudd_libcudd_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cudd_libcudd_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cudd_libcudd_la-cuddObj.lo `test -f 'cplusplus/cuddObj.cc' || echo '$(srcdir)/'`cplusplus/cuddObj.cc - -cplusplus/cplusplus_testmulti-testmulti.o: cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testmulti-testmulti.o -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo -c -o cplusplus/cplusplus_testmulti-testmulti.o `test -f 'cplusplus/testmulti.cc' || echo '$(srcdir)/'`cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testmulti.cc' object='cplusplus/cplusplus_testmulti-testmulti.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testmulti-testmulti.o `test -f 'cplusplus/testmulti.cc' || echo '$(srcdir)/'`cplusplus/testmulti.cc - -cplusplus/cplusplus_testmulti-testmulti.obj: cplusplus/testmulti.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testmulti-testmulti.obj -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo -c -o cplusplus/cplusplus_testmulti-testmulti.obj `if test -f 'cplusplus/testmulti.cc'; then $(CYGPATH_W) 'cplusplus/testmulti.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testmulti.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Tpo cplusplus/$(DEPDIR)/cplusplus_testmulti-testmulti.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testmulti.cc' object='cplusplus/cplusplus_testmulti-testmulti.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testmulti_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testmulti-testmulti.obj `if test -f 'cplusplus/testmulti.cc'; then $(CYGPATH_W) 'cplusplus/testmulti.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testmulti.cc'; fi` - -cplusplus/cplusplus_testobj-testobj.o: cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testobj-testobj.o -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo -c -o cplusplus/cplusplus_testobj-testobj.o `test -f 'cplusplus/testobj.cc' || echo '$(srcdir)/'`cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testobj.cc' object='cplusplus/cplusplus_testobj-testobj.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testobj-testobj.o `test -f 'cplusplus/testobj.cc' || echo '$(srcdir)/'`cplusplus/testobj.cc - -cplusplus/cplusplus_testobj-testobj.obj: cplusplus/testobj.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cplusplus/cplusplus_testobj-testobj.obj -MD -MP -MF cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo -c -o cplusplus/cplusplus_testobj-testobj.obj `if test -f 'cplusplus/testobj.cc'; then $(CYGPATH_W) 'cplusplus/testobj.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testobj.cc'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Tpo cplusplus/$(DEPDIR)/cplusplus_testobj-testobj.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='cplusplus/testobj.cc' object='cplusplus/cplusplus_testobj-testobj.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cplusplus_testobj_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cplusplus/cplusplus_testobj-testobj.obj `if test -f 'cplusplus/testobj.cc'; then $(CYGPATH_W) 'cplusplus/testobj.cc'; else $(CYGPATH_W) '$(srcdir)/cplusplus/testobj.cc'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -rm -rf cplusplus/.libs cplusplus/_libs - -rm -rf cudd/.libs cudd/_libs - -rm -rf dddmp/.libs dddmp/_libs - -rm -rf epd/.libs epd/_libs - -rm -rf mtr/.libs mtr/_libs - -rm -rf nanotrav/.libs nanotrav/_libs - -rm -rf st/.libs st/_libs - -rm -rf util/.libs util/_libs - -distclean-libtool: - -rm -f libtool config.lt -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) $(check_SCRIPTS) $(dist_check_DATA) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) \ - $(dist_check_DATA) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f cplusplus/$(DEPDIR)/$(am__dirstamp) - -rm -f cplusplus/$(am__dirstamp) - -rm -f cudd/$(DEPDIR)/$(am__dirstamp) - -rm -f cudd/$(am__dirstamp) - -rm -f dddmp/$(DEPDIR)/$(am__dirstamp) - -rm -f dddmp/$(am__dirstamp) - -rm -f epd/$(DEPDIR)/$(am__dirstamp) - -rm -f epd/$(am__dirstamp) - -rm -f mtr/$(DEPDIR)/$(am__dirstamp) - -rm -f mtr/$(am__dirstamp) - -rm -f nanotrav/$(DEPDIR)/$(am__dirstamp) - -rm -f nanotrav/$(am__dirstamp) - -rm -f st/$(DEPDIR)/$(am__dirstamp) - -rm -f st/$(am__dirstamp) - -rm -f util/$(DEPDIR)/$(am__dirstamp) - -rm -f util/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool clean-noinstLTLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf cplusplus/$(DEPDIR) cudd/$(DEPDIR) dddmp/$(DEPDIR) epd/$(DEPDIR) mtr/$(DEPDIR) nanotrav/$(DEPDIR) st/$(DEPDIR) util/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-includeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf cplusplus/$(DEPDIR) cudd/$(DEPDIR) dddmp/$(DEPDIR) epd/$(DEPDIR) mtr/$(DEPDIR) nanotrav/$(DEPDIR) st/$(DEPDIR) util/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.MAKE: all check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ - check-am clean clean-checkPROGRAMS clean-cscope clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ - cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ - dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am \ - uninstall-includeHEADERS uninstall-libLTLIBRARIES - -.PRECIOUS: Makefile - - -cudd/test_cudd.test: cudd/test_cudd.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -st/test_st.test: st/test_st.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -mtr/test_mtr.test: mtr/test_mtr.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -dddmp/test_dddmp.test: dddmp/test_dddmp.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -cplusplus/test_obj.test: cplusplus/test_obj.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -nanotrav/test_ntrv.test: nanotrav/test_ntrv.test.in Makefile - $(do_subst) $< > $@ - chmod +x $@ - -@HAVE_PDFLATEX_TRUE@doc/cudd.pdf: doc/cudd.tex $(top_srcdir)/doc/phase.pdf -@HAVE_PDFLATEX_TRUE@ @if $(AM_V_P); then dest='2>&1'; else dest='> /dev/null 2>&1'; fi; \ -@HAVE_PDFLATEX_TRUE@ cd doc && eval "$(PDFLATEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(MAKEINDEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(PDFLATEX) cudd $${dest}" && \ -@HAVE_PDFLATEX_TRUE@ eval "$(PDFLATEX) cudd $${dest}" - -@HAVE_PDFLATEX_FALSE@doc/cudd.pdf: - -dist-hook: - rm -rf `find $(distdir) -name .svn` - -.PHONY : - -all: html/index.html doc/cudd.pdf - -#if HAVE_DOXYGEN -# -#html/index.html: Doxyfile $(lib_LTLIBRARIES) -# @if $(AM_V_P); then dest='2>&1'; else dest='> /dev/null 2>&1'; fi; \ -# eval "$(DOXYGEN) $< $${dest}" -# -#clean-local: -# rm -rf html doxygen_sqlite3.db -# -#else - -html/index.html: - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/resources/3rdparty/cudd-3.0.0/aclocal.m4 b/resources/3rdparty/cudd-3.0.0/aclocal.m4 deleted file mode 100644 index b1d04ee86..000000000 --- a/resources/3rdparty/cudd-3.0.0/aclocal.m4 +++ /dev/null @@ -1,1256 +0,0 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. - -# 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# Copyright (C) 2011-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_PROG_AR([ACT-IF-FAIL]) -# ------------------------- -# Try to determine the archiver interface, and trigger the ar-lib wrapper -# if it is needed. If the detection of archiver interface fails, run -# ACT-IF-FAIL (default is to abort configure with a proper error message). -AC_DEFUN([AM_PROG_AR], -[AC_BEFORE([$0], [LT_INIT])dnl -AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([ar-lib])dnl -AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) -: ${AR=ar} - -AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], - [AC_LANG_PUSH([C]) - am_cv_ar_interface=ar - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], - [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([am_ar_try]) - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - ]) - AC_LANG_POP([C])]) - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - m4_default([$1], - [AC_MSG_ERROR([could not determine $AR interface])]) - ;; -esac -AC_SUBST([AR])dnl -]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_COND_IF -*- Autoconf -*- - -# Copyright (C) 2008-2017 Free Software Foundation, Inc. -# -# 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. - -# _AM_COND_IF -# _AM_COND_ELSE -# _AM_COND_ENDIF -# -------------- -# These macros are only used for tracing. -m4_define([_AM_COND_IF]) -m4_define([_AM_COND_ELSE]) -m4_define([_AM_COND_ENDIF]) - -# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) -# --------------------------------------- -# If the shell condition COND is true, execute IF-TRUE, otherwise execute -# IF-FALSE. Allow automake to learn about conditional instantiating macros -# (the AC_CONFIG_FOOS). -AC_DEFUN([AM_COND_IF], -[m4_ifndef([_AM_COND_VALUE_$1], - [m4_fatal([$0: no such condition "$1"])])dnl -_AM_COND_IF([$1])dnl -if test -z "$$1_TRUE"; then : - m4_n([$2])[]dnl -m4_ifval([$3], -[_AM_COND_ELSE([$1])dnl -else - $3 -])dnl -_AM_COND_ENDIF([$1])dnl -fi[]dnl -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# 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. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# 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. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. -# -# 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. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2017 Free Software Foundation, Inc. -# -# 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. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2017 Free Software Foundation, Inc. -# -# 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. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2017 Free Software Foundation, Inc. -# -# 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. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2017 Free Software Foundation, Inc. -# -# 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. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2017 Free Software Foundation, Inc. -# -# 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. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar <conftest.tar]) - AM_RUN_LOG([cat conftest.dir/file]) - grep GrepMe conftest.dir/file >/dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/libtool.m4]) -m4_include([m4/ltoptions.m4]) -m4_include([m4/ltsugar.m4]) -m4_include([m4/ltversion.m4]) -m4_include([m4/lt~obsolete.m4]) -m4_include([m4/modern_cxx.m4]) -m4_include([m4/w32.m4]) diff --git a/resources/3rdparty/cudd-3.0.0/configure b/resources/3rdparty/cudd-3.0.0/configure deleted file mode 100755 index 1494802d5..000000000 --- a/resources/3rdparty/cudd-3.0.0/configure +++ /dev/null @@ -1,19890 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for cudd 3.0.0. -# -# Report bugs to <Fabio@Colorado.EDU>. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 - - test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and Fabio@Colorado.EDU -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - -SHELL=${CONFIG_SHELL-/bin/sh} - - -test -n "$DJDIR" || exec 7<&0 </dev/null -exec 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='cudd' -PACKAGE_TARNAME='cudd' -PACKAGE_VERSION='3.0.0' -PACKAGE_STRING='cudd 3.0.0' -PACKAGE_BUGREPORT='Fabio@Colorado.EDU' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_unique_file="st/st.c" -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -MINGW64_FALSE -MINGW64_TRUE -HAVE_PTHREADS_FALSE -HAVE_PTHREADS_TRUE -HAVE_PDFLATEX_FALSE -HAVE_PDFLATEX_TRUE -MAKEINDEX -PDFLATEX -HAVE_DOXYGEN_FALSE -HAVE_DOXYGEN_TRUE -DOXYGEN -CROSS_COMPILING_FALSE -CROSS_COMPILING_TRUE -CXXCPP -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -MANIFEST_TOOL -RANLIB -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -LIBTOOL -OBJDUMP -DLLTOOL -AS -ac_ct_AR -AR -am__fastdepCXX_FALSE -am__fastdepCXX_TRUE -CXXDEPMODE -ac_ct_CXX -CXXFLAGS -CXX -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -OBJ_FALSE -OBJ_TRUE -DDDMP_FALSE -DDDMP_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_dddmp -enable_obj -with_system_qsort -enable_dependency_tracking -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -with_sysroot -enable_libtool_lock -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CXX -CXXFLAGS -CCC -CPP -CXXCPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures cudd 3.0.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/cudd] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of cudd 3.0.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-dddmp include libdddmp in libcudd - --enable-obj include libobj in libcudd - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-shared[=PKGS] build shared libraries [default=no] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-system-qsort use system qsort instead of portable one - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CPP C preprocessor - CXXCPP C++ preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to <Fabio@Colorado.EDU>. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -cudd configure 3.0.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_cxx_try_cpp LINENO -# ------------------------ -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_cpp - -# ac_fn_cxx_try_link LINENO -# ------------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_link - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## --------------------------------- ## -## Report this to Fabio@Colorado.EDU ## -## --------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_find_uintX_t LINENO BITS VAR -# ------------------------------------ -# Finds an unsigned integer type with width BITS, setting cache variable VAR -# accordingly. -ac_fn_c_find_uintX_t () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 -$as_echo_n "checking for uint$2_t... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - # Order is important - never check a type that is potentially smaller - # than half of the expected target width. - for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ - 'unsigned long long int' 'unsigned short int' 'unsigned char'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - case $ac_type in #( - uint$2_t) : - eval "$3=yes" ;; #( - *) : - eval "$3=\$ac_type" ;; -esac -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : - -else - break -fi - done -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_find_uintX_t - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include <stdio.h> -#include <stdlib.h> -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 <conftest.val; ac_retval=0 -else - ac_retval=1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -rm -f conftest.val - - fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_compute_int -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by cudd $as_me 3.0.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_aux_dir= -for ac_dir in build-aux "$srcdir"/build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='cudd' - VERSION='3.0.0' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - - - -# Check whether --enable-dddmp was given. -if test "${enable_dddmp+set}" = set; then : - enableval=$enable_dddmp; -fi - - if test x$enable_dddmp = xyes; then - DDDMP_TRUE= - DDDMP_FALSE='#' -else - DDDMP_TRUE='#' - DDDMP_FALSE= -fi - - -# Check whether --enable-obj was given. -if test "${enable_obj+set}" = set; then : - enableval=$enable_obj; -fi - - if test x$enable_obj = xyes; then - OBJ_TRUE= - OBJ_FALSE='#' -else - OBJ_TRUE='#' - OBJ_FALSE= -fi - - - -# Check whether --with-system-qsort was given. -if test "${with_system_qsort+set}" = set; then : - withval=$with_system_qsort; -else - with_system_qsort=no -fi - -if test x$with_system_qsort != xno ; then - -$as_echo "#define USE_SYSTEM_QSORT 1" >>confdefs.h - -fi - -# Set our own default (instead of "-g -O2") unless CFLAGS is already defined. -: ${CFLAGS="-Wall -Wextra -g -O3"} -: ${CXXFLAGS="-Wall -Wextra -std=c++0x -g -O3"} - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -else - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -depcc="$CXX" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CXX_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CXX_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CXX_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CXX_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } -CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then - am__fastdepCXX_TRUE= - am__fastdepCXX_FALSE='#' -else - am__fastdepCXX_TRUE='#' - am__fastdepCXX_FALSE= -fi - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar lib "link -lib" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar lib "link -lib" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 -$as_echo_n "checking the archiver ($AR) interface... " >&6; } -if ${am_cv_ar_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - am_cv_ar_interface=ar - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int some_variable = 0; -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=ar - else - am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 - (eval $am_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - am_cv_ar_interface=lib - else - am_cv_ar_interface=unknown - fi - fi - rm -f conftest.lib libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 -$as_echo "$am_cv_ar_interface" >&6; } - -case $am_cv_ar_interface in -ar) - ;; -lib) - # Microsoft lib, so override with the ar-lib wrapper script. - # FIXME: It is wrong to rewrite AR. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__AR in this case, - # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something - # similar. - AR="$am_aux_dir/ar-lib $AR" - ;; -unknown) - as_fn_error $? "could not determine $AR interface" "$LINENO" 5 - ;; -esac - - -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.2' -macro_revision='1.3337' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$lt_cv_path_LD" -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - if test -n "$ac_tool_prefix"; then - for ac_prog in dumpbin "link -dump" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in dumpbin "link -dump" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:$LINENO: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac - -fi - -to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - #assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac - -fi - -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then - reload_cmds=false - fi - ;; - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - - - - - - - -if test -n "$ac_tool_prefix"; then - for ac_prog in ar - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AR" && break - done -fi -if test -z "$AR"; then - ac_ct_AR=$AR - for ac_prog in ar -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_AR" && break -done - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -fi - -: ${AR=ar} -: ${AR_FLAGS=cru} - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ar_at_file=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 - (eval $lt_ar_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; -else - with_sysroot=no -fi - - -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } - as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 - ;; -esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line '$LINENO' "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in - *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; - *) - LD="${LD-ld} -m elf_i386" - ;; - esac - ;; - powerpc64le-*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - powerpcle-*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. -set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MANIFEST_TOOL"; then - ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL -if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_MANIFEST_TOOL"; then - ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL - # Extract the first word of "mt", so it can be a program name with args. -set dummy mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MANIFEST_TOOL"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL -if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_MANIFEST_TOOL" = x; then - MANIFEST_TOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL - fi -else - MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" -fi - -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&5 - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi - - - - - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&5 - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 - echo "$RANLIB libconftest.a" >&5 - $RANLIB libconftest.a 2>&5 - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&5 - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - - -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf - - - - - -# Set options -enable_win32_dll=yes - -case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. -set dummy ${ac_tool_prefix}as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AS"; then - ac_cv_prog_AS="$AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AS="${ac_tool_prefix}as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AS=$ac_cv_prog_AS -if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AS"; then - ac_ct_AS=$AS - # Extract the first word of "as", so it can be a program name with args. -set dummy as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AS"; then - ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AS="as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AS=$ac_cv_prog_ac_ct_AS -if test -n "$ac_ct_AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 -$as_echo "$ac_ct_AS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AS" = x; then - AS="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AS=$ac_ct_AS - fi -else - AS="$ac_cv_prog_AS" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. -set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DLLTOOL"; then - ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DLLTOOL=$ac_cv_prog_DLLTOOL -if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DLLTOOL"; then - ac_ct_DLLTOOL=$DLLTOOL - # Extract the first word of "dlltool", so it can be a program name with args. -set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DLLTOOL"; then - ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL -if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DLLTOOL" = x; then - DLLTOOL="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DLLTOOL=$ac_ct_DLLTOOL - fi -else - DLLTOOL="$ac_cv_prog_DLLTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - - ;; -esac - -test -z "$AS" && AS=as - - - - - -test -z "$DLLTOOL" && DLLTOOL=dlltool - - - - - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - -# Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=no -fi - - - - - - - - - - - enable_dlopen=no - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; - *) - lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - lt_prog_compiler_wl='-Xlinker ' - if test -n "$lt_prog_compiler_pic"; then - lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" - fi - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - nagfor*) - # NAG Fortran compiler - lt_prog_compiler_wl='-Wl,-Wl,,' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - *Sun\ F* | *Sun*Fortran*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Qoption ld ' - ;; - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Intel*\ [CF]*Compiler*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - *Portland\ Group*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } -lt_prog_compiler_pic=$lt_cv_prog_compiler_pic - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs=no - ;; - esac - - ld_shlibs=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; - *\ \(GNU\ Binutils\)\ [3-9]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs=yes - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - link_all_deplibs=no - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath_ -fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - fi - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - always_export_symbols=yes - file_list_spec='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, )='true' - enable_shared_with_static_runtimes=yes - exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - old_postinstall_cmds='chmod 644 $oldlib' - postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - enable_shared_with_static_runtimes=yes - ;; - esac - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec='' - fi - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -b" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler__b=yes - fi - else - lt_cv_prog_compiler__b=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } - -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' -else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' -fi - - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo (void) { return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_irix_exported_symbol=yes -else - lt_cv_irix_exported_symbol=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd* | netbsdelf*-gnu) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } - archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 -$as_echo_n "checking how to run the C++ preprocessor... " >&6; } -if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 -$as_echo "$CXXCPP" >&6; } -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -else - _lt_caught_CXX_error=yes -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -archive_cmds_need_lc_CXX=no -allow_undefined_flag_CXX= -always_export_symbols_CXX=no -archive_expsym_cmds_CXX= -compiler_needs_object_CXX=no -export_dynamic_flag_spec_CXX= -hardcode_direct_CXX=no -hardcode_direct_absolute_CXX=no -hardcode_libdir_flag_spec_CXX= -hardcode_libdir_separator_CXX= -hardcode_minus_L_CXX=no -hardcode_shlibpath_var_CXX=unsupported -hardcode_automatic_CXX=no -inherit_rpath_CXX=no -module_cmds_CXX= -module_expsym_cmds_CXX= -link_all_deplibs_CXX=unknown -old_archive_cmds_CXX=$old_archive_cmds -reload_flag_CXX=$reload_flag -reload_cmds_CXX=$reload_cmds -no_undefined_flag_CXX= -whole_archive_flag_spec_CXX= -enable_shared_with_static_runtimes_CXX=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -objext_CXX=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - - # save warnings/boilerplate of simple test code - ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - - ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - compiler_CXX=$CC - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` - - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' - else - lt_prog_compiler_no_builtin_flag_CXX= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$lt_cv_path_LD" -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec_CXX= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - ld_shlibs_CXX=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds_CXX='' - hardcode_direct_CXX=yes - hardcode_direct_absolute_CXX=yes - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - file_list_spec_CXX='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct_CXX=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L_CXX=yes - hardcode_libdir_flag_spec_CXX='-L$libdir' - hardcode_libdir_separator_CXX= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec_CXX='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - always_export_symbols_CXX=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag_CXX='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath__CXX -fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - - archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - - lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }' - lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" - fi - -fi - - aix_libpath=$lt_cv_aix_libpath__CXX -fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag_CXX=' ${wl}-bernotok' - allow_undefined_flag_CXX=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX='$convenience' - fi - archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag_CXX=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs_CXX=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec_CXX=' ' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=yes - file_list_spec_CXX='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' - enable_shared_with_static_runtimes_CXX=yes - # Don't use ranlib - old_postinstall_cmds_CXX='chmod 644 $oldlib' - postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec_CXX='-L$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' - allow_undefined_flag_CXX=unsupported - always_export_symbols_CXX=no - enable_shared_with_static_runtimes_CXX=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs_CXX=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - - - archive_cmds_need_lc_CXX=no - hardcode_direct_CXX=no - hardcode_automatic_CXX=yes - hardcode_shlibpath_var_CXX=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - - else - whole_archive_flag_spec_CXX='' - fi - link_all_deplibs_CXX=yes - allow_undefined_flag_CXX="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then - archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi - - else - ld_shlibs_CXX=no - fi - - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - freebsd2.*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - ld_shlibs_CXX=no - ;; - - freebsd-elf*) - archive_cmds_need_lc_CXX=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - ld_shlibs_CXX=yes - ;; - - haiku*) - archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - link_all_deplibs_CXX=yes - ;; - - hpux9*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' - hardcode_direct_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - export_dynamic_flag_spec_CXX='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - ;; - *) - hardcode_direct_CXX=yes - hardcode_direct_absolute_CXX=yes - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - interix[3-9]*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - link_all_deplibs_CXX=yes - ;; - esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - inherit_rpath_CXX=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - archive_cmds_need_lc_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [1-5].* | *pgcpp\ [1-5].*) - prelink_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - old_archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - hardcode_libdir_flag_spec_CXX='-R$libdir' - whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object_CXX=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - ld_shlibs_CXX=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - ld_shlibs_CXX=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - hardcode_direct_absolute_CXX=yes - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - export_dynamic_flag_spec_CXX='${wl}-E' - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - ld_shlibs_CXX=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - hardcode_libdir_separator_CXX=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - cxx*) - case $host in - osf3*) - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - ;; - *) - allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - hardcode_libdir_flag_spec_CXX='-rpath $libdir' - ;; - esac - - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator_CXX=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - archive_cmds_need_lc_CXX=yes - no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - hardcode_libdir_flag_spec_CXX='-R$libdir' - hardcode_shlibpath_var_CXX=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' - ;; - esac - link_all_deplibs_CXX=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - no_undefined_flag_CXX=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag_CXX='${wl}-z,text' - archive_cmds_need_lc_CXX=no - hardcode_shlibpath_var_CXX=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag_CXX='${wl}-z,text' - allow_undefined_flag_CXX='${wl}-z,nodefs' - archive_cmds_need_lc_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' - hardcode_libdir_separator_CXX=':' - link_all_deplibs_CXX=yes - export_dynamic_flag_spec_CXX='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ - '"$old_archive_cmds_CXX" - reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ - '"$reload_cmds_CXX" - ;; - *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } - test "$ld_shlibs_CXX" = no && can_build_shared=no - - GCC_CXX="$GXX" - LD_CXX="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - # Dependencies to place before and after the object being linked: -predep_objects_CXX= -postdep_objects_CXX= -predeps_CXX= -postdeps_CXX= -compiler_lib_search_path_CXX= - -cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF - - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; -esac - -if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$compiler_lib_search_path_CXX"; then - compiler_lib_search_path_CXX="${prev}${p}" - else - compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$postdeps_CXX"; then - postdeps_CXX="${prev}${p}" - else - postdeps_CXX="${postdeps_CXX} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$predep_objects_CXX"; then - predep_objects_CXX="$p" - else - predep_objects_CXX="$predep_objects_CXX $p" - fi - else - if test -z "$postdep_objects_CXX"; then - postdep_objects_CXX="$p" - else - postdep_objects_CXX="$postdep_objects_CXX $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling CXX test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -case $host_os in -interix[3-9]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - predep_objects_CXX= - postdep_objects_CXX= - postdeps_CXX= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac - - -case " $postdeps_CXX " in -*" -lc "*) archive_cmds_need_lc_CXX=no ;; -esac - compiler_lib_search_dirs_CXX= -if test -n "${compiler_lib_search_path_CXX}"; then - compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - lt_prog_compiler_wl_CXX= -lt_prog_compiler_pic_CXX= -lt_prog_compiler_static_CXX= - - - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic_CXX='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic_CXX='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - lt_prog_compiler_pic_CXX= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - lt_prog_compiler_static_CXX= - ;; - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic_CXX=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic_CXX='-fPIC -shared' - ;; - *) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - esac - else - case $host_os in - aix[4-9]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static_CXX='-Bstatic' - else - lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_CXX='-DDLL_EXPORT' - ;; - dgux*) - case $cc_basename in - ec++*) - lt_prog_compiler_pic_CXX='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - lt_prog_compiler_pic_CXX='+Z' - fi - ;; - aCC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic_CXX='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - lt_prog_compiler_wl_CXX='--backend -Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-fPIC' - lt_prog_compiler_static_CXX='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-fpic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-qpic' - lt_prog_compiler_static_CXX='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - lt_prog_compiler_pic_CXX='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd* | netbsdelf*-gnu) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic_CXX='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - lt_prog_compiler_wl_CXX='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - lt_prog_compiler_pic_CXX='-pic' - ;; - cxx*) - # Digital/Compaq C++ - lt_prog_compiler_wl_CXX='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - lt_prog_compiler_pic_CXX= - lt_prog_compiler_static_CXX='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - lt_prog_compiler_wl_CXX='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - lt_prog_compiler_pic_CXX='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - lt_prog_compiler_pic_CXX='-pic' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - lcc*) - # Lucid - lt_prog_compiler_pic_CXX='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_pic_CXX='-KPIC' - lt_prog_compiler_static_CXX='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - lt_prog_compiler_pic_CXX='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - lt_prog_compiler_can_build_shared_CXX=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic_CXX= - ;; - *) - lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" - ;; -esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } -lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } -if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works_CXX=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works_CXX=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then - case $lt_prog_compiler_pic_CXX in - "" | " "*) ;; - *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; - esac -else - lt_prog_compiler_pic_CXX= - lt_prog_compiler_can_build_shared_CXX=no -fi - -fi - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works_CXX=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works_CXX=yes - fi - else - lt_cv_prog_compiler_static_works_CXX=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } - -if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then - : -else - lt_prog_compiler_static_CXX= -fi - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o_CXX=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o_CXX=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - case $host_os in - aix[4-9]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - export_symbols_cmds_CXX="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) - exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' - exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' - ;; - esac - ;; - linux* | k*bsd*-gnu | gnu*) - link_all_deplibs_CXX=no - ;; - *) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } -test "$ld_shlibs_CXX" = no && can_build_shared=no - -with_gnu_ld_CXX=$with_gnu_ld - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc_CXX" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc_CXX=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds_CXX in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl_CXX - pic_flag=$lt_prog_compiler_pic_CXX - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag_CXX - allow_undefined_flag_CXX= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - lt_cv_archive_cmds_need_lc_CXX=no - else - lt_cv_archive_cmds_need_lc_CXX=yes - fi - allow_undefined_flag_CXX=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } - archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[23].*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2.*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -haiku*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[3-9]*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - lt_cv_shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - -fi - - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsdelf*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='NetBSD ld.elf_so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action_CXX= -if test -n "$hardcode_libdir_flag_spec_CXX" || - test -n "$runpath_var_CXX" || - test "X$hardcode_automatic_CXX" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct_CXX" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && - test "$hardcode_minus_L_CXX" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action_CXX=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action_CXX=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action_CXX=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 -$as_echo "$hardcode_action_CXX" >&6; } - -if test "$hardcode_action_CXX" = relink || - test "$inherit_rpath_CXX" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - - - -ac_config_headers="$ac_config_headers config.h" - - -# Checks for programs. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - - if test x$cross_compiling = xyes; then - CROSS_COMPILING_TRUE= - CROSS_COMPILING_FALSE='#' -else - CROSS_COMPILING_TRUE='#' - CROSS_COMPILING_FALSE= -fi - - -# Building documentation requires doxygen, pdflatex, and makeindex. -for ac_prog in doxygen -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DOXYGEN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DOXYGEN"; then - ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DOXYGEN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DOXYGEN=$ac_cv_prog_DOXYGEN -if test -n "$DOXYGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 -$as_echo "$DOXYGEN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DOXYGEN" && break -done - -if test -z "$DOXYGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Doxygen not found - continuing without Doxygen support" >&5 -$as_echo "$as_me: WARNING: Doxygen not found - continuing without Doxygen support" >&2;} -fi - if test -n "$DOXYGEN"; then - HAVE_DOXYGEN_TRUE= - HAVE_DOXYGEN_FALSE='#' -else - HAVE_DOXYGEN_TRUE='#' - HAVE_DOXYGEN_FALSE= -fi - -if test -z "$HAVE_DOXYGEN_TRUE"; then : - ac_config_files="$ac_config_files Doxyfile" - -fi - -for ac_prog in pdflatex -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PDFLATEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PDFLATEX"; then - ac_cv_prog_PDFLATEX="$PDFLATEX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PDFLATEX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -PDFLATEX=$ac_cv_prog_PDFLATEX -if test -n "$PDFLATEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PDFLATEX" >&5 -$as_echo "$PDFLATEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PDFLATEX" && break -done - -if test -z "$PDFLATEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pdflatex not found - unable to compile manual to PDF" >&5 -$as_echo "$as_me: WARNING: pdflatex not found - unable to compile manual to PDF" >&2;} -fi -for ac_prog in makeindex -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MAKEINDEX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MAKEINDEX"; then - ac_cv_prog_MAKEINDEX="$MAKEINDEX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MAKEINDEX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MAKEINDEX=$ac_cv_prog_MAKEINDEX -if test -n "$MAKEINDEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINDEX" >&5 -$as_echo "$MAKEINDEX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$MAKEINDEX" && break -done - -if test -z "$MAKEINDEX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: makeindex not found - unable to compile manual to PDF" >&5 -$as_echo "$as_me: WARNING: makeindex not found - unable to compile manual to PDF" >&2;} -fi - if test -n "$PDFLATEX" && test -n "$MAKEINDEX"; then - HAVE_PDFLATEX_TRUE= - HAVE_PDFLATEX_FALSE='#' -else - HAVE_PDFLATEX_TRUE='#' - HAVE_PDFLATEX_FALSE= -fi - -if test -z "$HAVE_PDFLATEX_TRUE"; then : - ac_config_files="$ac_config_files doc/cudd.tex" - -fi - -# Checks for libraries. -#AC_CHECK_LIB([m],[pow]) -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pow" >&5 -$as_echo_n "checking for library containing pow... " >&6; } -if ${ac_cv_search_pow+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pow (); -int -main () -{ -return pow (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pow=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pow+:} false; then : - break -fi -done -if ${ac_cv_search_pow+:} false; then : - -else - ac_cv_search_pow=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pow" >&5 -$as_echo "$ac_cv_search_pow" >&6; } -ac_res=$ac_cv_search_pow -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_create (); -int -main () -{ -return pthread_create (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pthread_pthread_create=yes -else - ac_cv_lib_pthread_pthread_create=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : - have_pthreads=yes -else - have_pthreads=no -fi - - if test x$have_pthreads = xyes; then - HAVE_PTHREADS_TRUE= - HAVE_PTHREADS_FALSE='#' -else - HAVE_PTHREADS_TRUE='#' - HAVE_PTHREADS_FALSE= -fi - -# Check for Windows API functions. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing WSAStartup" >&5 -$as_echo_n "checking for library containing WSAStartup... " >&6; } -if ${ac_cv_search_WSAStartup+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char WSAStartup (); -int -main () -{ -return WSAStartup (); - ; - return 0; -} -_ACEOF -for ac_lib in '' ws2_32; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_WSAStartup=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_WSAStartup+:} false; then : - break -fi -done -if ${ac_cv_search_WSAStartup+:} false; then : - -else - ac_cv_search_WSAStartup=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_WSAStartup" >&5 -$as_echo "$ac_cv_search_WSAStartup" >&6; } -ac_res=$ac_cv_search_WSAStartup -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing GetProcessMemoryInfo" >&5 -$as_echo_n "checking for library containing GetProcessMemoryInfo... " >&6; } -if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char GetProcessMemoryInfo (); -int -main () -{ -return GetProcessMemoryInfo (); - ; - return 0; -} -_ACEOF -for ac_lib in '' psapi; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_GetProcessMemoryInfo=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - break -fi -done -if ${ac_cv_search_GetProcessMemoryInfo+:} false; then : - -else - ac_cv_search_GetProcessMemoryInfo=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_GetProcessMemoryInfo" >&5 -$as_echo "$ac_cv_search_GetProcessMemoryInfo" >&6; } -ac_res=$ac_cv_search_GetProcessMemoryInfo -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -# Checks for header files. -# First check for mandatory headers... -for ac_header in float.h inttypes.h limits.h stddef.h stdlib.h string.h assert.h math.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - have_mandatory_headers=no -fi - -done - -if test "x${have_mandatory_headers}" = xno; then - as_fn_error $? "One or more mandatory headers missing. Check 'config.log'." "$LINENO" 5 -fi -# ...then check for optional C headers. -for ac_header in unistd.h sys/time.h sys/times.h sys/resource.h sys/wait.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -# Finally, check C++ optional headers. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working C++ thread header" >&5 -$as_echo_n "checking for working C++ thread header... " >&6; } -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <thread> -int -main () -{ - std::thread([] {}).join() - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - have_working_thread=yes -else - have_working_thread=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test x$have_working_thread = xyes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_WORKING_THREAD 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -# Checks for typedefs, structures, and compiler characteristics. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 -$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } -if ${ac_cv_header_stdbool_h+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include <stdbool.h> - #ifndef bool - "error: bool is not defined" - #endif - #ifndef false - "error: false is not defined" - #endif - #if false - "error: false is not 0" - #endif - #ifndef true - "error: true is not defined" - #endif - #if true != 1 - "error: true is not 1" - #endif - #ifndef __bool_true_false_are_defined - "error: __bool_true_false_are_defined is not defined" - #endif - - struct s { _Bool s: 1; _Bool t; } s; - - char a[true == 1 ? 1 : -1]; - char b[false == 0 ? 1 : -1]; - char c[__bool_true_false_are_defined == 1 ? 1 : -1]; - char d[(bool) 0.5 == true ? 1 : -1]; - /* See body of main program for 'e'. */ - char f[(_Bool) 0.0 == false ? 1 : -1]; - char g[true]; - char h[sizeof (_Bool)]; - char i[sizeof s.t]; - enum { j = false, k = true, l = false * true, m = true * 256 }; - /* The following fails for - HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ - _Bool n[m]; - char o[sizeof n == m * sizeof n[0] ? 1 : -1]; - char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; - /* Catch a bug in an HP-UX C compiler. See - http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html - http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html - */ - _Bool q = true; - _Bool *pq = &q; - -int -main () -{ - - bool e = &s; - *pq |= q; - *pq |= ! q; - /* Refer to every declared value, to avoid compiler optimizations. */ - return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l - + !m + !n + !o + !p + !q + !pq); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdbool_h=yes -else - ac_cv_header_stdbool_h=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 -$as_echo "$ac_cv_header_stdbool_h" >&6; } - ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" -if test "x$ac_cv_type__Bool" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE__BOOL 1 -_ACEOF - - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" -case $ac_cv_c_uint16_t in #( - no|yes) ;; #( - *) - - -cat >>confdefs.h <<_ACEOF -#define uint16_t $ac_cv_c_uint16_t -_ACEOF -;; - esac - -ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" -case $ac_cv_c_uint32_t in #( - no|yes) ;; #( - *) - -$as_echo "#define _UINT32_T 1" >>confdefs.h - - -cat >>confdefs.h <<_ACEOF -#define uint32_t $ac_cv_c_uint32_t -_ACEOF -;; - esac - -ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" -if test "x$ac_cv_type_ptrdiff_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_PTRDIFF_T 1 -_ACEOF - - -fi - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 -$as_echo_n "checking size of int... " >&6; } -if ${ac_cv_sizeof_int+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (int) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_int=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 -$as_echo "$ac_cv_sizeof_int" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_void_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_void_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 -$as_echo_n "checking size of long double... " >&6; } -if ${ac_cv_sizeof_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long_double" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long double) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long_double=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 -$as_echo "$ac_cv_sizeof_long_double" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double -_ACEOF - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are building for a Win32 host" >&5 -$as_echo_n "checking whether we are building for a Win32 host... " >&6; } -if ${mingw_cv_win32_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifdef _WIN32 - choke me -#endif -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - mingw_cv_win32_host=no -else - mingw_cv_win32_host=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $mingw_cv_win32_host" >&5 -$as_echo "$mingw_cv_win32_host" >&6; } - if test x$mingw_cv_win32_host = xyes; then - MINGW64_TRUE= - MINGW64_FALSE='#' -else - MINGW64_TRUE='#' - MINGW64_FALSE= -fi - -if test x$mingw_cv_win32_host = xyes ; then - -$as_echo "#define __USE_MINGW_ANSI_STDIO 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether enough of C++11 is supported" >&5 -$as_echo_n "checking whether enough of C++11 is supported... " >&6; } -if ${ac_cv_have_modern_cxx+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -class Myclass { explicit operator bool() const { return true; } }; -int main() { - void *p = nullptr; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_have_modern_cxx=yes -else - ac_cv_have_modern_cxx=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_modern_cxx" >&5 -$as_echo "$ac_cv_have_modern_cxx" >&6; } -if test x$ac_cv_have_modern_cxx = xyes ; then - -$as_echo "#define HAVE_MODERN_CXX 1" >>confdefs.h - -fi - -# Checks for library functions. -# First the mandatory functions... -for ac_func in pow sqrt strchr strstr -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - have_mandatory_functions=no -fi -done - -if test "x${have_mandatory_functions}" = xno; then - as_fn_error $? "One or more mandatory functions missing. Check 'config.log'." "$LINENO" 5 -fi -# ...then check for optional functions. -for ac_func in powl gethostname getrlimit getrusage sysconf -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -# Check for a working implementation of IEEE 754 floating point -# Specifically, check for correct treatment of +Infinity -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for +Infinity (IEEE 754 floating point)" >&5 -$as_echo_n "checking for +Infinity (IEEE 754 floating point)... " >&6; } -if ${ac_cv_have_ieee_754+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_ieee_754=maybe -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include <math.h> -main(void) -{ - if (HUGE_VAL != HUGE_VAL * 3 || HUGE_VAL != HUGE_VAL / 3) return 1; - return 0; -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_ieee_754=yes -else - ac_cv_have_ieee_754=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi - -if test x$ac_cv_have_ieee_754 = xmaybe ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <math.h> -int -main () -{ - double x = INFINITY - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_have_ieee_754=yes -else - ac_cv_have_ieee_754=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -if test x$ac_cv_have_ieee_754 = xyes ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define HAVE_IEEE_754 1" >>confdefs.h - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -ac_config_files="$ac_config_files Makefile" - -ac_config_files="$ac_config_files dddmp/exp/test1.sh" - -ac_config_files="$ac_config_files dddmp/exp/test2.sh" - -ac_config_files="$ac_config_files dddmp/exp/test3.sh" - -ac_config_files="$ac_config_files dddmp/exp/test4.sh" - -ac_config_files="$ac_config_files dddmp/exp/test5.sh" - -ac_config_files="$ac_config_files dddmp/exp/test6.sh" - -ac_config_files="$ac_config_files dddmp/exp/test7.sh" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${DDDMP_TRUE}" && test -z "${DDDMP_FALSE}"; then - as_fn_error $? "conditional \"DDDMP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${OBJ_TRUE}" && test -z "${OBJ_FALSE}"; then - as_fn_error $? "conditional \"OBJ\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then - as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then - as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_PDFLATEX_TRUE}" && test -z "${HAVE_PDFLATEX_FALSE}"; then - as_fn_error $? "conditional \"HAVE_PDFLATEX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then - as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${MINGW64_TRUE}" && test -z "${MINGW64_FALSE}"; then - as_fn_error $? "conditional \"MINGW64\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by cudd $as_me 3.0.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to <Fabio@Colorado.EDU>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -cudd config.status 3.0.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' -predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' -postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' -predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' -postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' -LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' -reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' -reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' -compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' -GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' -archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' -module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' -with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' -no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' -inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' -link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' -always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' -exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' -include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' -prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' -postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' -file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' -hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' -predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' -postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' -predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' -postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' -compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in AS \ -DLLTOOL \ -OBJDUMP \ -SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib \ -compiler_lib_search_dirs \ -predep_objects \ -postdep_objects \ -predeps \ -postdeps \ -compiler_lib_search_path \ -LD_CXX \ -reload_flag_CXX \ -compiler_CXX \ -lt_prog_compiler_no_builtin_flag_CXX \ -lt_prog_compiler_pic_CXX \ -lt_prog_compiler_wl_CXX \ -lt_prog_compiler_static_CXX \ -lt_cv_prog_compiler_c_o_CXX \ -export_dynamic_flag_spec_CXX \ -whole_archive_flag_spec_CXX \ -compiler_needs_object_CXX \ -with_gnu_ld_CXX \ -allow_undefined_flag_CXX \ -no_undefined_flag_CXX \ -hardcode_libdir_flag_spec_CXX \ -hardcode_libdir_separator_CXX \ -exclude_expsyms_CXX \ -include_expsyms_CXX \ -file_list_spec_CXX \ -compiler_lib_search_dirs_CXX \ -predep_objects_CXX \ -postdep_objects_CXX \ -predeps_CXX \ -postdeps_CXX \ -compiler_lib_search_path_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec \ -reload_cmds_CXX \ -old_archive_cmds_CXX \ -old_archive_from_new_cmds_CXX \ -old_archive_from_expsyms_cmds_CXX \ -archive_cmds_CXX \ -archive_expsym_cmds_CXX \ -module_cmds_CXX \ -module_expsym_cmds_CXX \ -export_symbols_cmds_CXX \ -prelink_cmds_CXX \ -postlink_cmds_CXX; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;; - "doc/cudd.tex") CONFIG_FILES="$CONFIG_FILES doc/cudd.tex" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "dddmp/exp/test1.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test1.sh" ;; - "dddmp/exp/test2.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test2.sh" ;; - "dddmp/exp/test3.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test3.sh" ;; - "dddmp/exp/test4.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test4.sh" ;; - "dddmp/exp/test5.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test5.sh" ;; - "dddmp/exp/test6.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test6.sh" ;; - "dddmp/exp/test7.sh") CONFIG_FILES="$CONFIG_FILES dddmp/exp/test7.sh" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool 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 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="CXX " - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Assembler program. -AS=$lt_AS - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Object dumper program. -OBJDUMP=$lt_OBJDUMP - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# The directories searched by this compiler when creating a shared library. -compiler_lib_search_dirs=$lt_compiler_lib_search_dirs - -# Dependencies to place before and after the objects being linked to -# create a shared library. -predep_objects=$lt_predep_objects -postdep_objects=$lt_postdep_objects -predeps=$lt_predeps -postdeps=$lt_postdeps - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - - cat <<_LT_EOF >> "$ofile" - -# ### BEGIN LIBTOOL TAG CONFIG: CXX - -# The linker used to build libraries. -LD=$lt_LD_CXX - -# How to create reloadable object files. -reload_flag=$lt_reload_flag_CXX -reload_cmds=$lt_reload_cmds_CXX - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds_CXX - -# A language specific compiler. -CC=$lt_compiler_CXX - -# Is the compiler the GNU compiler? -with_gcc=$GCC_CXX - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic_CXX - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl_CXX - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static_CXX - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc_CXX - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object_CXX - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds_CXX -archive_expsym_cmds=$lt_archive_expsym_cmds_CXX - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds_CXX -module_expsym_cmds=$lt_module_expsym_cmds_CXX - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld_CXX - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag_CXX - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag_CXX - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct_CXX - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute_CXX - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L_CXX - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic_CXX - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath_CXX - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs_CXX - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols_CXX - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds_CXX - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms_CXX - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms_CXX - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds_CXX - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds_CXX - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec_CXX - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action_CXX - -# The directories searched by this compiler when creating a shared library. -compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX - -# Dependencies to place before and after the objects being linked to -# create a shared library. -predep_objects=$lt_predep_objects_CXX -postdep_objects=$lt_postdep_objects_CXX -predeps=$lt_predeps_CXX -postdeps=$lt_postdeps_CXX - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_compiler_lib_search_path_CXX - -# ### END LIBTOOL TAG CONFIG: CXX -_LT_EOF - - ;; - "dddmp/exp/test1.sh":F) chmod +x dddmp/exp/test1.sh ;; - "dddmp/exp/test2.sh":F) chmod +x dddmp/exp/test2.sh ;; - "dddmp/exp/test3.sh":F) chmod +x dddmp/exp/test3.sh ;; - "dddmp/exp/test4.sh":F) chmod +x dddmp/exp/test4.sh ;; - "dddmp/exp/test5.sh":F) chmod +x dddmp/exp/test5.sh ;; - "dddmp/exp/test6.sh":F) chmod +x dddmp/exp/test6.sh ;; - "dddmp/exp/test7.sh":F) chmod +x dddmp/exp/test7.sh ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -echo \ -"-------------------------------------------------- -Configuration summary for ${PACKAGE_NAME} ${PACKAGE_VERSION} - -Build system : ${build} -Host system : ${host} -Prefix : '${prefix}' -Compilers : '${CC} ${AM_CPPFLAGS} ${CPPFLAGS} ${AM_CFLAGS} ${CFLAGS}' - : '${CXX} ${AM_CPPFLAGS} ${CPPFLAGS} ${AM_CXXFLAGS} ${CXXFLAGS}' -Shared library : ${enable_shared} - dddmp enabled : ${enable_dddmp:-no} - obj enabled : ${enable_obj:-no} ---------------------------------------------------" diff --git a/resources/cmake/find_modules/FindGurobi.cmake b/resources/cmake/find_modules/FindGurobi.cmake index 77595baa8..502630148 100644 --- a/resources/cmake/find_modules/FindGurobi.cmake +++ b/resources/cmake/find_modules/FindGurobi.cmake @@ -25,9 +25,7 @@ find_path(GUROBI_INCLUDE_DIR "/Library/gurobi651/mac64/include" "/Library/gurobi652/mac64/include" "/Library/gurobi702/mac64/include" - "C:\\libs\\gurobi502\\include" - "C:\\gurobi600\\win64\\include" - "${GUROBI_ROOT}/include" + "${GUROBI_ROOT}/include" ) find_library( GUROBI_LIBRARY @@ -42,6 +40,7 @@ find_library( GUROBI_LIBRARY gurobi60 gurobi65 gurobi70 + gurobi75 PATHS "$ENV{GUROBI_HOME}/lib" "/Library/gurobi502/mac64/lib" "/Library/gurobi602/mac64/lib" @@ -51,9 +50,7 @@ find_library( GUROBI_LIBRARY "/Library/gurobi651/mac64/lib" "/Library/gurobi652/mac64/lib" "/Library/gurobi702/mac64/lib" - "C:\\libs\\gurobi502\\lib" - "C:\\gurobi600\\win64\\lib" - "${GUROBI_ROOT}/lib" + "${GUROBI_ROOT}/lib" ) find_library( GUROBI_CXX_LIBRARY @@ -67,9 +64,7 @@ find_library( GUROBI_CXX_LIBRARY "/Library/gurobi651/mac64/lib" "/Library/gurobi652/mac64/lib" "/Library/gurobi702/mac64/lib" - "C:\\libs\\gurobi502\\lib" - "C:\\gurobi600\\win64\\lib" - "${GUROBI_ROOT}/lib" + "${GUROBI_ROOT}/lib" ) set(GUROBI_INCLUDE_DIRS "${GUROBI_INCLUDE_DIR}" ) @@ -86,4 +81,4 @@ find_package_handle_standard_args(GUROBI DEFAULT_MSG mark_as_advanced(GUROBI_INCLUDE_DIR GUROBI_LIBRARY GUROBI_CXX_LIBRARY) -endif(GUROBI_INCLUDE_DIR) \ No newline at end of file +endif(GUROBI_INCLUDE_DIR) diff --git a/resources/cmake/find_modules/FindZ3.cmake b/resources/cmake/find_modules/FindZ3.cmake index cf838874d..d0978b3bc 100644 --- a/resources/cmake/find_modules/FindZ3.cmake +++ b/resources/cmake/find_modules/FindZ3.cmake @@ -10,7 +10,7 @@ # find include dir by searching for a concrete file, which definitely must be in it find_path(Z3_INCLUDE_DIR NAMES z3++.h - PATHS ENV PATH INCLUDE "/usr/include/z3" "/usr/local/include/z3/" "${Z3_ROOT}/include" + PATHS ENV PATH INCLUDE "${Z3_ROOT}/include" "/usr/include/z3" "/usr/local/include/z3/" ) # find library @@ -44,4 +44,4 @@ ENDIF (NOT Z3_FIND_QUIETLY) #message(${Z3_LIBRARY}) # make the set variables only visible in advanced mode -mark_as_advanced(Z3_LIBRARY Z3_INCLUDE_DIR Z3_SOLVER, Z3_EXEC) \ No newline at end of file +mark_as_advanced(Z3_LIBRARY Z3_INCLUDE_DIR Z3_SOLVER, Z3_EXEC) diff --git a/resources/cmake/macros/GetGitRevisionDescription.cmake b/resources/cmake/macros/GetGitRevisionDescription.cmake index 3653b95be..8ab03bc5f 100644 --- a/resources/cmake/macros/GetGitRevisionDescription.cmake +++ b/resources/cmake/macros/GetGitRevisionDescription.cmake @@ -18,6 +18,12 @@ # and adjusting the output so that it tests false if there was no exact # matching tag. # +# git_local_changes(<var>) +# +# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. +# Uses the return code of "git diff-index --quiet HEAD --". +# Does not regard untracked files. +# # Requires CMake 2.6 or newer (uses the 'function' command) # # Original Author: @@ -37,10 +43,10 @@ set(__get_git_revision_description YES) # We must run the following at "include" time, not at function call time, # to find the path to this module rather than the path to a calling list file -get_filename_component(_gitdescmoddir GetGitRevisionDescription.cmake PATH) +get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) function(get_git_head_revision _refspecvar _hashvar) - set(GIT_PARENT_DIR ${PROJECT_SOURCE_DIR}) + set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(GIT_DIR "${GIT_PARENT_DIR}/.git") while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") @@ -71,7 +77,7 @@ function(get_git_head_revision _refspecvar _hashvar) set(HEAD_FILE "${GIT_DATA}/HEAD") configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) - configure_file("${PROJECT_SOURCE_DIR}/resources/cmake/macros/GetGitRevisionDescription.cmake.in" + configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" "${GIT_DATA}/grabRef.cmake" @ONLY) include("${GIT_DATA}/grabRef.cmake") @@ -110,7 +116,7 @@ function(git_describe _var) ${hash} ${ARGN} WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE @@ -124,7 +130,12 @@ function(git_describe _var) set(${_var} "${out}" PARENT_SCOPE) endfunction() -function(git_describe_checkout _var) +function(git_get_exact_tag _var) + git_describe(out --exact-match ${ARGN}) + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + +function(git_local_changes _var) if(NOT GIT_FOUND) find_package(Git QUIET) endif() @@ -138,39 +149,20 @@ function(git_describe_checkout _var) return() endif() - # TODO sanitize - #if((${ARGN}" MATCHES "&&") OR - # (ARGN MATCHES "||") OR - # (ARGN MATCHES "\\;")) - # message("Please report the following error to the project!") - # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") - #endif() - - #message(STATUS "Arguments to execute_process: ${ARGN}") - execute_process(COMMAND "${GIT_EXECUTABLE}" - describe - --tags - --dirty=-dirty - --long - ${ARGN} + diff-index --quiet HEAD -- WORKING_DIRECTORY - "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE out ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT res EQUAL 0) - set(out "${out}-${res}-NOTFOUND") + if(res EQUAL 0) + set(${_var} "CLEAN" PARENT_SCOPE) + else() + set(${_var} "DIRTY" PARENT_SCOPE) endif() - - set(${_var} "${out}" PARENT_SCOPE) endfunction() - -function(git_get_exact_tag _var) - git_describe(out --exact-match ${ARGN}) - set(${_var} "${out}" PARENT_SCOPE) -endfunction() \ No newline at end of file diff --git a/resources/cmake/macros/GetGitRevisionDescription.cmake.in b/resources/cmake/macros/GetGitRevisionDescription.cmake.in index 30a115594..6d8b708ef 100644 --- a/resources/cmake/macros/GetGitRevisionDescription.cmake.in +++ b/resources/cmake/macros/GetGitRevisionDescription.cmake.in @@ -1,4 +1,4 @@ -# +# # Internal file for GetGitRevisionDescription.cmake # # Requires CMake 2.6 or newer (uses the 'function' command) @@ -23,9 +23,12 @@ if(HEAD_CONTENTS MATCHES "ref") string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") if(EXISTS "@GIT_DIR@/${HEAD_REF}") configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") - configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) - set(HEAD_HASH "${HEAD_REF}") + else() + configure_file("@GIT_DIR@/packed-refs" "@GIT_DATA@/packed-refs" COPYONLY) + file(READ "@GIT_DATA@/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_HASH "${CMAKE_MATCH_1}") + endif() endif() else() # detached HEAD @@ -35,4 +38,4 @@ endif() if(NOT HEAD_HASH) file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) string(STRIP "${HEAD_HASH}" HEAD_HASH) -endif() \ No newline at end of file +endif() diff --git a/resources/cmake/macros/export.cmake b/resources/cmake/macros/export.cmake index eb2e8fa84..606bde62f 100644 --- a/resources/cmake/macros/export.cmake +++ b/resources/cmake/macros/export.cmake @@ -8,7 +8,7 @@ message(STATUS "Registered with cmake") export(PACKAGE storm) set(DEP_TARGETS "") -foreach(dt ${STORM_DEP_TARGETS}) +foreach(dt ${STORM_DEP_TARGETS}) export_target(DEP_TARGETS ${dt}) endforeach() @@ -19,10 +19,26 @@ endforeach() include(CMakePackageConfigHelpers) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/stormConfigVersion.cmake + VERSION 0.1.0 + COMPATIBILITY SameMajorVersion ) + +# For the build tree set(CONF_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/include/") configure_package_config_file( resources/cmake/stormConfig.cmake.in ${PROJECT_BINARY_DIR}/stormConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_DIR} - PATH_VARS INCLUDE_INSTALL_DIR #SYSCONFIG_INSTALL_DIR + PATH_VARS INCLUDE_INSTALL_DIR +) + + # For the install tree +file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_DIR}" "${INCLUDE_INSTALL_DIR}") +set(CONF_INCLUDE_DIRS "\${storm_CMAKE_DIR}/${REL_INCLUDE_DIR}/storm") + +configure_package_config_file( + resources/cmake/stormConfig.cmake.in + ${PROJECT_BINARY_DIR}/stormConfig.install.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DIR} + PATH_VARS INCLUDE_INSTALL_DIR ) diff --git a/resources/cmake/stormConfigVersion.cmake.in b/resources/cmake/stormConfigVersion.cmake.in new file mode 100644 index 000000000..d248393ad --- /dev/null +++ b/resources/cmake/stormConfigVersion.cmake.in @@ -0,0 +1,11 @@ +set(PACKAGE_VERSION "@storm_VERSION@") + +# Check whether the requested PACKAGE_FIND_VERSION is compatible +if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_COMPATIBLE FALSE) +else() + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") + set(PACKAGE_VERSION_EXACT TRUE) + endif() +endif() diff --git a/resources/examples/testfiles/ctmc/cluster2.drn b/resources/examples/testfiles/ctmc/cluster2.drn index a58875e50..4d32a5a0c 100644 --- a/resources/examples/testfiles/ctmc/cluster2.drn +++ b/resources/examples/testfiles/ctmc/cluster2.drn @@ -3,17 +3,19 @@ @type: CTMC @parameters +@reward_models +num_repairs @nr_states 276 @model -state 0 [0] init minimum premium +state 0 !0.0087 [0] init minimum premium action 0 [0] 1 : 0.004 2 : 0.004 3 : 0.0002 4 : 0.00025 5 : 0.00025 -state 1 [0] minimum premium +state 1 !10.0067 [0] minimum premium action 0 [0] 6 : 0.002 7 : 0.004 @@ -21,7 +23,7 @@ state 1 [0] minimum premium 9 : 0.00025 10 : 0.00025 11 : 10 -state 2 [0] minimum premium +state 2 !10.0067 [0] minimum premium action 0 [0] 7 : 0.004 12 : 0.002 @@ -29,35 +31,35 @@ state 2 [0] minimum premium 14 : 0.00025 15 : 0.00025 16 : 10 -state 3 [0] minimum premium +state 3 !10.0085 [0] minimum premium action 0 [0] 8 : 0.004 13 : 0.004 17 : 0.00025 18 : 0.00025 19 : 10 -state 4 [0] minimum premium +state 4 !10.0084 [0] minimum premium action 0 [0] 9 : 0.004 14 : 0.004 17 : 0.0002 20 : 0.00025 21 : 10 -state 5 [0] minimum premium +state 5 !10.0084 [0] minimum premium action 0 [0] 10 : 0.004 15 : 0.004 18 : 0.0002 20 : 0.00025 22 : 10 -state 6 [0] minimum premium +state 6 !10.0047 [0] minimum premium action 0 [0] 23 : 0.004 24 : 0.0002 25 : 0.00025 26 : 0.00025 27 : 10 -state 7 [0] minimum premium +state 7 !20.0047 [0] minimum premium action 0 [0] 23 : 0.002 28 : 0.002 @@ -66,7 +68,7 @@ state 7 [0] minimum premium 31 : 0.00025 32 : 10 33 : 10 -state 8 [0] minimum premium +state 8 !20.0065 [0] minimum premium action 0 [0] 24 : 0.002 29 : 0.004 @@ -74,7 +76,7 @@ state 8 [0] minimum premium 35 : 0.00025 36 : 10 37 : 10 -state 9 [0] minimum premium +state 9 !20.0065 [0] minimum premium action 0 [0] 25 : 0.002 30 : 0.004 @@ -82,7 +84,7 @@ state 9 [0] minimum premium 38 : 0.00025 39 : 10 40 : 10 -state 10 [0] minimum +state 10 !20.0065 [0] minimum action 0 [0] 26 : 0.002 31 : 0.004 @@ -90,7 +92,7 @@ state 10 [0] minimum 38 : 0.00025 41 : 10 42 : 10 -state 11 [0] minimum premium +state 11 !2.0067 [0] minimum premium action 0 [0.996661] 0 : 2 27 : 0.002 @@ -98,14 +100,14 @@ state 11 [0] minimum premium 36 : 0.0002 39 : 0.00025 41 : 0.00025 -state 12 [0] minimum premium +state 12 !10.0047 [0] minimum premium action 0 [0] 28 : 0.004 43 : 0.0002 44 : 0.00025 45 : 0.00025 46 : 10 -state 13 [0] minimum premium +state 13 !20.0065 [0] minimum premium action 0 [0] 29 : 0.004 43 : 0.002 @@ -113,7 +115,7 @@ state 13 [0] minimum premium 48 : 0.00025 49 : 10 50 : 10 -state 14 [0] minimum +state 14 !20.0065 [0] minimum action 0 [0] 30 : 0.004 44 : 0.002 @@ -121,7 +123,7 @@ state 14 [0] minimum 51 : 0.00025 52 : 10 53 : 10 -state 15 [0] minimum premium +state 15 !20.0065 [0] minimum premium action 0 [0] 31 : 0.004 45 : 0.002 @@ -129,7 +131,7 @@ state 15 [0] minimum premium 51 : 0.00025 54 : 10 55 : 10 -state 16 [0] minimum premium +state 16 !2.0067 [0] minimum premium action 0 [0.996661] 0 : 2 33 : 0.004 @@ -137,49 +139,49 @@ state 16 [0] minimum premium 49 : 0.0002 52 : 0.00025 54 : 0.00025 -state 17 [0] minimum premium +state 17 !20.0083 [0] minimum premium action 0 [0] 34 : 0.004 47 : 0.004 56 : 0.00025 57 : 10 58 : 10 -state 18 [0] minimum premium +state 18 !20.0083 [0] minimum premium action 0 [0] 35 : 0.004 48 : 0.004 56 : 0.00025 59 : 10 60 : 10 -state 19 [0] minimum premium +state 19 !0.1335 [0] minimum premium action 0 [0.93633] 0 : 0.125 37 : 0.004 50 : 0.004 58 : 0.00025 60 : 0.00025 -state 20 [0] +state 20 !20.0082 [0] action 0 [0] 38 : 0.004 51 : 0.004 56 : 0.0002 61 : 10 62 : 10 -state 21 [0] minimum premium +state 21 !0.25845 [0] minimum premium action 0 [0.967305] 0 : 0.25 40 : 0.004 53 : 0.004 57 : 0.0002 61 : 0.00025 -state 22 [0] minimum premium +state 22 !0.25845 [0] minimum premium action 0 [0.967305] 0 : 0.25 42 : 0.004 55 : 0.004 59 : 0.0002 62 : 0.00025 -state 23 [0] minimum +state 23 !20.0027 [0] minimum action 0 [0] 63 : 0.002 64 : 0.0002 @@ -187,35 +189,35 @@ state 23 [0] minimum 66 : 0.00025 67 : 10 68 : 10 -state 24 [0] minimum premium +state 24 !20.0045 [0] minimum premium action 0 [0] 64 : 0.004 69 : 0.00025 70 : 0.00025 71 : 10 72 : 10 -state 25 [0] minimum premium +state 25 !20.0044 [0] minimum premium action 0 [0] 65 : 0.004 69 : 0.0002 73 : 0.00025 74 : 10 75 : 10 -state 26 [0] +state 26 !20.0044 [0] action 0 [0] 66 : 0.004 70 : 0.0002 73 : 0.00025 76 : 10 77 : 10 -state 27 [0] minimum premium +state 27 !2.0047 [0] minimum premium action 0 [0.997656] 1 : 2 67 : 0.004 71 : 0.0002 74 : 0.00025 76 : 0.00025 -state 28 [0] minimum +state 28 !20.0027 [0] minimum action 0 [0] 63 : 0.002 78 : 0.0002 @@ -223,7 +225,7 @@ state 28 [0] minimum 80 : 0.00025 81 : 10 82 : 10 -state 29 [0] minimum +state 29 !30.0045 [0] minimum action 0 [0] 64 : 0.002 78 : 0.002 @@ -232,7 +234,7 @@ state 29 [0] minimum 85 : 10 86 : 10 87 : 10 -state 30 [0] minimum +state 30 !30.0044 [0] minimum action 0 [0] 65 : 0.002 79 : 0.002 @@ -241,7 +243,7 @@ state 30 [0] minimum 89 : 10 90 : 10 91 : 10 -state 31 [0] minimum +state 31 !30.0044 [0] minimum action 0 [0] 66 : 0.002 80 : 0.002 @@ -250,7 +252,7 @@ state 31 [0] minimum 92 : 10 93 : 10 94 : 10 -state 32 [0] minimum premium +state 32 !2.0047 [0] minimum premium action 0 [0.997656] 2 : 2 67 : 0.002 @@ -258,7 +260,7 @@ state 32 [0] minimum premium 85 : 0.0002 89 : 0.00025 92 : 0.00025 -state 33 [0] minimum premium +state 33 !2.0047 [0] minimum premium action 0 [0.997656] 1 : 2 68 : 0.002 @@ -266,7 +268,7 @@ state 33 [0] minimum premium 86 : 0.0002 90 : 0.00025 93 : 0.00025 -state 34 [0] minimum premium +state 34 !30.0063 [0] minimum premium action 0 [0] 69 : 0.002 83 : 0.004 @@ -274,7 +276,7 @@ state 34 [0] minimum premium 96 : 10 97 : 10 98 : 10 -state 35 [0] minimum +state 35 !30.0063 [0] minimum action 0 [0] 70 : 0.002 84 : 0.004 @@ -282,21 +284,21 @@ state 35 [0] minimum 99 : 10 100 : 10 101 : 10 -state 36 [0] minimum premium +state 36 !2.0065 [0] minimum premium action 0 [0.996761] 3 : 2 71 : 0.002 85 : 0.004 96 : 0.00025 99 : 0.00025 -state 37 [0] minimum premium +state 37 !0.1315 [0] minimum premium action 0 [0.95057] 1 : 0.125 72 : 0.002 87 : 0.004 98 : 0.00025 101 : 0.00025 -state 38 [0] +state 38 !30.0062 [0] action 0 [0] 73 : 0.002 88 : 0.004 @@ -304,63 +306,63 @@ state 38 [0] 102 : 10 103 : 10 104 : 10 -state 39 [0] minimum premium +state 39 !2.00645 [0] minimum premium action 0 [0.996785] 4 : 2 74 : 0.002 89 : 0.004 96 : 0.0002 102 : 0.00025 -state 40 [0] minimum premium +state 40 !0.25645 [0] minimum premium action 0 [0.974849] 1 : 0.25 75 : 0.002 91 : 0.004 97 : 0.0002 103 : 0.00025 -state 41 [0] minimum +state 41 !2.00645 [0] minimum action 0 [0.996785] 5 : 2 76 : 0.002 92 : 0.004 99 : 0.0002 102 : 0.00025 -state 42 [0] minimum +state 42 !0.25645 [0] minimum action 0 [0.974849] 1 : 0.25 77 : 0.002 94 : 0.004 100 : 0.0002 104 : 0.00025 -state 43 [0] minimum premium +state 43 !20.0045 [0] minimum premium action 0 [0] 78 : 0.004 105 : 0.00025 106 : 0.00025 107 : 10 108 : 10 -state 44 [0] +state 44 !20.0044 [0] action 0 [0] 79 : 0.004 105 : 0.0002 109 : 0.00025 110 : 10 111 : 10 -state 45 [0] minimum premium +state 45 !20.0044 [0] minimum premium action 0 [0] 80 : 0.004 106 : 0.0002 109 : 0.00025 112 : 10 113 : 10 -state 46 [0] minimum premium +state 46 !2.0047 [0] minimum premium action 0 [0.997656] 2 : 2 82 : 0.004 107 : 0.0002 110 : 0.00025 112 : 0.00025 -state 47 [0] minimum +state 47 !30.0063 [0] minimum action 0 [0] 83 : 0.004 105 : 0.002 @@ -368,7 +370,7 @@ state 47 [0] minimum 115 : 10 116 : 10 117 : 10 -state 48 [0] minimum premium +state 48 !30.0063 [0] minimum premium action 0 [0] 84 : 0.004 106 : 0.002 @@ -376,21 +378,21 @@ state 48 [0] minimum premium 118 : 10 119 : 10 120 : 10 -state 49 [0] minimum premium +state 49 !2.0065 [0] minimum premium action 0 [0.996761] 3 : 2 86 : 0.004 107 : 0.002 115 : 0.00025 118 : 0.00025 -state 50 [0] minimum premium +state 50 !0.1315 [0] minimum premium action 0 [0.95057] 2 : 0.125 87 : 0.004 108 : 0.002 117 : 0.00025 120 : 0.00025 -state 51 [0] +state 51 !30.0062 [0] action 0 [0] 88 : 0.004 109 : 0.002 @@ -398,85 +400,85 @@ state 51 [0] 121 : 10 122 : 10 123 : 10 -state 52 [0] minimum +state 52 !2.00645 [0] minimum action 0 [0.996785] 4 : 2 90 : 0.004 110 : 0.002 115 : 0.0002 121 : 0.00025 -state 53 [0] minimum +state 53 !0.25645 [0] minimum action 0 [0.974849] 2 : 0.25 91 : 0.004 111 : 0.002 116 : 0.0002 122 : 0.00025 -state 54 [0] minimum premium +state 54 !2.00645 [0] minimum premium action 0 [0.996785] 5 : 2 93 : 0.004 112 : 0.002 118 : 0.0002 121 : 0.00025 -state 55 [0] minimum premium +state 55 !0.25645 [0] minimum premium action 0 [0.974849] 2 : 0.25 94 : 0.004 113 : 0.002 119 : 0.0002 123 : 0.00025 -state 56 [0] +state 56 !30.008 [0] action 0 [0] 95 : 0.004 114 : 0.004 124 : 10 125 : 10 126 : 10 -state 57 [0] minimum premium +state 57 !0.25825 [0] minimum premium action 0 [0.968054] 3 : 0.25 97 : 0.004 116 : 0.004 124 : 0.00025 -state 58 [0] minimum premium +state 58 !0.13325 [0] minimum premium action 0 [0.938086] 4 : 0.125 98 : 0.004 117 : 0.004 126 : 0.00025 -state 59 [0] minimum premium +state 59 !0.25825 [0] minimum premium action 0 [0.968054] 3 : 0.25 100 : 0.004 119 : 0.004 125 : 0.00025 -state 60 [0] minimum premium +state 60 !0.13325 [0] minimum premium action 0 [0.938086] 5 : 0.125 101 : 0.004 120 : 0.004 126 : 0.00025 -state 61 [0] +state 61 !0.2582 [0] action 0 [0.968242] 5 : 0.25 103 : 0.004 122 : 0.004 124 : 0.0002 -state 62 [0] +state 62 !0.2582 [0] action 0 [0.968242] 4 : 0.25 104 : 0.004 123 : 0.004 125 : 0.0002 -state 63 [0] +state 63 !20.0007 [0] action 0 [0] 127 : 0.0002 128 : 0.00025 129 : 0.00025 130 : 10 131 : 10 -state 64 [0] minimum +state 64 !30.0025 [0] minimum action 0 [0] 127 : 0.002 132 : 0.00025 @@ -484,7 +486,7 @@ state 64 [0] minimum 134 : 10 135 : 10 136 : 10 -state 65 [0] minimum +state 65 !30.0024 [0] minimum action 0 [0] 128 : 0.002 132 : 0.0002 @@ -492,7 +494,7 @@ state 65 [0] minimum 138 : 10 139 : 10 140 : 10 -state 66 [0] +state 66 !30.0024 [0] action 0 [0] 129 : 0.002 133 : 0.0002 @@ -500,78 +502,78 @@ state 66 [0] 141 : 10 142 : 10 143 : 10 -state 67 [0] minimum +state 67 !2.0027 [0] minimum action 0 [0.998652] 7 : 2 130 : 0.002 134 : 0.0002 138 : 0.00025 141 : 0.00025 -state 68 [0] minimum +state 68 !2.0027 [0] minimum action 0 [0.998652] 6 : 2 131 : 0.002 135 : 0.0002 139 : 0.00025 142 : 0.00025 -state 69 [0] minimum premium +state 69 !30.0042 [0] minimum premium action 0 [0] 132 : 0.004 144 : 0.00025 145 : 10 146 : 10 147 : 10 -state 70 [0] +state 70 !30.0042 [0] action 0 [0] 133 : 0.004 144 : 0.00025 148 : 10 149 : 10 150 : 10 -state 71 [0] minimum premium +state 71 !2.0045 [0] minimum premium action 0 [0.997755] 8 : 2 134 : 0.004 145 : 0.00025 148 : 0.00025 -state 72 [0] minimum premium +state 72 !0.1295 [0] minimum premium action 0 [0.965251] 6 : 0.125 136 : 0.004 147 : 0.00025 150 : 0.00025 -state 73 [0] +state 73 !30.0042 [0] action 0 [0] 137 : 0.004 144 : 0.0002 151 : 10 152 : 10 153 : 10 -state 74 [0] minimum premium +state 74 !2.00445 [0] minimum premium action 0 [0.99778] 9 : 2 138 : 0.004 145 : 0.0002 151 : 0.00025 -state 75 [0] minimum premium +state 75 !0.25445 [0] minimum premium action 0 [0.982511] 6 : 0.25 140 : 0.004 146 : 0.0002 152 : 0.00025 -state 76 [0] +state 76 !2.00445 [0] action 0 [0.99778] 10 : 2 141 : 0.004 148 : 0.0002 151 : 0.00025 -state 77 [0] +state 77 !0.25445 [0] action 0 [0.982511] 6 : 0.25 143 : 0.004 149 : 0.0002 153 : 0.00025 -state 78 [0] minimum +state 78 !30.0025 [0] minimum action 0 [0] 127 : 0.002 154 : 0.00025 @@ -579,7 +581,7 @@ state 78 [0] minimum 156 : 10 157 : 10 158 : 10 -state 79 [0] +state 79 !30.0024 [0] action 0 [0] 128 : 0.002 154 : 0.0002 @@ -587,7 +589,7 @@ state 79 [0] 160 : 10 161 : 10 162 : 10 -state 80 [0] minimum +state 80 !30.0024 [0] minimum action 0 [0] 129 : 0.002 155 : 0.0002 @@ -595,21 +597,21 @@ state 80 [0] minimum 163 : 10 164 : 10 165 : 10 -state 81 [0] minimum +state 81 !2.0027 [0] minimum action 0 [0.998652] 12 : 2 130 : 0.002 156 : 0.0002 160 : 0.00025 163 : 0.00025 -state 82 [0] minimum +state 82 !2.0027 [0] minimum action 0 [0.998652] 7 : 2 131 : 0.002 157 : 0.0002 161 : 0.00025 164 : 0.00025 -state 83 [0] minimum +state 83 !40.0042 [0] minimum action 0 [0] 132 : 0.002 154 : 0.002 @@ -618,7 +620,7 @@ state 83 [0] minimum 168 : 10 169 : 10 170 : 10 -state 84 [0] minimum +state 84 !40.0042 [0] minimum action 0 [0] 133 : 0.002 155 : 0.002 @@ -627,28 +629,28 @@ state 84 [0] minimum 172 : 10 173 : 10 174 : 10 -state 85 [0] minimum +state 85 !2.0045 [0] minimum action 0 [0.997755] 13 : 2 134 : 0.002 156 : 0.002 167 : 0.00025 171 : 0.00025 -state 86 [0] minimum +state 86 !2.0045 [0] minimum action 0 [0.997755] 8 : 2 135 : 0.002 157 : 0.002 168 : 0.00025 172 : 0.00025 -state 87 [0] minimum +state 87 !0.1295 [0] minimum action 0 [0.965251] 7 : 0.125 136 : 0.002 158 : 0.002 170 : 0.00025 174 : 0.00025 -state 88 [0] +state 88 !40.0042 [0] action 0 [0] 137 : 0.002 159 : 0.002 @@ -657,49 +659,49 @@ state 88 [0] 176 : 10 177 : 10 178 : 10 -state 89 [0] minimum +state 89 !2.00445 [0] minimum action 0 [0.99778] 14 : 2 138 : 0.002 160 : 0.002 167 : 0.0002 175 : 0.00025 -state 90 [0] minimum +state 90 !2.00445 [0] minimum action 0 [0.99778] 9 : 2 139 : 0.002 161 : 0.002 168 : 0.0002 176 : 0.00025 -state 91 [0] minimum +state 91 !0.25445 [0] minimum action 0 [0.982511] 7 : 0.25 140 : 0.002 162 : 0.002 169 : 0.0002 177 : 0.00025 -state 92 [0] minimum +state 92 !2.00445 [0] minimum action 0 [0.99778] 15 : 2 141 : 0.002 163 : 0.002 171 : 0.0002 175 : 0.00025 -state 93 [0] minimum +state 93 !2.00445 [0] minimum action 0 [0.99778] 10 : 2 142 : 0.002 164 : 0.002 172 : 0.0002 176 : 0.00025 -state 94 [0] minimum +state 94 !0.25445 [0] minimum action 0 [0.982511] 7 : 0.25 143 : 0.002 165 : 0.002 173 : 0.0002 178 : 0.00025 -state 95 [0] +state 95 !40.006 [0] action 0 [0] 144 : 0.002 166 : 0.004 @@ -707,118 +709,118 @@ state 95 [0] 180 : 10 181 : 10 182 : 10 -state 96 [0] minimum premium +state 96 !2.00625 [0] minimum premium action 0 [0.996885] 17 : 2 145 : 0.002 167 : 0.004 179 : 0.00025 -state 97 [0] minimum premium +state 97 !0.25625 [0] minimum premium action 0 [0.97561] 8 : 0.25 146 : 0.002 169 : 0.004 180 : 0.00025 -state 98 [0] minimum premium +state 98 !0.13125 [0] minimum premium action 0 [0.952381] 9 : 0.125 147 : 0.002 170 : 0.004 182 : 0.00025 -state 99 [0] minimum +state 99 !2.00625 [0] minimum action 0 [0.996885] 18 : 2 148 : 0.002 171 : 0.004 179 : 0.00025 -state 100 [0] minimum +state 100 !0.25625 [0] minimum action 0 [0.97561] 8 : 0.25 149 : 0.002 173 : 0.004 181 : 0.00025 -state 101 [0] minimum +state 101 !0.13125 [0] minimum action 0 [0.952381] 10 : 0.125 150 : 0.002 174 : 0.004 182 : 0.00025 -state 102 [0] +state 102 !2.0062 [0] action 0 [0.99691] 20 : 2 151 : 0.002 175 : 0.004 179 : 0.0002 -state 103 [0] +state 103 !0.2562 [0] action 0 [0.9758] 10 : 0.25 152 : 0.002 177 : 0.004 180 : 0.0002 -state 104 [0] +state 104 !0.2562 [0] action 0 [0.9758] 9 : 0.25 153 : 0.002 178 : 0.004 181 : 0.0002 -state 105 [0] +state 105 !30.0042 [0] action 0 [0] 154 : 0.004 183 : 0.00025 184 : 10 185 : 10 186 : 10 -state 106 [0] minimum premium +state 106 !30.0042 [0] minimum premium action 0 [0] 155 : 0.004 183 : 0.00025 187 : 10 188 : 10 189 : 10 -state 107 [0] minimum premium +state 107 !2.0045 [0] minimum premium action 0 [0.997755] 13 : 2 157 : 0.004 184 : 0.00025 187 : 0.00025 -state 108 [0] minimum premium +state 108 !0.1295 [0] minimum premium action 0 [0.965251] 12 : 0.125 158 : 0.004 186 : 0.00025 189 : 0.00025 -state 109 [0] +state 109 !30.0042 [0] action 0 [0] 159 : 0.004 183 : 0.0002 190 : 10 191 : 10 192 : 10 -state 110 [0] +state 110 !2.00445 [0] action 0 [0.99778] 14 : 2 161 : 0.004 184 : 0.0002 190 : 0.00025 -state 111 [0] +state 111 !0.25445 [0] action 0 [0.982511] 12 : 0.25 162 : 0.004 185 : 0.0002 191 : 0.00025 -state 112 [0] minimum premium +state 112 !2.00445 [0] minimum premium action 0 [0.99778] 15 : 2 164 : 0.004 187 : 0.0002 190 : 0.00025 -state 113 [0] minimum premium +state 113 !0.25445 [0] minimum premium action 0 [0.982511] 12 : 0.25 165 : 0.004 188 : 0.0002 192 : 0.00025 -state 114 [0] +state 114 !40.006 [0] action 0 [0] 166 : 0.004 183 : 0.002 @@ -826,109 +828,109 @@ state 114 [0] 194 : 10 195 : 10 196 : 10 -state 115 [0] minimum +state 115 !2.00625 [0] minimum action 0 [0.996885] 17 : 2 168 : 0.004 184 : 0.002 193 : 0.00025 -state 116 [0] minimum +state 116 !0.25625 [0] minimum action 0 [0.97561] 13 : 0.25 169 : 0.004 185 : 0.002 194 : 0.00025 -state 117 [0] minimum +state 117 !0.13125 [0] minimum action 0 [0.952381] 14 : 0.125 170 : 0.004 186 : 0.002 196 : 0.00025 -state 118 [0] minimum premium +state 118 !2.00625 [0] minimum premium action 0 [0.996885] 18 : 2 172 : 0.004 187 : 0.002 193 : 0.00025 -state 119 [0] minimum premium +state 119 !0.25625 [0] minimum premium action 0 [0.97561] 13 : 0.25 173 : 0.004 188 : 0.002 195 : 0.00025 -state 120 [0] minimum premium +state 120 !0.13125 [0] minimum premium action 0 [0.952381] 15 : 0.125 174 : 0.004 189 : 0.002 196 : 0.00025 -state 121 [0] +state 121 !2.0062 [0] action 0 [0.99691] 20 : 2 176 : 0.004 190 : 0.002 193 : 0.0002 -state 122 [0] +state 122 !0.2562 [0] action 0 [0.9758] 15 : 0.25 177 : 0.004 191 : 0.002 194 : 0.0002 -state 123 [0] +state 123 !0.2562 [0] action 0 [0.9758] 14 : 0.25 178 : 0.004 192 : 0.002 195 : 0.0002 -state 124 [0] +state 124 !0.258 [0] action 0 [0.968992] 18 : 0.25 180 : 0.004 194 : 0.004 -state 125 [0] +state 125 !0.258 [0] action 0 [0.968992] 17 : 0.25 181 : 0.004 195 : 0.004 -state 126 [0] +state 126 !0.133 [0] action 0 [0.93985] 20 : 0.125 182 : 0.004 196 : 0.004 -state 127 [0] +state 127 !30.0005 [0] action 0 [0] 197 : 0.00025 198 : 0.00025 199 : 10 200 : 10 201 : 10 -state 128 [0] +state 128 !30.0005 [0] action 0 [0] 197 : 0.0002 202 : 0.00025 203 : 10 204 : 10 205 : 10 -state 129 [0] +state 129 !30.0005 [0] action 0 [0] 198 : 0.0002 202 : 0.00025 206 : 10 207 : 10 208 : 10 -state 130 [0] +state 130 !2.0007 [0] action 0 [0.99965] 28 : 2 199 : 0.0002 203 : 0.00025 206 : 0.00025 -state 131 [0] +state 131 !2.0007 [0] action 0 [0.99965] 23 : 2 200 : 0.0002 204 : 0.00025 207 : 0.00025 -state 132 [0] minimum +state 132 !40.0023 [0] minimum action 0 [0] 197 : 0.002 209 : 0.00025 @@ -936,7 +938,7 @@ state 132 [0] minimum 211 : 10 212 : 10 213 : 10 -state 133 [0] +state 133 !40.0023 [0] action 0 [0] 198 : 0.002 209 : 0.00025 @@ -944,25 +946,25 @@ state 133 [0] 215 : 10 216 : 10 217 : 10 -state 134 [0] minimum +state 134 !2.0025 [0] minimum action 0 [0.998752] 29 : 2 199 : 0.002 210 : 0.00025 214 : 0.00025 -state 135 [0] minimum +state 135 !2.0025 [0] minimum action 0 [0.998752] 24 : 2 200 : 0.002 211 : 0.00025 215 : 0.00025 -state 136 [0] minimum +state 136 !0.1275 [0] minimum action 0 [0.980392] 23 : 0.125 201 : 0.002 213 : 0.00025 217 : 0.00025 -state 137 [0] +state 137 !40.0022 [0] action 0 [0] 202 : 0.002 209 : 0.0002 @@ -970,95 +972,95 @@ state 137 [0] 219 : 10 220 : 10 221 : 10 -state 138 [0] minimum +state 138 !2.00245 [0] minimum action 0 [0.998776] 30 : 2 203 : 0.002 210 : 0.0002 218 : 0.00025 -state 139 [0] minimum +state 139 !2.00245 [0] minimum action 0 [0.998776] 25 : 2 204 : 0.002 211 : 0.0002 219 : 0.00025 -state 140 [0] minimum +state 140 !0.25245 [0] minimum action 0 [0.990295] 23 : 0.25 205 : 0.002 212 : 0.0002 220 : 0.00025 -state 141 [0] +state 141 !2.00245 [0] action 0 [0.998776] 31 : 2 206 : 0.002 214 : 0.0002 218 : 0.00025 -state 142 [0] +state 142 !2.00245 [0] action 0 [0.998776] 26 : 2 207 : 0.002 215 : 0.0002 219 : 0.00025 -state 143 [0] +state 143 !0.25245 [0] action 0 [0.990295] 23 : 0.25 208 : 0.002 216 : 0.0002 221 : 0.00025 -state 144 [0] +state 144 !40.004 [0] action 0 [0] 209 : 0.004 222 : 10 223 : 10 224 : 10 225 : 10 -state 145 [0] minimum premium +state 145 !2.00425 [0] minimum premium action 0 [0.99788] 34 : 2 210 : 0.004 222 : 0.00025 -state 146 [0] minimum premium +state 146 !0.25425 [0] minimum premium action 0 [0.983284] 24 : 0.25 212 : 0.004 223 : 0.00025 -state 147 [0] minimum premium +state 147 !0.12925 [0] minimum premium action 0 [0.967118] 25 : 0.125 213 : 0.004 225 : 0.00025 -state 148 [0] +state 148 !2.00425 [0] action 0 [0.99788] 35 : 2 214 : 0.004 222 : 0.00025 -state 149 [0] +state 149 !0.25425 [0] action 0 [0.983284] 24 : 0.25 216 : 0.004 224 : 0.00025 -state 150 [0] +state 150 !0.12925 [0] action 0 [0.967118] 26 : 0.125 217 : 0.004 225 : 0.00025 -state 151 [0] +state 151 !2.0042 [0] action 0 [0.997904] 38 : 2 218 : 0.004 222 : 0.0002 -state 152 [0] +state 152 !0.2542 [0] action 0 [0.983478] 26 : 0.25 220 : 0.004 223 : 0.0002 -state 153 [0] +state 153 !0.2542 [0] action 0 [0.983478] 25 : 0.25 221 : 0.004 224 : 0.0002 -state 154 [0] +state 154 !40.0023 [0] action 0 [0] 197 : 0.002 226 : 0.00025 @@ -1066,7 +1068,7 @@ state 154 [0] 228 : 10 229 : 10 230 : 10 -state 155 [0] minimum +state 155 !40.0023 [0] minimum action 0 [0] 198 : 0.002 226 : 0.00025 @@ -1074,25 +1076,25 @@ state 155 [0] minimum 232 : 10 233 : 10 234 : 10 -state 156 [0] minimum +state 156 !2.0025 [0] minimum action 0 [0.998752] 43 : 2 199 : 0.002 227 : 0.00025 231 : 0.00025 -state 157 [0] minimum +state 157 !2.0025 [0] minimum action 0 [0.998752] 29 : 2 200 : 0.002 228 : 0.00025 232 : 0.00025 -state 158 [0] minimum +state 158 !0.1275 [0] minimum action 0 [0.980392] 28 : 0.125 201 : 0.002 230 : 0.00025 234 : 0.00025 -state 159 [0] +state 159 !40.0022 [0] action 0 [0] 202 : 0.002 226 : 0.0002 @@ -1100,43 +1102,43 @@ state 159 [0] 236 : 10 237 : 10 238 : 10 -state 160 [0] +state 160 !2.00245 [0] action 0 [0.998776] 44 : 2 203 : 0.002 227 : 0.0002 235 : 0.00025 -state 161 [0] +state 161 !2.00245 [0] action 0 [0.998776] 30 : 2 204 : 0.002 228 : 0.0002 236 : 0.00025 -state 162 [0] +state 162 !0.25245 [0] action 0 [0.990295] 28 : 0.25 205 : 0.002 229 : 0.0002 237 : 0.00025 -state 163 [0] minimum +state 163 !2.00245 [0] minimum action 0 [0.998776] 45 : 2 206 : 0.002 231 : 0.0002 235 : 0.00025 -state 164 [0] minimum +state 164 !2.00245 [0] minimum action 0 [0.998776] 31 : 2 207 : 0.002 232 : 0.0002 236 : 0.00025 -state 165 [0] minimum +state 165 !0.25245 [0] minimum action 0 [0.990295] 28 : 0.25 208 : 0.002 233 : 0.0002 238 : 0.00025 -state 166 [0] +state 166 !50.004 [0] action 0 [0] 209 : 0.002 226 : 0.002 @@ -1145,237 +1147,237 @@ state 166 [0] 241 : 10 242 : 10 243 : 10 -state 167 [0] minimum +state 167 !2.00425 [0] minimum action 0 [0.99788] 47 : 2 210 : 0.002 227 : 0.002 239 : 0.00025 -state 168 [0] minimum +state 168 !2.00425 [0] minimum action 0 [0.99788] 34 : 2 211 : 0.002 228 : 0.002 240 : 0.00025 -state 169 [0] minimum +state 169 !0.25425 [0] minimum action 0 [0.983284] 29 : 0.25 212 : 0.002 229 : 0.002 241 : 0.00025 -state 170 [0] minimum +state 170 !0.12925 [0] minimum action 0 [0.967118] 30 : 0.125 213 : 0.002 230 : 0.002 243 : 0.00025 -state 171 [0] minimum +state 171 !2.00425 [0] minimum action 0 [0.99788] 48 : 2 214 : 0.002 231 : 0.002 239 : 0.00025 -state 172 [0] minimum +state 172 !2.00425 [0] minimum action 0 [0.99788] 35 : 2 215 : 0.002 232 : 0.002 240 : 0.00025 -state 173 [0] minimum +state 173 !0.25425 [0] minimum action 0 [0.983284] 29 : 0.25 216 : 0.002 233 : 0.002 242 : 0.00025 -state 174 [0] minimum +state 174 !0.12925 [0] minimum action 0 [0.967118] 31 : 0.125 217 : 0.002 234 : 0.002 243 : 0.00025 -state 175 [0] +state 175 !2.0042 [0] action 0 [0.997904] 51 : 2 218 : 0.002 235 : 0.002 239 : 0.0002 -state 176 [0] +state 176 !2.0042 [0] action 0 [0.997904] 38 : 2 219 : 0.002 236 : 0.002 240 : 0.0002 -state 177 [0] +state 177 !0.2542 [0] action 0 [0.983478] 31 : 0.25 220 : 0.002 237 : 0.002 241 : 0.0002 -state 178 [0] +state 178 !0.2542 [0] action 0 [0.983478] 30 : 0.25 221 : 0.002 238 : 0.002 242 : 0.0002 -state 179 [0] +state 179 !2.006 [0] action 0 [0.997009] 56 : 2 222 : 0.002 239 : 0.004 -state 180 [0] +state 180 !0.256 [0] action 0 [0.976562] 35 : 0.25 223 : 0.002 241 : 0.004 -state 181 [0] +state 181 !0.256 [0] action 0 [0.976562] 34 : 0.25 224 : 0.002 242 : 0.004 -state 182 [0] +state 182 !0.131 [0] action 0 [0.954198] 38 : 0.125 225 : 0.002 243 : 0.004 -state 183 [0] +state 183 !40.004 [0] action 0 [0] 226 : 0.004 244 : 10 245 : 10 246 : 10 247 : 10 -state 184 [0] +state 184 !2.00425 [0] action 0 [0.99788] 47 : 2 228 : 0.004 244 : 0.00025 -state 185 [0] +state 185 !0.25425 [0] action 0 [0.983284] 43 : 0.25 229 : 0.004 245 : 0.00025 -state 186 [0] +state 186 !0.12925 [0] action 0 [0.967118] 44 : 0.125 230 : 0.004 247 : 0.00025 -state 187 [0] minimum premium +state 187 !2.00425 [0] minimum premium action 0 [0.99788] 48 : 2 232 : 0.004 244 : 0.00025 -state 188 [0] minimum premium +state 188 !0.25425 [0] minimum premium action 0 [0.983284] 43 : 0.25 233 : 0.004 246 : 0.00025 -state 189 [0] minimum premium +state 189 !0.12925 [0] minimum premium action 0 [0.967118] 45 : 0.125 234 : 0.004 247 : 0.00025 -state 190 [0] +state 190 !2.0042 [0] action 0 [0.997904] 51 : 2 236 : 0.004 244 : 0.0002 -state 191 [0] +state 191 !0.2542 [0] action 0 [0.983478] 45 : 0.25 237 : 0.004 245 : 0.0002 -state 192 [0] +state 192 !0.2542 [0] action 0 [0.983478] 44 : 0.25 238 : 0.004 246 : 0.0002 -state 193 [0] +state 193 !2.006 [0] action 0 [0.997009] 56 : 2 240 : 0.004 244 : 0.002 -state 194 [0] +state 194 !0.256 [0] action 0 [0.976562] 48 : 0.25 241 : 0.004 245 : 0.002 -state 195 [0] +state 195 !0.256 [0] action 0 [0.976562] 47 : 0.25 242 : 0.004 246 : 0.002 -state 196 [0] +state 196 !0.131 [0] action 0 [0.954198] 51 : 0.125 243 : 0.004 247 : 0.002 -state 197 [0] +state 197 !40.0003 [0] action 0 [0] 248 : 0.00025 249 : 10 250 : 10 251 : 10 252 : 10 -state 198 [0] +state 198 !40.0003 [0] action 0 [0] 248 : 0.00025 253 : 10 254 : 10 255 : 10 256 : 10 -state 199 [0] +state 199 !2.0005 [0] action 0 [0.99975] 78 : 2 249 : 0.00025 253 : 0.00025 -state 200 [0] +state 200 !2.0005 [0] action 0 [0.99975] 64 : 2 250 : 0.00025 254 : 0.00025 -state 201 [0] +state 201 !0.1255 [0] action 0 [0.996016] 63 : 0.125 252 : 0.00025 256 : 0.00025 -state 202 [0] +state 202 !40.0002 [0] action 0 [0] 248 : 0.0002 257 : 10 258 : 10 259 : 10 260 : 10 -state 203 [0] +state 203 !2.00045 [0] action 0 [0.999775] 79 : 2 249 : 0.0002 257 : 0.00025 -state 204 [0] +state 204 !2.00045 [0] action 0 [0.999775] 65 : 2 250 : 0.0002 258 : 0.00025 -state 205 [0] +state 205 !0.25045 [0] action 0 [0.998203] 63 : 0.25 251 : 0.0002 259 : 0.00025 -state 206 [0] +state 206 !2.00045 [0] action 0 [0.999775] 80 : 2 253 : 0.0002 257 : 0.00025 -state 207 [0] +state 207 !2.00045 [0] action 0 [0.999775] 66 : 2 254 : 0.0002 258 : 0.00025 -state 208 [0] +state 208 !0.25045 [0] action 0 [0.998203] 63 : 0.25 255 : 0.0002 260 : 0.00025 -state 209 [0] +state 209 !50.002 [0] action 0 [0] 248 : 0.002 261 : 10 @@ -1383,83 +1385,83 @@ state 209 [0] 263 : 10 264 : 10 265 : 10 -state 210 [0] minimum +state 210 !2.00225 [0] minimum action 0 [0.998876] 83 : 2 249 : 0.002 261 : 0.00025 -state 211 [0] minimum +state 211 !2.00225 [0] minimum action 0 [0.998876] 69 : 2 250 : 0.002 262 : 0.00025 -state 212 [0] minimum +state 212 !0.25225 [0] minimum action 0 [0.99108] 64 : 0.25 251 : 0.002 263 : 0.00025 -state 213 [0] minimum +state 213 !0.12725 [0] minimum action 0 [0.982318] 65 : 0.125 252 : 0.002 265 : 0.00025 -state 214 [0] +state 214 !2.00225 [0] action 0 [0.998876] 84 : 2 253 : 0.002 261 : 0.00025 -state 215 [0] +state 215 !2.00225 [0] action 0 [0.998876] 70 : 2 254 : 0.002 262 : 0.00025 -state 216 [0] +state 216 !0.25225 [0] action 0 [0.99108] 64 : 0.25 255 : 0.002 264 : 0.00025 -state 217 [0] +state 217 !0.12725 [0] action 0 [0.982318] 66 : 0.125 256 : 0.002 265 : 0.00025 -state 218 [0] +state 218 !2.0022 [0] action 0 [0.998901] 88 : 2 257 : 0.002 261 : 0.0002 -state 219 [0] +state 219 !2.0022 [0] action 0 [0.998901] 73 : 2 258 : 0.002 262 : 0.0002 -state 220 [0] +state 220 !0.2522 [0] action 0 [0.991277] 66 : 0.25 259 : 0.002 263 : 0.0002 -state 221 [0] +state 221 !0.2522 [0] action 0 [0.991277] 65 : 0.25 260 : 0.002 264 : 0.0002 -state 222 [0] +state 222 !2.004 [0] action 0 [0.998004] 95 : 2 261 : 0.004 -state 223 [0] +state 223 !0.254 [0] action 0 [0.984252] 70 : 0.25 263 : 0.004 -state 224 [0] +state 224 !0.254 [0] action 0 [0.984252] 69 : 0.25 264 : 0.004 -state 225 [0] +state 225 !0.129 [0] action 0 [0.968992] 73 : 0.125 265 : 0.004 -state 226 [0] +state 226 !50.002 [0] action 0 [0] 248 : 0.002 266 : 10 @@ -1467,214 +1469,214 @@ state 226 [0] 268 : 10 269 : 10 270 : 10 -state 227 [0] +state 227 !2.00225 [0] action 0 [0.998876] 105 : 2 249 : 0.002 266 : 0.00025 -state 228 [0] +state 228 !2.00225 [0] action 0 [0.998876] 83 : 2 250 : 0.002 267 : 0.00025 -state 229 [0] +state 229 !0.25225 [0] action 0 [0.99108] 78 : 0.25 251 : 0.002 268 : 0.00025 -state 230 [0] +state 230 !0.12725 [0] action 0 [0.982318] 79 : 0.125 252 : 0.002 270 : 0.00025 -state 231 [0] minimum +state 231 !2.00225 [0] minimum action 0 [0.998876] 106 : 2 253 : 0.002 266 : 0.00025 -state 232 [0] minimum +state 232 !2.00225 [0] minimum action 0 [0.998876] 84 : 2 254 : 0.002 267 : 0.00025 -state 233 [0] minimum +state 233 !0.25225 [0] minimum action 0 [0.99108] 78 : 0.25 255 : 0.002 269 : 0.00025 -state 234 [0] minimum +state 234 !0.12725 [0] minimum action 0 [0.982318] 80 : 0.125 256 : 0.002 270 : 0.00025 -state 235 [0] +state 235 !2.0022 [0] action 0 [0.998901] 109 : 2 257 : 0.002 266 : 0.0002 -state 236 [0] +state 236 !2.0022 [0] action 0 [0.998901] 88 : 2 258 : 0.002 267 : 0.0002 -state 237 [0] +state 237 !0.2522 [0] action 0 [0.991277] 80 : 0.25 259 : 0.002 268 : 0.0002 -state 238 [0] +state 238 !0.2522 [0] action 0 [0.991277] 79 : 0.25 260 : 0.002 269 : 0.0002 -state 239 [0] +state 239 !2.004 [0] action 0 [0.998004] 114 : 2 261 : 0.002 266 : 0.002 -state 240 [0] +state 240 !2.004 [0] action 0 [0.998004] 95 : 2 262 : 0.002 267 : 0.002 -state 241 [0] +state 241 !0.254 [0] action 0 [0.984252] 84 : 0.25 263 : 0.002 268 : 0.002 -state 242 [0] +state 242 !0.254 [0] action 0 [0.984252] 83 : 0.25 264 : 0.002 269 : 0.002 -state 243 [0] +state 243 !0.129 [0] action 0 [0.968992] 88 : 0.125 265 : 0.002 270 : 0.002 -state 244 [0] +state 244 !2.004 [0] action 0 [0.998004] 114 : 2 267 : 0.004 -state 245 [0] +state 245 !0.254 [0] action 0 [0.984252] 106 : 0.25 268 : 0.004 -state 246 [0] +state 246 !0.254 [0] action 0 [0.984252] 105 : 0.25 269 : 0.004 -state 247 [0] +state 247 !0.129 [0] action 0 [0.968992] 109 : 0.125 270 : 0.004 -state 248 [0] +state 248 !50 [0] action 0 [0] 271 : 10 272 : 10 273 : 10 274 : 10 275 : 10 -state 249 [0] +state 249 !2.00025 [0] action 0 [0.999875] 154 : 2 271 : 0.00025 -state 250 [0] +state 250 !2.00025 [0] action 0 [0.999875] 132 : 2 272 : 0.00025 -state 251 [0] +state 251 !0.25025 [0] action 0 [0.999001] 127 : 0.25 273 : 0.00025 -state 252 [0] +state 252 !0.12525 [0] action 0 [0.998004] 128 : 0.125 275 : 0.00025 -state 253 [0] +state 253 !2.00025 [0] action 0 [0.999875] 155 : 2 271 : 0.00025 -state 254 [0] +state 254 !2.00025 [0] action 0 [0.999875] 133 : 2 272 : 0.00025 -state 255 [0] +state 255 !0.25025 [0] action 0 [0.999001] 127 : 0.25 274 : 0.00025 -state 256 [0] +state 256 !0.12525 [0] action 0 [0.998004] 129 : 0.125 275 : 0.00025 -state 257 [0] +state 257 !2.0002 [0] action 0 [0.9999] 159 : 2 271 : 0.0002 -state 258 [0] +state 258 !2.0002 [0] action 0 [0.9999] 137 : 2 272 : 0.0002 -state 259 [0] +state 259 !0.2502 [0] action 0 [0.999201] 129 : 0.25 273 : 0.0002 -state 260 [0] +state 260 !0.2502 [0] action 0 [0.999201] 128 : 0.25 274 : 0.0002 -state 261 [0] +state 261 !2.002 [0] action 0 [0.999001] 166 : 2 271 : 0.002 -state 262 [0] +state 262 !2.002 [0] action 0 [0.999001] 144 : 2 272 : 0.002 -state 263 [0] +state 263 !0.252 [0] action 0 [0.992063] 133 : 0.25 273 : 0.002 -state 264 [0] +state 264 !0.252 [0] action 0 [0.992063] 132 : 0.25 274 : 0.002 -state 265 [0] +state 265 !0.127 [0] action 0 [0.984252] 137 : 0.125 275 : 0.002 -state 266 [0] +state 266 !2.002 [0] action 0 [0.999001] 183 : 2 271 : 0.002 -state 267 [0] +state 267 !2.002 [0] action 0 [0.999001] 166 : 2 272 : 0.002 -state 268 [0] +state 268 !0.252 [0] action 0 [0.992063] 155 : 0.25 273 : 0.002 -state 269 [0] +state 269 !0.252 [0] action 0 [0.992063] 154 : 0.25 274 : 0.002 -state 270 [0] +state 270 !0.127 [0] action 0 [0.984252] 159 : 0.125 275 : 0.002 -state 271 [0] +state 271 !2 [0] action 0 [1] 226 : 2 -state 272 [0] +state 272 !2 [0] action 0 [1] 209 : 2 -state 273 [0] +state 273 !0.25 [0] action 0 [1] 198 : 0.25 -state 274 [0] +state 274 !0.25 [0] action 0 [1] 197 : 0.25 -state 275 [0] +state 275 !0.125 [0] action 0 [1] 202 : 0.125 diff --git a/resources/examples/testfiles/dft/and.dft b/resources/examples/testfiles/dft/and.dft new file mode 100644 index 000000000..2b06cbe95 --- /dev/null +++ b/resources/examples/testfiles/dft/and.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" and "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/fdep.dft b/resources/examples/testfiles/dft/fdep.dft new file mode 100644 index 000000000..e597c46ce --- /dev/null +++ b/resources/examples/testfiles/dft/fdep.dft @@ -0,0 +1,8 @@ +toplevel "System"; +"System" or "Power" "Machine"; +"Power" fdep "B_Power" "P" "B"; +"Machine" or "P" "B"; + +"B_Power" lambda=0.5 dorm=0; +"P" lambda=0.5 dorm=0; +"B" lambda=0.5 dorm=0.5; diff --git a/resources/examples/testfiles/dft/fdep2.dft b/resources/examples/testfiles/dft/fdep2.dft new file mode 100644 index 000000000..a444ed4be --- /dev/null +++ b/resources/examples/testfiles/dft/fdep2.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C"; +"F" fdep "B" "C"; +"B" lambda=0.5 dorm=0; +"C" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep3.dft b/resources/examples/testfiles/dft/fdep3.dft new file mode 100644 index 000000000..3815c9973 --- /dev/null +++ b/resources/examples/testfiles/dft/fdep3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C" "F"; +"F" fdep "B" "C"; +"B" lambda=0.4 dorm=0; +"C" lambda=0.8 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep4.dft b/resources/examples/testfiles/dft/fdep4.dft new file mode 100644 index 000000000..7e3c5642a --- /dev/null +++ b/resources/examples/testfiles/dft/fdep4.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" or "F" "B"; +"F" fdep "E" "C" "D"; +"B" wsp "C" "D"; +"C" lambda=1 dorm=0; +"D" lambda=1 dorm=0.5; +"E" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/fdep5.dft b/resources/examples/testfiles/dft/fdep5.dft new file mode 100644 index 000000000..2e0625dfb --- /dev/null +++ b/resources/examples/testfiles/dft/fdep5.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" and "B" "C" "D" "E"; +"F" fdep "B" "C" "D"; +"B" lambda=0.5 dorm=0; +"C" lambda=0.5 dorm=0; +"D" lambda=0.5 dorm=0; +"E" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/or.dft b/resources/examples/testfiles/dft/or.dft new file mode 100644 index 000000000..b1003da11 --- /dev/null +++ b/resources/examples/testfiles/dft/or.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" or "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/pand.dft b/resources/examples/testfiles/dft/pand.dft new file mode 100644 index 000000000..d752517b4 --- /dev/null +++ b/resources/examples/testfiles/dft/pand.dft @@ -0,0 +1,4 @@ +toplevel "A"; +"A" pand "B" "C"; +"B" lambda=0.4 dorm=0.3; +"C" lambda=0.2 dorm=0.3; diff --git a/resources/examples/testfiles/dft/pdep.dft b/resources/examples/testfiles/dft/pdep.dft new file mode 100644 index 000000000..f8cb0382b --- /dev/null +++ b/resources/examples/testfiles/dft/pdep.dft @@ -0,0 +1,12 @@ +// From Junges2015 +// Example 3.19 + +toplevel "SF"; +"SF" or "A" "B" "PDEP"; +"A" pand "S" "MA"; +"B" and "MA" "MB"; +"PDEP" pdep=0.2 "MA" "S"; + +"S" lambda=0.5 dorm=0; +"MA" lambda=0.5 dorm=0; +"MB" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep2.dft b/resources/examples/testfiles/dft/pdep2.dft new file mode 100644 index 000000000..ab1c7a9b8 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep2.dft @@ -0,0 +1,9 @@ +toplevel "SF"; +"SF" or "A" "B" "PDEP"; +"A" pand "S" "MA"; +"B" and "MA" "MB"; +"PDEP" pdep=0.2 "MA" "S" "MB"; + +"S" lambda=0.5 dorm=0; +"MA" lambda=0.5 dorm=0; +"MB" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep3.dft b/resources/examples/testfiles/dft/pdep3.dft new file mode 100644 index 000000000..a9a73f472 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C" "F"; +"F" pdep=0.3 "B" "C"; +"B" lambda=0.4 dorm=0; +"C" lambda=0.8 dorm=0; diff --git a/resources/examples/testfiles/dft/pdep4.dft b/resources/examples/testfiles/dft/pdep4.dft new file mode 100644 index 000000000..eace91847 --- /dev/null +++ b/resources/examples/testfiles/dft/pdep4.dft @@ -0,0 +1,7 @@ +toplevel "SF"; +"SF" pand "S" "A" "B"; +"PDEP" pdep=0.2 "S" "A" "B"; + +"S" lambda=0.5 dorm=0; +"A" lambda=0.5 dorm=0; +"B" lambda=0.5 dorm=0; diff --git a/resources/examples/testfiles/dft/por.dft b/resources/examples/testfiles/dft/por.dft new file mode 100644 index 000000000..020687f62 --- /dev/null +++ b/resources/examples/testfiles/dft/por.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" por "B" "C" "D"; +"B" lambda=0.4 dorm=0.0; +"C" lambda=0.2 dorm=0.0; +"D" lambda=0.2 dorm=0.0; diff --git a/resources/examples/testfiles/dft/seq.dft b/resources/examples/testfiles/dft/seq.dft new file mode 100644 index 000000000..8f5459fd2 --- /dev/null +++ b/resources/examples/testfiles/dft/seq.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" and "B" "C"; +"X" seq "B" "C"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq2.dft b/resources/examples/testfiles/dft/seq2.dft new file mode 100644 index 000000000..408d4c26d --- /dev/null +++ b/resources/examples/testfiles/dft/seq2.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" and "B" "C" "D"; +"X" seq "B" "C" "D"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; +"D" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq3.dft b/resources/examples/testfiles/dft/seq3.dft new file mode 100644 index 000000000..b22b9e8b6 --- /dev/null +++ b/resources/examples/testfiles/dft/seq3.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" and "C" "D"; +"X" seq "B" "C" "D"; +"B" lambda=0.5 dorm=0.3; +"C" lambda=0.5 dorm=0.3; +"D" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq4.dft b/resources/examples/testfiles/dft/seq4.dft new file mode 100644 index 000000000..60bf149af --- /dev/null +++ b/resources/examples/testfiles/dft/seq4.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" and "T1" "B3"; +"T1" or "B1" "B2"; +"X" seq "B1" "B2" "B3"; +"B1" lambda=0.5 dorm=0.3; +"B2" lambda=0.5 dorm=0.3; +"B3" lambda=0.5 dorm=0.3; diff --git a/resources/examples/testfiles/dft/seq5.dft b/resources/examples/testfiles/dft/seq5.dft new file mode 100644 index 000000000..77b13ddeb --- /dev/null +++ b/resources/examples/testfiles/dft/seq5.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" and "T1" "T2"; +"T1" pand "B1" "B2"; +"T2" pand "B3" "B4"; +"X" seq "B4" "B3"; +"B1" lambda=0.7 dorm=0.3; +"B2" lambda=0.5 dorm=0.3; +"B3" lambda=0.5 dorm=0.3; +"B4" lambda=0.7 dorm=0.3; diff --git a/resources/examples/testfiles/dft/spare.dft b/resources/examples/testfiles/dft/spare.dft new file mode 100644 index 000000000..4c5d44ff4 --- /dev/null +++ b/resources/examples/testfiles/dft/spare.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" wsp "I" "M"; +"I" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare2.dft b/resources/examples/testfiles/dft/spare2.dft new file mode 100644 index 000000000..21b40cf73 --- /dev/null +++ b/resources/examples/testfiles/dft/spare2.dft @@ -0,0 +1,8 @@ +toplevel "A"; +"A" or "B" "C"; +"B" wsp "I" "J"; +"C" wsp "M" "J"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare3.dft b/resources/examples/testfiles/dft/spare3.dft new file mode 100644 index 000000000..ba0ac01d4 --- /dev/null +++ b/resources/examples/testfiles/dft/spare3.dft @@ -0,0 +1,10 @@ +toplevel "A"; +"A" or "B" "C" "D"; +"B" wsp "I" "M"; +"C" wsp "J" "M"; +"D" wsp "K" "M"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare4.dft b/resources/examples/testfiles/dft/spare4.dft new file mode 100644 index 000000000..a217c6e43 --- /dev/null +++ b/resources/examples/testfiles/dft/spare4.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" and "B" "C"; +"B" wsp "I" "J" "K"; +"C" wsp "M" "J"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; +"M" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/spare5.dft b/resources/examples/testfiles/dft/spare5.dft new file mode 100644 index 000000000..0cd15bf0e --- /dev/null +++ b/resources/examples/testfiles/dft/spare5.dft @@ -0,0 +1,9 @@ +toplevel "A"; +"A" wsp "I" "B"; +"B" or "C" "J"; +"C" or "K" "L"; +"I" lambda=0.5 dorm=0; +"J" lambda=0.5 dorm=0; +"K" lambda=0.5 dorm=0; +"L" lambda=0.5 dorm=0; + diff --git a/resources/examples/testfiles/dft/spare6.dft b/resources/examples/testfiles/dft/spare6.dft new file mode 100644 index 000000000..d5f2b270b --- /dev/null +++ b/resources/examples/testfiles/dft/spare6.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" or "I" "B"; +"B" wsp "J" "M"; +"I" lambda=0.5 dorm=0.5; +"J" lambda=0.5 dorm=0.5; +"M" lambda=0.5 dorm=0.5; + diff --git a/resources/examples/testfiles/dft/spare7.dft b/resources/examples/testfiles/dft/spare7.dft new file mode 100644 index 000000000..a16429e6f --- /dev/null +++ b/resources/examples/testfiles/dft/spare7.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" wsp "K" "J" "I"; +"I" lambda=0.5 dorm=0.5; +"J" lambda=1 dorm=0.5; +"K" lambda=0.5 dorm=0.5; diff --git a/resources/examples/testfiles/dft/spare8.dft b/resources/examples/testfiles/dft/spare8.dft new file mode 100644 index 000000000..c67eaf022 --- /dev/null +++ b/resources/examples/testfiles/dft/spare8.dft @@ -0,0 +1,7 @@ +toplevel "A"; +"A" wsp "I" "B"; +"B" wsp "J" "K"; +"I" lambda=0.5 dorm=0.3; +"J" lambda=0.5 dorm=0.3; +"K" lambda=0.5 dorm=0.3; + diff --git a/resources/examples/testfiles/dft/voting.dft b/resources/examples/testfiles/dft/voting.dft new file mode 100644 index 000000000..5c648d424 --- /dev/null +++ b/resources/examples/testfiles/dft/voting.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 1of3 "B" "C" "D"; +"B" lambda=0.1 dorm=0; +"C" lambda=0.2 dorm=0; +"D" lambda=0.3 dorm=0; diff --git a/resources/examples/testfiles/dft/voting2.dft b/resources/examples/testfiles/dft/voting2.dft new file mode 100644 index 000000000..9cdf299f3 --- /dev/null +++ b/resources/examples/testfiles/dft/voting2.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 1of3 "B" "C" "D"; +"B" lambda=0.3 dorm=0; +"C" lambda=0.4 dorm=0; +"D" lambda=1 dorm=0; diff --git a/resources/examples/testfiles/dft/voting3.dft b/resources/examples/testfiles/dft/voting3.dft new file mode 100644 index 000000000..107408fce --- /dev/null +++ b/resources/examples/testfiles/dft/voting3.dft @@ -0,0 +1,5 @@ +toplevel "A"; +"A" 2of3 "B" "C" "D"; +"B" lambda=0.3 dorm=0; +"C" lambda=0.4 dorm=0; +"D" lambda=1 dorm=0; diff --git a/resources/examples/testfiles/dft/voting4.dft b/resources/examples/testfiles/dft/voting4.dft new file mode 100644 index 000000000..412df12e5 --- /dev/null +++ b/resources/examples/testfiles/dft/voting4.dft @@ -0,0 +1,6 @@ +toplevel "A"; +"A" 2of3 "B" "C" "D"; +"D" or "E"; +"B" lambda=1 dorm=0.0; +"C" lambda=1 dorm=0.0; +"E" lambda=1 dorm=0.0; diff --git a/resources/examples/testfiles/dtmc/crowds-5-5.drn b/resources/examples/testfiles/dtmc/crowds-5-5.drn new file mode 100644 index 000000000..54dfa7161 --- /dev/null +++ b/resources/examples/testfiles/dtmc/crowds-5-5.drn @@ -0,0 +1,32337 @@ +// Exported by storm +// Original model type: DTMC +@type: DTMC +@parameters + +@reward_models + +@nr_states +8607 +@model +state 0 init + action 0 + 1 : 1 +state 1 + action 0 + 2 : 0.833 + 3 : 0.167 +state 2 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 3 + action 0 + 9 : 1 +state 4 + action 0 + 10 : 0.8 + 11 : 0.2 +state 5 + action 0 + 12 : 0.8 + 13 : 0.2 +state 6 + action 0 + 14 : 0.8 + 15 : 0.2 +state 7 + action 0 + 16 : 0.8 + 17 : 0.2 +state 8 + action 0 + 18 : 0.8 + 19 : 0.2 +state 9 + action 0 + 20 : 1 +state 10 + action 0 + 2 : 0.833 + 3 : 0.167 +state 11 + action 0 + 21 : 1 +state 12 + action 0 + 22 : 0.833 + 23 : 0.167 +state 13 + action 0 + 24 : 1 +state 14 + action 0 + 25 : 0.833 + 26 : 0.167 +state 15 + action 0 + 27 : 1 +state 16 + action 0 + 28 : 0.833 + 29 : 0.167 +state 17 + action 0 + 30 : 1 +state 18 + action 0 + 31 : 0.833 + 32 : 0.167 +state 19 + action 0 + 33 : 1 +state 20 + action 0 + 34 : 1 +state 21 + action 0 + 35 : 1 +state 22 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 23 + action 0 + 36 : 1 +state 24 + action 0 + 35 : 1 +state 25 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 26 + action 0 + 37 : 1 +state 27 + action 0 + 35 : 1 +state 28 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 29 + action 0 + 38 : 1 +state 30 + action 0 + 35 : 1 +state 31 + action 0 + 4 : 0.2 + 5 : 0.2 + 6 : 0.2 + 7 : 0.2 + 8 : 0.2 +state 32 + action 0 + 39 : 1 +state 33 + action 0 + 35 : 1 +state 34 + action 0 + 40 : 0.833 + 41 : 0.167 +state 35 + action 0 + 42 : 0.833 + 43 : 0.167 +state 36 + action 0 + 44 : 1 +state 37 + action 0 + 45 : 1 +state 38 + action 0 + 46 : 1 +state 39 + action 0 + 47 : 1 +state 40 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 41 + action 0 + 53 : 1 +state 42 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 43 + action 0 + 59 : 1 +state 44 + action 0 + 60 : 1 +state 45 + action 0 + 61 : 1 +state 46 + action 0 + 62 : 1 +state 47 + action 0 + 63 : 1 +state 48 + action 0 + 64 : 0.8 + 65 : 0.2 +state 49 + action 0 + 66 : 0.8 + 67 : 0.2 +state 50 + action 0 + 68 : 0.8 + 69 : 0.2 +state 51 + action 0 + 70 : 0.8 + 71 : 0.2 +state 52 + action 0 + 72 : 0.8 + 73 : 0.2 +state 53 observe0Greater1 observeOnlyTrueSender + action 0 + 74 : 1 +state 54 + action 0 + 35 : 0.8 + 75 : 0.2 +state 55 + action 0 + 76 : 0.8 + 77 : 0.2 +state 56 + action 0 + 78 : 0.8 + 79 : 0.2 +state 57 + action 0 + 80 : 0.8 + 81 : 0.2 +state 58 + action 0 + 82 : 0.8 + 83 : 0.2 +state 59 + action 0 + 84 : 1 +state 60 + action 0 + 85 : 0.833 + 86 : 0.167 +state 61 + action 0 + 87 : 0.833 + 88 : 0.167 +state 62 + action 0 + 89 : 0.833 + 90 : 0.167 +state 63 + action 0 + 91 : 0.833 + 92 : 0.167 +state 64 + action 0 + 40 : 0.833 + 41 : 0.167 +state 65 + action 0 + 93 : 1 +state 66 + action 0 + 94 : 0.833 + 95 : 0.167 +state 67 + action 0 + 96 : 1 +state 68 + action 0 + 97 : 0.833 + 98 : 0.167 +state 69 + action 0 + 99 : 1 +state 70 + action 0 + 100 : 0.833 + 101 : 0.167 +state 71 + action 0 + 102 : 1 +state 72 + action 0 + 103 : 0.833 + 104 : 0.167 +state 73 + action 0 + 105 : 1 +state 74 observe0Greater1 observeOnlyTrueSender + action 0 + 106 : 1 +state 75 + action 0 + 107 : 1 +state 76 + action 0 + 108 : 0.833 + 109 : 0.167 +state 77 + action 0 + 110 : 1 +state 78 + action 0 + 111 : 0.833 + 112 : 0.167 +state 79 + action 0 + 113 : 1 +state 80 + action 0 + 114 : 0.833 + 115 : 0.167 +state 81 + action 0 + 116 : 1 +state 82 + action 0 + 117 : 0.833 + 118 : 0.167 +state 83 + action 0 + 119 : 1 +state 84 + action 0 + 120 : 1 +state 85 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 86 + action 0 + 126 : 1 +state 87 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 88 + action 0 + 132 : 1 +state 89 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 90 + action 0 + 138 : 1 +state 91 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 92 + action 0 + 144 : 1 +state 93 + action 0 + 145 : 1 +state 94 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 95 + action 0 + 146 : 1 +state 96 + action 0 + 145 : 1 +state 97 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 98 + action 0 + 147 : 1 +state 99 + action 0 + 145 : 1 +state 100 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 101 + action 0 + 148 : 1 +state 102 + action 0 + 145 : 1 +state 103 + action 0 + 48 : 0.2 + 49 : 0.2 + 50 : 0.2 + 51 : 0.2 + 52 : 0.2 +state 104 + action 0 + 149 : 1 +state 105 + action 0 + 145 : 1 +state 106 observe0Greater1 observeOnlyTrueSender + action 0 + 150 : 0.833 + 151 : 0.167 +state 107 + action 0 + 152 : 1 +state 108 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 109 + action 0 + 153 : 1 +state 110 + action 0 + 152 : 1 +state 111 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 112 + action 0 + 154 : 1 +state 113 + action 0 + 152 : 1 +state 114 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 115 + action 0 + 155 : 1 +state 116 + action 0 + 152 : 1 +state 117 + action 0 + 54 : 0.2 + 55 : 0.2 + 56 : 0.2 + 57 : 0.2 + 58 : 0.2 +state 118 + action 0 + 156 : 1 +state 119 + action 0 + 152 : 1 +state 120 + action 0 + 157 : 0.833 + 158 : 0.167 +state 121 + action 0 + 159 : 0.8 + 160 : 0.2 +state 122 + action 0 + 161 : 0.8 + 162 : 0.2 +state 123 + action 0 + 163 : 0.8 + 164 : 0.2 +state 124 + action 0 + 165 : 0.8 + 166 : 0.2 +state 125 + action 0 + 167 : 0.8 + 168 : 0.2 +state 126 + action 0 + 169 : 1 +state 127 + action 0 + 170 : 0.8 + 171 : 0.2 +state 128 + action 0 + 172 : 0.8 + 173 : 0.2 +state 129 + action 0 + 174 : 0.8 + 175 : 0.2 +state 130 + action 0 + 176 : 0.8 + 177 : 0.2 +state 131 + action 0 + 178 : 0.8 + 179 : 0.2 +state 132 + action 0 + 180 : 1 +state 133 + action 0 + 181 : 0.8 + 182 : 0.2 +state 134 + action 0 + 183 : 0.8 + 184 : 0.2 +state 135 + action 0 + 185 : 0.8 + 186 : 0.2 +state 136 + action 0 + 187 : 0.8 + 188 : 0.2 +state 137 + action 0 + 189 : 0.8 + 190 : 0.2 +state 138 + action 0 + 191 : 1 +state 139 + action 0 + 192 : 0.8 + 193 : 0.2 +state 140 + action 0 + 194 : 0.8 + 195 : 0.2 +state 141 + action 0 + 196 : 0.8 + 197 : 0.2 +state 142 + action 0 + 198 : 0.8 + 199 : 0.2 +state 143 + action 0 + 200 : 0.8 + 201 : 0.2 +state 144 + action 0 + 202 : 1 +state 145 + action 0 + 157 : 0.833 + 158 : 0.167 +state 146 + action 0 + 203 : 1 +state 147 + action 0 + 204 : 1 +state 148 + action 0 + 205 : 1 +state 149 + action 0 + 206 : 1 +state 150 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 151 observe0Greater1 observeOnlyTrueSender + action 0 + 212 : 1 +state 152 + action 0 + 213 : 0.833 + 214 : 0.167 +state 153 + action 0 + 215 : 1 +state 154 + action 0 + 216 : 1 +state 155 + action 0 + 217 : 1 +state 156 + action 0 + 218 : 1 +state 157 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 158 + action 0 + 224 : 1 +state 159 + action 0 + 85 : 0.833 + 86 : 0.167 +state 160 + action 0 + 225 : 1 +state 161 + action 0 + 226 : 0.833 + 227 : 0.167 +state 162 + action 0 + 228 : 1 +state 163 + action 0 + 229 : 0.833 + 230 : 0.167 +state 164 + action 0 + 231 : 1 +state 165 + action 0 + 232 : 0.833 + 233 : 0.167 +state 166 + action 0 + 234 : 1 +state 167 + action 0 + 235 : 0.833 + 236 : 0.167 +state 168 + action 0 + 237 : 1 +state 169 + action 0 + 238 : 1 +state 170 + action 0 + 87 : 0.833 + 88 : 0.167 +state 171 + action 0 + 239 : 1 +state 172 + action 0 + 240 : 0.833 + 241 : 0.167 +state 173 + action 0 + 242 : 1 +state 174 + action 0 + 243 : 0.833 + 244 : 0.167 +state 175 + action 0 + 245 : 1 +state 176 + action 0 + 246 : 0.833 + 247 : 0.167 +state 177 + action 0 + 248 : 1 +state 178 + action 0 + 249 : 0.833 + 250 : 0.167 +state 179 + action 0 + 251 : 1 +state 180 + action 0 + 252 : 1 +state 181 + action 0 + 89 : 0.833 + 90 : 0.167 +state 182 + action 0 + 253 : 1 +state 183 + action 0 + 254 : 0.833 + 255 : 0.167 +state 184 + action 0 + 256 : 1 +state 185 + action 0 + 257 : 0.833 + 258 : 0.167 +state 186 + action 0 + 259 : 1 +state 187 + action 0 + 260 : 0.833 + 261 : 0.167 +state 188 + action 0 + 262 : 1 +state 189 + action 0 + 263 : 0.833 + 264 : 0.167 +state 190 + action 0 + 265 : 1 +state 191 + action 0 + 266 : 1 +state 192 + action 0 + 91 : 0.833 + 92 : 0.167 +state 193 + action 0 + 267 : 1 +state 194 + action 0 + 268 : 0.833 + 269 : 0.167 +state 195 + action 0 + 270 : 1 +state 196 + action 0 + 271 : 0.833 + 272 : 0.167 +state 197 + action 0 + 273 : 1 +state 198 + action 0 + 274 : 0.833 + 275 : 0.167 +state 199 + action 0 + 276 : 1 +state 200 + action 0 + 277 : 0.833 + 278 : 0.167 +state 201 + action 0 + 279 : 1 +state 202 + action 0 + 280 : 1 +state 203 + action 0 + 238 : 1 +state 204 + action 0 + 252 : 1 +state 205 + action 0 + 266 : 1 +state 206 + action 0 + 280 : 1 +state 207 observe0Greater1 observeOnlyTrueSender + action 0 + 281 : 0.8 + 282 : 0.2 +state 208 observe0Greater1 observeOnlyTrueSender + action 0 + 283 : 0.8 + 284 : 0.2 +state 209 observe0Greater1 observeOnlyTrueSender + action 0 + 285 : 0.8 + 286 : 0.2 +state 210 observe0Greater1 observeOnlyTrueSender + action 0 + 287 : 0.8 + 288 : 0.2 +state 211 observe0Greater1 observeOnlyTrueSender + action 0 + 289 : 0.8 + 290 : 0.2 +state 212 observe0Greater1 observeOnlyTrueSender + action 0 + 291 : 1 +state 213 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 214 + action 0 + 297 : 1 +state 215 + action 0 + 298 : 1 +state 216 + action 0 + 299 : 1 +state 217 + action 0 + 300 : 1 +state 218 + action 0 + 301 : 1 +state 219 + action 0 + 145 : 0.8 + 302 : 0.2 +state 220 + action 0 + 303 : 0.8 + 304 : 0.2 +state 221 + action 0 + 305 : 0.8 + 306 : 0.2 +state 222 + action 0 + 307 : 0.8 + 308 : 0.2 +state 223 + action 0 + 309 : 0.8 + 310 : 0.2 +state 224 observe0Greater1 observeOnlyTrueSender + action 0 + 311 : 1 +state 225 + action 0 + 312 : 1 +state 226 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 227 + action 0 + 313 : 1 +state 228 + action 0 + 312 : 1 +state 229 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 230 + action 0 + 314 : 1 +state 231 + action 0 + 312 : 1 +state 232 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 233 + action 0 + 315 : 1 +state 234 + action 0 + 312 : 1 +state 235 + action 0 + 121 : 0.2 + 122 : 0.2 + 123 : 0.2 + 124 : 0.2 + 125 : 0.2 +state 236 + action 0 + 316 : 1 +state 237 + action 0 + 312 : 1 +state 238 + action 0 + 317 : 0.833 + 318 : 0.167 +state 239 + action 0 + 319 : 1 +state 240 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 241 + action 0 + 320 : 1 +state 242 + action 0 + 319 : 1 +state 243 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 244 + action 0 + 321 : 1 +state 245 + action 0 + 319 : 1 +state 246 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 247 + action 0 + 322 : 1 +state 248 + action 0 + 319 : 1 +state 249 + action 0 + 127 : 0.2 + 128 : 0.2 + 129 : 0.2 + 130 : 0.2 + 131 : 0.2 +state 250 + action 0 + 323 : 1 +state 251 + action 0 + 319 : 1 +state 252 + action 0 + 324 : 0.833 + 325 : 0.167 +state 253 + action 0 + 326 : 1 +state 254 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 255 + action 0 + 327 : 1 +state 256 + action 0 + 326 : 1 +state 257 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 258 + action 0 + 328 : 1 +state 259 + action 0 + 326 : 1 +state 260 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 261 + action 0 + 329 : 1 +state 262 + action 0 + 326 : 1 +state 263 + action 0 + 133 : 0.2 + 134 : 0.2 + 135 : 0.2 + 136 : 0.2 + 137 : 0.2 +state 264 + action 0 + 330 : 1 +state 265 + action 0 + 326 : 1 +state 266 + action 0 + 331 : 0.833 + 332 : 0.167 +state 267 + action 0 + 333 : 1 +state 268 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 269 + action 0 + 334 : 1 +state 270 + action 0 + 333 : 1 +state 271 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 272 + action 0 + 335 : 1 +state 273 + action 0 + 333 : 1 +state 274 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 275 + action 0 + 336 : 1 +state 276 + action 0 + 333 : 1 +state 277 + action 0 + 139 : 0.2 + 140 : 0.2 + 141 : 0.2 + 142 : 0.2 + 143 : 0.2 +state 278 + action 0 + 337 : 1 +state 279 + action 0 + 333 : 1 +state 280 + action 0 + 338 : 0.833 + 339 : 0.167 +state 281 observe0Greater1 observeOnlyTrueSender + action 0 + 150 : 0.833 + 151 : 0.167 +state 282 observe0Greater1 observeOnlyTrueSender + action 0 + 340 : 1 +state 283 observe0Greater1 observeOnlyTrueSender + action 0 + 341 : 0.833 + 342 : 0.167 +state 284 observe0Greater1 observeOnlyTrueSender + action 0 + 343 : 1 +state 285 observe0Greater1 observeOnlyTrueSender + action 0 + 344 : 0.833 + 345 : 0.167 +state 286 observe0Greater1 observeOnlyTrueSender + action 0 + 346 : 1 +state 287 observe0Greater1 observeOnlyTrueSender + action 0 + 347 : 0.833 + 348 : 0.167 +state 288 observe0Greater1 observeOnlyTrueSender + action 0 + 349 : 1 +state 289 observe0Greater1 observeOnlyTrueSender + action 0 + 350 : 0.833 + 351 : 0.167 +state 290 observe0Greater1 observeOnlyTrueSender + action 0 + 352 : 1 +state 291 observe0Greater1 observeOnlyTrueSender + action 0 + 353 : 1 +state 292 + action 0 + 152 : 0.8 + 354 : 0.2 +state 293 + action 0 + 355 : 0.8 + 356 : 0.2 +state 294 + action 0 + 357 : 0.8 + 358 : 0.2 +state 295 + action 0 + 359 : 0.8 + 360 : 0.2 +state 296 + action 0 + 361 : 0.8 + 362 : 0.2 +state 297 + action 0 + 363 : 1 +state 298 + action 0 + 364 : 0.833 + 365 : 0.167 +state 299 + action 0 + 366 : 0.833 + 367 : 0.167 +state 300 + action 0 + 368 : 0.833 + 369 : 0.167 +state 301 + action 0 + 370 : 0.833 + 371 : 0.167 +state 302 + action 0 + 372 : 1 +state 303 + action 0 + 373 : 0.833 + 374 : 0.167 +state 304 + action 0 + 375 : 1 +state 305 + action 0 + 376 : 0.833 + 377 : 0.167 +state 306 + action 0 + 378 : 1 +state 307 + action 0 + 379 : 0.833 + 380 : 0.167 +state 308 + action 0 + 381 : 1 +state 309 + action 0 + 382 : 0.833 + 383 : 0.167 +state 310 + action 0 + 384 : 1 +state 311 observe0Greater1 observeOnlyTrueSender + action 0 + 385 : 1 +state 312 + action 0 + 364 : 0.833 + 365 : 0.167 +state 313 observe1Greater1 observeIGreater1 + action 0 + 386 : 1 +state 314 + action 0 + 387 : 1 +state 315 + action 0 + 388 : 1 +state 316 + action 0 + 389 : 1 +state 317 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 318 + action 0 + 395 : 1 +state 319 + action 0 + 366 : 0.833 + 367 : 0.167 +state 320 + action 0 + 396 : 1 +state 321 observe2Greater1 observeIGreater1 + action 0 + 397 : 1 +state 322 + action 0 + 398 : 1 +state 323 + action 0 + 399 : 1 +state 324 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 325 + action 0 + 405 : 1 +state 326 + action 0 + 368 : 0.833 + 369 : 0.167 +state 327 + action 0 + 406 : 1 +state 328 + action 0 + 407 : 1 +state 329 observe3Greater1 observeIGreater1 + action 0 + 408 : 1 +state 330 + action 0 + 409 : 1 +state 331 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 332 + action 0 + 415 : 1 +state 333 + action 0 + 370 : 0.833 + 371 : 0.167 +state 334 + action 0 + 416 : 1 +state 335 + action 0 + 417 : 1 +state 336 + action 0 + 418 : 1 +state 337 observe4Greater1 observeIGreater1 + action 0 + 419 : 1 +state 338 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 339 + action 0 + 425 : 1 +state 340 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 341 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 342 observe0Greater1 observeOnlyTrueSender + action 0 + 427 : 1 +state 343 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 344 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 345 observe0Greater1 observeOnlyTrueSender + action 0 + 428 : 1 +state 346 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 347 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 348 observe0Greater1 observeOnlyTrueSender + action 0 + 429 : 1 +state 349 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 350 observe0Greater1 observeOnlyTrueSender + action 0 + 207 : 0.2 + 208 : 0.2 + 209 : 0.2 + 210 : 0.2 + 211 : 0.2 +state 351 observe0Greater1 observeOnlyTrueSender + action 0 + 430 : 1 +state 352 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 1 +state 353 observe0Greater1 observeOnlyTrueSender + action 0 + 431 : 0.833 + 432 : 0.167 +state 354 + action 0 + 433 : 1 +state 355 + action 0 + 434 : 0.833 + 435 : 0.167 +state 356 + action 0 + 436 : 1 +state 357 + action 0 + 437 : 0.833 + 438 : 0.167 +state 358 + action 0 + 439 : 1 +state 359 + action 0 + 440 : 0.833 + 441 : 0.167 +state 360 + action 0 + 442 : 1 +state 361 + action 0 + 443 : 0.833 + 444 : 0.167 +state 362 + action 0 + 445 : 1 +state 363 + action 0 + 446 : 1 +state 364 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 365 + action 0 + 452 : 1 +state 366 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 367 + action 0 + 458 : 1 +state 368 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 369 + action 0 + 464 : 1 +state 370 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 371 + action 0 + 470 : 1 +state 372 + action 0 + 471 : 1 +state 373 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 374 + action 0 + 472 : 1 +state 375 + action 0 + 471 : 1 +state 376 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 377 + action 0 + 473 : 1 +state 378 + action 0 + 471 : 1 +state 379 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 380 + action 0 + 474 : 1 +state 381 + action 0 + 471 : 1 +state 382 + action 0 + 219 : 0.2 + 220 : 0.2 + 221 : 0.2 + 222 : 0.2 + 223 : 0.2 +state 383 + action 0 + 475 : 1 +state 384 + action 0 + 471 : 1 +state 385 observe0Greater1 observeOnlyTrueSender + action 0 + 476 : 0.833 + 477 : 0.167 +state 386 observe1Greater1 observeIGreater1 + action 0 + 478 : 1 +state 387 + action 0 + 479 : 1 +state 388 + action 0 + 480 : 1 +state 389 + action 0 + 481 : 1 +state 390 + action 0 + 482 : 0.8 + 483 : 0.2 +state 391 + action 0 + 484 : 0.8 + 485 : 0.2 +state 392 + action 0 + 486 : 0.8 + 487 : 0.2 +state 393 + action 0 + 488 : 0.8 + 489 : 0.2 +state 394 + action 0 + 490 : 0.8 + 491 : 0.2 +state 395 observe0Greater1 observeOnlyTrueSender + action 0 + 492 : 1 +state 396 + action 0 + 479 : 1 +state 397 observe2Greater1 observeIGreater1 + action 0 + 493 : 1 +state 398 + action 0 + 494 : 1 +state 399 + action 0 + 495 : 1 +state 400 + action 0 + 496 : 0.8 + 497 : 0.2 +state 401 + action 0 + 498 : 0.8 + 499 : 0.2 +state 402 + action 0 + 500 : 0.8 + 501 : 0.2 +state 403 + action 0 + 502 : 0.8 + 503 : 0.2 +state 404 + action 0 + 504 : 0.8 + 505 : 0.2 +state 405 observe0Greater1 observeOnlyTrueSender + action 0 + 506 : 1 +state 406 + action 0 + 480 : 1 +state 407 + action 0 + 494 : 1 +state 408 observe3Greater1 observeIGreater1 + action 0 + 507 : 1 +state 409 + action 0 + 508 : 1 +state 410 + action 0 + 509 : 0.8 + 510 : 0.2 +state 411 + action 0 + 511 : 0.8 + 512 : 0.2 +state 412 + action 0 + 513 : 0.8 + 514 : 0.2 +state 413 + action 0 + 515 : 0.8 + 516 : 0.2 +state 414 + action 0 + 517 : 0.8 + 518 : 0.2 +state 415 observe0Greater1 observeOnlyTrueSender + action 0 + 519 : 1 +state 416 + action 0 + 481 : 1 +state 417 + action 0 + 495 : 1 +state 418 + action 0 + 508 : 1 +state 419 observe4Greater1 observeIGreater1 + action 0 + 520 : 1 +state 420 + action 0 + 521 : 0.8 + 522 : 0.2 +state 421 + action 0 + 523 : 0.8 + 524 : 0.2 +state 422 + action 0 + 525 : 0.8 + 526 : 0.2 +state 423 + action 0 + 527 : 0.8 + 528 : 0.2 +state 424 + action 0 + 529 : 0.8 + 530 : 0.2 +state 425 observe0Greater1 observeOnlyTrueSender + action 0 + 531 : 1 +state 426 observe0Greater1 observeOnlyTrueSender + action 0 + 476 : 0.833 + 477 : 0.167 +state 427 observe0Greater1 observeOnlyTrueSender + action 0 + 532 : 1 +state 428 observe0Greater1 observeOnlyTrueSender + action 0 + 533 : 1 +state 429 observe0Greater1 observeOnlyTrueSender + action 0 + 534 : 1 +state 430 observe0Greater1 observeOnlyTrueSender + action 0 + 535 : 1 +state 431 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 432 observe0Greater1 observeOnlyTrueSender + action 0 + 541 : 1 +state 433 + action 0 + 542 : 1 +state 434 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 435 + action 0 + 543 : 1 +state 436 + action 0 + 542 : 1 +state 437 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 438 + action 0 + 544 : 1 +state 439 + action 0 + 542 : 1 +state 440 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 441 + action 0 + 545 : 1 +state 442 + action 0 + 542 : 1 +state 443 + action 0 + 292 : 0.2 + 293 : 0.2 + 294 : 0.2 + 295 : 0.2 + 296 : 0.2 +state 444 + action 0 + 546 : 1 +state 445 + action 0 + 542 : 1 +state 446 + action 0 + 547 : 0.833 + 548 : 0.167 +state 447 + action 0 + 312 : 0.8 + 549 : 0.2 +state 448 + action 0 + 550 : 0.8 + 551 : 0.2 +state 449 + action 0 + 552 : 0.8 + 553 : 0.2 +state 450 + action 0 + 554 : 0.8 + 555 : 0.2 +state 451 + action 0 + 556 : 0.8 + 557 : 0.2 +state 452 + action 0 + 558 : 1 +state 453 + action 0 + 319 : 0.8 + 559 : 0.2 +state 454 + action 0 + 560 : 0.8 + 561 : 0.2 +state 455 + action 0 + 562 : 0.8 + 563 : 0.2 +state 456 + action 0 + 564 : 0.8 + 565 : 0.2 +state 457 + action 0 + 566 : 0.8 + 567 : 0.2 +state 458 + action 0 + 568 : 1 +state 459 + action 0 + 326 : 0.8 + 569 : 0.2 +state 460 + action 0 + 570 : 0.8 + 571 : 0.2 +state 461 + action 0 + 572 : 0.8 + 573 : 0.2 +state 462 + action 0 + 574 : 0.8 + 575 : 0.2 +state 463 + action 0 + 576 : 0.8 + 577 : 0.2 +state 464 + action 0 + 578 : 1 +state 465 + action 0 + 333 : 0.8 + 579 : 0.2 +state 466 + action 0 + 580 : 0.8 + 581 : 0.2 +state 467 + action 0 + 582 : 0.8 + 583 : 0.2 +state 468 + action 0 + 584 : 0.8 + 585 : 0.2 +state 469 + action 0 + 586 : 0.8 + 587 : 0.2 +state 470 + action 0 + 588 : 1 +state 471 + action 0 + 547 : 0.833 + 548 : 0.167 +state 472 + action 0 + 589 : 1 +state 473 + action 0 + 590 : 1 +state 474 + action 0 + 591 : 1 +state 475 + action 0 + 592 : 1 +state 476 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 477 observe0Greater1 observeOnlyTrueSender + action 0 + 598 : 1 +state 478 observe1Greater1 observeIGreater1 + action 0 + 599 : 0.833 + 600 : 0.167 +state 479 + action 0 + 601 : 0.833 + 602 : 0.167 +state 480 + action 0 + 603 : 0.833 + 604 : 0.167 +state 481 + action 0 + 605 : 0.833 + 606 : 0.167 +state 482 + action 0 + 317 : 0.833 + 318 : 0.167 +state 483 + action 0 + 607 : 1 +state 484 + action 0 + 608 : 0.833 + 609 : 0.167 +state 485 + action 0 + 610 : 1 +state 486 + action 0 + 611 : 0.833 + 612 : 0.167 +state 487 + action 0 + 613 : 1 +state 488 + action 0 + 614 : 0.833 + 615 : 0.167 +state 489 + action 0 + 616 : 1 +state 490 + action 0 + 617 : 0.833 + 618 : 0.167 +state 491 + action 0 + 619 : 1 +state 492 observe0Greater1 observeOnlyTrueSender + action 0 + 620 : 1 +state 493 observe2Greater1 observeIGreater1 + action 0 + 621 : 0.833 + 622 : 0.167 +state 494 + action 0 + 623 : 0.833 + 624 : 0.167 +state 495 + action 0 + 625 : 0.833 + 626 : 0.167 +state 496 + action 0 + 324 : 0.833 + 325 : 0.167 +state 497 + action 0 + 627 : 1 +state 498 + action 0 + 628 : 0.833 + 629 : 0.167 +state 499 + action 0 + 630 : 1 +state 500 + action 0 + 631 : 0.833 + 632 : 0.167 +state 501 + action 0 + 633 : 1 +state 502 + action 0 + 634 : 0.833 + 635 : 0.167 +state 503 + action 0 + 636 : 1 +state 504 + action 0 + 637 : 0.833 + 638 : 0.167 +state 505 + action 0 + 639 : 1 +state 506 observe0Greater1 observeOnlyTrueSender + action 0 + 640 : 1 +state 507 observe3Greater1 observeIGreater1 + action 0 + 641 : 0.833 + 642 : 0.167 +state 508 + action 0 + 643 : 0.833 + 644 : 0.167 +state 509 + action 0 + 331 : 0.833 + 332 : 0.167 +state 510 + action 0 + 645 : 1 +state 511 + action 0 + 646 : 0.833 + 647 : 0.167 +state 512 + action 0 + 648 : 1 +state 513 + action 0 + 649 : 0.833 + 650 : 0.167 +state 514 + action 0 + 651 : 1 +state 515 + action 0 + 652 : 0.833 + 653 : 0.167 +state 516 + action 0 + 654 : 1 +state 517 + action 0 + 655 : 0.833 + 656 : 0.167 +state 518 + action 0 + 657 : 1 +state 519 observe0Greater1 observeOnlyTrueSender + action 0 + 658 : 1 +state 520 observe4Greater1 observeIGreater1 + action 0 + 659 : 0.833 + 660 : 0.167 +state 521 + action 0 + 338 : 0.833 + 339 : 0.167 +state 522 + action 0 + 661 : 1 +state 523 + action 0 + 662 : 0.833 + 663 : 0.167 +state 524 + action 0 + 664 : 1 +state 525 + action 0 + 665 : 0.833 + 666 : 0.167 +state 526 + action 0 + 667 : 1 +state 527 + action 0 + 668 : 0.833 + 669 : 0.167 +state 528 + action 0 + 670 : 1 +state 529 + action 0 + 671 : 0.833 + 672 : 0.167 +state 530 + action 0 + 673 : 1 +state 531 observe0Greater1 observeOnlyTrueSender + action 0 + 674 : 1 +state 532 observe0Greater1 observeOnlyTrueSender + action 0 + 620 : 1 +state 533 observe0Greater1 observeOnlyTrueSender + action 0 + 640 : 1 +state 534 observe0Greater1 observeOnlyTrueSender + action 0 + 658 : 1 +state 535 observe0Greater1 observeOnlyTrueSender + action 0 + 674 : 1 +state 536 observe0Greater1 observeOnlyTrueSender + action 0 + 675 : 0.8 + 676 : 0.2 +state 537 observe0Greater1 observeOnlyTrueSender + action 0 + 677 : 0.8 + 678 : 0.2 +state 538 observe0Greater1 observeOnlyTrueSender + action 0 + 679 : 0.8 + 680 : 0.2 +state 539 observe0Greater1 observeOnlyTrueSender + action 0 + 681 : 0.8 + 682 : 0.2 +state 540 observe0Greater1 observeOnlyTrueSender + action 0 + 683 : 0.8 + 684 : 0.2 +state 541 observe0Greater1 observeOnlyTrueSender + action 0 + 685 : 1 +state 542 + action 0 + 686 : 0.833 + 687 : 0.167 +state 543 + action 0 + 688 : 1 +state 544 + action 0 + 689 : 1 +state 545 + action 0 + 690 : 1 +state 546 + action 0 + 691 : 1 +state 547 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 548 + action 0 + 697 : 1 +state 549 + action 0 + 698 : 1 +state 550 + action 0 + 699 : 0.833 + 700 : 0.167 +state 551 + action 0 + 701 : 1 +state 552 + action 0 + 702 : 0.833 + 703 : 0.167 +state 553 + action 0 + 704 : 1 +state 554 + action 0 + 705 : 0.833 + 706 : 0.167 +state 555 + action 0 + 707 : 1 +state 556 + action 0 + 708 : 0.833 + 709 : 0.167 +state 557 + action 0 + 710 : 1 +state 558 + action 0 + 711 : 1 +state 559 + action 0 + 712 : 1 +state 560 + action 0 + 713 : 0.833 + 714 : 0.167 +state 561 + action 0 + 715 : 1 +state 562 + action 0 + 716 : 0.833 + 717 : 0.167 +state 563 + action 0 + 718 : 1 +state 564 + action 0 + 719 : 0.833 + 720 : 0.167 +state 565 + action 0 + 721 : 1 +state 566 + action 0 + 722 : 0.833 + 723 : 0.167 +state 567 + action 0 + 724 : 1 +state 568 + action 0 + 725 : 1 +state 569 + action 0 + 726 : 1 +state 570 + action 0 + 727 : 0.833 + 728 : 0.167 +state 571 + action 0 + 729 : 1 +state 572 + action 0 + 730 : 0.833 + 731 : 0.167 +state 573 + action 0 + 732 : 1 +state 574 + action 0 + 733 : 0.833 + 734 : 0.167 +state 575 + action 0 + 735 : 1 +state 576 + action 0 + 736 : 0.833 + 737 : 0.167 +state 577 + action 0 + 738 : 1 +state 578 + action 0 + 739 : 1 +state 579 + action 0 + 740 : 1 +state 580 + action 0 + 741 : 0.833 + 742 : 0.167 +state 581 + action 0 + 743 : 1 +state 582 + action 0 + 744 : 0.833 + 745 : 0.167 +state 583 + action 0 + 746 : 1 +state 584 + action 0 + 747 : 0.833 + 748 : 0.167 +state 585 + action 0 + 749 : 1 +state 586 + action 0 + 750 : 0.833 + 751 : 0.167 +state 587 + action 0 + 752 : 1 +state 588 + action 0 + 753 : 1 +state 589 + action 0 + 711 : 1 +state 590 + action 0 + 725 : 1 +state 591 + action 0 + 739 : 1 +state 592 + action 0 + 753 : 1 +state 593 observe0Greater1 observeOnlyTrueSender + action 0 + 426 : 0.8 + 754 : 0.2 +state 594 observe0Greater1 observeOnlyTrueSender + action 0 + 755 : 0.8 + 756 : 0.2 +state 595 observe0Greater1 observeOnlyTrueSender + action 0 + 757 : 0.8 + 758 : 0.2 +state 596 observe0Greater1 observeOnlyTrueSender + action 0 + 759 : 0.8 + 760 : 0.2 +state 597 observe0Greater1 observeOnlyTrueSender + action 0 + 761 : 0.8 + 762 : 0.2 +state 598 observe0Greater1 observeOnlyTrueSender + action 0 + 763 : 1 +state 599 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 600 observe1Greater1 observeIGreater1 + action 0 + 769 : 1 +state 601 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 602 + action 0 + 775 : 1 +state 603 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 604 + action 0 + 781 : 1 +state 605 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 606 + action 0 + 787 : 1 +state 607 + action 0 + 788 : 1 +state 608 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 609 + action 0 + 789 : 1 +state 610 + action 0 + 788 : 1 +state 611 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 612 + action 0 + 790 : 1 +state 613 + action 0 + 788 : 1 +state 614 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 615 + action 0 + 791 : 1 +state 616 + action 0 + 788 : 1 +state 617 + action 0 + 390 : 0.2 + 391 : 0.2 + 392 : 0.2 + 393 : 0.2 + 394 : 0.2 +state 618 + action 0 + 792 : 1 +state 619 + action 0 + 788 : 1 +state 620 observe0Greater1 observeOnlyTrueSender + action 0 + 793 : 0.833 + 794 : 0.167 +state 621 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 622 observe2Greater1 observeIGreater1 + action 0 + 800 : 1 +state 623 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 624 + action 0 + 806 : 1 +state 625 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 626 + action 0 + 812 : 1 +state 627 + action 0 + 813 : 1 +state 628 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 629 + action 0 + 814 : 1 +state 630 + action 0 + 813 : 1 +state 631 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 632 + action 0 + 815 : 1 +state 633 + action 0 + 813 : 1 +state 634 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 635 + action 0 + 816 : 1 +state 636 + action 0 + 813 : 1 +state 637 + action 0 + 400 : 0.2 + 401 : 0.2 + 402 : 0.2 + 403 : 0.2 + 404 : 0.2 +state 638 + action 0 + 817 : 1 +state 639 + action 0 + 813 : 1 +state 640 observe0Greater1 observeOnlyTrueSender + action 0 + 818 : 0.833 + 819 : 0.167 +state 641 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 642 observe3Greater1 observeIGreater1 + action 0 + 825 : 1 +state 643 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 644 + action 0 + 831 : 1 +state 645 + action 0 + 832 : 1 +state 646 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 647 + action 0 + 833 : 1 +state 648 + action 0 + 832 : 1 +state 649 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 650 + action 0 + 834 : 1 +state 651 + action 0 + 832 : 1 +state 652 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 653 + action 0 + 835 : 1 +state 654 + action 0 + 832 : 1 +state 655 + action 0 + 410 : 0.2 + 411 : 0.2 + 412 : 0.2 + 413 : 0.2 + 414 : 0.2 +state 656 + action 0 + 836 : 1 +state 657 + action 0 + 832 : 1 +state 658 observe0Greater1 observeOnlyTrueSender + action 0 + 837 : 0.833 + 838 : 0.167 +state 659 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 660 observe4Greater1 observeIGreater1 + action 0 + 844 : 1 +state 661 + action 0 + 845 : 1 +state 662 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 663 + action 0 + 846 : 1 +state 664 + action 0 + 845 : 1 +state 665 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 666 + action 0 + 847 : 1 +state 667 + action 0 + 845 : 1 +state 668 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 669 + action 0 + 848 : 1 +state 670 + action 0 + 845 : 1 +state 671 + action 0 + 420 : 0.2 + 421 : 0.2 + 422 : 0.2 + 423 : 0.2 + 424 : 0.2 +state 672 + action 0 + 849 : 1 +state 673 + action 0 + 845 : 1 +state 674 observe0Greater1 observeOnlyTrueSender + action 0 + 850 : 0.833 + 851 : 0.167 +state 675 observe0Greater1 observeOnlyTrueSender + action 0 + 431 : 0.833 + 432 : 0.167 +state 676 observe0Greater1 observeOnlyTrueSender + action 0 + 852 : 1 +state 677 observe0Greater1 observeOnlyTrueSender + action 0 + 853 : 0.833 + 854 : 0.167 +state 678 observe0Greater1 observeOnlyTrueSender + action 0 + 855 : 1 +state 679 observe0Greater1 observeOnlyTrueSender + action 0 + 856 : 0.833 + 857 : 0.167 +state 680 observe0Greater1 observeOnlyTrueSender + action 0 + 858 : 1 +state 681 observe0Greater1 observeOnlyTrueSender + action 0 + 859 : 0.833 + 860 : 0.167 +state 682 observe0Greater1 observeOnlyTrueSender + action 0 + 861 : 1 +state 683 observe0Greater1 observeOnlyTrueSender + action 0 + 862 : 0.833 + 863 : 0.167 +state 684 observe0Greater1 observeOnlyTrueSender + action 0 + 864 : 1 +state 685 observe0Greater1 observeOnlyTrueSender + action 0 + 865 : 1 +state 686 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 687 + action 0 + 871 : 1 +state 688 + action 0 + 872 : 1 +state 689 + action 0 + 873 : 1 +state 690 + action 0 + 874 : 1 +state 691 + action 0 + 875 : 1 +state 692 + action 0 + 471 : 0.8 + 876 : 0.2 +state 693 + action 0 + 877 : 0.8 + 878 : 0.2 +state 694 + action 0 + 879 : 0.8 + 880 : 0.2 +state 695 + action 0 + 881 : 0.8 + 882 : 0.2 +state 696 + action 0 + 883 : 0.8 + 884 : 0.2 +state 697 observe0Greater1 observeOnlyTrueSender + action 0 + 885 : 1 +state 698 + action 0 + 886 : 1 +state 699 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 700 + action 0 + 887 : 1 +state 701 + action 0 + 886 : 1 +state 702 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 703 + action 0 + 888 : 1 +state 704 + action 0 + 886 : 1 +state 705 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 706 + action 0 + 889 : 1 +state 707 + action 0 + 886 : 1 +state 708 + action 0 + 447 : 0.2 + 448 : 0.2 + 449 : 0.2 + 450 : 0.2 + 451 : 0.2 +state 709 + action 0 + 890 : 1 +state 710 + action 0 + 886 : 1 +state 711 + action 0 + 891 : 0.833 + 892 : 0.167 +state 712 + action 0 + 893 : 1 +state 713 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 714 + action 0 + 894 : 1 +state 715 + action 0 + 893 : 1 +state 716 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 717 + action 0 + 895 : 1 +state 718 + action 0 + 893 : 1 +state 719 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 720 + action 0 + 896 : 1 +state 721 + action 0 + 893 : 1 +state 722 + action 0 + 453 : 0.2 + 454 : 0.2 + 455 : 0.2 + 456 : 0.2 + 457 : 0.2 +state 723 + action 0 + 897 : 1 +state 724 + action 0 + 893 : 1 +state 725 + action 0 + 898 : 0.833 + 899 : 0.167 +state 726 + action 0 + 900 : 1 +state 727 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 728 + action 0 + 901 : 1 +state 729 + action 0 + 900 : 1 +state 730 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 731 + action 0 + 902 : 1 +state 732 + action 0 + 900 : 1 +state 733 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 734 + action 0 + 903 : 1 +state 735 + action 0 + 900 : 1 +state 736 + action 0 + 459 : 0.2 + 460 : 0.2 + 461 : 0.2 + 462 : 0.2 + 463 : 0.2 +state 737 + action 0 + 904 : 1 +state 738 + action 0 + 900 : 1 +state 739 + action 0 + 905 : 0.833 + 906 : 0.167 +state 740 + action 0 + 907 : 1 +state 741 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 742 + action 0 + 908 : 1 +state 743 + action 0 + 907 : 1 +state 744 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 745 + action 0 + 909 : 1 +state 746 + action 0 + 907 : 1 +state 747 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 748 + action 0 + 910 : 1 +state 749 + action 0 + 907 : 1 +state 750 + action 0 + 465 : 0.2 + 466 : 0.2 + 467 : 0.2 + 468 : 0.2 + 469 : 0.2 +state 751 + action 0 + 911 : 1 +state 752 + action 0 + 907 : 1 +state 753 + action 0 + 912 : 0.833 + 913 : 0.167 +state 754 observe0Greater1 observeOnlyTrueSender + action 0 + 914 : 1 +state 755 observe0Greater1 observeOnlyTrueSender + action 0 + 915 : 0.833 + 916 : 0.167 +state 756 observe0Greater1 observeOnlyTrueSender + action 0 + 917 : 1 +state 757 observe0Greater1 observeOnlyTrueSender + action 0 + 918 : 0.833 + 919 : 0.167 +state 758 observe0Greater1 observeOnlyTrueSender + action 0 + 920 : 1 +state 759 observe0Greater1 observeOnlyTrueSender + action 0 + 921 : 0.833 + 922 : 0.167 +state 760 observe0Greater1 observeOnlyTrueSender + action 0 + 923 : 1 +state 761 observe0Greater1 observeOnlyTrueSender + action 0 + 924 : 0.833 + 925 : 0.167 +state 762 observe0Greater1 observeOnlyTrueSender + action 0 + 926 : 1 +state 763 observe0Greater1 observeOnlyTrueSender + action 0 + 927 : 1 +state 764 observe1Greater1 observeIGreater1 + action 0 + 928 : 0.8 + 929 : 0.2 +state 765 observe1Greater1 observeIGreater1 + action 0 + 930 : 0.8 + 931 : 0.2 +state 766 observe1Greater1 observeIGreater1 + action 0 + 932 : 0.8 + 933 : 0.2 +state 767 observe1Greater1 observeIGreater1 + action 0 + 934 : 0.8 + 935 : 0.2 +state 768 observe1Greater1 observeIGreater1 + action 0 + 936 : 0.8 + 937 : 0.2 +state 769 observe1Greater1 observeIGreater1 + action 0 + 938 : 1 +state 770 + action 0 + 939 : 0.8 + 940 : 0.2 +state 771 + action 0 + 941 : 0.8 + 942 : 0.2 +state 772 + action 0 + 943 : 0.8 + 944 : 0.2 +state 773 + action 0 + 945 : 0.8 + 946 : 0.2 +state 774 + action 0 + 947 : 0.8 + 948 : 0.2 +state 775 + action 0 + 949 : 1 +state 776 + action 0 + 950 : 0.8 + 951 : 0.2 +state 777 + action 0 + 952 : 0.8 + 953 : 0.2 +state 778 + action 0 + 954 : 0.8 + 955 : 0.2 +state 779 + action 0 + 956 : 0.8 + 957 : 0.2 +state 780 + action 0 + 958 : 0.8 + 959 : 0.2 +state 781 + action 0 + 960 : 1 +state 782 + action 0 + 961 : 0.8 + 962 : 0.2 +state 783 + action 0 + 963 : 0.8 + 964 : 0.2 +state 784 + action 0 + 965 : 0.8 + 966 : 0.2 +state 785 + action 0 + 967 : 0.8 + 968 : 0.2 +state 786 + action 0 + 969 : 0.8 + 970 : 0.2 +state 787 + action 0 + 971 : 1 +state 788 + action 0 + 891 : 0.833 + 892 : 0.167 +state 789 observe1Greater1 observeIGreater1 + action 0 + 972 : 1 +state 790 + action 0 + 973 : 1 +state 791 + action 0 + 974 : 1 +state 792 + action 0 + 975 : 1 +state 793 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 794 observe0Greater1 observeOnlyTrueSender + action 0 + 981 : 1 +state 795 observe2Greater1 observeIGreater1 + action 0 + 982 : 0.8 + 983 : 0.2 +state 796 observe2Greater1 observeIGreater1 + action 0 + 984 : 0.8 + 985 : 0.2 +state 797 observe2Greater1 observeIGreater1 + action 0 + 986 : 0.8 + 987 : 0.2 +state 798 observe2Greater1 observeIGreater1 + action 0 + 988 : 0.8 + 989 : 0.2 +state 799 observe2Greater1 observeIGreater1 + action 0 + 990 : 0.8 + 991 : 0.2 +state 800 observe2Greater1 observeIGreater1 + action 0 + 992 : 1 +state 801 + action 0 + 993 : 0.8 + 994 : 0.2 +state 802 + action 0 + 995 : 0.8 + 996 : 0.2 +state 803 + action 0 + 997 : 0.8 + 998 : 0.2 +state 804 + action 0 + 999 : 0.8 + 1000 : 0.2 +state 805 + action 0 + 1001 : 0.8 + 1002 : 0.2 +state 806 + action 0 + 1003 : 1 +state 807 + action 0 + 1004 : 0.8 + 1005 : 0.2 +state 808 + action 0 + 1006 : 0.8 + 1007 : 0.2 +state 809 + action 0 + 1008 : 0.8 + 1009 : 0.2 +state 810 + action 0 + 1010 : 0.8 + 1011 : 0.2 +state 811 + action 0 + 1012 : 0.8 + 1013 : 0.2 +state 812 + action 0 + 1014 : 1 +state 813 + action 0 + 898 : 0.833 + 899 : 0.167 +state 814 + action 0 + 1015 : 1 +state 815 observe2Greater1 observeIGreater1 + action 0 + 1016 : 1 +state 816 + action 0 + 1017 : 1 +state 817 + action 0 + 1018 : 1 +state 818 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 819 observe0Greater1 observeOnlyTrueSender + action 0 + 1024 : 1 +state 820 observe3Greater1 observeIGreater1 + action 0 + 1025 : 0.8 + 1026 : 0.2 +state 821 observe3Greater1 observeIGreater1 + action 0 + 1027 : 0.8 + 1028 : 0.2 +state 822 observe3Greater1 observeIGreater1 + action 0 + 1029 : 0.8 + 1030 : 0.2 +state 823 observe3Greater1 observeIGreater1 + action 0 + 1031 : 0.8 + 1032 : 0.2 +state 824 observe3Greater1 observeIGreater1 + action 0 + 1033 : 0.8 + 1034 : 0.2 +state 825 observe3Greater1 observeIGreater1 + action 0 + 1035 : 1 +state 826 + action 0 + 1036 : 0.8 + 1037 : 0.2 +state 827 + action 0 + 1038 : 0.8 + 1039 : 0.2 +state 828 + action 0 + 1040 : 0.8 + 1041 : 0.2 +state 829 + action 0 + 1042 : 0.8 + 1043 : 0.2 +state 830 + action 0 + 1044 : 0.8 + 1045 : 0.2 +state 831 + action 0 + 1046 : 1 +state 832 + action 0 + 905 : 0.833 + 906 : 0.167 +state 833 + action 0 + 1047 : 1 +state 834 + action 0 + 1048 : 1 +state 835 observe3Greater1 observeIGreater1 + action 0 + 1049 : 1 +state 836 + action 0 + 1050 : 1 +state 837 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 838 observe0Greater1 observeOnlyTrueSender + action 0 + 1056 : 1 +state 839 observe4Greater1 observeIGreater1 + action 0 + 1057 : 0.8 + 1058 : 0.2 +state 840 observe4Greater1 observeIGreater1 + action 0 + 1059 : 0.8 + 1060 : 0.2 +state 841 observe4Greater1 observeIGreater1 + action 0 + 1061 : 0.8 + 1062 : 0.2 +state 842 observe4Greater1 observeIGreater1 + action 0 + 1063 : 0.8 + 1064 : 0.2 +state 843 observe4Greater1 observeIGreater1 + action 0 + 1065 : 0.8 + 1066 : 0.2 +state 844 observe4Greater1 observeIGreater1 + action 0 + 1067 : 1 +state 845 + action 0 + 912 : 0.833 + 913 : 0.167 +state 846 + action 0 + 1068 : 1 +state 847 + action 0 + 1069 : 1 +state 848 + action 0 + 1070 : 1 +state 849 observe4Greater1 observeIGreater1 + action 0 + 1071 : 1 +state 850 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 851 observe0Greater1 observeOnlyTrueSender + action 0 + 1077 : 1 +state 852 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 853 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 854 observe0Greater1 observeOnlyTrueSender + action 0 + 1079 : 1 +state 855 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 856 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 857 observe0Greater1 observeOnlyTrueSender + action 0 + 1080 : 1 +state 858 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 859 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 860 observe0Greater1 observeOnlyTrueSender + action 0 + 1081 : 1 +state 861 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 862 observe0Greater1 observeOnlyTrueSender + action 0 + 536 : 0.2 + 537 : 0.2 + 538 : 0.2 + 539 : 0.2 + 540 : 0.2 +state 863 observe0Greater1 observeOnlyTrueSender + action 0 + 1082 : 1 +state 864 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 1 +state 865 observe0Greater1 observeOnlyTrueSender + action 0 + 1083 : 0.833 + 1084 : 0.167 +state 866 + action 0 + 542 : 0.8 + 1085 : 0.2 +state 867 + action 0 + 1086 : 0.8 + 1087 : 0.2 +state 868 + action 0 + 1088 : 0.8 + 1089 : 0.2 +state 869 + action 0 + 1090 : 0.8 + 1091 : 0.2 +state 870 + action 0 + 1092 : 0.8 + 1093 : 0.2 +state 871 + action 0 + 1094 : 1 +state 872 + action 0 + 1095 : 0.833 + 1096 : 0.167 +state 873 + action 0 + 1097 : 0.833 + 1098 : 0.167 +state 874 + action 0 + 1099 : 0.833 + 1100 : 0.167 +state 875 + action 0 + 1101 : 0.833 + 1102 : 0.167 +state 876 + action 0 + 1103 : 1 +state 877 + action 0 + 1104 : 0.833 + 1105 : 0.167 +state 878 + action 0 + 1106 : 1 +state 879 + action 0 + 1107 : 0.833 + 1108 : 0.167 +state 880 + action 0 + 1109 : 1 +state 881 + action 0 + 1110 : 0.833 + 1111 : 0.167 +state 882 + action 0 + 1112 : 1 +state 883 + action 0 + 1113 : 0.833 + 1114 : 0.167 +state 884 + action 0 + 1115 : 1 +state 885 observe0Greater1 observeOnlyTrueSender + action 0 + 1116 : 1 +state 886 + action 0 + 1095 : 0.833 + 1096 : 0.167 +state 887 observe1Greater1 observeIGreater1 + action 0 + 1117 : 1 +state 888 + action 0 + 1118 : 1 +state 889 + action 0 + 1119 : 1 +state 890 + action 0 + 1120 : 1 +state 891 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 892 + action 0 + 1126 : 1 +state 893 + action 0 + 1097 : 0.833 + 1098 : 0.167 +state 894 + action 0 + 1127 : 1 +state 895 observe2Greater1 observeIGreater1 + action 0 + 1128 : 1 +state 896 + action 0 + 1129 : 1 +state 897 + action 0 + 1130 : 1 +state 898 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 899 + action 0 + 1136 : 1 +state 900 + action 0 + 1099 : 0.833 + 1100 : 0.167 +state 901 + action 0 + 1137 : 1 +state 902 + action 0 + 1138 : 1 +state 903 observe3Greater1 observeIGreater1 + action 0 + 1139 : 1 +state 904 + action 0 + 1140 : 1 +state 905 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 906 + action 0 + 1146 : 1 +state 907 + action 0 + 1101 : 0.833 + 1102 : 0.167 +state 908 + action 0 + 1147 : 1 +state 909 + action 0 + 1148 : 1 +state 910 + action 0 + 1149 : 1 +state 911 observe4Greater1 observeIGreater1 + action 0 + 1150 : 1 +state 912 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 913 + action 0 + 1156 : 1 +state 914 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 915 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 916 observe0Greater1 observeOnlyTrueSender + action 0 + 1158 : 1 +state 917 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 918 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 919 observe0Greater1 observeOnlyTrueSender + action 0 + 1159 : 1 +state 920 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 921 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 922 observe0Greater1 observeOnlyTrueSender + action 0 + 1160 : 1 +state 923 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 924 observe0Greater1 observeOnlyTrueSender + action 0 + 593 : 0.2 + 594 : 0.2 + 595 : 0.2 + 596 : 0.2 + 597 : 0.2 +state 925 observe0Greater1 observeOnlyTrueSender + action 0 + 1161 : 1 +state 926 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 1 +state 927 observe0Greater1 observeOnlyTrueSender + action 0 + 1162 : 0.833 + 1163 : 0.167 +state 928 observe1Greater1 observeIGreater1 + action 0 + 599 : 0.833 + 600 : 0.167 +state 929 observe1Greater1 observeIGreater1 + action 0 + 1164 : 1 +state 930 observe1Greater1 observeIGreater1 + action 0 + 1165 : 0.833 + 1166 : 0.167 +state 931 observe1Greater1 observeIGreater1 + action 0 + 1167 : 1 +state 932 observe1Greater1 observeIGreater1 + action 0 + 1168 : 0.833 + 1169 : 0.167 +state 933 observe1Greater1 observeIGreater1 + action 0 + 1170 : 1 +state 934 observe1Greater1 observeIGreater1 + action 0 + 1171 : 0.833 + 1172 : 0.167 +state 935 observe1Greater1 observeIGreater1 + action 0 + 1173 : 1 +state 936 observe1Greater1 observeIGreater1 + action 0 + 1174 : 0.833 + 1175 : 0.167 +state 937 observe1Greater1 observeIGreater1 + action 0 + 1176 : 1 +state 938 observe1Greater1 observeIGreater1 + action 0 + 1177 : 1 +state 939 + action 0 + 601 : 0.833 + 602 : 0.167 +state 940 + action 0 + 1178 : 1 +state 941 + action 0 + 1179 : 0.833 + 1180 : 0.167 +state 942 + action 0 + 1181 : 1 +state 943 + action 0 + 1182 : 0.833 + 1183 : 0.167 +state 944 + action 0 + 1184 : 1 +state 945 + action 0 + 1185 : 0.833 + 1186 : 0.167 +state 946 + action 0 + 1187 : 1 +state 947 + action 0 + 1188 : 0.833 + 1189 : 0.167 +state 948 + action 0 + 1190 : 1 +state 949 + action 0 + 1191 : 1 +state 950 + action 0 + 603 : 0.833 + 604 : 0.167 +state 951 + action 0 + 1192 : 1 +state 952 + action 0 + 1193 : 0.833 + 1194 : 0.167 +state 953 + action 0 + 1195 : 1 +state 954 + action 0 + 1196 : 0.833 + 1197 : 0.167 +state 955 + action 0 + 1198 : 1 +state 956 + action 0 + 1199 : 0.833 + 1200 : 0.167 +state 957 + action 0 + 1201 : 1 +state 958 + action 0 + 1202 : 0.833 + 1203 : 0.167 +state 959 + action 0 + 1204 : 1 +state 960 + action 0 + 1205 : 1 +state 961 + action 0 + 605 : 0.833 + 606 : 0.167 +state 962 + action 0 + 1206 : 1 +state 963 + action 0 + 1207 : 0.833 + 1208 : 0.167 +state 964 + action 0 + 1209 : 1 +state 965 + action 0 + 1210 : 0.833 + 1211 : 0.167 +state 966 + action 0 + 1212 : 1 +state 967 + action 0 + 1213 : 0.833 + 1214 : 0.167 +state 968 + action 0 + 1215 : 1 +state 969 + action 0 + 1216 : 0.833 + 1217 : 0.167 +state 970 + action 0 + 1218 : 1 +state 971 + action 0 + 1219 : 1 +state 972 observe1Greater1 observeIGreater1 + action 0 + 1177 : 1 +state 973 + action 0 + 1191 : 1 +state 974 + action 0 + 1205 : 1 +state 975 + action 0 + 1219 : 1 +state 976 observe0Greater1 observeOnlyTrueSender + action 0 + 1220 : 0.8 + 1221 : 0.2 +state 977 observe0Greater1 observeOnlyTrueSender + action 0 + 1222 : 0.8 + 1223 : 0.2 +state 978 observe0Greater1 observeOnlyTrueSender + action 0 + 1224 : 0.8 + 1225 : 0.2 +state 979 observe0Greater1 observeOnlyTrueSender + action 0 + 1226 : 0.8 + 1227 : 0.2 +state 980 observe0Greater1 observeOnlyTrueSender + action 0 + 1228 : 0.8 + 1229 : 0.2 +state 981 observe0Greater1 observeOnlyTrueSender + action 0 + 1230 : 1 +state 982 observe2Greater1 observeIGreater1 + action 0 + 621 : 0.833 + 622 : 0.167 +state 983 observe2Greater1 observeIGreater1 + action 0 + 1231 : 1 +state 984 observe2Greater1 observeIGreater1 + action 0 + 1232 : 0.833 + 1233 : 0.167 +state 985 observe2Greater1 observeIGreater1 + action 0 + 1234 : 1 +state 986 observe2Greater1 observeIGreater1 + action 0 + 1235 : 0.833 + 1236 : 0.167 +state 987 observe2Greater1 observeIGreater1 + action 0 + 1237 : 1 +state 988 observe2Greater1 observeIGreater1 + action 0 + 1238 : 0.833 + 1239 : 0.167 +state 989 observe2Greater1 observeIGreater1 + action 0 + 1240 : 1 +state 990 observe2Greater1 observeIGreater1 + action 0 + 1241 : 0.833 + 1242 : 0.167 +state 991 observe2Greater1 observeIGreater1 + action 0 + 1243 : 1 +state 992 observe2Greater1 observeIGreater1 + action 0 + 1244 : 1 +state 993 + action 0 + 623 : 0.833 + 624 : 0.167 +state 994 + action 0 + 1245 : 1 +state 995 + action 0 + 1246 : 0.833 + 1247 : 0.167 +state 996 + action 0 + 1248 : 1 +state 997 + action 0 + 1249 : 0.833 + 1250 : 0.167 +state 998 + action 0 + 1251 : 1 +state 999 + action 0 + 1252 : 0.833 + 1253 : 0.167 +state 1000 + action 0 + 1254 : 1 +state 1001 + action 0 + 1255 : 0.833 + 1256 : 0.167 +state 1002 + action 0 + 1257 : 1 +state 1003 + action 0 + 1258 : 1 +state 1004 + action 0 + 625 : 0.833 + 626 : 0.167 +state 1005 + action 0 + 1259 : 1 +state 1006 + action 0 + 1260 : 0.833 + 1261 : 0.167 +state 1007 + action 0 + 1262 : 1 +state 1008 + action 0 + 1263 : 0.833 + 1264 : 0.167 +state 1009 + action 0 + 1265 : 1 +state 1010 + action 0 + 1266 : 0.833 + 1267 : 0.167 +state 1011 + action 0 + 1268 : 1 +state 1012 + action 0 + 1269 : 0.833 + 1270 : 0.167 +state 1013 + action 0 + 1271 : 1 +state 1014 + action 0 + 1272 : 1 +state 1015 + action 0 + 1191 : 1 +state 1016 observe2Greater1 observeIGreater1 + action 0 + 1244 : 1 +state 1017 + action 0 + 1258 : 1 +state 1018 + action 0 + 1272 : 1 +state 1019 observe0Greater1 observeOnlyTrueSender + action 0 + 1273 : 0.8 + 1274 : 0.2 +state 1020 observe0Greater1 observeOnlyTrueSender + action 0 + 1275 : 0.8 + 1276 : 0.2 +state 1021 observe0Greater1 observeOnlyTrueSender + action 0 + 1277 : 0.8 + 1278 : 0.2 +state 1022 observe0Greater1 observeOnlyTrueSender + action 0 + 1279 : 0.8 + 1280 : 0.2 +state 1023 observe0Greater1 observeOnlyTrueSender + action 0 + 1281 : 0.8 + 1282 : 0.2 +state 1024 observe0Greater1 observeOnlyTrueSender + action 0 + 1283 : 1 +state 1025 observe3Greater1 observeIGreater1 + action 0 + 641 : 0.833 + 642 : 0.167 +state 1026 observe3Greater1 observeIGreater1 + action 0 + 1284 : 1 +state 1027 observe3Greater1 observeIGreater1 + action 0 + 1285 : 0.833 + 1286 : 0.167 +state 1028 observe3Greater1 observeIGreater1 + action 0 + 1287 : 1 +state 1029 observe3Greater1 observeIGreater1 + action 0 + 1288 : 0.833 + 1289 : 0.167 +state 1030 observe3Greater1 observeIGreater1 + action 0 + 1290 : 1 +state 1031 observe3Greater1 observeIGreater1 + action 0 + 1291 : 0.833 + 1292 : 0.167 +state 1032 observe3Greater1 observeIGreater1 + action 0 + 1293 : 1 +state 1033 observe3Greater1 observeIGreater1 + action 0 + 1294 : 0.833 + 1295 : 0.167 +state 1034 observe3Greater1 observeIGreater1 + action 0 + 1296 : 1 +state 1035 observe3Greater1 observeIGreater1 + action 0 + 1297 : 1 +state 1036 + action 0 + 643 : 0.833 + 644 : 0.167 +state 1037 + action 0 + 1298 : 1 +state 1038 + action 0 + 1299 : 0.833 + 1300 : 0.167 +state 1039 + action 0 + 1301 : 1 +state 1040 + action 0 + 1302 : 0.833 + 1303 : 0.167 +state 1041 + action 0 + 1304 : 1 +state 1042 + action 0 + 1305 : 0.833 + 1306 : 0.167 +state 1043 + action 0 + 1307 : 1 +state 1044 + action 0 + 1308 : 0.833 + 1309 : 0.167 +state 1045 + action 0 + 1310 : 1 +state 1046 + action 0 + 1311 : 1 +state 1047 + action 0 + 1205 : 1 +state 1048 + action 0 + 1258 : 1 +state 1049 observe3Greater1 observeIGreater1 + action 0 + 1297 : 1 +state 1050 + action 0 + 1311 : 1 +state 1051 observe0Greater1 observeOnlyTrueSender + action 0 + 1312 : 0.8 + 1313 : 0.2 +state 1052 observe0Greater1 observeOnlyTrueSender + action 0 + 1314 : 0.8 + 1315 : 0.2 +state 1053 observe0Greater1 observeOnlyTrueSender + action 0 + 1316 : 0.8 + 1317 : 0.2 +state 1054 observe0Greater1 observeOnlyTrueSender + action 0 + 1318 : 0.8 + 1319 : 0.2 +state 1055 observe0Greater1 observeOnlyTrueSender + action 0 + 1320 : 0.8 + 1321 : 0.2 +state 1056 observe0Greater1 observeOnlyTrueSender + action 0 + 1322 : 1 +state 1057 observe4Greater1 observeIGreater1 + action 0 + 659 : 0.833 + 660 : 0.167 +state 1058 observe4Greater1 observeIGreater1 + action 0 + 1323 : 1 +state 1059 observe4Greater1 observeIGreater1 + action 0 + 1324 : 0.833 + 1325 : 0.167 +state 1060 observe4Greater1 observeIGreater1 + action 0 + 1326 : 1 +state 1061 observe4Greater1 observeIGreater1 + action 0 + 1327 : 0.833 + 1328 : 0.167 +state 1062 observe4Greater1 observeIGreater1 + action 0 + 1329 : 1 +state 1063 observe4Greater1 observeIGreater1 + action 0 + 1330 : 0.833 + 1331 : 0.167 +state 1064 observe4Greater1 observeIGreater1 + action 0 + 1332 : 1 +state 1065 observe4Greater1 observeIGreater1 + action 0 + 1333 : 0.833 + 1334 : 0.167 +state 1066 observe4Greater1 observeIGreater1 + action 0 + 1335 : 1 +state 1067 observe4Greater1 observeIGreater1 + action 0 + 1336 : 1 +state 1068 + action 0 + 1219 : 1 +state 1069 + action 0 + 1272 : 1 +state 1070 + action 0 + 1311 : 1 +state 1071 observe4Greater1 observeIGreater1 + action 0 + 1336 : 1 +state 1072 observe0Greater1 observeOnlyTrueSender + action 0 + 1337 : 0.8 + 1338 : 0.2 +state 1073 observe0Greater1 observeOnlyTrueSender + action 0 + 1339 : 0.8 + 1340 : 0.2 +state 1074 observe0Greater1 observeOnlyTrueSender + action 0 + 1341 : 0.8 + 1342 : 0.2 +state 1075 observe0Greater1 observeOnlyTrueSender + action 0 + 1343 : 0.8 + 1344 : 0.2 +state 1076 observe0Greater1 observeOnlyTrueSender + action 0 + 1345 : 0.8 + 1346 : 0.2 +state 1077 observe0Greater1 observeOnlyTrueSender + action 0 + 1347 : 1 +state 1078 observe0Greater1 observeOnlyTrueSender + action 0 + 1162 : 0.833 + 1163 : 0.167 +state 1079 observe0Greater1 observeOnlyTrueSender + action 0 + 1348 : 1 +state 1080 observe0Greater1 observeOnlyTrueSender + action 0 + 1349 : 1 +state 1081 observe0Greater1 observeOnlyTrueSender + action 0 + 1350 : 1 +state 1082 observe0Greater1 observeOnlyTrueSender + action 0 + 1351 : 1 +state 1083 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1084 observe0Greater1 observeOnlyTrueSender + action 0 + 1357 : 1 +state 1085 + action 0 + 1358 : 1 +state 1086 + action 0 + 1359 : 0.833 + 1360 : 0.167 +state 1087 + action 0 + 1361 : 1 +state 1088 + action 0 + 1362 : 0.833 + 1363 : 0.167 +state 1089 + action 0 + 1364 : 1 +state 1090 + action 0 + 1365 : 0.833 + 1366 : 0.167 +state 1091 + action 0 + 1367 : 1 +state 1092 + action 0 + 1368 : 0.833 + 1369 : 0.167 +state 1093 + action 0 + 1370 : 1 +state 1094 + action 0 + 1371 : 1 +state 1095 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1096 + action 0 + 1377 : 1 +state 1097 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1098 + action 0 + 1383 : 1 +state 1099 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1100 + action 0 + 1389 : 1 +state 1101 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1102 + action 0 + 1395 : 1 +state 1103 + action 0 + 1396 : 1 +state 1104 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1105 + action 0 + 1397 : 1 +state 1106 + action 0 + 1396 : 1 +state 1107 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1108 + action 0 + 1398 : 1 +state 1109 + action 0 + 1396 : 1 +state 1110 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1111 + action 0 + 1399 : 1 +state 1112 + action 0 + 1396 : 1 +state 1113 + action 0 + 692 : 0.2 + 693 : 0.2 + 694 : 0.2 + 695 : 0.2 + 696 : 0.2 +state 1114 + action 0 + 1400 : 1 +state 1115 + action 0 + 1396 : 1 +state 1116 observe0Greater1 observeOnlyTrueSender + action 0 + 1401 : 0.833 + 1402 : 0.167 +state 1117 observe1Greater1 observeIGreater1 + action 0 + 1403 : 1 +state 1118 + action 0 + 1404 : 1 +state 1119 + action 0 + 1405 : 1 +state 1120 + action 0 + 1406 : 1 +state 1121 + action 0 + 788 : 0.8 + 1407 : 0.2 +state 1122 + action 0 + 1408 : 0.8 + 1409 : 0.2 +state 1123 + action 0 + 1410 : 0.8 + 1411 : 0.2 +state 1124 + action 0 + 1412 : 0.8 + 1413 : 0.2 +state 1125 + action 0 + 1414 : 0.8 + 1415 : 0.2 +state 1126 observe0Greater1 observeOnlyTrueSender + action 0 + 1416 : 1 +state 1127 + action 0 + 1404 : 1 +state 1128 observe2Greater1 observeIGreater1 + action 0 + 1417 : 1 +state 1129 + action 0 + 1418 : 1 +state 1130 + action 0 + 1419 : 1 +state 1131 + action 0 + 813 : 0.8 + 1420 : 0.2 +state 1132 + action 0 + 1421 : 0.8 + 1422 : 0.2 +state 1133 + action 0 + 1423 : 0.8 + 1424 : 0.2 +state 1134 + action 0 + 1425 : 0.8 + 1426 : 0.2 +state 1135 + action 0 + 1427 : 0.8 + 1428 : 0.2 +state 1136 observe0Greater1 observeOnlyTrueSender + action 0 + 1429 : 1 +state 1137 + action 0 + 1405 : 1 +state 1138 + action 0 + 1418 : 1 +state 1139 observe3Greater1 observeIGreater1 + action 0 + 1430 : 1 +state 1140 + action 0 + 1431 : 1 +state 1141 + action 0 + 832 : 0.8 + 1432 : 0.2 +state 1142 + action 0 + 1433 : 0.8 + 1434 : 0.2 +state 1143 + action 0 + 1435 : 0.8 + 1436 : 0.2 +state 1144 + action 0 + 1437 : 0.8 + 1438 : 0.2 +state 1145 + action 0 + 1439 : 0.8 + 1440 : 0.2 +state 1146 observe0Greater1 observeOnlyTrueSender + action 0 + 1441 : 1 +state 1147 + action 0 + 1406 : 1 +state 1148 + action 0 + 1419 : 1 +state 1149 + action 0 + 1431 : 1 +state 1150 observe4Greater1 observeIGreater1 + action 0 + 1442 : 1 +state 1151 + action 0 + 845 : 0.8 + 1443 : 0.2 +state 1152 + action 0 + 1444 : 0.8 + 1445 : 0.2 +state 1153 + action 0 + 1446 : 0.8 + 1447 : 0.2 +state 1154 + action 0 + 1448 : 0.8 + 1449 : 0.2 +state 1155 + action 0 + 1450 : 0.8 + 1451 : 0.2 +state 1156 observe0Greater1 observeOnlyTrueSender + action 0 + 1452 : 1 +state 1157 observe0Greater1 observeOnlyTrueSender + action 0 + 1401 : 0.833 + 1402 : 0.167 +state 1158 observe0Greater1 observeOnlyTrueSender + action 0 + 1453 : 1 +state 1159 observe0Greater1 observeOnlyTrueSender + action 0 + 1454 : 1 +state 1160 observe0Greater1 observeOnlyTrueSender + action 0 + 1455 : 1 +state 1161 observe0Greater1 observeOnlyTrueSender + action 0 + 1456 : 1 +state 1162 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 1163 observe0Greater1 observeOnlyTrueSender + action 0 + 1462 : 1 +state 1164 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1165 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1166 observe1Greater1 observeIGreater1 + action 0 + 1464 : 1 +state 1167 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1168 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1169 observe1Greater1 observeIGreater1 + action 0 + 1465 : 1 +state 1170 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1171 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1172 observe1Greater1 observeIGreater1 + action 0 + 1466 : 1 +state 1173 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1174 observe1Greater1 observeIGreater1 + action 0 + 764 : 0.2 + 765 : 0.2 + 766 : 0.2 + 767 : 0.2 + 768 : 0.2 +state 1175 observe1Greater1 observeIGreater1 + action 0 + 1467 : 1 +state 1176 observe1Greater1 observeIGreater1 + action 0 + 1463 : 1 +state 1177 observe1Greater1 observeIGreater1 + action 0 + 1468 : 0.833 + 1469 : 0.167 +state 1178 + action 0 + 1470 : 1 +state 1179 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1180 + action 0 + 1471 : 1 +state 1181 + action 0 + 1470 : 1 +state 1182 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1183 + action 0 + 1472 : 1 +state 1184 + action 0 + 1470 : 1 +state 1185 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1186 + action 0 + 1473 : 1 +state 1187 + action 0 + 1470 : 1 +state 1188 + action 0 + 770 : 0.2 + 771 : 0.2 + 772 : 0.2 + 773 : 0.2 + 774 : 0.2 +state 1189 + action 0 + 1474 : 1 +state 1190 + action 0 + 1470 : 1 +state 1191 + action 0 + 1475 : 0.833 + 1476 : 0.167 +state 1192 + action 0 + 1477 : 1 +state 1193 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1194 + action 0 + 1478 : 1 +state 1195 + action 0 + 1477 : 1 +state 1196 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1197 + action 0 + 1479 : 1 +state 1198 + action 0 + 1477 : 1 +state 1199 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1200 + action 0 + 1480 : 1 +state 1201 + action 0 + 1477 : 1 +state 1202 + action 0 + 776 : 0.2 + 777 : 0.2 + 778 : 0.2 + 779 : 0.2 + 780 : 0.2 +state 1203 + action 0 + 1481 : 1 +state 1204 + action 0 + 1477 : 1 +state 1205 + action 0 + 1482 : 0.833 + 1483 : 0.167 +state 1206 + action 0 + 1484 : 1 +state 1207 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1208 + action 0 + 1485 : 1 +state 1209 + action 0 + 1484 : 1 +state 1210 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1211 + action 0 + 1486 : 1 +state 1212 + action 0 + 1484 : 1 +state 1213 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1214 + action 0 + 1487 : 1 +state 1215 + action 0 + 1484 : 1 +state 1216 + action 0 + 782 : 0.2 + 783 : 0.2 + 784 : 0.2 + 785 : 0.2 + 786 : 0.2 +state 1217 + action 0 + 1488 : 1 +state 1218 + action 0 + 1484 : 1 +state 1219 + action 0 + 1489 : 0.833 + 1490 : 0.167 +state 1220 observe0Greater1 observeOnlyTrueSender + action 0 + 793 : 0.833 + 794 : 0.167 +state 1221 observe0Greater1 observeOnlyTrueSender + action 0 + 1491 : 1 +state 1222 observe0Greater1 observeOnlyTrueSender + action 0 + 1492 : 0.833 + 1493 : 0.167 +state 1223 observe0Greater1 observeOnlyTrueSender + action 0 + 1494 : 1 +state 1224 observe0Greater1 observeOnlyTrueSender + action 0 + 1495 : 0.833 + 1496 : 0.167 +state 1225 observe0Greater1 observeOnlyTrueSender + action 0 + 1497 : 1 +state 1226 observe0Greater1 observeOnlyTrueSender + action 0 + 1498 : 0.833 + 1499 : 0.167 +state 1227 observe0Greater1 observeOnlyTrueSender + action 0 + 1500 : 1 +state 1228 observe0Greater1 observeOnlyTrueSender + action 0 + 1501 : 0.833 + 1502 : 0.167 +state 1229 observe0Greater1 observeOnlyTrueSender + action 0 + 1503 : 1 +state 1230 observe0Greater1 observeOnlyTrueSender + action 0 + 1504 : 1 +state 1231 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1232 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1233 observe2Greater1 observeIGreater1 + action 0 + 1506 : 1 +state 1234 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1235 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1236 observe2Greater1 observeIGreater1 + action 0 + 1507 : 1 +state 1237 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1238 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1239 observe2Greater1 observeIGreater1 + action 0 + 1508 : 1 +state 1240 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1241 observe2Greater1 observeIGreater1 + action 0 + 795 : 0.2 + 796 : 0.2 + 797 : 0.2 + 798 : 0.2 + 799 : 0.2 +state 1242 observe2Greater1 observeIGreater1 + action 0 + 1509 : 1 +state 1243 observe2Greater1 observeIGreater1 + action 0 + 1505 : 1 +state 1244 observe2Greater1 observeIGreater1 + action 0 + 1510 : 0.833 + 1511 : 0.167 +state 1245 + action 0 + 1512 : 1 +state 1246 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1247 + action 0 + 1513 : 1 +state 1248 + action 0 + 1512 : 1 +state 1249 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1250 + action 0 + 1514 : 1 +state 1251 + action 0 + 1512 : 1 +state 1252 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1253 + action 0 + 1515 : 1 +state 1254 + action 0 + 1512 : 1 +state 1255 + action 0 + 801 : 0.2 + 802 : 0.2 + 803 : 0.2 + 804 : 0.2 + 805 : 0.2 +state 1256 + action 0 + 1516 : 1 +state 1257 + action 0 + 1512 : 1 +state 1258 + action 0 + 1517 : 0.833 + 1518 : 0.167 +state 1259 + action 0 + 1519 : 1 +state 1260 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1261 + action 0 + 1520 : 1 +state 1262 + action 0 + 1519 : 1 +state 1263 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1264 + action 0 + 1521 : 1 +state 1265 + action 0 + 1519 : 1 +state 1266 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1267 + action 0 + 1522 : 1 +state 1268 + action 0 + 1519 : 1 +state 1269 + action 0 + 807 : 0.2 + 808 : 0.2 + 809 : 0.2 + 810 : 0.2 + 811 : 0.2 +state 1270 + action 0 + 1523 : 1 +state 1271 + action 0 + 1519 : 1 +state 1272 + action 0 + 1524 : 0.833 + 1525 : 0.167 +state 1273 observe0Greater1 observeOnlyTrueSender + action 0 + 818 : 0.833 + 819 : 0.167 +state 1274 observe0Greater1 observeOnlyTrueSender + action 0 + 1526 : 1 +state 1275 observe0Greater1 observeOnlyTrueSender + action 0 + 1527 : 0.833 + 1528 : 0.167 +state 1276 observe0Greater1 observeOnlyTrueSender + action 0 + 1529 : 1 +state 1277 observe0Greater1 observeOnlyTrueSender + action 0 + 1530 : 0.833 + 1531 : 0.167 +state 1278 observe0Greater1 observeOnlyTrueSender + action 0 + 1532 : 1 +state 1279 observe0Greater1 observeOnlyTrueSender + action 0 + 1533 : 0.833 + 1534 : 0.167 +state 1280 observe0Greater1 observeOnlyTrueSender + action 0 + 1535 : 1 +state 1281 observe0Greater1 observeOnlyTrueSender + action 0 + 1536 : 0.833 + 1537 : 0.167 +state 1282 observe0Greater1 observeOnlyTrueSender + action 0 + 1538 : 1 +state 1283 observe0Greater1 observeOnlyTrueSender + action 0 + 1539 : 1 +state 1284 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1285 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1286 observe3Greater1 observeIGreater1 + action 0 + 1541 : 1 +state 1287 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1288 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1289 observe3Greater1 observeIGreater1 + action 0 + 1542 : 1 +state 1290 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1291 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1292 observe3Greater1 observeIGreater1 + action 0 + 1543 : 1 +state 1293 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1294 observe3Greater1 observeIGreater1 + action 0 + 820 : 0.2 + 821 : 0.2 + 822 : 0.2 + 823 : 0.2 + 824 : 0.2 +state 1295 observe3Greater1 observeIGreater1 + action 0 + 1544 : 1 +state 1296 observe3Greater1 observeIGreater1 + action 0 + 1540 : 1 +state 1297 observe3Greater1 observeIGreater1 + action 0 + 1545 : 0.833 + 1546 : 0.167 +state 1298 + action 0 + 1547 : 1 +state 1299 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1300 + action 0 + 1548 : 1 +state 1301 + action 0 + 1547 : 1 +state 1302 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1303 + action 0 + 1549 : 1 +state 1304 + action 0 + 1547 : 1 +state 1305 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1306 + action 0 + 1550 : 1 +state 1307 + action 0 + 1547 : 1 +state 1308 + action 0 + 826 : 0.2 + 827 : 0.2 + 828 : 0.2 + 829 : 0.2 + 830 : 0.2 +state 1309 + action 0 + 1551 : 1 +state 1310 + action 0 + 1547 : 1 +state 1311 + action 0 + 1552 : 0.833 + 1553 : 0.167 +state 1312 observe0Greater1 observeOnlyTrueSender + action 0 + 837 : 0.833 + 838 : 0.167 +state 1313 observe0Greater1 observeOnlyTrueSender + action 0 + 1554 : 1 +state 1314 observe0Greater1 observeOnlyTrueSender + action 0 + 1555 : 0.833 + 1556 : 0.167 +state 1315 observe0Greater1 observeOnlyTrueSender + action 0 + 1557 : 1 +state 1316 observe0Greater1 observeOnlyTrueSender + action 0 + 1558 : 0.833 + 1559 : 0.167 +state 1317 observe0Greater1 observeOnlyTrueSender + action 0 + 1560 : 1 +state 1318 observe0Greater1 observeOnlyTrueSender + action 0 + 1561 : 0.833 + 1562 : 0.167 +state 1319 observe0Greater1 observeOnlyTrueSender + action 0 + 1563 : 1 +state 1320 observe0Greater1 observeOnlyTrueSender + action 0 + 1564 : 0.833 + 1565 : 0.167 +state 1321 observe0Greater1 observeOnlyTrueSender + action 0 + 1566 : 1 +state 1322 observe0Greater1 observeOnlyTrueSender + action 0 + 1567 : 1 +state 1323 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1324 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1325 observe4Greater1 observeIGreater1 + action 0 + 1569 : 1 +state 1326 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1327 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1328 observe4Greater1 observeIGreater1 + action 0 + 1570 : 1 +state 1329 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1330 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1331 observe4Greater1 observeIGreater1 + action 0 + 1571 : 1 +state 1332 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1333 observe4Greater1 observeIGreater1 + action 0 + 839 : 0.2 + 840 : 0.2 + 841 : 0.2 + 842 : 0.2 + 843 : 0.2 +state 1334 observe4Greater1 observeIGreater1 + action 0 + 1572 : 1 +state 1335 observe4Greater1 observeIGreater1 + action 0 + 1568 : 1 +state 1336 observe4Greater1 observeIGreater1 + action 0 + 1573 : 0.833 + 1574 : 0.167 +state 1337 observe0Greater1 observeOnlyTrueSender + action 0 + 850 : 0.833 + 851 : 0.167 +state 1338 observe0Greater1 observeOnlyTrueSender + action 0 + 1575 : 1 +state 1339 observe0Greater1 observeOnlyTrueSender + action 0 + 1576 : 0.833 + 1577 : 0.167 +state 1340 observe0Greater1 observeOnlyTrueSender + action 0 + 1578 : 1 +state 1341 observe0Greater1 observeOnlyTrueSender + action 0 + 1579 : 0.833 + 1580 : 0.167 +state 1342 observe0Greater1 observeOnlyTrueSender + action 0 + 1581 : 1 +state 1343 observe0Greater1 observeOnlyTrueSender + action 0 + 1582 : 0.833 + 1583 : 0.167 +state 1344 observe0Greater1 observeOnlyTrueSender + action 0 + 1584 : 1 +state 1345 observe0Greater1 observeOnlyTrueSender + action 0 + 1585 : 0.833 + 1586 : 0.167 +state 1346 observe0Greater1 observeOnlyTrueSender + action 0 + 1587 : 1 +state 1347 observe0Greater1 observeOnlyTrueSender + action 0 + 1588 : 1 +state 1348 observe0Greater1 observeOnlyTrueSender + action 0 + 1504 : 1 +state 1349 observe0Greater1 observeOnlyTrueSender + action 0 + 1539 : 1 +state 1350 observe0Greater1 observeOnlyTrueSender + action 0 + 1567 : 1 +state 1351 observe0Greater1 observeOnlyTrueSender + action 0 + 1588 : 1 +state 1352 observe0Greater1 observeOnlyTrueSender + action 0 + 1589 : 0.8 + 1590 : 0.2 +state 1353 observe0Greater1 observeOnlyTrueSender + action 0 + 1591 : 0.8 + 1592 : 0.2 +state 1354 observe0Greater1 observeOnlyTrueSender + action 0 + 1593 : 0.8 + 1594 : 0.2 +state 1355 observe0Greater1 observeOnlyTrueSender + action 0 + 1595 : 0.8 + 1596 : 0.2 +state 1356 observe0Greater1 observeOnlyTrueSender + action 0 + 1597 : 0.8 + 1598 : 0.2 +state 1357 observe0Greater1 observeOnlyTrueSender + action 0 + 1599 : 1 +state 1358 + action 0 + 1600 : 1 +state 1359 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1360 + action 0 + 1601 : 1 +state 1361 + action 0 + 1600 : 1 +state 1362 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1363 + action 0 + 1602 : 1 +state 1364 + action 0 + 1600 : 1 +state 1365 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1366 + action 0 + 1603 : 1 +state 1367 + action 0 + 1600 : 1 +state 1368 + action 0 + 866 : 0.2 + 867 : 0.2 + 868 : 0.2 + 869 : 0.2 + 870 : 0.2 +state 1369 + action 0 + 1604 : 1 +state 1370 + action 0 + 1600 : 1 +state 1371 + action 0 + 1605 : 0.833 + 1606 : 0.167 +state 1372 + action 0 + 886 : 0.8 + 1607 : 0.2 +state 1373 + action 0 + 1608 : 0.8 + 1609 : 0.2 +state 1374 + action 0 + 1610 : 0.8 + 1611 : 0.2 +state 1375 + action 0 + 1612 : 0.8 + 1613 : 0.2 +state 1376 + action 0 + 1614 : 0.8 + 1615 : 0.2 +state 1377 + action 0 + 1616 : 1 +state 1378 + action 0 + 893 : 0.8 + 1617 : 0.2 +state 1379 + action 0 + 1618 : 0.8 + 1619 : 0.2 +state 1380 + action 0 + 1620 : 0.8 + 1621 : 0.2 +state 1381 + action 0 + 1622 : 0.8 + 1623 : 0.2 +state 1382 + action 0 + 1624 : 0.8 + 1625 : 0.2 +state 1383 + action 0 + 1626 : 1 +state 1384 + action 0 + 900 : 0.8 + 1627 : 0.2 +state 1385 + action 0 + 1628 : 0.8 + 1629 : 0.2 +state 1386 + action 0 + 1630 : 0.8 + 1631 : 0.2 +state 1387 + action 0 + 1632 : 0.8 + 1633 : 0.2 +state 1388 + action 0 + 1634 : 0.8 + 1635 : 0.2 +state 1389 + action 0 + 1636 : 1 +state 1390 + action 0 + 907 : 0.8 + 1637 : 0.2 +state 1391 + action 0 + 1638 : 0.8 + 1639 : 0.2 +state 1392 + action 0 + 1640 : 0.8 + 1641 : 0.2 +state 1393 + action 0 + 1642 : 0.8 + 1643 : 0.2 +state 1394 + action 0 + 1644 : 0.8 + 1645 : 0.2 +state 1395 + action 0 + 1646 : 1 +state 1396 + action 0 + 1605 : 0.833 + 1606 : 0.167 +state 1397 + action 0 + 1647 : 1 +state 1398 + action 0 + 1648 : 1 +state 1399 + action 0 + 1649 : 1 +state 1400 + action 0 + 1650 : 1 +state 1401 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 1402 observe0Greater1 observeOnlyTrueSender + action 0 + 1656 : 1 +state 1403 observe1Greater1 observeIGreater1 + action 0 + 1657 : 0.833 + 1658 : 0.167 +state 1404 + action 0 + 1659 : 0.833 + 1660 : 0.167 +state 1405 + action 0 + 1661 : 0.833 + 1662 : 0.167 +state 1406 + action 0 + 1663 : 0.833 + 1664 : 0.167 +state 1407 + action 0 + 1665 : 1 +state 1408 + action 0 + 1666 : 0.833 + 1667 : 0.167 +state 1409 + action 0 + 1668 : 1 +state 1410 + action 0 + 1669 : 0.833 + 1670 : 0.167 +state 1411 + action 0 + 1671 : 1 +state 1412 + action 0 + 1672 : 0.833 + 1673 : 0.167 +state 1413 + action 0 + 1674 : 1 +state 1414 + action 0 + 1675 : 0.833 + 1676 : 0.167 +state 1415 + action 0 + 1677 : 1 +state 1416 observe0Greater1 observeOnlyTrueSender + action 0 + 1678 : 1 +state 1417 observe2Greater1 observeIGreater1 + action 0 + 1679 : 0.833 + 1680 : 0.167 +state 1418 + action 0 + 1681 : 0.833 + 1682 : 0.167 +state 1419 + action 0 + 1683 : 0.833 + 1684 : 0.167 +state 1420 + action 0 + 1685 : 1 +state 1421 + action 0 + 1686 : 0.833 + 1687 : 0.167 +state 1422 + action 0 + 1688 : 1 +state 1423 + action 0 + 1689 : 0.833 + 1690 : 0.167 +state 1424 + action 0 + 1691 : 1 +state 1425 + action 0 + 1692 : 0.833 + 1693 : 0.167 +state 1426 + action 0 + 1694 : 1 +state 1427 + action 0 + 1695 : 0.833 + 1696 : 0.167 +state 1428 + action 0 + 1697 : 1 +state 1429 observe0Greater1 observeOnlyTrueSender + action 0 + 1698 : 1 +state 1430 observe3Greater1 observeIGreater1 + action 0 + 1699 : 0.833 + 1700 : 0.167 +state 1431 + action 0 + 1701 : 0.833 + 1702 : 0.167 +state 1432 + action 0 + 1703 : 1 +state 1433 + action 0 + 1704 : 0.833 + 1705 : 0.167 +state 1434 + action 0 + 1706 : 1 +state 1435 + action 0 + 1707 : 0.833 + 1708 : 0.167 +state 1436 + action 0 + 1709 : 1 +state 1437 + action 0 + 1710 : 0.833 + 1711 : 0.167 +state 1438 + action 0 + 1712 : 1 +state 1439 + action 0 + 1713 : 0.833 + 1714 : 0.167 +state 1440 + action 0 + 1715 : 1 +state 1441 observe0Greater1 observeOnlyTrueSender + action 0 + 1716 : 1 +state 1442 observe4Greater1 observeIGreater1 + action 0 + 1717 : 0.833 + 1718 : 0.167 +state 1443 + action 0 + 1719 : 1 +state 1444 + action 0 + 1720 : 0.833 + 1721 : 0.167 +state 1445 + action 0 + 1722 : 1 +state 1446 + action 0 + 1723 : 0.833 + 1724 : 0.167 +state 1447 + action 0 + 1725 : 1 +state 1448 + action 0 + 1726 : 0.833 + 1727 : 0.167 +state 1449 + action 0 + 1728 : 1 +state 1450 + action 0 + 1729 : 0.833 + 1730 : 0.167 +state 1451 + action 0 + 1731 : 1 +state 1452 observe0Greater1 observeOnlyTrueSender + action 0 + 1732 : 1 +state 1453 observe0Greater1 observeOnlyTrueSender + action 0 + 1678 : 1 +state 1454 observe0Greater1 observeOnlyTrueSender + action 0 + 1698 : 1 +state 1455 observe0Greater1 observeOnlyTrueSender + action 0 + 1716 : 1 +state 1456 observe0Greater1 observeOnlyTrueSender + action 0 + 1732 : 1 +state 1457 observe0Greater1 observeOnlyTrueSender + action 0 + 1078 : 0.8 + 1733 : 0.2 +state 1458 observe0Greater1 observeOnlyTrueSender + action 0 + 1734 : 0.8 + 1735 : 0.2 +state 1459 observe0Greater1 observeOnlyTrueSender + action 0 + 1736 : 0.8 + 1737 : 0.2 +state 1460 observe0Greater1 observeOnlyTrueSender + action 0 + 1738 : 0.8 + 1739 : 0.2 +state 1461 observe0Greater1 observeOnlyTrueSender + action 0 + 1740 : 0.8 + 1741 : 0.2 +state 1462 observe0Greater1 observeOnlyTrueSender + action 0 + 1742 : 1 +state 1463 observe1Greater1 observeIGreater1 + action 0 + 1657 : 0.833 + 1658 : 0.167 +state 1464 observe1Greater1 observeIGreater1 + action 0 + 1743 : 1 +state 1465 observe1Greater1 observeIGreater1 + action 0 + 1744 : 1 +state 1466 observe1Greater1 observeIGreater1 + action 0 + 1745 : 1 +state 1467 observe1Greater1 observeIGreater1 + action 0 + 1746 : 1 +state 1468 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 1469 observe1Greater1 observeIGreater1 + action 0 + 1752 : 1 +state 1470 + action 0 + 1659 : 0.833 + 1660 : 0.167 +state 1471 observe1Greater1 observeIGreater1 + action 0 + 1753 : 1 +state 1472 observe2Greater1 observeIGreater1 + action 0 + 1754 : 1 +state 1473 + action 0 + 1755 : 1 +state 1474 + action 0 + 1756 : 1 +state 1475 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 1476 + action 0 + 1762 : 1 +state 1477 + action 0 + 1661 : 0.833 + 1662 : 0.167 +state 1478 observe1Greater1 observeIGreater1 + action 0 + 1763 : 1 +state 1479 + action 0 + 1764 : 1 +state 1480 observe3Greater1 observeIGreater1 + action 0 + 1765 : 1 +state 1481 + action 0 + 1766 : 1 +state 1482 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 1483 + action 0 + 1772 : 1 +state 1484 + action 0 + 1663 : 0.833 + 1664 : 0.167 +state 1485 observe1Greater1 observeIGreater1 + action 0 + 1773 : 1 +state 1486 + action 0 + 1774 : 1 +state 1487 + action 0 + 1775 : 1 +state 1488 observe4Greater1 observeIGreater1 + action 0 + 1776 : 1 +state 1489 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 1490 + action 0 + 1782 : 1 +state 1491 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1492 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1493 observe0Greater1 observeOnlyTrueSender + action 0 + 1784 : 1 +state 1494 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1495 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1496 observe0Greater1 observeOnlyTrueSender + action 0 + 1785 : 1 +state 1497 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1498 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1499 observe0Greater1 observeOnlyTrueSender + action 0 + 1786 : 1 +state 1500 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1501 observe0Greater1 observeOnlyTrueSender + action 0 + 976 : 0.2 + 977 : 0.2 + 978 : 0.2 + 979 : 0.2 + 980 : 0.2 +state 1502 observe0Greater1 observeOnlyTrueSender + action 0 + 1787 : 1 +state 1503 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 1 +state 1504 observe0Greater1 observeOnlyTrueSender + action 0 + 1788 : 0.833 + 1789 : 0.167 +state 1505 observe2Greater1 observeIGreater1 + action 0 + 1679 : 0.833 + 1680 : 0.167 +state 1506 observe2Greater1 observeIGreater1 + action 0 + 1790 : 1 +state 1507 observe2Greater1 observeIGreater1 + action 0 + 1791 : 1 +state 1508 observe2Greater1 observeIGreater1 + action 0 + 1792 : 1 +state 1509 observe2Greater1 observeIGreater1 + action 0 + 1793 : 1 +state 1510 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 1511 observe2Greater1 observeIGreater1 + action 0 + 1799 : 1 +state 1512 + action 0 + 1681 : 0.833 + 1682 : 0.167 +state 1513 + action 0 + 1800 : 1 +state 1514 observe2Greater1 observeIGreater1 + action 0 + 1801 : 1 +state 1515 observe3Greater1 observeIGreater1 + action 0 + 1802 : 1 +state 1516 + action 0 + 1803 : 1 +state 1517 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 1518 + action 0 + 1809 : 1 +state 1519 + action 0 + 1683 : 0.833 + 1684 : 0.167 +state 1520 + action 0 + 1810 : 1 +state 1521 observe2Greater1 observeIGreater1 + action 0 + 1811 : 1 +state 1522 + action 0 + 1812 : 1 +state 1523 observe4Greater1 observeIGreater1 + action 0 + 1813 : 1 +state 1524 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 1525 + action 0 + 1819 : 1 +state 1526 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1527 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1528 observe0Greater1 observeOnlyTrueSender + action 0 + 1821 : 1 +state 1529 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1530 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1531 observe0Greater1 observeOnlyTrueSender + action 0 + 1822 : 1 +state 1532 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1533 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1534 observe0Greater1 observeOnlyTrueSender + action 0 + 1823 : 1 +state 1535 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1536 observe0Greater1 observeOnlyTrueSender + action 0 + 1019 : 0.2 + 1020 : 0.2 + 1021 : 0.2 + 1022 : 0.2 + 1023 : 0.2 +state 1537 observe0Greater1 observeOnlyTrueSender + action 0 + 1824 : 1 +state 1538 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 1 +state 1539 observe0Greater1 observeOnlyTrueSender + action 0 + 1825 : 0.833 + 1826 : 0.167 +state 1540 observe3Greater1 observeIGreater1 + action 0 + 1699 : 0.833 + 1700 : 0.167 +state 1541 observe3Greater1 observeIGreater1 + action 0 + 1827 : 1 +state 1542 observe3Greater1 observeIGreater1 + action 0 + 1828 : 1 +state 1543 observe3Greater1 observeIGreater1 + action 0 + 1829 : 1 +state 1544 observe3Greater1 observeIGreater1 + action 0 + 1830 : 1 +state 1545 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 1546 observe3Greater1 observeIGreater1 + action 0 + 1836 : 1 +state 1547 + action 0 + 1701 : 0.833 + 1702 : 0.167 +state 1548 + action 0 + 1837 : 1 +state 1549 + action 0 + 1838 : 1 +state 1550 observe3Greater1 observeIGreater1 + action 0 + 1839 : 1 +state 1551 observe4Greater1 observeIGreater1 + action 0 + 1840 : 1 +state 1552 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 1553 + action 0 + 1846 : 1 +state 1554 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1555 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1556 observe0Greater1 observeOnlyTrueSender + action 0 + 1848 : 1 +state 1557 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1558 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1559 observe0Greater1 observeOnlyTrueSender + action 0 + 1849 : 1 +state 1560 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1561 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1562 observe0Greater1 observeOnlyTrueSender + action 0 + 1850 : 1 +state 1563 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1564 observe0Greater1 observeOnlyTrueSender + action 0 + 1051 : 0.2 + 1052 : 0.2 + 1053 : 0.2 + 1054 : 0.2 + 1055 : 0.2 +state 1565 observe0Greater1 observeOnlyTrueSender + action 0 + 1851 : 1 +state 1566 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 1 +state 1567 observe0Greater1 observeOnlyTrueSender + action 0 + 1852 : 0.833 + 1853 : 0.167 +state 1568 observe4Greater1 observeIGreater1 + action 0 + 1717 : 0.833 + 1718 : 0.167 +state 1569 observe4Greater1 observeIGreater1 + action 0 + 1854 : 1 +state 1570 observe4Greater1 observeIGreater1 + action 0 + 1855 : 1 +state 1571 observe4Greater1 observeIGreater1 + action 0 + 1856 : 1 +state 1572 observe4Greater1 observeIGreater1 + action 0 + 1857 : 1 +state 1573 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 1574 observe4Greater1 observeIGreater1 + action 0 + 1863 : 1 +state 1575 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1576 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1577 observe0Greater1 observeOnlyTrueSender + action 0 + 1865 : 1 +state 1578 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1579 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1580 observe0Greater1 observeOnlyTrueSender + action 0 + 1866 : 1 +state 1581 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1582 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1583 observe0Greater1 observeOnlyTrueSender + action 0 + 1867 : 1 +state 1584 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1585 observe0Greater1 observeOnlyTrueSender + action 0 + 1072 : 0.2 + 1073 : 0.2 + 1074 : 0.2 + 1075 : 0.2 + 1076 : 0.2 +state 1586 observe0Greater1 observeOnlyTrueSender + action 0 + 1868 : 1 +state 1587 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 1 +state 1588 observe0Greater1 observeOnlyTrueSender + action 0 + 1869 : 0.833 + 1870 : 0.167 +state 1589 observe0Greater1 observeOnlyTrueSender + action 0 + 1083 : 0.833 + 1084 : 0.167 +state 1590 observe0Greater1 observeOnlyTrueSender + action 0 + 1871 : 1 +state 1591 observe0Greater1 observeOnlyTrueSender + action 0 + 1872 : 0.833 + 1873 : 0.167 +state 1592 observe0Greater1 observeOnlyTrueSender + action 0 + 1874 : 1 +state 1593 observe0Greater1 observeOnlyTrueSender + action 0 + 1875 : 0.833 + 1876 : 0.167 +state 1594 observe0Greater1 observeOnlyTrueSender + action 0 + 1877 : 1 +state 1595 observe0Greater1 observeOnlyTrueSender + action 0 + 1878 : 0.833 + 1879 : 0.167 +state 1596 observe0Greater1 observeOnlyTrueSender + action 0 + 1880 : 1 +state 1597 observe0Greater1 observeOnlyTrueSender + action 0 + 1881 : 0.833 + 1882 : 0.167 +state 1598 observe0Greater1 observeOnlyTrueSender + action 0 + 1883 : 1 +state 1599 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1599 : 1 +state 1600 + action 0 + 1884 : 0.833 + 1885 : 0.167 +state 1601 + action 0 + 1886 : 1 +state 1602 + action 0 + 1887 : 1 +state 1603 + action 0 + 1888 : 1 +state 1604 + action 0 + 1889 : 1 +state 1605 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 1606 + action 0 + 1895 : 1 +state 1607 + action 0 + 1896 : 1 +state 1608 + action 0 + 1897 : 0.833 + 1898 : 0.167 +state 1609 + action 0 + 1899 : 1 +state 1610 + action 0 + 1900 : 0.833 + 1901 : 0.167 +state 1611 + action 0 + 1902 : 1 +state 1612 + action 0 + 1903 : 0.833 + 1904 : 0.167 +state 1613 + action 0 + 1905 : 1 +state 1614 + action 0 + 1906 : 0.833 + 1907 : 0.167 +state 1615 + action 0 + 1908 : 1 +state 1616 + action 0 + 1909 : 1 +state 1617 + action 0 + 1910 : 1 +state 1618 + action 0 + 1911 : 0.833 + 1912 : 0.167 +state 1619 + action 0 + 1913 : 1 +state 1620 + action 0 + 1914 : 0.833 + 1915 : 0.167 +state 1621 + action 0 + 1916 : 1 +state 1622 + action 0 + 1917 : 0.833 + 1918 : 0.167 +state 1623 + action 0 + 1919 : 1 +state 1624 + action 0 + 1920 : 0.833 + 1921 : 0.167 +state 1625 + action 0 + 1922 : 1 +state 1626 + action 0 + 1923 : 1 +state 1627 + action 0 + 1924 : 1 +state 1628 + action 0 + 1925 : 0.833 + 1926 : 0.167 +state 1629 + action 0 + 1927 : 1 +state 1630 + action 0 + 1928 : 0.833 + 1929 : 0.167 +state 1631 + action 0 + 1930 : 1 +state 1632 + action 0 + 1931 : 0.833 + 1932 : 0.167 +state 1633 + action 0 + 1933 : 1 +state 1634 + action 0 + 1934 : 0.833 + 1935 : 0.167 +state 1635 + action 0 + 1936 : 1 +state 1636 + action 0 + 1937 : 1 +state 1637 + action 0 + 1938 : 1 +state 1638 + action 0 + 1939 : 0.833 + 1940 : 0.167 +state 1639 + action 0 + 1941 : 1 +state 1640 + action 0 + 1942 : 0.833 + 1943 : 0.167 +state 1641 + action 0 + 1944 : 1 +state 1642 + action 0 + 1945 : 0.833 + 1946 : 0.167 +state 1643 + action 0 + 1947 : 1 +state 1644 + action 0 + 1948 : 0.833 + 1949 : 0.167 +state 1645 + action 0 + 1950 : 1 +state 1646 + action 0 + 1951 : 1 +state 1647 + action 0 + 1909 : 1 +state 1648 + action 0 + 1923 : 1 +state 1649 + action 0 + 1937 : 1 +state 1650 + action 0 + 1951 : 1 +state 1651 observe0Greater1 observeOnlyTrueSender + action 0 + 1157 : 0.8 + 1952 : 0.2 +state 1652 observe0Greater1 observeOnlyTrueSender + action 0 + 1953 : 0.8 + 1954 : 0.2 +state 1653 observe0Greater1 observeOnlyTrueSender + action 0 + 1955 : 0.8 + 1956 : 0.2 +state 1654 observe0Greater1 observeOnlyTrueSender + action 0 + 1957 : 0.8 + 1958 : 0.2 +state 1655 observe0Greater1 observeOnlyTrueSender + action 0 + 1959 : 0.8 + 1960 : 0.2 +state 1656 observe0Greater1 observeOnlyTrueSender + action 0 + 1961 : 1 +state 1657 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 1658 observe1Greater1 observeIGreater1 + action 0 + 1967 : 1 +state 1659 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 1660 + action 0 + 1973 : 1 +state 1661 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 1662 + action 0 + 1979 : 1 +state 1663 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 1664 + action 0 + 1985 : 1 +state 1665 + action 0 + 1986 : 1 +state 1666 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1667 + action 0 + 1987 : 1 +state 1668 + action 0 + 1986 : 1 +state 1669 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1670 + action 0 + 1988 : 1 +state 1671 + action 0 + 1986 : 1 +state 1672 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1673 + action 0 + 1989 : 1 +state 1674 + action 0 + 1986 : 1 +state 1675 + action 0 + 1121 : 0.2 + 1122 : 0.2 + 1123 : 0.2 + 1124 : 0.2 + 1125 : 0.2 +state 1676 + action 0 + 1990 : 1 +state 1677 + action 0 + 1986 : 1 +state 1678 observe0Greater1 observeOnlyTrueSender + action 0 + 1991 : 0.833 + 1992 : 0.167 +state 1679 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 1680 observe2Greater1 observeIGreater1 + action 0 + 1998 : 1 +state 1681 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 1682 + action 0 + 2004 : 1 +state 1683 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 1684 + action 0 + 2010 : 1 +state 1685 + action 0 + 2011 : 1 +state 1686 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1687 + action 0 + 2012 : 1 +state 1688 + action 0 + 2011 : 1 +state 1689 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1690 + action 0 + 2013 : 1 +state 1691 + action 0 + 2011 : 1 +state 1692 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1693 + action 0 + 2014 : 1 +state 1694 + action 0 + 2011 : 1 +state 1695 + action 0 + 1131 : 0.2 + 1132 : 0.2 + 1133 : 0.2 + 1134 : 0.2 + 1135 : 0.2 +state 1696 + action 0 + 2015 : 1 +state 1697 + action 0 + 2011 : 1 +state 1698 observe0Greater1 observeOnlyTrueSender + action 0 + 2016 : 0.833 + 2017 : 0.167 +state 1699 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 1700 observe3Greater1 observeIGreater1 + action 0 + 2023 : 1 +state 1701 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 1702 + action 0 + 2029 : 1 +state 1703 + action 0 + 2030 : 1 +state 1704 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1705 + action 0 + 2031 : 1 +state 1706 + action 0 + 2030 : 1 +state 1707 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1708 + action 0 + 2032 : 1 +state 1709 + action 0 + 2030 : 1 +state 1710 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1711 + action 0 + 2033 : 1 +state 1712 + action 0 + 2030 : 1 +state 1713 + action 0 + 1141 : 0.2 + 1142 : 0.2 + 1143 : 0.2 + 1144 : 0.2 + 1145 : 0.2 +state 1714 + action 0 + 2034 : 1 +state 1715 + action 0 + 2030 : 1 +state 1716 observe0Greater1 observeOnlyTrueSender + action 0 + 2035 : 0.833 + 2036 : 0.167 +state 1717 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 1718 observe4Greater1 observeIGreater1 + action 0 + 2042 : 1 +state 1719 + action 0 + 2043 : 1 +state 1720 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1721 + action 0 + 2044 : 1 +state 1722 + action 0 + 2043 : 1 +state 1723 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1724 + action 0 + 2045 : 1 +state 1725 + action 0 + 2043 : 1 +state 1726 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1727 + action 0 + 2046 : 1 +state 1728 + action 0 + 2043 : 1 +state 1729 + action 0 + 1151 : 0.2 + 1152 : 0.2 + 1153 : 0.2 + 1154 : 0.2 + 1155 : 0.2 +state 1730 + action 0 + 2047 : 1 +state 1731 + action 0 + 2043 : 1 +state 1732 observe0Greater1 observeOnlyTrueSender + action 0 + 2048 : 0.833 + 2049 : 0.167 +state 1733 observe0Greater1 observeOnlyTrueSender + action 0 + 2050 : 1 +state 1734 observe0Greater1 observeOnlyTrueSender + action 0 + 2051 : 0.833 + 2052 : 0.167 +state 1735 observe0Greater1 observeOnlyTrueSender + action 0 + 2053 : 1 +state 1736 observe0Greater1 observeOnlyTrueSender + action 0 + 2054 : 0.833 + 2055 : 0.167 +state 1737 observe0Greater1 observeOnlyTrueSender + action 0 + 2056 : 1 +state 1738 observe0Greater1 observeOnlyTrueSender + action 0 + 2057 : 0.833 + 2058 : 0.167 +state 1739 observe0Greater1 observeOnlyTrueSender + action 0 + 2059 : 1 +state 1740 observe0Greater1 observeOnlyTrueSender + action 0 + 2060 : 0.833 + 2061 : 0.167 +state 1741 observe0Greater1 observeOnlyTrueSender + action 0 + 2062 : 1 +state 1742 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1742 : 1 +state 1743 observe1Greater1 observeIGreater1 + action 0 + 2063 : 1 +state 1744 observe1Greater1 observeIGreater1 + action 0 + 2064 : 1 +state 1745 observe1Greater1 observeIGreater1 + action 0 + 2065 : 1 +state 1746 observe1Greater1 observeIGreater1 + action 0 + 2066 : 1 +state 1747 observe1Greater1 observeIGreater1 + action 0 + 2067 : 0.8 + 2068 : 0.2 +state 1748 observe1Greater1 observeIGreater1 + action 0 + 2069 : 0.8 + 2070 : 0.2 +state 1749 observe1Greater1 observeIGreater1 + action 0 + 2071 : 0.8 + 2072 : 0.2 +state 1750 observe1Greater1 observeIGreater1 + action 0 + 2073 : 0.8 + 2074 : 0.2 +state 1751 observe1Greater1 observeIGreater1 + action 0 + 2075 : 0.8 + 2076 : 0.2 +state 1752 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2077 : 1 +state 1753 observe1Greater1 observeIGreater1 + action 0 + 2064 : 1 +state 1754 observe2Greater1 observeIGreater1 + action 0 + 2078 : 1 +state 1755 + action 0 + 2079 : 1 +state 1756 + action 0 + 2080 : 1 +state 1757 + action 0 + 2081 : 0.8 + 2082 : 0.2 +state 1758 + action 0 + 2083 : 0.8 + 2084 : 0.2 +state 1759 + action 0 + 2085 : 0.8 + 2086 : 0.2 +state 1760 + action 0 + 2087 : 0.8 + 2088 : 0.2 +state 1761 + action 0 + 2089 : 0.8 + 2090 : 0.2 +state 1762 observe0Greater1 observeOnlyTrueSender + action 0 + 2091 : 1 +state 1763 observe1Greater1 observeIGreater1 + action 0 + 2065 : 1 +state 1764 + action 0 + 2079 : 1 +state 1765 observe3Greater1 observeIGreater1 + action 0 + 2092 : 1 +state 1766 + action 0 + 2093 : 1 +state 1767 + action 0 + 2094 : 0.8 + 2095 : 0.2 +state 1768 + action 0 + 2096 : 0.8 + 2097 : 0.2 +state 1769 + action 0 + 2098 : 0.8 + 2099 : 0.2 +state 1770 + action 0 + 2100 : 0.8 + 2101 : 0.2 +state 1771 + action 0 + 2102 : 0.8 + 2103 : 0.2 +state 1772 observe0Greater1 observeOnlyTrueSender + action 0 + 2104 : 1 +state 1773 observe1Greater1 observeIGreater1 + action 0 + 2066 : 1 +state 1774 + action 0 + 2080 : 1 +state 1775 + action 0 + 2093 : 1 +state 1776 observe4Greater1 observeIGreater1 + action 0 + 2105 : 1 +state 1777 + action 0 + 2106 : 0.8 + 2107 : 0.2 +state 1778 + action 0 + 2108 : 0.8 + 2109 : 0.2 +state 1779 + action 0 + 2110 : 0.8 + 2111 : 0.2 +state 1780 + action 0 + 2112 : 0.8 + 2113 : 0.2 +state 1781 + action 0 + 2114 : 0.8 + 2115 : 0.2 +state 1782 observe0Greater1 observeOnlyTrueSender + action 0 + 2116 : 1 +state 1783 observe0Greater1 observeOnlyTrueSender + action 0 + 1991 : 0.833 + 1992 : 0.167 +state 1784 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2117 : 1 +state 1785 observe0Greater1 observeOnlyTrueSender + action 0 + 2118 : 1 +state 1786 observe0Greater1 observeOnlyTrueSender + action 0 + 2119 : 1 +state 1787 observe0Greater1 observeOnlyTrueSender + action 0 + 2120 : 1 +state 1788 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 1789 observe0Greater1 observeOnlyTrueSender + action 0 + 2126 : 1 +state 1790 observe2Greater1 observeIGreater1 + action 0 + 2078 : 1 +state 1791 observe2Greater1 observeIGreater1 + action 0 + 2127 : 1 +state 1792 observe2Greater1 observeIGreater1 + action 0 + 2128 : 1 +state 1793 observe2Greater1 observeIGreater1 + action 0 + 2129 : 1 +state 1794 observe2Greater1 observeIGreater1 + action 0 + 2130 : 0.8 + 2131 : 0.2 +state 1795 observe2Greater1 observeIGreater1 + action 0 + 2132 : 0.8 + 2133 : 0.2 +state 1796 observe2Greater1 observeIGreater1 + action 0 + 2134 : 0.8 + 2135 : 0.2 +state 1797 observe2Greater1 observeIGreater1 + action 0 + 2136 : 0.8 + 2137 : 0.2 +state 1798 observe2Greater1 observeIGreater1 + action 0 + 2138 : 0.8 + 2139 : 0.2 +state 1799 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2140 : 1 +state 1800 + action 0 + 2079 : 1 +state 1801 observe2Greater1 observeIGreater1 + action 0 + 2128 : 1 +state 1802 observe3Greater1 observeIGreater1 + action 0 + 2141 : 1 +state 1803 + action 0 + 2142 : 1 +state 1804 + action 0 + 2143 : 0.8 + 2144 : 0.2 +state 1805 + action 0 + 2145 : 0.8 + 2146 : 0.2 +state 1806 + action 0 + 2147 : 0.8 + 2148 : 0.2 +state 1807 + action 0 + 2149 : 0.8 + 2150 : 0.2 +state 1808 + action 0 + 2151 : 0.8 + 2152 : 0.2 +state 1809 observe0Greater1 observeOnlyTrueSender + action 0 + 2153 : 1 +state 1810 + action 0 + 2080 : 1 +state 1811 observe2Greater1 observeIGreater1 + action 0 + 2129 : 1 +state 1812 + action 0 + 2142 : 1 +state 1813 observe4Greater1 observeIGreater1 + action 0 + 2154 : 1 +state 1814 + action 0 + 2155 : 0.8 + 2156 : 0.2 +state 1815 + action 0 + 2157 : 0.8 + 2158 : 0.2 +state 1816 + action 0 + 2159 : 0.8 + 2160 : 0.2 +state 1817 + action 0 + 2161 : 0.8 + 2162 : 0.2 +state 1818 + action 0 + 2163 : 0.8 + 2164 : 0.2 +state 1819 observe0Greater1 observeOnlyTrueSender + action 0 + 2165 : 1 +state 1820 observe0Greater1 observeOnlyTrueSender + action 0 + 2016 : 0.833 + 2017 : 0.167 +state 1821 observe0Greater1 observeOnlyTrueSender + action 0 + 2166 : 1 +state 1822 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2167 : 1 +state 1823 observe0Greater1 observeOnlyTrueSender + action 0 + 2168 : 1 +state 1824 observe0Greater1 observeOnlyTrueSender + action 0 + 2169 : 1 +state 1825 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 1826 observe0Greater1 observeOnlyTrueSender + action 0 + 2175 : 1 +state 1827 observe3Greater1 observeIGreater1 + action 0 + 2092 : 1 +state 1828 observe3Greater1 observeIGreater1 + action 0 + 2141 : 1 +state 1829 observe3Greater1 observeIGreater1 + action 0 + 2176 : 1 +state 1830 observe3Greater1 observeIGreater1 + action 0 + 2177 : 1 +state 1831 observe3Greater1 observeIGreater1 + action 0 + 2178 : 0.8 + 2179 : 0.2 +state 1832 observe3Greater1 observeIGreater1 + action 0 + 2180 : 0.8 + 2181 : 0.2 +state 1833 observe3Greater1 observeIGreater1 + action 0 + 2182 : 0.8 + 2183 : 0.2 +state 1834 observe3Greater1 observeIGreater1 + action 0 + 2184 : 0.8 + 2185 : 0.2 +state 1835 observe3Greater1 observeIGreater1 + action 0 + 2186 : 0.8 + 2187 : 0.2 +state 1836 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2188 : 1 +state 1837 + action 0 + 2093 : 1 +state 1838 + action 0 + 2142 : 1 +state 1839 observe3Greater1 observeIGreater1 + action 0 + 2177 : 1 +state 1840 observe4Greater1 observeIGreater1 + action 0 + 2189 : 1 +state 1841 + action 0 + 2190 : 0.8 + 2191 : 0.2 +state 1842 + action 0 + 2192 : 0.8 + 2193 : 0.2 +state 1843 + action 0 + 2194 : 0.8 + 2195 : 0.2 +state 1844 + action 0 + 2196 : 0.8 + 2197 : 0.2 +state 1845 + action 0 + 2198 : 0.8 + 2199 : 0.2 +state 1846 observe0Greater1 observeOnlyTrueSender + action 0 + 2200 : 1 +state 1847 observe0Greater1 observeOnlyTrueSender + action 0 + 2035 : 0.833 + 2036 : 0.167 +state 1848 observe0Greater1 observeOnlyTrueSender + action 0 + 2201 : 1 +state 1849 observe0Greater1 observeOnlyTrueSender + action 0 + 2202 : 1 +state 1850 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2203 : 1 +state 1851 observe0Greater1 observeOnlyTrueSender + action 0 + 2204 : 1 +state 1852 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 1853 observe0Greater1 observeOnlyTrueSender + action 0 + 2210 : 1 +state 1854 observe4Greater1 observeIGreater1 + action 0 + 2105 : 1 +state 1855 observe4Greater1 observeIGreater1 + action 0 + 2154 : 1 +state 1856 observe4Greater1 observeIGreater1 + action 0 + 2189 : 1 +state 1857 observe4Greater1 observeIGreater1 + action 0 + 2211 : 1 +state 1858 observe4Greater1 observeIGreater1 + action 0 + 2212 : 0.8 + 2213 : 0.2 +state 1859 observe4Greater1 observeIGreater1 + action 0 + 2214 : 0.8 + 2215 : 0.2 +state 1860 observe4Greater1 observeIGreater1 + action 0 + 2216 : 0.8 + 2217 : 0.2 +state 1861 observe4Greater1 observeIGreater1 + action 0 + 2218 : 0.8 + 2219 : 0.2 +state 1862 observe4Greater1 observeIGreater1 + action 0 + 2220 : 0.8 + 2221 : 0.2 +state 1863 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2222 : 1 +state 1864 observe0Greater1 observeOnlyTrueSender + action 0 + 2048 : 0.833 + 2049 : 0.167 +state 1865 observe0Greater1 observeOnlyTrueSender + action 0 + 2223 : 1 +state 1866 observe0Greater1 observeOnlyTrueSender + action 0 + 2224 : 1 +state 1867 observe0Greater1 observeOnlyTrueSender + action 0 + 2225 : 1 +state 1868 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2226 : 1 +state 1869 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 1870 observe0Greater1 observeOnlyTrueSender + action 0 + 2232 : 1 +state 1871 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1871 : 1 +state 1872 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1873 observe0Greater1 observeOnlyTrueSender + action 0 + 2233 : 1 +state 1874 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1874 : 1 +state 1875 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1876 observe0Greater1 observeOnlyTrueSender + action 0 + 2234 : 1 +state 1877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1877 : 1 +state 1878 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1879 observe0Greater1 observeOnlyTrueSender + action 0 + 2235 : 1 +state 1880 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1880 : 1 +state 1881 observe0Greater1 observeOnlyTrueSender + action 0 + 1352 : 0.2 + 1353 : 0.2 + 1354 : 0.2 + 1355 : 0.2 + 1356 : 0.2 +state 1882 observe0Greater1 observeOnlyTrueSender + action 0 + 2236 : 1 +state 1883 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1883 : 1 +state 1884 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 1885 + action 0 + 2242 : 1 +state 1886 + action 0 + 2243 : 1 +state 1887 + action 0 + 2244 : 1 +state 1888 + action 0 + 2245 : 1 +state 1889 + action 0 + 2246 : 1 +state 1890 + action 0 + 1396 : 0.8 + 2247 : 0.2 +state 1891 + action 0 + 2248 : 0.8 + 2249 : 0.2 +state 1892 + action 0 + 2250 : 0.8 + 2251 : 0.2 +state 1893 + action 0 + 2252 : 0.8 + 2253 : 0.2 +state 1894 + action 0 + 2254 : 0.8 + 2255 : 0.2 +state 1895 observe0Greater1 observeOnlyTrueSender + action 0 + 2256 : 1 +state 1896 + action 0 + 2257 : 1 +state 1897 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1898 + action 0 + 2258 : 1 +state 1899 + action 0 + 2257 : 1 +state 1900 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1901 + action 0 + 2259 : 1 +state 1902 + action 0 + 2257 : 1 +state 1903 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1904 + action 0 + 2260 : 1 +state 1905 + action 0 + 2257 : 1 +state 1906 + action 0 + 1372 : 0.2 + 1373 : 0.2 + 1374 : 0.2 + 1375 : 0.2 + 1376 : 0.2 +state 1907 + action 0 + 2261 : 1 +state 1908 + action 0 + 2257 : 1 +state 1909 + action 0 + 2262 : 0.833 + 2263 : 0.167 +state 1910 + action 0 + 2264 : 1 +state 1911 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1912 + action 0 + 2265 : 1 +state 1913 + action 0 + 2264 : 1 +state 1914 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1915 + action 0 + 2266 : 1 +state 1916 + action 0 + 2264 : 1 +state 1917 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1918 + action 0 + 2267 : 1 +state 1919 + action 0 + 2264 : 1 +state 1920 + action 0 + 1378 : 0.2 + 1379 : 0.2 + 1380 : 0.2 + 1381 : 0.2 + 1382 : 0.2 +state 1921 + action 0 + 2268 : 1 +state 1922 + action 0 + 2264 : 1 +state 1923 + action 0 + 2269 : 0.833 + 2270 : 0.167 +state 1924 + action 0 + 2271 : 1 +state 1925 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1926 + action 0 + 2272 : 1 +state 1927 + action 0 + 2271 : 1 +state 1928 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1929 + action 0 + 2273 : 1 +state 1930 + action 0 + 2271 : 1 +state 1931 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1932 + action 0 + 2274 : 1 +state 1933 + action 0 + 2271 : 1 +state 1934 + action 0 + 1384 : 0.2 + 1385 : 0.2 + 1386 : 0.2 + 1387 : 0.2 + 1388 : 0.2 +state 1935 + action 0 + 2275 : 1 +state 1936 + action 0 + 2271 : 1 +state 1937 + action 0 + 2276 : 0.833 + 2277 : 0.167 +state 1938 + action 0 + 2278 : 1 +state 1939 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1940 + action 0 + 2279 : 1 +state 1941 + action 0 + 2278 : 1 +state 1942 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1943 + action 0 + 2280 : 1 +state 1944 + action 0 + 2278 : 1 +state 1945 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1946 + action 0 + 2281 : 1 +state 1947 + action 0 + 2278 : 1 +state 1948 + action 0 + 1390 : 0.2 + 1391 : 0.2 + 1392 : 0.2 + 1393 : 0.2 + 1394 : 0.2 +state 1949 + action 0 + 2282 : 1 +state 1950 + action 0 + 2278 : 1 +state 1951 + action 0 + 2283 : 0.833 + 2284 : 0.167 +state 1952 observe0Greater1 observeOnlyTrueSender + action 0 + 2285 : 1 +state 1953 observe0Greater1 observeOnlyTrueSender + action 0 + 2286 : 0.833 + 2287 : 0.167 +state 1954 observe0Greater1 observeOnlyTrueSender + action 0 + 2288 : 1 +state 1955 observe0Greater1 observeOnlyTrueSender + action 0 + 2289 : 0.833 + 2290 : 0.167 +state 1956 observe0Greater1 observeOnlyTrueSender + action 0 + 2291 : 1 +state 1957 observe0Greater1 observeOnlyTrueSender + action 0 + 2292 : 0.833 + 2293 : 0.167 +state 1958 observe0Greater1 observeOnlyTrueSender + action 0 + 2294 : 1 +state 1959 observe0Greater1 observeOnlyTrueSender + action 0 + 2295 : 0.833 + 2296 : 0.167 +state 1960 observe0Greater1 observeOnlyTrueSender + action 0 + 2297 : 1 +state 1961 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 1961 : 1 +state 1962 observe1Greater1 observeIGreater1 + action 0 + 1463 : 0.8 + 2298 : 0.2 +state 1963 observe1Greater1 observeIGreater1 + action 0 + 2299 : 0.8 + 2300 : 0.2 +state 1964 observe1Greater1 observeIGreater1 + action 0 + 2301 : 0.8 + 2302 : 0.2 +state 1965 observe1Greater1 observeIGreater1 + action 0 + 2303 : 0.8 + 2304 : 0.2 +state 1966 observe1Greater1 observeIGreater1 + action 0 + 2305 : 0.8 + 2306 : 0.2 +state 1967 observe1Greater1 observeIGreater1 + action 0 + 2307 : 1 +state 1968 + action 0 + 1470 : 0.8 + 2308 : 0.2 +state 1969 + action 0 + 2309 : 0.8 + 2310 : 0.2 +state 1970 + action 0 + 2311 : 0.8 + 2312 : 0.2 +state 1971 + action 0 + 2313 : 0.8 + 2314 : 0.2 +state 1972 + action 0 + 2315 : 0.8 + 2316 : 0.2 +state 1973 + action 0 + 2317 : 1 +state 1974 + action 0 + 1477 : 0.8 + 2318 : 0.2 +state 1975 + action 0 + 2319 : 0.8 + 2320 : 0.2 +state 1976 + action 0 + 2321 : 0.8 + 2322 : 0.2 +state 1977 + action 0 + 2323 : 0.8 + 2324 : 0.2 +state 1978 + action 0 + 2325 : 0.8 + 2326 : 0.2 +state 1979 + action 0 + 2327 : 1 +state 1980 + action 0 + 1484 : 0.8 + 2328 : 0.2 +state 1981 + action 0 + 2329 : 0.8 + 2330 : 0.2 +state 1982 + action 0 + 2331 : 0.8 + 2332 : 0.2 +state 1983 + action 0 + 2333 : 0.8 + 2334 : 0.2 +state 1984 + action 0 + 2335 : 0.8 + 2336 : 0.2 +state 1985 + action 0 + 2337 : 1 +state 1986 + action 0 + 2262 : 0.833 + 2263 : 0.167 +state 1987 observe1Greater1 observeIGreater1 + action 0 + 2338 : 1 +state 1988 + action 0 + 2339 : 1 +state 1989 + action 0 + 2340 : 1 +state 1990 + action 0 + 2341 : 1 +state 1991 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 1992 observe0Greater1 observeOnlyTrueSender + action 0 + 2347 : 1 +state 1993 observe2Greater1 observeIGreater1 + action 0 + 1505 : 0.8 + 2348 : 0.2 +state 1994 observe2Greater1 observeIGreater1 + action 0 + 2349 : 0.8 + 2350 : 0.2 +state 1995 observe2Greater1 observeIGreater1 + action 0 + 2351 : 0.8 + 2352 : 0.2 +state 1996 observe2Greater1 observeIGreater1 + action 0 + 2353 : 0.8 + 2354 : 0.2 +state 1997 observe2Greater1 observeIGreater1 + action 0 + 2355 : 0.8 + 2356 : 0.2 +state 1998 observe2Greater1 observeIGreater1 + action 0 + 2357 : 1 +state 1999 + action 0 + 1512 : 0.8 + 2358 : 0.2 +state 2000 + action 0 + 2359 : 0.8 + 2360 : 0.2 +state 2001 + action 0 + 2361 : 0.8 + 2362 : 0.2 +state 2002 + action 0 + 2363 : 0.8 + 2364 : 0.2 +state 2003 + action 0 + 2365 : 0.8 + 2366 : 0.2 +state 2004 + action 0 + 2367 : 1 +state 2005 + action 0 + 1519 : 0.8 + 2368 : 0.2 +state 2006 + action 0 + 2369 : 0.8 + 2370 : 0.2 +state 2007 + action 0 + 2371 : 0.8 + 2372 : 0.2 +state 2008 + action 0 + 2373 : 0.8 + 2374 : 0.2 +state 2009 + action 0 + 2375 : 0.8 + 2376 : 0.2 +state 2010 + action 0 + 2377 : 1 +state 2011 + action 0 + 2269 : 0.833 + 2270 : 0.167 +state 2012 + action 0 + 2378 : 1 +state 2013 observe2Greater1 observeIGreater1 + action 0 + 2379 : 1 +state 2014 + action 0 + 2380 : 1 +state 2015 + action 0 + 2381 : 1 +state 2016 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 2017 observe0Greater1 observeOnlyTrueSender + action 0 + 2387 : 1 +state 2018 observe3Greater1 observeIGreater1 + action 0 + 1540 : 0.8 + 2388 : 0.2 +state 2019 observe3Greater1 observeIGreater1 + action 0 + 2389 : 0.8 + 2390 : 0.2 +state 2020 observe3Greater1 observeIGreater1 + action 0 + 2391 : 0.8 + 2392 : 0.2 +state 2021 observe3Greater1 observeIGreater1 + action 0 + 2393 : 0.8 + 2394 : 0.2 +state 2022 observe3Greater1 observeIGreater1 + action 0 + 2395 : 0.8 + 2396 : 0.2 +state 2023 observe3Greater1 observeIGreater1 + action 0 + 2397 : 1 +state 2024 + action 0 + 1547 : 0.8 + 2398 : 0.2 +state 2025 + action 0 + 2399 : 0.8 + 2400 : 0.2 +state 2026 + action 0 + 2401 : 0.8 + 2402 : 0.2 +state 2027 + action 0 + 2403 : 0.8 + 2404 : 0.2 +state 2028 + action 0 + 2405 : 0.8 + 2406 : 0.2 +state 2029 + action 0 + 2407 : 1 +state 2030 + action 0 + 2276 : 0.833 + 2277 : 0.167 +state 2031 + action 0 + 2408 : 1 +state 2032 + action 0 + 2409 : 1 +state 2033 observe3Greater1 observeIGreater1 + action 0 + 2410 : 1 +state 2034 + action 0 + 2411 : 1 +state 2035 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 2036 observe0Greater1 observeOnlyTrueSender + action 0 + 2417 : 1 +state 2037 observe4Greater1 observeIGreater1 + action 0 + 1568 : 0.8 + 2418 : 0.2 +state 2038 observe4Greater1 observeIGreater1 + action 0 + 2419 : 0.8 + 2420 : 0.2 +state 2039 observe4Greater1 observeIGreater1 + action 0 + 2421 : 0.8 + 2422 : 0.2 +state 2040 observe4Greater1 observeIGreater1 + action 0 + 2423 : 0.8 + 2424 : 0.2 +state 2041 observe4Greater1 observeIGreater1 + action 0 + 2425 : 0.8 + 2426 : 0.2 +state 2042 observe4Greater1 observeIGreater1 + action 0 + 2427 : 1 +state 2043 + action 0 + 2283 : 0.833 + 2284 : 0.167 +state 2044 + action 0 + 2428 : 1 +state 2045 + action 0 + 2429 : 1 +state 2046 + action 0 + 2430 : 1 +state 2047 observe4Greater1 observeIGreater1 + action 0 + 2431 : 1 +state 2048 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 2049 observe0Greater1 observeOnlyTrueSender + action 0 + 2437 : 1 +state 2050 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2050 : 1 +state 2051 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2052 observe0Greater1 observeOnlyTrueSender + action 0 + 2438 : 1 +state 2053 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2053 : 1 +state 2054 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2055 observe0Greater1 observeOnlyTrueSender + action 0 + 2439 : 1 +state 2056 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2056 : 1 +state 2057 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2058 observe0Greater1 observeOnlyTrueSender + action 0 + 2440 : 1 +state 2059 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2059 : 1 +state 2060 observe0Greater1 observeOnlyTrueSender + action 0 + 1457 : 0.2 + 1458 : 0.2 + 1459 : 0.2 + 1460 : 0.2 + 1461 : 0.2 +state 2061 observe0Greater1 observeOnlyTrueSender + action 0 + 2441 : 1 +state 2062 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2062 : 1 +state 2063 observe1Greater1 observeIGreater1 + action 0 + 2442 : 0.833 + 2443 : 0.167 +state 2064 observe1Greater1 observeIGreater1 + action 0 + 2444 : 0.833 + 2445 : 0.167 +state 2065 observe1Greater1 observeIGreater1 + action 0 + 2446 : 0.833 + 2447 : 0.167 +state 2066 observe1Greater1 observeIGreater1 + action 0 + 2448 : 0.833 + 2449 : 0.167 +state 2067 observe1Greater1 observeIGreater1 + action 0 + 1468 : 0.833 + 1469 : 0.167 +state 2068 observe1Greater1 observeIGreater1 + action 0 + 2450 : 1 +state 2069 observe1Greater1 observeIGreater1 + action 0 + 2451 : 0.833 + 2452 : 0.167 +state 2070 observe1Greater1 observeIGreater1 + action 0 + 2453 : 1 +state 2071 observe1Greater1 observeIGreater1 + action 0 + 2454 : 0.833 + 2455 : 0.167 +state 2072 observe1Greater1 observeIGreater1 + action 0 + 2456 : 1 +state 2073 observe1Greater1 observeIGreater1 + action 0 + 2457 : 0.833 + 2458 : 0.167 +state 2074 observe1Greater1 observeIGreater1 + action 0 + 2459 : 1 +state 2075 observe1Greater1 observeIGreater1 + action 0 + 2460 : 0.833 + 2461 : 0.167 +state 2076 observe1Greater1 observeIGreater1 + action 0 + 2462 : 1 +state 2077 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2463 : 1 +state 2078 observe2Greater1 observeIGreater1 + action 0 + 2464 : 0.833 + 2465 : 0.167 +state 2079 + action 0 + 2466 : 0.833 + 2467 : 0.167 +state 2080 + action 0 + 2468 : 0.833 + 2469 : 0.167 +state 2081 + action 0 + 1475 : 0.833 + 1476 : 0.167 +state 2082 + action 0 + 2470 : 1 +state 2083 + action 0 + 2471 : 0.833 + 2472 : 0.167 +state 2084 + action 0 + 2473 : 1 +state 2085 + action 0 + 2474 : 0.833 + 2475 : 0.167 +state 2086 + action 0 + 2476 : 1 +state 2087 + action 0 + 2477 : 0.833 + 2478 : 0.167 +state 2088 + action 0 + 2479 : 1 +state 2089 + action 0 + 2480 : 0.833 + 2481 : 0.167 +state 2090 + action 0 + 2482 : 1 +state 2091 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2092 observe3Greater1 observeIGreater1 + action 0 + 2484 : 0.833 + 2485 : 0.167 +state 2093 + action 0 + 2486 : 0.833 + 2487 : 0.167 +state 2094 + action 0 + 1482 : 0.833 + 1483 : 0.167 +state 2095 + action 0 + 2488 : 1 +state 2096 + action 0 + 2489 : 0.833 + 2490 : 0.167 +state 2097 + action 0 + 2491 : 1 +state 2098 + action 0 + 2492 : 0.833 + 2493 : 0.167 +state 2099 + action 0 + 2494 : 1 +state 2100 + action 0 + 2495 : 0.833 + 2496 : 0.167 +state 2101 + action 0 + 2497 : 1 +state 2102 + action 0 + 2498 : 0.833 + 2499 : 0.167 +state 2103 + action 0 + 2500 : 1 +state 2104 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2105 observe4Greater1 observeIGreater1 + action 0 + 2502 : 0.833 + 2503 : 0.167 +state 2106 + action 0 + 1489 : 0.833 + 1490 : 0.167 +state 2107 + action 0 + 2504 : 1 +state 2108 + action 0 + 2505 : 0.833 + 2506 : 0.167 +state 2109 + action 0 + 2507 : 1 +state 2110 + action 0 + 2508 : 0.833 + 2509 : 0.167 +state 2111 + action 0 + 2510 : 1 +state 2112 + action 0 + 2511 : 0.833 + 2512 : 0.167 +state 2113 + action 0 + 2513 : 1 +state 2114 + action 0 + 2514 : 0.833 + 2515 : 0.167 +state 2115 + action 0 + 2516 : 1 +state 2116 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2117 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2463 : 1 +state 2118 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2119 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2120 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2121 observe0Greater1 observeOnlyTrueSender + action 0 + 2518 : 0.8 + 2519 : 0.2 +state 2122 observe0Greater1 observeOnlyTrueSender + action 0 + 2520 : 0.8 + 2521 : 0.2 +state 2123 observe0Greater1 observeOnlyTrueSender + action 0 + 2522 : 0.8 + 2523 : 0.2 +state 2124 observe0Greater1 observeOnlyTrueSender + action 0 + 2524 : 0.8 + 2525 : 0.2 +state 2125 observe0Greater1 observeOnlyTrueSender + action 0 + 2526 : 0.8 + 2527 : 0.2 +state 2126 observe0Greater1 observeOnlyTrueSender + action 0 + 2528 : 1 +state 2127 observe2Greater1 observeIGreater1 + action 0 + 2529 : 0.833 + 2530 : 0.167 +state 2128 observe2Greater1 observeIGreater1 + action 0 + 2531 : 0.833 + 2532 : 0.167 +state 2129 observe2Greater1 observeIGreater1 + action 0 + 2533 : 0.833 + 2534 : 0.167 +state 2130 observe2Greater1 observeIGreater1 + action 0 + 1510 : 0.833 + 1511 : 0.167 +state 2131 observe2Greater1 observeIGreater1 + action 0 + 2535 : 1 +state 2132 observe2Greater1 observeIGreater1 + action 0 + 2536 : 0.833 + 2537 : 0.167 +state 2133 observe2Greater1 observeIGreater1 + action 0 + 2538 : 1 +state 2134 observe2Greater1 observeIGreater1 + action 0 + 2539 : 0.833 + 2540 : 0.167 +state 2135 observe2Greater1 observeIGreater1 + action 0 + 2541 : 1 +state 2136 observe2Greater1 observeIGreater1 + action 0 + 2542 : 0.833 + 2543 : 0.167 +state 2137 observe2Greater1 observeIGreater1 + action 0 + 2544 : 1 +state 2138 observe2Greater1 observeIGreater1 + action 0 + 2545 : 0.833 + 2546 : 0.167 +state 2139 observe2Greater1 observeIGreater1 + action 0 + 2547 : 1 +state 2140 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2548 : 1 +state 2141 observe3Greater1 observeIGreater1 + action 0 + 2549 : 0.833 + 2550 : 0.167 +state 2142 + action 0 + 2551 : 0.833 + 2552 : 0.167 +state 2143 + action 0 + 1517 : 0.833 + 1518 : 0.167 +state 2144 + action 0 + 2553 : 1 +state 2145 + action 0 + 2554 : 0.833 + 2555 : 0.167 +state 2146 + action 0 + 2556 : 1 +state 2147 + action 0 + 2557 : 0.833 + 2558 : 0.167 +state 2148 + action 0 + 2559 : 1 +state 2149 + action 0 + 2560 : 0.833 + 2561 : 0.167 +state 2150 + action 0 + 2562 : 1 +state 2151 + action 0 + 2563 : 0.833 + 2564 : 0.167 +state 2152 + action 0 + 2565 : 1 +state 2153 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2154 observe4Greater1 observeIGreater1 + action 0 + 2567 : 0.833 + 2568 : 0.167 +state 2155 + action 0 + 1524 : 0.833 + 1525 : 0.167 +state 2156 + action 0 + 2569 : 1 +state 2157 + action 0 + 2570 : 0.833 + 2571 : 0.167 +state 2158 + action 0 + 2572 : 1 +state 2159 + action 0 + 2573 : 0.833 + 2574 : 0.167 +state 2160 + action 0 + 2575 : 1 +state 2161 + action 0 + 2576 : 0.833 + 2577 : 0.167 +state 2162 + action 0 + 2578 : 1 +state 2163 + action 0 + 2579 : 0.833 + 2580 : 0.167 +state 2164 + action 0 + 2581 : 1 +state 2165 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2166 observe0Greater1 observeOnlyTrueSender + action 0 + 2483 : 1 +state 2167 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 2548 : 1 +state 2168 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2169 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2170 observe0Greater1 observeOnlyTrueSender + action 0 + 2583 : 0.8 + 2584 : 0.2 +state 2171 observe0Greater1 observeOnlyTrueSender + action 0 + 2585 : 0.8 + 2586 : 0.2 +state 2172 observe0Greater1 observeOnlyTrueSender + action 0 + 2587 : 0.8 + 2588 : 0.2 +state 2173 observe0Greater1 observeOnlyTrueSender + action 0 + 2589 : 0.8 + 2590 : 0.2 +state 2174 observe0Greater1 observeOnlyTrueSender + action 0 + 2591 : 0.8 + 2592 : 0.2 +state 2175 observe0Greater1 observeOnlyTrueSender + action 0 + 2593 : 1 +state 2176 observe3Greater1 observeIGreater1 + action 0 + 2594 : 0.833 + 2595 : 0.167 +state 2177 observe3Greater1 observeIGreater1 + action 0 + 2596 : 0.833 + 2597 : 0.167 +state 2178 observe3Greater1 observeIGreater1 + action 0 + 1545 : 0.833 + 1546 : 0.167 +state 2179 observe3Greater1 observeIGreater1 + action 0 + 2598 : 1 +state 2180 observe3Greater1 observeIGreater1 + action 0 + 2599 : 0.833 + 2600 : 0.167 +state 2181 observe3Greater1 observeIGreater1 + action 0 + 2601 : 1 +state 2182 observe3Greater1 observeIGreater1 + action 0 + 2602 : 0.833 + 2603 : 0.167 +state 2183 observe3Greater1 observeIGreater1 + action 0 + 2604 : 1 +state 2184 observe3Greater1 observeIGreater1 + action 0 + 2605 : 0.833 + 2606 : 0.167 +state 2185 observe3Greater1 observeIGreater1 + action 0 + 2607 : 1 +state 2186 observe3Greater1 observeIGreater1 + action 0 + 2608 : 0.833 + 2609 : 0.167 +state 2187 observe3Greater1 observeIGreater1 + action 0 + 2610 : 1 +state 2188 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2611 : 1 +state 2189 observe4Greater1 observeIGreater1 + action 0 + 2612 : 0.833 + 2613 : 0.167 +state 2190 + action 0 + 1552 : 0.833 + 1553 : 0.167 +state 2191 + action 0 + 2614 : 1 +state 2192 + action 0 + 2615 : 0.833 + 2616 : 0.167 +state 2193 + action 0 + 2617 : 1 +state 2194 + action 0 + 2618 : 0.833 + 2619 : 0.167 +state 2195 + action 0 + 2620 : 1 +state 2196 + action 0 + 2621 : 0.833 + 2622 : 0.167 +state 2197 + action 0 + 2623 : 1 +state 2198 + action 0 + 2624 : 0.833 + 2625 : 0.167 +state 2199 + action 0 + 2626 : 1 +state 2200 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2201 observe0Greater1 observeOnlyTrueSender + action 0 + 2501 : 1 +state 2202 observe0Greater1 observeOnlyTrueSender + action 0 + 2566 : 1 +state 2203 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 2611 : 1 +state 2204 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2205 observe0Greater1 observeOnlyTrueSender + action 0 + 2628 : 0.8 + 2629 : 0.2 +state 2206 observe0Greater1 observeOnlyTrueSender + action 0 + 2630 : 0.8 + 2631 : 0.2 +state 2207 observe0Greater1 observeOnlyTrueSender + action 0 + 2632 : 0.8 + 2633 : 0.2 +state 2208 observe0Greater1 observeOnlyTrueSender + action 0 + 2634 : 0.8 + 2635 : 0.2 +state 2209 observe0Greater1 observeOnlyTrueSender + action 0 + 2636 : 0.8 + 2637 : 0.2 +state 2210 observe0Greater1 observeOnlyTrueSender + action 0 + 2638 : 1 +state 2211 observe4Greater1 observeIGreater1 + action 0 + 2639 : 0.833 + 2640 : 0.167 +state 2212 observe4Greater1 observeIGreater1 + action 0 + 1573 : 0.833 + 1574 : 0.167 +state 2213 observe4Greater1 observeIGreater1 + action 0 + 2641 : 1 +state 2214 observe4Greater1 observeIGreater1 + action 0 + 2642 : 0.833 + 2643 : 0.167 +state 2215 observe4Greater1 observeIGreater1 + action 0 + 2644 : 1 +state 2216 observe4Greater1 observeIGreater1 + action 0 + 2645 : 0.833 + 2646 : 0.167 +state 2217 observe4Greater1 observeIGreater1 + action 0 + 2647 : 1 +state 2218 observe4Greater1 observeIGreater1 + action 0 + 2648 : 0.833 + 2649 : 0.167 +state 2219 observe4Greater1 observeIGreater1 + action 0 + 2650 : 1 +state 2220 observe4Greater1 observeIGreater1 + action 0 + 2651 : 0.833 + 2652 : 0.167 +state 2221 observe4Greater1 observeIGreater1 + action 0 + 2653 : 1 +state 2222 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2654 : 1 +state 2223 observe0Greater1 observeOnlyTrueSender + action 0 + 2517 : 1 +state 2224 observe0Greater1 observeOnlyTrueSender + action 0 + 2582 : 1 +state 2225 observe0Greater1 observeOnlyTrueSender + action 0 + 2627 : 1 +state 2226 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 2654 : 1 +state 2227 observe0Greater1 observeOnlyTrueSender + action 0 + 2655 : 0.8 + 2656 : 0.2 +state 2228 observe0Greater1 observeOnlyTrueSender + action 0 + 2657 : 0.8 + 2658 : 0.2 +state 2229 observe0Greater1 observeOnlyTrueSender + action 0 + 2659 : 0.8 + 2660 : 0.2 +state 2230 observe0Greater1 observeOnlyTrueSender + action 0 + 2661 : 0.8 + 2662 : 0.2 +state 2231 observe0Greater1 observeOnlyTrueSender + action 0 + 2663 : 0.8 + 2664 : 0.2 +state 2232 observe0Greater1 observeOnlyTrueSender + action 0 + 2665 : 1 +state 2233 observe0Greater1 observeOnlyTrueSender + action 0 + 2666 : 1 +state 2234 observe0Greater1 observeOnlyTrueSender + action 0 + 2667 : 1 +state 2235 observe0Greater1 observeOnlyTrueSender + action 0 + 2668 : 1 +state 2236 observe0Greater1 observeOnlyTrueSender + action 0 + 2669 : 1 +state 2237 + action 0 + 1600 : 0.8 + 2670 : 0.2 +state 2238 + action 0 + 2671 : 0.8 + 2672 : 0.2 +state 2239 + action 0 + 2673 : 0.8 + 2674 : 0.2 +state 2240 + action 0 + 2675 : 0.8 + 2676 : 0.2 +state 2241 + action 0 + 2677 : 0.8 + 2678 : 0.2 +state 2242 + action 0 + 2679 : 1 +state 2243 + action 0 + 2680 : 0.833 + 2681 : 0.167 +state 2244 + action 0 + 2682 : 0.833 + 2683 : 0.167 +state 2245 + action 0 + 2684 : 0.833 + 2685 : 0.167 +state 2246 + action 0 + 2686 : 0.833 + 2687 : 0.167 +state 2247 + action 0 + 2688 : 1 +state 2248 + action 0 + 2689 : 0.833 + 2690 : 0.167 +state 2249 + action 0 + 2691 : 1 +state 2250 + action 0 + 2692 : 0.833 + 2693 : 0.167 +state 2251 + action 0 + 2694 : 1 +state 2252 + action 0 + 2695 : 0.833 + 2696 : 0.167 +state 2253 + action 0 + 2697 : 1 +state 2254 + action 0 + 2698 : 0.833 + 2699 : 0.167 +state 2255 + action 0 + 2700 : 1 +state 2256 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2256 : 1 +state 2257 + action 0 + 2680 : 0.833 + 2681 : 0.167 +state 2258 observe1Greater1 observeIGreater1 + action 0 + 2701 : 1 +state 2259 + action 0 + 2702 : 1 +state 2260 + action 0 + 2703 : 1 +state 2261 + action 0 + 2704 : 1 +state 2262 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 2263 + action 0 + 2710 : 1 +state 2264 + action 0 + 2682 : 0.833 + 2683 : 0.167 +state 2265 + action 0 + 2711 : 1 +state 2266 observe2Greater1 observeIGreater1 + action 0 + 2712 : 1 +state 2267 + action 0 + 2713 : 1 +state 2268 + action 0 + 2714 : 1 +state 2269 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 2270 + action 0 + 2720 : 1 +state 2271 + action 0 + 2684 : 0.833 + 2685 : 0.167 +state 2272 + action 0 + 2721 : 1 +state 2273 + action 0 + 2722 : 1 +state 2274 observe3Greater1 observeIGreater1 + action 0 + 2723 : 1 +state 2275 + action 0 + 2724 : 1 +state 2276 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 2277 + action 0 + 2730 : 1 +state 2278 + action 0 + 2686 : 0.833 + 2687 : 0.167 +state 2279 + action 0 + 2731 : 1 +state 2280 + action 0 + 2732 : 1 +state 2281 + action 0 + 2733 : 1 +state 2282 observe4Greater1 observeIGreater1 + action 0 + 2734 : 1 +state 2283 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 2284 + action 0 + 2740 : 1 +state 2285 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2285 : 1 +state 2286 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2287 observe0Greater1 observeOnlyTrueSender + action 0 + 2741 : 1 +state 2288 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2288 : 1 +state 2289 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2290 observe0Greater1 observeOnlyTrueSender + action 0 + 2742 : 1 +state 2291 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2291 : 1 +state 2292 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2293 observe0Greater1 observeOnlyTrueSender + action 0 + 2743 : 1 +state 2294 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2294 : 1 +state 2295 observe0Greater1 observeOnlyTrueSender + action 0 + 1651 : 0.2 + 1652 : 0.2 + 1653 : 0.2 + 1654 : 0.2 + 1655 : 0.2 +state 2296 observe0Greater1 observeOnlyTrueSender + action 0 + 2744 : 1 +state 2297 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2297 : 1 +state 2298 observe1Greater1 observeIGreater1 + action 0 + 2745 : 1 +state 2299 observe1Greater1 observeIGreater1 + action 0 + 2746 : 0.833 + 2747 : 0.167 +state 2300 observe1Greater1 observeIGreater1 + action 0 + 2748 : 1 +state 2301 observe1Greater1 observeIGreater1 + action 0 + 2749 : 0.833 + 2750 : 0.167 +state 2302 observe1Greater1 observeIGreater1 + action 0 + 2751 : 1 +state 2303 observe1Greater1 observeIGreater1 + action 0 + 2752 : 0.833 + 2753 : 0.167 +state 2304 observe1Greater1 observeIGreater1 + action 0 + 2754 : 1 +state 2305 observe1Greater1 observeIGreater1 + action 0 + 2755 : 0.833 + 2756 : 0.167 +state 2306 observe1Greater1 observeIGreater1 + action 0 + 2757 : 1 +state 2307 observe1Greater1 observeIGreater1 + action 0 + 2758 : 1 +state 2308 + action 0 + 2759 : 1 +state 2309 + action 0 + 2760 : 0.833 + 2761 : 0.167 +state 2310 + action 0 + 2762 : 1 +state 2311 + action 0 + 2763 : 0.833 + 2764 : 0.167 +state 2312 + action 0 + 2765 : 1 +state 2313 + action 0 + 2766 : 0.833 + 2767 : 0.167 +state 2314 + action 0 + 2768 : 1 +state 2315 + action 0 + 2769 : 0.833 + 2770 : 0.167 +state 2316 + action 0 + 2771 : 1 +state 2317 + action 0 + 2772 : 1 +state 2318 + action 0 + 2773 : 1 +state 2319 + action 0 + 2774 : 0.833 + 2775 : 0.167 +state 2320 + action 0 + 2776 : 1 +state 2321 + action 0 + 2777 : 0.833 + 2778 : 0.167 +state 2322 + action 0 + 2779 : 1 +state 2323 + action 0 + 2780 : 0.833 + 2781 : 0.167 +state 2324 + action 0 + 2782 : 1 +state 2325 + action 0 + 2783 : 0.833 + 2784 : 0.167 +state 2326 + action 0 + 2785 : 1 +state 2327 + action 0 + 2786 : 1 +state 2328 + action 0 + 2787 : 1 +state 2329 + action 0 + 2788 : 0.833 + 2789 : 0.167 +state 2330 + action 0 + 2790 : 1 +state 2331 + action 0 + 2791 : 0.833 + 2792 : 0.167 +state 2332 + action 0 + 2793 : 1 +state 2333 + action 0 + 2794 : 0.833 + 2795 : 0.167 +state 2334 + action 0 + 2796 : 1 +state 2335 + action 0 + 2797 : 0.833 + 2798 : 0.167 +state 2336 + action 0 + 2799 : 1 +state 2337 + action 0 + 2800 : 1 +state 2338 observe1Greater1 observeIGreater1 + action 0 + 2758 : 1 +state 2339 + action 0 + 2772 : 1 +state 2340 + action 0 + 2786 : 1 +state 2341 + action 0 + 2800 : 1 +state 2342 observe0Greater1 observeOnlyTrueSender + action 0 + 1783 : 0.8 + 2801 : 0.2 +state 2343 observe0Greater1 observeOnlyTrueSender + action 0 + 2802 : 0.8 + 2803 : 0.2 +state 2344 observe0Greater1 observeOnlyTrueSender + action 0 + 2804 : 0.8 + 2805 : 0.2 +state 2345 observe0Greater1 observeOnlyTrueSender + action 0 + 2806 : 0.8 + 2807 : 0.2 +state 2346 observe0Greater1 observeOnlyTrueSender + action 0 + 2808 : 0.8 + 2809 : 0.2 +state 2347 observe0Greater1 observeOnlyTrueSender + action 0 + 2810 : 1 +state 2348 observe2Greater1 observeIGreater1 + action 0 + 2811 : 1 +state 2349 observe2Greater1 observeIGreater1 + action 0 + 2812 : 0.833 + 2813 : 0.167 +state 2350 observe2Greater1 observeIGreater1 + action 0 + 2814 : 1 +state 2351 observe2Greater1 observeIGreater1 + action 0 + 2815 : 0.833 + 2816 : 0.167 +state 2352 observe2Greater1 observeIGreater1 + action 0 + 2817 : 1 +state 2353 observe2Greater1 observeIGreater1 + action 0 + 2818 : 0.833 + 2819 : 0.167 +state 2354 observe2Greater1 observeIGreater1 + action 0 + 2820 : 1 +state 2355 observe2Greater1 observeIGreater1 + action 0 + 2821 : 0.833 + 2822 : 0.167 +state 2356 observe2Greater1 observeIGreater1 + action 0 + 2823 : 1 +state 2357 observe2Greater1 observeIGreater1 + action 0 + 2824 : 1 +state 2358 + action 0 + 2825 : 1 +state 2359 + action 0 + 2826 : 0.833 + 2827 : 0.167 +state 2360 + action 0 + 2828 : 1 +state 2361 + action 0 + 2829 : 0.833 + 2830 : 0.167 +state 2362 + action 0 + 2831 : 1 +state 2363 + action 0 + 2832 : 0.833 + 2833 : 0.167 +state 2364 + action 0 + 2834 : 1 +state 2365 + action 0 + 2835 : 0.833 + 2836 : 0.167 +state 2366 + action 0 + 2837 : 1 +state 2367 + action 0 + 2838 : 1 +state 2368 + action 0 + 2839 : 1 +state 2369 + action 0 + 2840 : 0.833 + 2841 : 0.167 +state 2370 + action 0 + 2842 : 1 +state 2371 + action 0 + 2843 : 0.833 + 2844 : 0.167 +state 2372 + action 0 + 2845 : 1 +state 2373 + action 0 + 2846 : 0.833 + 2847 : 0.167 +state 2374 + action 0 + 2848 : 1 +state 2375 + action 0 + 2849 : 0.833 + 2850 : 0.167 +state 2376 + action 0 + 2851 : 1 +state 2377 + action 0 + 2852 : 1 +state 2378 + action 0 + 2772 : 1 +state 2379 observe2Greater1 observeIGreater1 + action 0 + 2824 : 1 +state 2380 + action 0 + 2838 : 1 +state 2381 + action 0 + 2852 : 1 +state 2382 observe0Greater1 observeOnlyTrueSender + action 0 + 1820 : 0.8 + 2853 : 0.2 +state 2383 observe0Greater1 observeOnlyTrueSender + action 0 + 2854 : 0.8 + 2855 : 0.2 +state 2384 observe0Greater1 observeOnlyTrueSender + action 0 + 2856 : 0.8 + 2857 : 0.2 +state 2385 observe0Greater1 observeOnlyTrueSender + action 0 + 2858 : 0.8 + 2859 : 0.2 +state 2386 observe0Greater1 observeOnlyTrueSender + action 0 + 2860 : 0.8 + 2861 : 0.2 +state 2387 observe0Greater1 observeOnlyTrueSender + action 0 + 2862 : 1 +state 2388 observe3Greater1 observeIGreater1 + action 0 + 2863 : 1 +state 2389 observe3Greater1 observeIGreater1 + action 0 + 2864 : 0.833 + 2865 : 0.167 +state 2390 observe3Greater1 observeIGreater1 + action 0 + 2866 : 1 +state 2391 observe3Greater1 observeIGreater1 + action 0 + 2867 : 0.833 + 2868 : 0.167 +state 2392 observe3Greater1 observeIGreater1 + action 0 + 2869 : 1 +state 2393 observe3Greater1 observeIGreater1 + action 0 + 2870 : 0.833 + 2871 : 0.167 +state 2394 observe3Greater1 observeIGreater1 + action 0 + 2872 : 1 +state 2395 observe3Greater1 observeIGreater1 + action 0 + 2873 : 0.833 + 2874 : 0.167 +state 2396 observe3Greater1 observeIGreater1 + action 0 + 2875 : 1 +state 2397 observe3Greater1 observeIGreater1 + action 0 + 2876 : 1 +state 2398 + action 0 + 2877 : 1 +state 2399 + action 0 + 2878 : 0.833 + 2879 : 0.167 +state 2400 + action 0 + 2880 : 1 +state 2401 + action 0 + 2881 : 0.833 + 2882 : 0.167 +state 2402 + action 0 + 2883 : 1 +state 2403 + action 0 + 2884 : 0.833 + 2885 : 0.167 +state 2404 + action 0 + 2886 : 1 +state 2405 + action 0 + 2887 : 0.833 + 2888 : 0.167 +state 2406 + action 0 + 2889 : 1 +state 2407 + action 0 + 2890 : 1 +state 2408 + action 0 + 2786 : 1 +state 2409 + action 0 + 2838 : 1 +state 2410 observe3Greater1 observeIGreater1 + action 0 + 2876 : 1 +state 2411 + action 0 + 2890 : 1 +state 2412 observe0Greater1 observeOnlyTrueSender + action 0 + 1847 : 0.8 + 2891 : 0.2 +state 2413 observe0Greater1 observeOnlyTrueSender + action 0 + 2892 : 0.8 + 2893 : 0.2 +state 2414 observe0Greater1 observeOnlyTrueSender + action 0 + 2894 : 0.8 + 2895 : 0.2 +state 2415 observe0Greater1 observeOnlyTrueSender + action 0 + 2896 : 0.8 + 2897 : 0.2 +state 2416 observe0Greater1 observeOnlyTrueSender + action 0 + 2898 : 0.8 + 2899 : 0.2 +state 2417 observe0Greater1 observeOnlyTrueSender + action 0 + 2900 : 1 +state 2418 observe4Greater1 observeIGreater1 + action 0 + 2901 : 1 +state 2419 observe4Greater1 observeIGreater1 + action 0 + 2902 : 0.833 + 2903 : 0.167 +state 2420 observe4Greater1 observeIGreater1 + action 0 + 2904 : 1 +state 2421 observe4Greater1 observeIGreater1 + action 0 + 2905 : 0.833 + 2906 : 0.167 +state 2422 observe4Greater1 observeIGreater1 + action 0 + 2907 : 1 +state 2423 observe4Greater1 observeIGreater1 + action 0 + 2908 : 0.833 + 2909 : 0.167 +state 2424 observe4Greater1 observeIGreater1 + action 0 + 2910 : 1 +state 2425 observe4Greater1 observeIGreater1 + action 0 + 2911 : 0.833 + 2912 : 0.167 +state 2426 observe4Greater1 observeIGreater1 + action 0 + 2913 : 1 +state 2427 observe4Greater1 observeIGreater1 + action 0 + 2914 : 1 +state 2428 + action 0 + 2800 : 1 +state 2429 + action 0 + 2852 : 1 +state 2430 + action 0 + 2890 : 1 +state 2431 observe4Greater1 observeIGreater1 + action 0 + 2914 : 1 +state 2432 observe0Greater1 observeOnlyTrueSender + action 0 + 1864 : 0.8 + 2915 : 0.2 +state 2433 observe0Greater1 observeOnlyTrueSender + action 0 + 2916 : 0.8 + 2917 : 0.2 +state 2434 observe0Greater1 observeOnlyTrueSender + action 0 + 2918 : 0.8 + 2919 : 0.2 +state 2435 observe0Greater1 observeOnlyTrueSender + action 0 + 2920 : 0.8 + 2921 : 0.2 +state 2436 observe0Greater1 observeOnlyTrueSender + action 0 + 2922 : 0.8 + 2923 : 0.2 +state 2437 observe0Greater1 observeOnlyTrueSender + action 0 + 2924 : 1 +state 2438 observe0Greater1 observeOnlyTrueSender + action 0 + 2925 : 1 +state 2439 observe0Greater1 observeOnlyTrueSender + action 0 + 2926 : 1 +state 2440 observe0Greater1 observeOnlyTrueSender + action 0 + 2927 : 1 +state 2441 observe0Greater1 observeOnlyTrueSender + action 0 + 2928 : 1 +state 2442 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 2443 observe1Greater1 observeIGreater1 + action 0 + 2934 : 1 +state 2444 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 2445 observe1Greater1 observeIGreater1 + action 0 + 2940 : 1 +state 2446 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 2447 observe1Greater1 observeIGreater1 + action 0 + 2946 : 1 +state 2448 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 2449 observe1Greater1 observeIGreater1 + action 0 + 2952 : 1 +state 2450 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2451 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2452 observe1Greater1 observeIGreater1 + action 0 + 2954 : 1 +state 2453 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2454 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2455 observe1Greater1 observeIGreater1 + action 0 + 2955 : 1 +state 2456 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2457 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2458 observe1Greater1 observeIGreater1 + action 0 + 2956 : 1 +state 2459 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2460 observe1Greater1 observeIGreater1 + action 0 + 1747 : 0.2 + 1748 : 0.2 + 1749 : 0.2 + 1750 : 0.2 + 1751 : 0.2 +state 2461 observe1Greater1 observeIGreater1 + action 0 + 2957 : 1 +state 2462 observe1Greater1 observeIGreater1 + action 0 + 2953 : 1 +state 2463 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2958 : 0.833 + 2959 : 0.167 +state 2464 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 2465 observe2Greater1 observeIGreater1 + action 0 + 2965 : 1 +state 2466 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 2467 + action 0 + 2971 : 1 +state 2468 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 2469 + action 0 + 2977 : 1 +state 2470 + action 0 + 2978 : 1 +state 2471 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2472 + action 0 + 2979 : 1 +state 2473 + action 0 + 2978 : 1 +state 2474 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2475 + action 0 + 2980 : 1 +state 2476 + action 0 + 2978 : 1 +state 2477 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2478 + action 0 + 2981 : 1 +state 2479 + action 0 + 2978 : 1 +state 2480 + action 0 + 1757 : 0.2 + 1758 : 0.2 + 1759 : 0.2 + 1760 : 0.2 + 1761 : 0.2 +state 2481 + action 0 + 2982 : 1 +state 2482 + action 0 + 2978 : 1 +state 2483 observe0Greater1 observeOnlyTrueSender + action 0 + 2983 : 0.833 + 2984 : 0.167 +state 2484 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 2485 observe3Greater1 observeIGreater1 + action 0 + 2990 : 1 +state 2486 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 2487 + action 0 + 2996 : 1 +state 2488 + action 0 + 2997 : 1 +state 2489 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2490 + action 0 + 2998 : 1 +state 2491 + action 0 + 2997 : 1 +state 2492 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2493 + action 0 + 2999 : 1 +state 2494 + action 0 + 2997 : 1 +state 2495 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2496 + action 0 + 3000 : 1 +state 2497 + action 0 + 2997 : 1 +state 2498 + action 0 + 1767 : 0.2 + 1768 : 0.2 + 1769 : 0.2 + 1770 : 0.2 + 1771 : 0.2 +state 2499 + action 0 + 3001 : 1 +state 2500 + action 0 + 2997 : 1 +state 2501 observe0Greater1 observeOnlyTrueSender + action 0 + 3002 : 0.833 + 3003 : 0.167 +state 2502 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 2503 observe4Greater1 observeIGreater1 + action 0 + 3009 : 1 +state 2504 + action 0 + 3010 : 1 +state 2505 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2506 + action 0 + 3011 : 1 +state 2507 + action 0 + 3010 : 1 +state 2508 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2509 + action 0 + 3012 : 1 +state 2510 + action 0 + 3010 : 1 +state 2511 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2512 + action 0 + 3013 : 1 +state 2513 + action 0 + 3010 : 1 +state 2514 + action 0 + 1777 : 0.2 + 1778 : 0.2 + 1779 : 0.2 + 1780 : 0.2 + 1781 : 0.2 +state 2515 + action 0 + 3014 : 1 +state 2516 + action 0 + 3010 : 1 +state 2517 observe0Greater1 observeOnlyTrueSender + action 0 + 3015 : 0.833 + 3016 : 0.167 +state 2518 observe0Greater1 observeOnlyTrueSender + action 0 + 1788 : 0.833 + 1789 : 0.167 +state 2519 observe0Greater1 observeOnlyTrueSender + action 0 + 3017 : 1 +state 2520 observe0Greater1 observeOnlyTrueSender + action 0 + 3018 : 0.833 + 3019 : 0.167 +state 2521 observe0Greater1 observeOnlyTrueSender + action 0 + 3020 : 1 +state 2522 observe0Greater1 observeOnlyTrueSender + action 0 + 3021 : 0.833 + 3022 : 0.167 +state 2523 observe0Greater1 observeOnlyTrueSender + action 0 + 3023 : 1 +state 2524 observe0Greater1 observeOnlyTrueSender + action 0 + 3024 : 0.833 + 3025 : 0.167 +state 2525 observe0Greater1 observeOnlyTrueSender + action 0 + 3026 : 1 +state 2526 observe0Greater1 observeOnlyTrueSender + action 0 + 3027 : 0.833 + 3028 : 0.167 +state 2527 observe0Greater1 observeOnlyTrueSender + action 0 + 3029 : 1 +state 2528 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2528 : 1 +state 2529 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 2530 observe2Greater1 observeIGreater1 + action 0 + 3035 : 1 +state 2531 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 2532 observe2Greater1 observeIGreater1 + action 0 + 3041 : 1 +state 2533 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 2534 observe2Greater1 observeIGreater1 + action 0 + 3047 : 1 +state 2535 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2536 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2537 observe2Greater1 observeIGreater1 + action 0 + 3049 : 1 +state 2538 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2539 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2540 observe2Greater1 observeIGreater1 + action 0 + 3050 : 1 +state 2541 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2542 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2543 observe2Greater1 observeIGreater1 + action 0 + 3051 : 1 +state 2544 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2545 observe2Greater1 observeIGreater1 + action 0 + 1794 : 0.2 + 1795 : 0.2 + 1796 : 0.2 + 1797 : 0.2 + 1798 : 0.2 +state 2546 observe2Greater1 observeIGreater1 + action 0 + 3052 : 1 +state 2547 observe2Greater1 observeIGreater1 + action 0 + 3048 : 1 +state 2548 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3053 : 0.833 + 3054 : 0.167 +state 2549 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 2550 observe3Greater1 observeIGreater1 + action 0 + 3060 : 1 +state 2551 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 2552 + action 0 + 3066 : 1 +state 2553 + action 0 + 3067 : 1 +state 2554 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2555 + action 0 + 3068 : 1 +state 2556 + action 0 + 3067 : 1 +state 2557 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2558 + action 0 + 3069 : 1 +state 2559 + action 0 + 3067 : 1 +state 2560 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2561 + action 0 + 3070 : 1 +state 2562 + action 0 + 3067 : 1 +state 2563 + action 0 + 1804 : 0.2 + 1805 : 0.2 + 1806 : 0.2 + 1807 : 0.2 + 1808 : 0.2 +state 2564 + action 0 + 3071 : 1 +state 2565 + action 0 + 3067 : 1 +state 2566 observe0Greater1 observeOnlyTrueSender + action 0 + 3072 : 0.833 + 3073 : 0.167 +state 2567 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 2568 observe4Greater1 observeIGreater1 + action 0 + 3079 : 1 +state 2569 + action 0 + 3080 : 1 +state 2570 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2571 + action 0 + 3081 : 1 +state 2572 + action 0 + 3080 : 1 +state 2573 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2574 + action 0 + 3082 : 1 +state 2575 + action 0 + 3080 : 1 +state 2576 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2577 + action 0 + 3083 : 1 +state 2578 + action 0 + 3080 : 1 +state 2579 + action 0 + 1814 : 0.2 + 1815 : 0.2 + 1816 : 0.2 + 1817 : 0.2 + 1818 : 0.2 +state 2580 + action 0 + 3084 : 1 +state 2581 + action 0 + 3080 : 1 +state 2582 observe0Greater1 observeOnlyTrueSender + action 0 + 3085 : 0.833 + 3086 : 0.167 +state 2583 observe0Greater1 observeOnlyTrueSender + action 0 + 1825 : 0.833 + 1826 : 0.167 +state 2584 observe0Greater1 observeOnlyTrueSender + action 0 + 3087 : 1 +state 2585 observe0Greater1 observeOnlyTrueSender + action 0 + 3088 : 0.833 + 3089 : 0.167 +state 2586 observe0Greater1 observeOnlyTrueSender + action 0 + 3090 : 1 +state 2587 observe0Greater1 observeOnlyTrueSender + action 0 + 3091 : 0.833 + 3092 : 0.167 +state 2588 observe0Greater1 observeOnlyTrueSender + action 0 + 3093 : 1 +state 2589 observe0Greater1 observeOnlyTrueSender + action 0 + 3094 : 0.833 + 3095 : 0.167 +state 2590 observe0Greater1 observeOnlyTrueSender + action 0 + 3096 : 1 +state 2591 observe0Greater1 observeOnlyTrueSender + action 0 + 3097 : 0.833 + 3098 : 0.167 +state 2592 observe0Greater1 observeOnlyTrueSender + action 0 + 3099 : 1 +state 2593 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2593 : 1 +state 2594 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 2595 observe3Greater1 observeIGreater1 + action 0 + 3105 : 1 +state 2596 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 2597 observe3Greater1 observeIGreater1 + action 0 + 3111 : 1 +state 2598 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2599 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2600 observe3Greater1 observeIGreater1 + action 0 + 3113 : 1 +state 2601 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2602 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2603 observe3Greater1 observeIGreater1 + action 0 + 3114 : 1 +state 2604 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2605 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2606 observe3Greater1 observeIGreater1 + action 0 + 3115 : 1 +state 2607 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2608 observe3Greater1 observeIGreater1 + action 0 + 1831 : 0.2 + 1832 : 0.2 + 1833 : 0.2 + 1834 : 0.2 + 1835 : 0.2 +state 2609 observe3Greater1 observeIGreater1 + action 0 + 3116 : 1 +state 2610 observe3Greater1 observeIGreater1 + action 0 + 3112 : 1 +state 2611 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3117 : 0.833 + 3118 : 0.167 +state 2612 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 2613 observe4Greater1 observeIGreater1 + action 0 + 3124 : 1 +state 2614 + action 0 + 3125 : 1 +state 2615 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2616 + action 0 + 3126 : 1 +state 2617 + action 0 + 3125 : 1 +state 2618 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2619 + action 0 + 3127 : 1 +state 2620 + action 0 + 3125 : 1 +state 2621 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2622 + action 0 + 3128 : 1 +state 2623 + action 0 + 3125 : 1 +state 2624 + action 0 + 1841 : 0.2 + 1842 : 0.2 + 1843 : 0.2 + 1844 : 0.2 + 1845 : 0.2 +state 2625 + action 0 + 3129 : 1 +state 2626 + action 0 + 3125 : 1 +state 2627 observe0Greater1 observeOnlyTrueSender + action 0 + 3130 : 0.833 + 3131 : 0.167 +state 2628 observe0Greater1 observeOnlyTrueSender + action 0 + 1852 : 0.833 + 1853 : 0.167 +state 2629 observe0Greater1 observeOnlyTrueSender + action 0 + 3132 : 1 +state 2630 observe0Greater1 observeOnlyTrueSender + action 0 + 3133 : 0.833 + 3134 : 0.167 +state 2631 observe0Greater1 observeOnlyTrueSender + action 0 + 3135 : 1 +state 2632 observe0Greater1 observeOnlyTrueSender + action 0 + 3136 : 0.833 + 3137 : 0.167 +state 2633 observe0Greater1 observeOnlyTrueSender + action 0 + 3138 : 1 +state 2634 observe0Greater1 observeOnlyTrueSender + action 0 + 3139 : 0.833 + 3140 : 0.167 +state 2635 observe0Greater1 observeOnlyTrueSender + action 0 + 3141 : 1 +state 2636 observe0Greater1 observeOnlyTrueSender + action 0 + 3142 : 0.833 + 3143 : 0.167 +state 2637 observe0Greater1 observeOnlyTrueSender + action 0 + 3144 : 1 +state 2638 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2638 : 1 +state 2639 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 2640 observe4Greater1 observeIGreater1 + action 0 + 3150 : 1 +state 2641 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2642 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2643 observe4Greater1 observeIGreater1 + action 0 + 3152 : 1 +state 2644 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2645 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2646 observe4Greater1 observeIGreater1 + action 0 + 3153 : 1 +state 2647 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2648 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2649 observe4Greater1 observeIGreater1 + action 0 + 3154 : 1 +state 2650 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2651 observe4Greater1 observeIGreater1 + action 0 + 1858 : 0.2 + 1859 : 0.2 + 1860 : 0.2 + 1861 : 0.2 + 1862 : 0.2 +state 2652 observe4Greater1 observeIGreater1 + action 0 + 3155 : 1 +state 2653 observe4Greater1 observeIGreater1 + action 0 + 3151 : 1 +state 2654 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3156 : 0.833 + 3157 : 0.167 +state 2655 observe0Greater1 observeOnlyTrueSender + action 0 + 1869 : 0.833 + 1870 : 0.167 +state 2656 observe0Greater1 observeOnlyTrueSender + action 0 + 3158 : 1 +state 2657 observe0Greater1 observeOnlyTrueSender + action 0 + 3159 : 0.833 + 3160 : 0.167 +state 2658 observe0Greater1 observeOnlyTrueSender + action 0 + 3161 : 1 +state 2659 observe0Greater1 observeOnlyTrueSender + action 0 + 3162 : 0.833 + 3163 : 0.167 +state 2660 observe0Greater1 observeOnlyTrueSender + action 0 + 3164 : 1 +state 2661 observe0Greater1 observeOnlyTrueSender + action 0 + 3165 : 0.833 + 3166 : 0.167 +state 2662 observe0Greater1 observeOnlyTrueSender + action 0 + 3167 : 1 +state 2663 observe0Greater1 observeOnlyTrueSender + action 0 + 3168 : 0.833 + 3169 : 0.167 +state 2664 observe0Greater1 observeOnlyTrueSender + action 0 + 3170 : 1 +state 2665 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2665 : 1 +state 2666 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2666 : 1 +state 2667 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2667 : 1 +state 2668 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2668 : 1 +state 2669 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2669 : 1 +state 2670 + action 0 + 3171 : 1 +state 2671 + action 0 + 3172 : 0.833 + 3173 : 0.167 +state 2672 + action 0 + 3174 : 1 +state 2673 + action 0 + 3175 : 0.833 + 3176 : 0.167 +state 2674 + action 0 + 3177 : 1 +state 2675 + action 0 + 3178 : 0.833 + 3179 : 0.167 +state 2676 + action 0 + 3180 : 1 +state 2677 + action 0 + 3181 : 0.833 + 3182 : 0.167 +state 2678 + action 0 + 3183 : 1 +state 2679 deadlock + action 0 + 2679 : 1 +state 2680 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 2681 + action 0 + 3189 : 1 +state 2682 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 2683 + action 0 + 3195 : 1 +state 2684 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 2685 + action 0 + 3201 : 1 +state 2686 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 2687 + action 0 + 3207 : 1 +state 2688 deadlock + action 0 + 2688 : 1 +state 2689 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2690 + action 0 + 3208 : 1 +state 2691 deadlock + action 0 + 2691 : 1 +state 2692 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2693 + action 0 + 3209 : 1 +state 2694 deadlock + action 0 + 2694 : 1 +state 2695 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2696 + action 0 + 3210 : 1 +state 2697 deadlock + action 0 + 2697 : 1 +state 2698 + action 0 + 1890 : 0.2 + 1891 : 0.2 + 1892 : 0.2 + 1893 : 0.2 + 1894 : 0.2 +state 2699 + action 0 + 3211 : 1 +state 2700 deadlock + action 0 + 2700 : 1 +state 2701 observe1Greater1 observeIGreater1 + action 0 + 3212 : 1 +state 2702 + action 0 + 3213 : 1 +state 2703 + action 0 + 3214 : 1 +state 2704 + action 0 + 3215 : 1 +state 2705 + action 0 + 1986 : 0.8 + 3216 : 0.2 +state 2706 + action 0 + 3217 : 0.8 + 3218 : 0.2 +state 2707 + action 0 + 3219 : 0.8 + 3220 : 0.2 +state 2708 + action 0 + 3221 : 0.8 + 3222 : 0.2 +state 2709 + action 0 + 3223 : 0.8 + 3224 : 0.2 +state 2710 observe0Greater1 observeOnlyTrueSender + action 0 + 3225 : 1 +state 2711 + action 0 + 3213 : 1 +state 2712 observe2Greater1 observeIGreater1 + action 0 + 3226 : 1 +state 2713 + action 0 + 3227 : 1 +state 2714 + action 0 + 3228 : 1 +state 2715 + action 0 + 2011 : 0.8 + 3229 : 0.2 +state 2716 + action 0 + 3230 : 0.8 + 3231 : 0.2 +state 2717 + action 0 + 3232 : 0.8 + 3233 : 0.2 +state 2718 + action 0 + 3234 : 0.8 + 3235 : 0.2 +state 2719 + action 0 + 3236 : 0.8 + 3237 : 0.2 +state 2720 observe0Greater1 observeOnlyTrueSender + action 0 + 3238 : 1 +state 2721 + action 0 + 3214 : 1 +state 2722 + action 0 + 3227 : 1 +state 2723 observe3Greater1 observeIGreater1 + action 0 + 3239 : 1 +state 2724 + action 0 + 3240 : 1 +state 2725 + action 0 + 2030 : 0.8 + 3241 : 0.2 +state 2726 + action 0 + 3242 : 0.8 + 3243 : 0.2 +state 2727 + action 0 + 3244 : 0.8 + 3245 : 0.2 +state 2728 + action 0 + 3246 : 0.8 + 3247 : 0.2 +state 2729 + action 0 + 3248 : 0.8 + 3249 : 0.2 +state 2730 observe0Greater1 observeOnlyTrueSender + action 0 + 3250 : 1 +state 2731 + action 0 + 3215 : 1 +state 2732 + action 0 + 3228 : 1 +state 2733 + action 0 + 3240 : 1 +state 2734 observe4Greater1 observeIGreater1 + action 0 + 3251 : 1 +state 2735 + action 0 + 2043 : 0.8 + 3252 : 0.2 +state 2736 + action 0 + 3253 : 0.8 + 3254 : 0.2 +state 2737 + action 0 + 3255 : 0.8 + 3256 : 0.2 +state 2738 + action 0 + 3257 : 0.8 + 3258 : 0.2 +state 2739 + action 0 + 3259 : 0.8 + 3260 : 0.2 +state 2740 observe0Greater1 observeOnlyTrueSender + action 0 + 3261 : 1 +state 2741 observe0Greater1 observeOnlyTrueSender + action 0 + 3262 : 1 +state 2742 observe0Greater1 observeOnlyTrueSender + action 0 + 3263 : 1 +state 2743 observe0Greater1 observeOnlyTrueSender + action 0 + 3264 : 1 +state 2744 observe0Greater1 observeOnlyTrueSender + action 0 + 3265 : 1 +state 2745 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2746 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2747 observe1Greater1 observeIGreater1 + action 0 + 3267 : 1 +state 2748 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2749 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2750 observe1Greater1 observeIGreater1 + action 0 + 3268 : 1 +state 2751 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2752 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2753 observe1Greater1 observeIGreater1 + action 0 + 3269 : 1 +state 2754 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2755 observe1Greater1 observeIGreater1 + action 0 + 1962 : 0.2 + 1963 : 0.2 + 1964 : 0.2 + 1965 : 0.2 + 1966 : 0.2 +state 2756 observe1Greater1 observeIGreater1 + action 0 + 3270 : 1 +state 2757 observe1Greater1 observeIGreater1 + action 0 + 3266 : 1 +state 2758 observe1Greater1 observeIGreater1 + action 0 + 3271 : 0.833 + 3272 : 0.167 +state 2759 + action 0 + 3273 : 1 +state 2760 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2761 + action 0 + 3274 : 1 +state 2762 + action 0 + 3273 : 1 +state 2763 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2764 + action 0 + 3275 : 1 +state 2765 + action 0 + 3273 : 1 +state 2766 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2767 + action 0 + 3276 : 1 +state 2768 + action 0 + 3273 : 1 +state 2769 + action 0 + 1968 : 0.2 + 1969 : 0.2 + 1970 : 0.2 + 1971 : 0.2 + 1972 : 0.2 +state 2770 + action 0 + 3277 : 1 +state 2771 + action 0 + 3273 : 1 +state 2772 + action 0 + 3278 : 0.833 + 3279 : 0.167 +state 2773 + action 0 + 3280 : 1 +state 2774 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2775 + action 0 + 3281 : 1 +state 2776 + action 0 + 3280 : 1 +state 2777 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2778 + action 0 + 3282 : 1 +state 2779 + action 0 + 3280 : 1 +state 2780 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2781 + action 0 + 3283 : 1 +state 2782 + action 0 + 3280 : 1 +state 2783 + action 0 + 1974 : 0.2 + 1975 : 0.2 + 1976 : 0.2 + 1977 : 0.2 + 1978 : 0.2 +state 2784 + action 0 + 3284 : 1 +state 2785 + action 0 + 3280 : 1 +state 2786 + action 0 + 3285 : 0.833 + 3286 : 0.167 +state 2787 + action 0 + 3287 : 1 +state 2788 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2789 + action 0 + 3288 : 1 +state 2790 + action 0 + 3287 : 1 +state 2791 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2792 + action 0 + 3289 : 1 +state 2793 + action 0 + 3287 : 1 +state 2794 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2795 + action 0 + 3290 : 1 +state 2796 + action 0 + 3287 : 1 +state 2797 + action 0 + 1980 : 0.2 + 1981 : 0.2 + 1982 : 0.2 + 1983 : 0.2 + 1984 : 0.2 +state 2798 + action 0 + 3291 : 1 +state 2799 + action 0 + 3287 : 1 +state 2800 + action 0 + 3292 : 0.833 + 3293 : 0.167 +state 2801 observe0Greater1 observeOnlyTrueSender + action 0 + 3294 : 1 +state 2802 observe0Greater1 observeOnlyTrueSender + action 0 + 3295 : 0.833 + 3296 : 0.167 +state 2803 observe0Greater1 observeOnlyTrueSender + action 0 + 3297 : 1 +state 2804 observe0Greater1 observeOnlyTrueSender + action 0 + 3298 : 0.833 + 3299 : 0.167 +state 2805 observe0Greater1 observeOnlyTrueSender + action 0 + 3300 : 1 +state 2806 observe0Greater1 observeOnlyTrueSender + action 0 + 3301 : 0.833 + 3302 : 0.167 +state 2807 observe0Greater1 observeOnlyTrueSender + action 0 + 3303 : 1 +state 2808 observe0Greater1 observeOnlyTrueSender + action 0 + 3304 : 0.833 + 3305 : 0.167 +state 2809 observe0Greater1 observeOnlyTrueSender + action 0 + 3306 : 1 +state 2810 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2810 : 1 +state 2811 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2812 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2813 observe2Greater1 observeIGreater1 + action 0 + 3308 : 1 +state 2814 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2815 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2816 observe2Greater1 observeIGreater1 + action 0 + 3309 : 1 +state 2817 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2818 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2819 observe2Greater1 observeIGreater1 + action 0 + 3310 : 1 +state 2820 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2821 observe2Greater1 observeIGreater1 + action 0 + 1993 : 0.2 + 1994 : 0.2 + 1995 : 0.2 + 1996 : 0.2 + 1997 : 0.2 +state 2822 observe2Greater1 observeIGreater1 + action 0 + 3311 : 1 +state 2823 observe2Greater1 observeIGreater1 + action 0 + 3307 : 1 +state 2824 observe2Greater1 observeIGreater1 + action 0 + 3312 : 0.833 + 3313 : 0.167 +state 2825 + action 0 + 3314 : 1 +state 2826 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2827 + action 0 + 3315 : 1 +state 2828 + action 0 + 3314 : 1 +state 2829 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2830 + action 0 + 3316 : 1 +state 2831 + action 0 + 3314 : 1 +state 2832 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2833 + action 0 + 3317 : 1 +state 2834 + action 0 + 3314 : 1 +state 2835 + action 0 + 1999 : 0.2 + 2000 : 0.2 + 2001 : 0.2 + 2002 : 0.2 + 2003 : 0.2 +state 2836 + action 0 + 3318 : 1 +state 2837 + action 0 + 3314 : 1 +state 2838 + action 0 + 3319 : 0.833 + 3320 : 0.167 +state 2839 + action 0 + 3321 : 1 +state 2840 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2841 + action 0 + 3322 : 1 +state 2842 + action 0 + 3321 : 1 +state 2843 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2844 + action 0 + 3323 : 1 +state 2845 + action 0 + 3321 : 1 +state 2846 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2847 + action 0 + 3324 : 1 +state 2848 + action 0 + 3321 : 1 +state 2849 + action 0 + 2005 : 0.2 + 2006 : 0.2 + 2007 : 0.2 + 2008 : 0.2 + 2009 : 0.2 +state 2850 + action 0 + 3325 : 1 +state 2851 + action 0 + 3321 : 1 +state 2852 + action 0 + 3326 : 0.833 + 3327 : 0.167 +state 2853 observe0Greater1 observeOnlyTrueSender + action 0 + 3328 : 1 +state 2854 observe0Greater1 observeOnlyTrueSender + action 0 + 3329 : 0.833 + 3330 : 0.167 +state 2855 observe0Greater1 observeOnlyTrueSender + action 0 + 3331 : 1 +state 2856 observe0Greater1 observeOnlyTrueSender + action 0 + 3332 : 0.833 + 3333 : 0.167 +state 2857 observe0Greater1 observeOnlyTrueSender + action 0 + 3334 : 1 +state 2858 observe0Greater1 observeOnlyTrueSender + action 0 + 3335 : 0.833 + 3336 : 0.167 +state 2859 observe0Greater1 observeOnlyTrueSender + action 0 + 3337 : 1 +state 2860 observe0Greater1 observeOnlyTrueSender + action 0 + 3338 : 0.833 + 3339 : 0.167 +state 2861 observe0Greater1 observeOnlyTrueSender + action 0 + 3340 : 1 +state 2862 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2862 : 1 +state 2863 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2864 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2865 observe3Greater1 observeIGreater1 + action 0 + 3342 : 1 +state 2866 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2867 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2868 observe3Greater1 observeIGreater1 + action 0 + 3343 : 1 +state 2869 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2870 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2871 observe3Greater1 observeIGreater1 + action 0 + 3344 : 1 +state 2872 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2873 observe3Greater1 observeIGreater1 + action 0 + 2018 : 0.2 + 2019 : 0.2 + 2020 : 0.2 + 2021 : 0.2 + 2022 : 0.2 +state 2874 observe3Greater1 observeIGreater1 + action 0 + 3345 : 1 +state 2875 observe3Greater1 observeIGreater1 + action 0 + 3341 : 1 +state 2876 observe3Greater1 observeIGreater1 + action 0 + 3346 : 0.833 + 3347 : 0.167 +state 2877 + action 0 + 3348 : 1 +state 2878 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2879 + action 0 + 3349 : 1 +state 2880 + action 0 + 3348 : 1 +state 2881 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2882 + action 0 + 3350 : 1 +state 2883 + action 0 + 3348 : 1 +state 2884 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2885 + action 0 + 3351 : 1 +state 2886 + action 0 + 3348 : 1 +state 2887 + action 0 + 2024 : 0.2 + 2025 : 0.2 + 2026 : 0.2 + 2027 : 0.2 + 2028 : 0.2 +state 2888 + action 0 + 3352 : 1 +state 2889 + action 0 + 3348 : 1 +state 2890 + action 0 + 3353 : 0.833 + 3354 : 0.167 +state 2891 observe0Greater1 observeOnlyTrueSender + action 0 + 3355 : 1 +state 2892 observe0Greater1 observeOnlyTrueSender + action 0 + 3356 : 0.833 + 3357 : 0.167 +state 2893 observe0Greater1 observeOnlyTrueSender + action 0 + 3358 : 1 +state 2894 observe0Greater1 observeOnlyTrueSender + action 0 + 3359 : 0.833 + 3360 : 0.167 +state 2895 observe0Greater1 observeOnlyTrueSender + action 0 + 3361 : 1 +state 2896 observe0Greater1 observeOnlyTrueSender + action 0 + 3362 : 0.833 + 3363 : 0.167 +state 2897 observe0Greater1 observeOnlyTrueSender + action 0 + 3364 : 1 +state 2898 observe0Greater1 observeOnlyTrueSender + action 0 + 3365 : 0.833 + 3366 : 0.167 +state 2899 observe0Greater1 observeOnlyTrueSender + action 0 + 3367 : 1 +state 2900 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2900 : 1 +state 2901 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2902 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2903 observe4Greater1 observeIGreater1 + action 0 + 3369 : 1 +state 2904 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2905 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2906 observe4Greater1 observeIGreater1 + action 0 + 3370 : 1 +state 2907 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2908 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2909 observe4Greater1 observeIGreater1 + action 0 + 3371 : 1 +state 2910 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2911 observe4Greater1 observeIGreater1 + action 0 + 2037 : 0.2 + 2038 : 0.2 + 2039 : 0.2 + 2040 : 0.2 + 2041 : 0.2 +state 2912 observe4Greater1 observeIGreater1 + action 0 + 3372 : 1 +state 2913 observe4Greater1 observeIGreater1 + action 0 + 3368 : 1 +state 2914 observe4Greater1 observeIGreater1 + action 0 + 3373 : 0.833 + 3374 : 0.167 +state 2915 observe0Greater1 observeOnlyTrueSender + action 0 + 3375 : 1 +state 2916 observe0Greater1 observeOnlyTrueSender + action 0 + 3376 : 0.833 + 3377 : 0.167 +state 2917 observe0Greater1 observeOnlyTrueSender + action 0 + 3378 : 1 +state 2918 observe0Greater1 observeOnlyTrueSender + action 0 + 3379 : 0.833 + 3380 : 0.167 +state 2919 observe0Greater1 observeOnlyTrueSender + action 0 + 3381 : 1 +state 2920 observe0Greater1 observeOnlyTrueSender + action 0 + 3382 : 0.833 + 3383 : 0.167 +state 2921 observe0Greater1 observeOnlyTrueSender + action 0 + 3384 : 1 +state 2922 observe0Greater1 observeOnlyTrueSender + action 0 + 3385 : 0.833 + 3386 : 0.167 +state 2923 observe0Greater1 observeOnlyTrueSender + action 0 + 3387 : 1 +state 2924 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2924 : 1 +state 2925 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2925 : 1 +state 2926 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2926 : 1 +state 2927 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2927 : 1 +state 2928 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 2928 : 1 +state 2929 observe1Greater1 observeIGreater1 + action 0 + 3388 : 0.8 + 3389 : 0.2 +state 2930 observe1Greater1 observeIGreater1 + action 0 + 3390 : 0.8 + 3391 : 0.2 +state 2931 observe1Greater1 observeIGreater1 + action 0 + 3392 : 0.8 + 3393 : 0.2 +state 2932 observe1Greater1 observeIGreater1 + action 0 + 3394 : 0.8 + 3395 : 0.2 +state 2933 observe1Greater1 observeIGreater1 + action 0 + 3396 : 0.8 + 3397 : 0.2 +state 2934 observe1Greater1 observeIGreater1 + action 0 + 3398 : 1 +state 2935 observe1Greater1 observeIGreater1 + action 0 + 3399 : 0.8 + 3400 : 0.2 +state 2936 observe1Greater1 observeIGreater1 + action 0 + 3401 : 0.8 + 3402 : 0.2 +state 2937 observe1Greater1 observeIGreater1 + action 0 + 3403 : 0.8 + 3404 : 0.2 +state 2938 observe1Greater1 observeIGreater1 + action 0 + 3405 : 0.8 + 3406 : 0.2 +state 2939 observe1Greater1 observeIGreater1 + action 0 + 3407 : 0.8 + 3408 : 0.2 +state 2940 observe1Greater1 observeIGreater1 + action 0 + 3409 : 1 +state 2941 observe1Greater1 observeIGreater1 + action 0 + 3410 : 0.8 + 3411 : 0.2 +state 2942 observe1Greater1 observeIGreater1 + action 0 + 3412 : 0.8 + 3413 : 0.2 +state 2943 observe1Greater1 observeIGreater1 + action 0 + 3414 : 0.8 + 3415 : 0.2 +state 2944 observe1Greater1 observeIGreater1 + action 0 + 3416 : 0.8 + 3417 : 0.2 +state 2945 observe1Greater1 observeIGreater1 + action 0 + 3418 : 0.8 + 3419 : 0.2 +state 2946 observe1Greater1 observeIGreater1 + action 0 + 3420 : 1 +state 2947 observe1Greater1 observeIGreater1 + action 0 + 3421 : 0.8 + 3422 : 0.2 +state 2948 observe1Greater1 observeIGreater1 + action 0 + 3423 : 0.8 + 3424 : 0.2 +state 2949 observe1Greater1 observeIGreater1 + action 0 + 3425 : 0.8 + 3426 : 0.2 +state 2950 observe1Greater1 observeIGreater1 + action 0 + 3427 : 0.8 + 3428 : 0.2 +state 2951 observe1Greater1 observeIGreater1 + action 0 + 3429 : 0.8 + 3430 : 0.2 +state 2952 observe1Greater1 observeIGreater1 + action 0 + 3431 : 1 +state 2953 observe1Greater1 observeIGreater1 + action 0 + 3271 : 0.833 + 3272 : 0.167 +state 2954 observe1Greater1 observeIGreater1 + action 0 + 3432 : 1 +state 2955 observe1Greater1 observeIGreater1 + action 0 + 3433 : 1 +state 2956 observe1Greater1 observeIGreater1 + action 0 + 3434 : 1 +state 2957 observe1Greater1 observeIGreater1 + action 0 + 3435 : 1 +state 2958 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 2959 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3441 : 1 +state 2960 observe2Greater1 observeIGreater1 + action 0 + 3442 : 0.8 + 3443 : 0.2 +state 2961 observe2Greater1 observeIGreater1 + action 0 + 3444 : 0.8 + 3445 : 0.2 +state 2962 observe2Greater1 observeIGreater1 + action 0 + 3446 : 0.8 + 3447 : 0.2 +state 2963 observe2Greater1 observeIGreater1 + action 0 + 3448 : 0.8 + 3449 : 0.2 +state 2964 observe2Greater1 observeIGreater1 + action 0 + 3450 : 0.8 + 3451 : 0.2 +state 2965 observe2Greater1 observeIGreater1 + action 0 + 3452 : 1 +state 2966 + action 0 + 3453 : 0.8 + 3454 : 0.2 +state 2967 + action 0 + 3455 : 0.8 + 3456 : 0.2 +state 2968 + action 0 + 3457 : 0.8 + 3458 : 0.2 +state 2969 + action 0 + 3459 : 0.8 + 3460 : 0.2 +state 2970 + action 0 + 3461 : 0.8 + 3462 : 0.2 +state 2971 + action 0 + 3463 : 1 +state 2972 + action 0 + 3464 : 0.8 + 3465 : 0.2 +state 2973 + action 0 + 3466 : 0.8 + 3467 : 0.2 +state 2974 + action 0 + 3468 : 0.8 + 3469 : 0.2 +state 2975 + action 0 + 3470 : 0.8 + 3471 : 0.2 +state 2976 + action 0 + 3472 : 0.8 + 3473 : 0.2 +state 2977 + action 0 + 3474 : 1 +state 2978 + action 0 + 3278 : 0.833 + 3279 : 0.167 +state 2979 observe1Greater1 observeIGreater1 + action 0 + 3475 : 1 +state 2980 observe2Greater1 observeIGreater1 + action 0 + 3476 : 1 +state 2981 + action 0 + 3477 : 1 +state 2982 + action 0 + 3478 : 1 +state 2983 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 2984 observe0Greater1 observeOnlyTrueSender + action 0 + 3484 : 1 +state 2985 observe3Greater1 observeIGreater1 + action 0 + 3485 : 0.8 + 3486 : 0.2 +state 2986 observe3Greater1 observeIGreater1 + action 0 + 3487 : 0.8 + 3488 : 0.2 +state 2987 observe3Greater1 observeIGreater1 + action 0 + 3489 : 0.8 + 3490 : 0.2 +state 2988 observe3Greater1 observeIGreater1 + action 0 + 3491 : 0.8 + 3492 : 0.2 +state 2989 observe3Greater1 observeIGreater1 + action 0 + 3493 : 0.8 + 3494 : 0.2 +state 2990 observe3Greater1 observeIGreater1 + action 0 + 3495 : 1 +state 2991 + action 0 + 3496 : 0.8 + 3497 : 0.2 +state 2992 + action 0 + 3498 : 0.8 + 3499 : 0.2 +state 2993 + action 0 + 3500 : 0.8 + 3501 : 0.2 +state 2994 + action 0 + 3502 : 0.8 + 3503 : 0.2 +state 2995 + action 0 + 3504 : 0.8 + 3505 : 0.2 +state 2996 + action 0 + 3506 : 1 +state 2997 + action 0 + 3285 : 0.833 + 3286 : 0.167 +state 2998 observe1Greater1 observeIGreater1 + action 0 + 3507 : 1 +state 2999 + action 0 + 3508 : 1 +state 3000 observe3Greater1 observeIGreater1 + action 0 + 3509 : 1 +state 3001 + action 0 + 3510 : 1 +state 3002 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 3003 observe0Greater1 observeOnlyTrueSender + action 0 + 3516 : 1 +state 3004 observe4Greater1 observeIGreater1 + action 0 + 3517 : 0.8 + 3518 : 0.2 +state 3005 observe4Greater1 observeIGreater1 + action 0 + 3519 : 0.8 + 3520 : 0.2 +state 3006 observe4Greater1 observeIGreater1 + action 0 + 3521 : 0.8 + 3522 : 0.2 +state 3007 observe4Greater1 observeIGreater1 + action 0 + 3523 : 0.8 + 3524 : 0.2 +state 3008 observe4Greater1 observeIGreater1 + action 0 + 3525 : 0.8 + 3526 : 0.2 +state 3009 observe4Greater1 observeIGreater1 + action 0 + 3527 : 1 +state 3010 + action 0 + 3292 : 0.833 + 3293 : 0.167 +state 3011 observe1Greater1 observeIGreater1 + action 0 + 3528 : 1 +state 3012 + action 0 + 3529 : 1 +state 3013 + action 0 + 3530 : 1 +state 3014 observe4Greater1 observeIGreater1 + action 0 + 3531 : 1 +state 3015 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 3016 observe0Greater1 observeOnlyTrueSender + action 0 + 3537 : 1 +state 3017 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3017 : 1 +state 3018 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3019 observe0Greater1 observeOnlyTrueSender + action 0 + 3538 : 1 +state 3020 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3020 : 1 +state 3021 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3022 observe0Greater1 observeOnlyTrueSender + action 0 + 3539 : 1 +state 3023 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3023 : 1 +state 3024 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3025 observe0Greater1 observeOnlyTrueSender + action 0 + 3540 : 1 +state 3026 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3026 : 1 +state 3027 observe0Greater1 observeOnlyTrueSender + action 0 + 2121 : 0.2 + 2122 : 0.2 + 2123 : 0.2 + 2124 : 0.2 + 2125 : 0.2 +state 3028 observe0Greater1 observeOnlyTrueSender + action 0 + 3541 : 1 +state 3029 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3029 : 1 +state 3030 observe2Greater1 observeIGreater1 + action 0 + 3542 : 0.8 + 3543 : 0.2 +state 3031 observe2Greater1 observeIGreater1 + action 0 + 3544 : 0.8 + 3545 : 0.2 +state 3032 observe2Greater1 observeIGreater1 + action 0 + 3546 : 0.8 + 3547 : 0.2 +state 3033 observe2Greater1 observeIGreater1 + action 0 + 3548 : 0.8 + 3549 : 0.2 +state 3034 observe2Greater1 observeIGreater1 + action 0 + 3550 : 0.8 + 3551 : 0.2 +state 3035 observe2Greater1 observeIGreater1 + action 0 + 3552 : 1 +state 3036 observe2Greater1 observeIGreater1 + action 0 + 3553 : 0.8 + 3554 : 0.2 +state 3037 observe2Greater1 observeIGreater1 + action 0 + 3555 : 0.8 + 3556 : 0.2 +state 3038 observe2Greater1 observeIGreater1 + action 0 + 3557 : 0.8 + 3558 : 0.2 +state 3039 observe2Greater1 observeIGreater1 + action 0 + 3559 : 0.8 + 3560 : 0.2 +state 3040 observe2Greater1 observeIGreater1 + action 0 + 3561 : 0.8 + 3562 : 0.2 +state 3041 observe2Greater1 observeIGreater1 + action 0 + 3563 : 1 +state 3042 observe2Greater1 observeIGreater1 + action 0 + 3564 : 0.8 + 3565 : 0.2 +state 3043 observe2Greater1 observeIGreater1 + action 0 + 3566 : 0.8 + 3567 : 0.2 +state 3044 observe2Greater1 observeIGreater1 + action 0 + 3568 : 0.8 + 3569 : 0.2 +state 3045 observe2Greater1 observeIGreater1 + action 0 + 3570 : 0.8 + 3571 : 0.2 +state 3046 observe2Greater1 observeIGreater1 + action 0 + 3572 : 0.8 + 3573 : 0.2 +state 3047 observe2Greater1 observeIGreater1 + action 0 + 3574 : 1 +state 3048 observe2Greater1 observeIGreater1 + action 0 + 3312 : 0.833 + 3313 : 0.167 +state 3049 observe2Greater1 observeIGreater1 + action 0 + 3575 : 1 +state 3050 observe2Greater1 observeIGreater1 + action 0 + 3576 : 1 +state 3051 observe2Greater1 observeIGreater1 + action 0 + 3577 : 1 +state 3052 observe2Greater1 observeIGreater1 + action 0 + 3578 : 1 +state 3053 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 3054 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3584 : 1 +state 3055 observe3Greater1 observeIGreater1 + action 0 + 3585 : 0.8 + 3586 : 0.2 +state 3056 observe3Greater1 observeIGreater1 + action 0 + 3587 : 0.8 + 3588 : 0.2 +state 3057 observe3Greater1 observeIGreater1 + action 0 + 3589 : 0.8 + 3590 : 0.2 +state 3058 observe3Greater1 observeIGreater1 + action 0 + 3591 : 0.8 + 3592 : 0.2 +state 3059 observe3Greater1 observeIGreater1 + action 0 + 3593 : 0.8 + 3594 : 0.2 +state 3060 observe3Greater1 observeIGreater1 + action 0 + 3595 : 1 +state 3061 + action 0 + 3596 : 0.8 + 3597 : 0.2 +state 3062 + action 0 + 3598 : 0.8 + 3599 : 0.2 +state 3063 + action 0 + 3600 : 0.8 + 3601 : 0.2 +state 3064 + action 0 + 3602 : 0.8 + 3603 : 0.2 +state 3065 + action 0 + 3604 : 0.8 + 3605 : 0.2 +state 3066 + action 0 + 3606 : 1 +state 3067 + action 0 + 3319 : 0.833 + 3320 : 0.167 +state 3068 + action 0 + 3607 : 1 +state 3069 observe2Greater1 observeIGreater1 + action 0 + 3608 : 1 +state 3070 observe3Greater1 observeIGreater1 + action 0 + 3609 : 1 +state 3071 + action 0 + 3610 : 1 +state 3072 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 3073 observe0Greater1 observeOnlyTrueSender + action 0 + 3616 : 1 +state 3074 observe4Greater1 observeIGreater1 + action 0 + 3617 : 0.8 + 3618 : 0.2 +state 3075 observe4Greater1 observeIGreater1 + action 0 + 3619 : 0.8 + 3620 : 0.2 +state 3076 observe4Greater1 observeIGreater1 + action 0 + 3621 : 0.8 + 3622 : 0.2 +state 3077 observe4Greater1 observeIGreater1 + action 0 + 3623 : 0.8 + 3624 : 0.2 +state 3078 observe4Greater1 observeIGreater1 + action 0 + 3625 : 0.8 + 3626 : 0.2 +state 3079 observe4Greater1 observeIGreater1 + action 0 + 3627 : 1 +state 3080 + action 0 + 3326 : 0.833 + 3327 : 0.167 +state 3081 + action 0 + 3628 : 1 +state 3082 observe2Greater1 observeIGreater1 + action 0 + 3629 : 1 +state 3083 + action 0 + 3630 : 1 +state 3084 observe4Greater1 observeIGreater1 + action 0 + 3631 : 1 +state 3085 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 3086 observe0Greater1 observeOnlyTrueSender + action 0 + 3637 : 1 +state 3087 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3087 : 1 +state 3088 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3089 observe0Greater1 observeOnlyTrueSender + action 0 + 3638 : 1 +state 3090 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3090 : 1 +state 3091 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3092 observe0Greater1 observeOnlyTrueSender + action 0 + 3639 : 1 +state 3093 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3093 : 1 +state 3094 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3095 observe0Greater1 observeOnlyTrueSender + action 0 + 3640 : 1 +state 3096 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3096 : 1 +state 3097 observe0Greater1 observeOnlyTrueSender + action 0 + 2170 : 0.2 + 2171 : 0.2 + 2172 : 0.2 + 2173 : 0.2 + 2174 : 0.2 +state 3098 observe0Greater1 observeOnlyTrueSender + action 0 + 3641 : 1 +state 3099 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3099 : 1 +state 3100 observe3Greater1 observeIGreater1 + action 0 + 3642 : 0.8 + 3643 : 0.2 +state 3101 observe3Greater1 observeIGreater1 + action 0 + 3644 : 0.8 + 3645 : 0.2 +state 3102 observe3Greater1 observeIGreater1 + action 0 + 3646 : 0.8 + 3647 : 0.2 +state 3103 observe3Greater1 observeIGreater1 + action 0 + 3648 : 0.8 + 3649 : 0.2 +state 3104 observe3Greater1 observeIGreater1 + action 0 + 3650 : 0.8 + 3651 : 0.2 +state 3105 observe3Greater1 observeIGreater1 + action 0 + 3652 : 1 +state 3106 observe3Greater1 observeIGreater1 + action 0 + 3653 : 0.8 + 3654 : 0.2 +state 3107 observe3Greater1 observeIGreater1 + action 0 + 3655 : 0.8 + 3656 : 0.2 +state 3108 observe3Greater1 observeIGreater1 + action 0 + 3657 : 0.8 + 3658 : 0.2 +state 3109 observe3Greater1 observeIGreater1 + action 0 + 3659 : 0.8 + 3660 : 0.2 +state 3110 observe3Greater1 observeIGreater1 + action 0 + 3661 : 0.8 + 3662 : 0.2 +state 3111 observe3Greater1 observeIGreater1 + action 0 + 3663 : 1 +state 3112 observe3Greater1 observeIGreater1 + action 0 + 3346 : 0.833 + 3347 : 0.167 +state 3113 observe3Greater1 observeIGreater1 + action 0 + 3664 : 1 +state 3114 observe3Greater1 observeIGreater1 + action 0 + 3665 : 1 +state 3115 observe3Greater1 observeIGreater1 + action 0 + 3666 : 1 +state 3116 observe3Greater1 observeIGreater1 + action 0 + 3667 : 1 +state 3117 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 3118 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3673 : 1 +state 3119 observe4Greater1 observeIGreater1 + action 0 + 3674 : 0.8 + 3675 : 0.2 +state 3120 observe4Greater1 observeIGreater1 + action 0 + 3676 : 0.8 + 3677 : 0.2 +state 3121 observe4Greater1 observeIGreater1 + action 0 + 3678 : 0.8 + 3679 : 0.2 +state 3122 observe4Greater1 observeIGreater1 + action 0 + 3680 : 0.8 + 3681 : 0.2 +state 3123 observe4Greater1 observeIGreater1 + action 0 + 3682 : 0.8 + 3683 : 0.2 +state 3124 observe4Greater1 observeIGreater1 + action 0 + 3684 : 1 +state 3125 + action 0 + 3353 : 0.833 + 3354 : 0.167 +state 3126 + action 0 + 3685 : 1 +state 3127 + action 0 + 3686 : 1 +state 3128 observe3Greater1 observeIGreater1 + action 0 + 3687 : 1 +state 3129 observe4Greater1 observeIGreater1 + action 0 + 3688 : 1 +state 3130 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 3131 observe0Greater1 observeOnlyTrueSender + action 0 + 3694 : 1 +state 3132 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3132 : 1 +state 3133 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3134 observe0Greater1 observeOnlyTrueSender + action 0 + 3695 : 1 +state 3135 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3135 : 1 +state 3136 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3137 observe0Greater1 observeOnlyTrueSender + action 0 + 3696 : 1 +state 3138 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3138 : 1 +state 3139 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3140 observe0Greater1 observeOnlyTrueSender + action 0 + 3697 : 1 +state 3141 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3141 : 1 +state 3142 observe0Greater1 observeOnlyTrueSender + action 0 + 2205 : 0.2 + 2206 : 0.2 + 2207 : 0.2 + 2208 : 0.2 + 2209 : 0.2 +state 3143 observe0Greater1 observeOnlyTrueSender + action 0 + 3698 : 1 +state 3144 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3144 : 1 +state 3145 observe4Greater1 observeIGreater1 + action 0 + 3699 : 0.8 + 3700 : 0.2 +state 3146 observe4Greater1 observeIGreater1 + action 0 + 3701 : 0.8 + 3702 : 0.2 +state 3147 observe4Greater1 observeIGreater1 + action 0 + 3703 : 0.8 + 3704 : 0.2 +state 3148 observe4Greater1 observeIGreater1 + action 0 + 3705 : 0.8 + 3706 : 0.2 +state 3149 observe4Greater1 observeIGreater1 + action 0 + 3707 : 0.8 + 3708 : 0.2 +state 3150 observe4Greater1 observeIGreater1 + action 0 + 3709 : 1 +state 3151 observe4Greater1 observeIGreater1 + action 0 + 3373 : 0.833 + 3374 : 0.167 +state 3152 observe4Greater1 observeIGreater1 + action 0 + 3710 : 1 +state 3153 observe4Greater1 observeIGreater1 + action 0 + 3711 : 1 +state 3154 observe4Greater1 observeIGreater1 + action 0 + 3712 : 1 +state 3155 observe4Greater1 observeIGreater1 + action 0 + 3713 : 1 +state 3156 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 3157 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3719 : 1 +state 3158 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3158 : 1 +state 3159 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3160 observe0Greater1 observeOnlyTrueSender + action 0 + 3720 : 1 +state 3161 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3161 : 1 +state 3162 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3163 observe0Greater1 observeOnlyTrueSender + action 0 + 3721 : 1 +state 3164 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3164 : 1 +state 3165 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3166 observe0Greater1 observeOnlyTrueSender + action 0 + 3722 : 1 +state 3167 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3167 : 1 +state 3168 observe0Greater1 observeOnlyTrueSender + action 0 + 2227 : 0.2 + 2228 : 0.2 + 2229 : 0.2 + 2230 : 0.2 + 2231 : 0.2 +state 3169 observe0Greater1 observeOnlyTrueSender + action 0 + 3723 : 1 +state 3170 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3170 : 1 +state 3171 deadlock + action 0 + 3171 : 1 +state 3172 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3173 + action 0 + 3724 : 1 +state 3174 deadlock + action 0 + 3174 : 1 +state 3175 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3176 + action 0 + 3725 : 1 +state 3177 deadlock + action 0 + 3177 : 1 +state 3178 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3179 + action 0 + 3726 : 1 +state 3180 deadlock + action 0 + 3180 : 1 +state 3181 + action 0 + 2237 : 0.2 + 2238 : 0.2 + 2239 : 0.2 + 2240 : 0.2 + 2241 : 0.2 +state 3182 + action 0 + 3727 : 1 +state 3183 deadlock + action 0 + 3183 : 1 +state 3184 + action 0 + 2257 : 0.8 + 3728 : 0.2 +state 3185 + action 0 + 3729 : 0.8 + 3730 : 0.2 +state 3186 + action 0 + 3731 : 0.8 + 3732 : 0.2 +state 3187 + action 0 + 3733 : 0.8 + 3734 : 0.2 +state 3188 + action 0 + 3735 : 0.8 + 3736 : 0.2 +state 3189 + action 0 + 3737 : 1 +state 3190 + action 0 + 2264 : 0.8 + 3738 : 0.2 +state 3191 + action 0 + 3739 : 0.8 + 3740 : 0.2 +state 3192 + action 0 + 3741 : 0.8 + 3742 : 0.2 +state 3193 + action 0 + 3743 : 0.8 + 3744 : 0.2 +state 3194 + action 0 + 3745 : 0.8 + 3746 : 0.2 +state 3195 + action 0 + 3747 : 1 +state 3196 + action 0 + 2271 : 0.8 + 3748 : 0.2 +state 3197 + action 0 + 3749 : 0.8 + 3750 : 0.2 +state 3198 + action 0 + 3751 : 0.8 + 3752 : 0.2 +state 3199 + action 0 + 3753 : 0.8 + 3754 : 0.2 +state 3200 + action 0 + 3755 : 0.8 + 3756 : 0.2 +state 3201 + action 0 + 3757 : 1 +state 3202 + action 0 + 2278 : 0.8 + 3758 : 0.2 +state 3203 + action 0 + 3759 : 0.8 + 3760 : 0.2 +state 3204 + action 0 + 3761 : 0.8 + 3762 : 0.2 +state 3205 + action 0 + 3763 : 0.8 + 3764 : 0.2 +state 3206 + action 0 + 3765 : 0.8 + 3766 : 0.2 +state 3207 + action 0 + 3767 : 1 +state 3208 + action 0 + 3768 : 1 +state 3209 + action 0 + 3769 : 1 +state 3210 + action 0 + 3770 : 1 +state 3211 + action 0 + 3771 : 1 +state 3212 observe1Greater1 observeIGreater1 + action 0 + 3772 : 0.833 + 3773 : 0.167 +state 3213 + action 0 + 3774 : 0.833 + 3775 : 0.167 +state 3214 + action 0 + 3776 : 0.833 + 3777 : 0.167 +state 3215 + action 0 + 3778 : 0.833 + 3779 : 0.167 +state 3216 + action 0 + 3780 : 1 +state 3217 + action 0 + 3781 : 0.833 + 3782 : 0.167 +state 3218 + action 0 + 3783 : 1 +state 3219 + action 0 + 3784 : 0.833 + 3785 : 0.167 +state 3220 + action 0 + 3786 : 1 +state 3221 + action 0 + 3787 : 0.833 + 3788 : 0.167 +state 3222 + action 0 + 3789 : 1 +state 3223 + action 0 + 3790 : 0.833 + 3791 : 0.167 +state 3224 + action 0 + 3792 : 1 +state 3225 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3225 : 1 +state 3226 observe2Greater1 observeIGreater1 + action 0 + 3793 : 0.833 + 3794 : 0.167 +state 3227 + action 0 + 3795 : 0.833 + 3796 : 0.167 +state 3228 + action 0 + 3797 : 0.833 + 3798 : 0.167 +state 3229 + action 0 + 3799 : 1 +state 3230 + action 0 + 3800 : 0.833 + 3801 : 0.167 +state 3231 + action 0 + 3802 : 1 +state 3232 + action 0 + 3803 : 0.833 + 3804 : 0.167 +state 3233 + action 0 + 3805 : 1 +state 3234 + action 0 + 3806 : 0.833 + 3807 : 0.167 +state 3235 + action 0 + 3808 : 1 +state 3236 + action 0 + 3809 : 0.833 + 3810 : 0.167 +state 3237 + action 0 + 3811 : 1 +state 3238 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3238 : 1 +state 3239 observe3Greater1 observeIGreater1 + action 0 + 3812 : 0.833 + 3813 : 0.167 +state 3240 + action 0 + 3814 : 0.833 + 3815 : 0.167 +state 3241 + action 0 + 3816 : 1 +state 3242 + action 0 + 3817 : 0.833 + 3818 : 0.167 +state 3243 + action 0 + 3819 : 1 +state 3244 + action 0 + 3820 : 0.833 + 3821 : 0.167 +state 3245 + action 0 + 3822 : 1 +state 3246 + action 0 + 3823 : 0.833 + 3824 : 0.167 +state 3247 + action 0 + 3825 : 1 +state 3248 + action 0 + 3826 : 0.833 + 3827 : 0.167 +state 3249 + action 0 + 3828 : 1 +state 3250 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3250 : 1 +state 3251 observe4Greater1 observeIGreater1 + action 0 + 3829 : 0.833 + 3830 : 0.167 +state 3252 + action 0 + 3831 : 1 +state 3253 + action 0 + 3832 : 0.833 + 3833 : 0.167 +state 3254 + action 0 + 3834 : 1 +state 3255 + action 0 + 3835 : 0.833 + 3836 : 0.167 +state 3256 + action 0 + 3837 : 1 +state 3257 + action 0 + 3838 : 0.833 + 3839 : 0.167 +state 3258 + action 0 + 3840 : 1 +state 3259 + action 0 + 3841 : 0.833 + 3842 : 0.167 +state 3260 + action 0 + 3843 : 1 +state 3261 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3261 : 1 +state 3262 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3262 : 1 +state 3263 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3263 : 1 +state 3264 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3264 : 1 +state 3265 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3265 : 1 +state 3266 observe1Greater1 observeIGreater1 + action 0 + 3772 : 0.833 + 3773 : 0.167 +state 3267 observe1Greater1 observeIGreater1 + action 0 + 3844 : 1 +state 3268 observe1Greater1 observeIGreater1 + action 0 + 3845 : 1 +state 3269 observe1Greater1 observeIGreater1 + action 0 + 3846 : 1 +state 3270 observe1Greater1 observeIGreater1 + action 0 + 3847 : 1 +state 3271 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 3272 observe1Greater1 observeIGreater1 + action 0 + 3853 : 1 +state 3273 + action 0 + 3774 : 0.833 + 3775 : 0.167 +state 3274 observe1Greater1 observeIGreater1 + action 0 + 3854 : 1 +state 3275 observe2Greater1 observeIGreater1 + action 0 + 3855 : 1 +state 3276 + action 0 + 3856 : 1 +state 3277 + action 0 + 3857 : 1 +state 3278 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 3279 + action 0 + 3863 : 1 +state 3280 + action 0 + 3776 : 0.833 + 3777 : 0.167 +state 3281 observe1Greater1 observeIGreater1 + action 0 + 3864 : 1 +state 3282 + action 0 + 3865 : 1 +state 3283 observe3Greater1 observeIGreater1 + action 0 + 3866 : 1 +state 3284 + action 0 + 3867 : 1 +state 3285 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 3286 + action 0 + 3873 : 1 +state 3287 + action 0 + 3778 : 0.833 + 3779 : 0.167 +state 3288 observe1Greater1 observeIGreater1 + action 0 + 3874 : 1 +state 3289 + action 0 + 3875 : 1 +state 3290 + action 0 + 3876 : 1 +state 3291 observe4Greater1 observeIGreater1 + action 0 + 3877 : 1 +state 3292 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 3293 + action 0 + 3883 : 1 +state 3294 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3294 : 1 +state 3295 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3296 observe0Greater1 observeOnlyTrueSender + action 0 + 3884 : 1 +state 3297 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3297 : 1 +state 3298 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3299 observe0Greater1 observeOnlyTrueSender + action 0 + 3885 : 1 +state 3300 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3300 : 1 +state 3301 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3302 observe0Greater1 observeOnlyTrueSender + action 0 + 3886 : 1 +state 3303 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3303 : 1 +state 3304 observe0Greater1 observeOnlyTrueSender + action 0 + 2342 : 0.2 + 2343 : 0.2 + 2344 : 0.2 + 2345 : 0.2 + 2346 : 0.2 +state 3305 observe0Greater1 observeOnlyTrueSender + action 0 + 3887 : 1 +state 3306 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3306 : 1 +state 3307 observe2Greater1 observeIGreater1 + action 0 + 3793 : 0.833 + 3794 : 0.167 +state 3308 observe2Greater1 observeIGreater1 + action 0 + 3888 : 1 +state 3309 observe2Greater1 observeIGreater1 + action 0 + 3889 : 1 +state 3310 observe2Greater1 observeIGreater1 + action 0 + 3890 : 1 +state 3311 observe2Greater1 observeIGreater1 + action 0 + 3891 : 1 +state 3312 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 3313 observe2Greater1 observeIGreater1 + action 0 + 3897 : 1 +state 3314 + action 0 + 3795 : 0.833 + 3796 : 0.167 +state 3315 + action 0 + 3898 : 1 +state 3316 observe2Greater1 observeIGreater1 + action 0 + 3899 : 1 +state 3317 observe3Greater1 observeIGreater1 + action 0 + 3900 : 1 +state 3318 + action 0 + 3901 : 1 +state 3319 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 3320 + action 0 + 3907 : 1 +state 3321 + action 0 + 3797 : 0.833 + 3798 : 0.167 +state 3322 + action 0 + 3908 : 1 +state 3323 observe2Greater1 observeIGreater1 + action 0 + 3909 : 1 +state 3324 + action 0 + 3910 : 1 +state 3325 observe4Greater1 observeIGreater1 + action 0 + 3911 : 1 +state 3326 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 3327 + action 0 + 3917 : 1 +state 3328 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3328 : 1 +state 3329 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3330 observe0Greater1 observeOnlyTrueSender + action 0 + 3918 : 1 +state 3331 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3331 : 1 +state 3332 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3333 observe0Greater1 observeOnlyTrueSender + action 0 + 3919 : 1 +state 3334 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3334 : 1 +state 3335 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3336 observe0Greater1 observeOnlyTrueSender + action 0 + 3920 : 1 +state 3337 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3337 : 1 +state 3338 observe0Greater1 observeOnlyTrueSender + action 0 + 2382 : 0.2 + 2383 : 0.2 + 2384 : 0.2 + 2385 : 0.2 + 2386 : 0.2 +state 3339 observe0Greater1 observeOnlyTrueSender + action 0 + 3921 : 1 +state 3340 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3340 : 1 +state 3341 observe3Greater1 observeIGreater1 + action 0 + 3812 : 0.833 + 3813 : 0.167 +state 3342 observe3Greater1 observeIGreater1 + action 0 + 3922 : 1 +state 3343 observe3Greater1 observeIGreater1 + action 0 + 3923 : 1 +state 3344 observe3Greater1 observeIGreater1 + action 0 + 3924 : 1 +state 3345 observe3Greater1 observeIGreater1 + action 0 + 3925 : 1 +state 3346 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 3347 observe3Greater1 observeIGreater1 + action 0 + 3931 : 1 +state 3348 + action 0 + 3814 : 0.833 + 3815 : 0.167 +state 3349 + action 0 + 3932 : 1 +state 3350 + action 0 + 3933 : 1 +state 3351 observe3Greater1 observeIGreater1 + action 0 + 3934 : 1 +state 3352 observe4Greater1 observeIGreater1 + action 0 + 3935 : 1 +state 3353 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 3354 + action 0 + 3941 : 1 +state 3355 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3355 : 1 +state 3356 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3357 observe0Greater1 observeOnlyTrueSender + action 0 + 3942 : 1 +state 3358 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3358 : 1 +state 3359 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3360 observe0Greater1 observeOnlyTrueSender + action 0 + 3943 : 1 +state 3361 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3361 : 1 +state 3362 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3363 observe0Greater1 observeOnlyTrueSender + action 0 + 3944 : 1 +state 3364 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3364 : 1 +state 3365 observe0Greater1 observeOnlyTrueSender + action 0 + 2412 : 0.2 + 2413 : 0.2 + 2414 : 0.2 + 2415 : 0.2 + 2416 : 0.2 +state 3366 observe0Greater1 observeOnlyTrueSender + action 0 + 3945 : 1 +state 3367 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3367 : 1 +state 3368 observe4Greater1 observeIGreater1 + action 0 + 3829 : 0.833 + 3830 : 0.167 +state 3369 observe4Greater1 observeIGreater1 + action 0 + 3946 : 1 +state 3370 observe4Greater1 observeIGreater1 + action 0 + 3947 : 1 +state 3371 observe4Greater1 observeIGreater1 + action 0 + 3948 : 1 +state 3372 observe4Greater1 observeIGreater1 + action 0 + 3949 : 1 +state 3373 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 3374 observe4Greater1 observeIGreater1 + action 0 + 3955 : 1 +state 3375 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3375 : 1 +state 3376 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3377 observe0Greater1 observeOnlyTrueSender + action 0 + 3956 : 1 +state 3378 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3378 : 1 +state 3379 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3380 observe0Greater1 observeOnlyTrueSender + action 0 + 3957 : 1 +state 3381 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3381 : 1 +state 3382 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3383 observe0Greater1 observeOnlyTrueSender + action 0 + 3958 : 1 +state 3384 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3384 : 1 +state 3385 observe0Greater1 observeOnlyTrueSender + action 0 + 2432 : 0.2 + 2433 : 0.2 + 2434 : 0.2 + 2435 : 0.2 + 2436 : 0.2 +state 3386 observe0Greater1 observeOnlyTrueSender + action 0 + 3959 : 1 +state 3387 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 3387 : 1 +state 3388 observe1Greater1 observeIGreater1 + action 0 + 2442 : 0.833 + 2443 : 0.167 +state 3389 observe1Greater1 observeIGreater1 + action 0 + 3960 : 1 +state 3390 observe1Greater1 observeIGreater1 + action 0 + 3961 : 0.833 + 3962 : 0.167 +state 3391 observe1Greater1 observeIGreater1 + action 0 + 3963 : 1 +state 3392 observe1Greater1 observeIGreater1 + action 0 + 3964 : 0.833 + 3965 : 0.167 +state 3393 observe1Greater1 observeIGreater1 + action 0 + 3966 : 1 +state 3394 observe1Greater1 observeIGreater1 + action 0 + 3967 : 0.833 + 3968 : 0.167 +state 3395 observe1Greater1 observeIGreater1 + action 0 + 3969 : 1 +state 3396 observe1Greater1 observeIGreater1 + action 0 + 3970 : 0.833 + 3971 : 0.167 +state 3397 observe1Greater1 observeIGreater1 + action 0 + 3972 : 1 +state 3398 observe1Greater1 observeIGreater1 + action 0 + 3973 : 1 +state 3399 observe1Greater1 observeIGreater1 + action 0 + 2444 : 0.833 + 2445 : 0.167 +state 3400 observe1Greater1 observeIGreater1 + action 0 + 3974 : 1 +state 3401 observe1Greater1 observeIGreater1 + action 0 + 3975 : 0.833 + 3976 : 0.167 +state 3402 observe1Greater1 observeIGreater1 + action 0 + 3977 : 1 +state 3403 observe1Greater1 observeIGreater1 + action 0 + 3978 : 0.833 + 3979 : 0.167 +state 3404 observe1Greater1 observeIGreater1 + action 0 + 3980 : 1 +state 3405 observe1Greater1 observeIGreater1 + action 0 + 3981 : 0.833 + 3982 : 0.167 +state 3406 observe1Greater1 observeIGreater1 + action 0 + 3983 : 1 +state 3407 observe1Greater1 observeIGreater1 + action 0 + 3984 : 0.833 + 3985 : 0.167 +state 3408 observe1Greater1 observeIGreater1 + action 0 + 3986 : 1 +state 3409 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3410 observe1Greater1 observeIGreater1 + action 0 + 2446 : 0.833 + 2447 : 0.167 +state 3411 observe1Greater1 observeIGreater1 + action 0 + 3988 : 1 +state 3412 observe1Greater1 observeIGreater1 + action 0 + 3989 : 0.833 + 3990 : 0.167 +state 3413 observe1Greater1 observeIGreater1 + action 0 + 3991 : 1 +state 3414 observe1Greater1 observeIGreater1 + action 0 + 3992 : 0.833 + 3993 : 0.167 +state 3415 observe1Greater1 observeIGreater1 + action 0 + 3994 : 1 +state 3416 observe1Greater1 observeIGreater1 + action 0 + 3995 : 0.833 + 3996 : 0.167 +state 3417 observe1Greater1 observeIGreater1 + action 0 + 3997 : 1 +state 3418 observe1Greater1 observeIGreater1 + action 0 + 3998 : 0.833 + 3999 : 0.167 +state 3419 observe1Greater1 observeIGreater1 + action 0 + 4000 : 1 +state 3420 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3421 observe1Greater1 observeIGreater1 + action 0 + 2448 : 0.833 + 2449 : 0.167 +state 3422 observe1Greater1 observeIGreater1 + action 0 + 4002 : 1 +state 3423 observe1Greater1 observeIGreater1 + action 0 + 4003 : 0.833 + 4004 : 0.167 +state 3424 observe1Greater1 observeIGreater1 + action 0 + 4005 : 1 +state 3425 observe1Greater1 observeIGreater1 + action 0 + 4006 : 0.833 + 4007 : 0.167 +state 3426 observe1Greater1 observeIGreater1 + action 0 + 4008 : 1 +state 3427 observe1Greater1 observeIGreater1 + action 0 + 4009 : 0.833 + 4010 : 0.167 +state 3428 observe1Greater1 observeIGreater1 + action 0 + 4011 : 1 +state 3429 observe1Greater1 observeIGreater1 + action 0 + 4012 : 0.833 + 4013 : 0.167 +state 3430 observe1Greater1 observeIGreater1 + action 0 + 4014 : 1 +state 3431 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3432 observe1Greater1 observeIGreater1 + action 0 + 3973 : 1 +state 3433 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3434 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3435 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3436 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4016 : 0.8 + 4017 : 0.2 +state 3437 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4018 : 0.8 + 4019 : 0.2 +state 3438 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4020 : 0.8 + 4021 : 0.2 +state 3439 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4022 : 0.8 + 4023 : 0.2 +state 3440 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4024 : 0.8 + 4025 : 0.2 +state 3441 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4026 : 1 +state 3442 observe2Greater1 observeIGreater1 + action 0 + 2464 : 0.833 + 2465 : 0.167 +state 3443 observe2Greater1 observeIGreater1 + action 0 + 4027 : 1 +state 3444 observe2Greater1 observeIGreater1 + action 0 + 4028 : 0.833 + 4029 : 0.167 +state 3445 observe2Greater1 observeIGreater1 + action 0 + 4030 : 1 +state 3446 observe2Greater1 observeIGreater1 + action 0 + 4031 : 0.833 + 4032 : 0.167 +state 3447 observe2Greater1 observeIGreater1 + action 0 + 4033 : 1 +state 3448 observe2Greater1 observeIGreater1 + action 0 + 4034 : 0.833 + 4035 : 0.167 +state 3449 observe2Greater1 observeIGreater1 + action 0 + 4036 : 1 +state 3450 observe2Greater1 observeIGreater1 + action 0 + 4037 : 0.833 + 4038 : 0.167 +state 3451 observe2Greater1 observeIGreater1 + action 0 + 4039 : 1 +state 3452 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3453 + action 0 + 2466 : 0.833 + 2467 : 0.167 +state 3454 + action 0 + 4041 : 1 +state 3455 + action 0 + 4042 : 0.833 + 4043 : 0.167 +state 3456 + action 0 + 4044 : 1 +state 3457 + action 0 + 4045 : 0.833 + 4046 : 0.167 +state 3458 + action 0 + 4047 : 1 +state 3459 + action 0 + 4048 : 0.833 + 4049 : 0.167 +state 3460 + action 0 + 4050 : 1 +state 3461 + action 0 + 4051 : 0.833 + 4052 : 0.167 +state 3462 + action 0 + 4053 : 1 +state 3463 + action 0 + 4054 : 1 +state 3464 + action 0 + 2468 : 0.833 + 2469 : 0.167 +state 3465 + action 0 + 4055 : 1 +state 3466 + action 0 + 4056 : 0.833 + 4057 : 0.167 +state 3467 + action 0 + 4058 : 1 +state 3468 + action 0 + 4059 : 0.833 + 4060 : 0.167 +state 3469 + action 0 + 4061 : 1 +state 3470 + action 0 + 4062 : 0.833 + 4063 : 0.167 +state 3471 + action 0 + 4064 : 1 +state 3472 + action 0 + 4065 : 0.833 + 4066 : 0.167 +state 3473 + action 0 + 4067 : 1 +state 3474 + action 0 + 4068 : 1 +state 3475 observe1Greater1 observeIGreater1 + action 0 + 3987 : 1 +state 3476 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3477 + action 0 + 4054 : 1 +state 3478 + action 0 + 4068 : 1 +state 3479 observe0Greater1 observeOnlyTrueSender + action 0 + 4069 : 0.8 + 4070 : 0.2 +state 3480 observe0Greater1 observeOnlyTrueSender + action 0 + 4071 : 0.8 + 4072 : 0.2 +state 3481 observe0Greater1 observeOnlyTrueSender + action 0 + 4073 : 0.8 + 4074 : 0.2 +state 3482 observe0Greater1 observeOnlyTrueSender + action 0 + 4075 : 0.8 + 4076 : 0.2 +state 3483 observe0Greater1 observeOnlyTrueSender + action 0 + 4077 : 0.8 + 4078 : 0.2 +state 3484 observe0Greater1 observeOnlyTrueSender + action 0 + 4079 : 1 +state 3485 observe3Greater1 observeIGreater1 + action 0 + 2484 : 0.833 + 2485 : 0.167 +state 3486 observe3Greater1 observeIGreater1 + action 0 + 4080 : 1 +state 3487 observe3Greater1 observeIGreater1 + action 0 + 4081 : 0.833 + 4082 : 0.167 +state 3488 observe3Greater1 observeIGreater1 + action 0 + 4083 : 1 +state 3489 observe3Greater1 observeIGreater1 + action 0 + 4084 : 0.833 + 4085 : 0.167 +state 3490 observe3Greater1 observeIGreater1 + action 0 + 4086 : 1 +state 3491 observe3Greater1 observeIGreater1 + action 0 + 4087 : 0.833 + 4088 : 0.167 +state 3492 observe3Greater1 observeIGreater1 + action 0 + 4089 : 1 +state 3493 observe3Greater1 observeIGreater1 + action 0 + 4090 : 0.833 + 4091 : 0.167 +state 3494 observe3Greater1 observeIGreater1 + action 0 + 4092 : 1 +state 3495 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3496 + action 0 + 2486 : 0.833 + 2487 : 0.167 +state 3497 + action 0 + 4094 : 1 +state 3498 + action 0 + 4095 : 0.833 + 4096 : 0.167 +state 3499 + action 0 + 4097 : 1 +state 3500 + action 0 + 4098 : 0.833 + 4099 : 0.167 +state 3501 + action 0 + 4100 : 1 +state 3502 + action 0 + 4101 : 0.833 + 4102 : 0.167 +state 3503 + action 0 + 4103 : 1 +state 3504 + action 0 + 4104 : 0.833 + 4105 : 0.167 +state 3505 + action 0 + 4106 : 1 +state 3506 + action 0 + 4107 : 1 +state 3507 observe1Greater1 observeIGreater1 + action 0 + 4001 : 1 +state 3508 + action 0 + 4054 : 1 +state 3509 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3510 + action 0 + 4107 : 1 +state 3511 observe0Greater1 observeOnlyTrueSender + action 0 + 4108 : 0.8 + 4109 : 0.2 +state 3512 observe0Greater1 observeOnlyTrueSender + action 0 + 4110 : 0.8 + 4111 : 0.2 +state 3513 observe0Greater1 observeOnlyTrueSender + action 0 + 4112 : 0.8 + 4113 : 0.2 +state 3514 observe0Greater1 observeOnlyTrueSender + action 0 + 4114 : 0.8 + 4115 : 0.2 +state 3515 observe0Greater1 observeOnlyTrueSender + action 0 + 4116 : 0.8 + 4117 : 0.2 +state 3516 observe0Greater1 observeOnlyTrueSender + action 0 + 4118 : 1 +state 3517 observe4Greater1 observeIGreater1 + action 0 + 2502 : 0.833 + 2503 : 0.167 +state 3518 observe4Greater1 observeIGreater1 + action 0 + 4119 : 1 +state 3519 observe4Greater1 observeIGreater1 + action 0 + 4120 : 0.833 + 4121 : 0.167 +state 3520 observe4Greater1 observeIGreater1 + action 0 + 4122 : 1 +state 3521 observe4Greater1 observeIGreater1 + action 0 + 4123 : 0.833 + 4124 : 0.167 +state 3522 observe4Greater1 observeIGreater1 + action 0 + 4125 : 1 +state 3523 observe4Greater1 observeIGreater1 + action 0 + 4126 : 0.833 + 4127 : 0.167 +state 3524 observe4Greater1 observeIGreater1 + action 0 + 4128 : 1 +state 3525 observe4Greater1 observeIGreater1 + action 0 + 4129 : 0.833 + 4130 : 0.167 +state 3526 observe4Greater1 observeIGreater1 + action 0 + 4131 : 1 +state 3527 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3528 observe1Greater1 observeIGreater1 + action 0 + 4015 : 1 +state 3529 + action 0 + 4068 : 1 +state 3530 + action 0 + 4107 : 1 +state 3531 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3532 observe0Greater1 observeOnlyTrueSender + action 0 + 4133 : 0.8 + 4134 : 0.2 +state 3533 observe0Greater1 observeOnlyTrueSender + action 0 + 4135 : 0.8 + 4136 : 0.2 +state 3534 observe0Greater1 observeOnlyTrueSender + action 0 + 4137 : 0.8 + 4138 : 0.2 +state 3535 observe0Greater1 observeOnlyTrueSender + action 0 + 4139 : 0.8 + 4140 : 0.2 +state 3536 observe0Greater1 observeOnlyTrueSender + action 0 + 4141 : 0.8 + 4142 : 0.2 +state 3537 observe0Greater1 observeOnlyTrueSender + action 0 + 4143 : 1 +state 3538 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4144 : 1 +state 3539 observe0Greater1 observeOnlyTrueSender + action 0 + 4145 : 1 +state 3540 observe0Greater1 observeOnlyTrueSender + action 0 + 4146 : 1 +state 3541 observe0Greater1 observeOnlyTrueSender + action 0 + 4147 : 1 +state 3542 observe2Greater1 observeIGreater1 + action 0 + 2529 : 0.833 + 2530 : 0.167 +state 3543 observe2Greater1 observeIGreater1 + action 0 + 4148 : 1 +state 3544 observe2Greater1 observeIGreater1 + action 0 + 4149 : 0.833 + 4150 : 0.167 +state 3545 observe2Greater1 observeIGreater1 + action 0 + 4151 : 1 +state 3546 observe2Greater1 observeIGreater1 + action 0 + 4152 : 0.833 + 4153 : 0.167 +state 3547 observe2Greater1 observeIGreater1 + action 0 + 4154 : 1 +state 3548 observe2Greater1 observeIGreater1 + action 0 + 4155 : 0.833 + 4156 : 0.167 +state 3549 observe2Greater1 observeIGreater1 + action 0 + 4157 : 1 +state 3550 observe2Greater1 observeIGreater1 + action 0 + 4158 : 0.833 + 4159 : 0.167 +state 3551 observe2Greater1 observeIGreater1 + action 0 + 4160 : 1 +state 3552 observe2Greater1 observeIGreater1 + action 0 + 4161 : 1 +state 3553 observe2Greater1 observeIGreater1 + action 0 + 2531 : 0.833 + 2532 : 0.167 +state 3554 observe2Greater1 observeIGreater1 + action 0 + 4162 : 1 +state 3555 observe2Greater1 observeIGreater1 + action 0 + 4163 : 0.833 + 4164 : 0.167 +state 3556 observe2Greater1 observeIGreater1 + action 0 + 4165 : 1 +state 3557 observe2Greater1 observeIGreater1 + action 0 + 4166 : 0.833 + 4167 : 0.167 +state 3558 observe2Greater1 observeIGreater1 + action 0 + 4168 : 1 +state 3559 observe2Greater1 observeIGreater1 + action 0 + 4169 : 0.833 + 4170 : 0.167 +state 3560 observe2Greater1 observeIGreater1 + action 0 + 4171 : 1 +state 3561 observe2Greater1 observeIGreater1 + action 0 + 4172 : 0.833 + 4173 : 0.167 +state 3562 observe2Greater1 observeIGreater1 + action 0 + 4174 : 1 +state 3563 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3564 observe2Greater1 observeIGreater1 + action 0 + 2533 : 0.833 + 2534 : 0.167 +state 3565 observe2Greater1 observeIGreater1 + action 0 + 4176 : 1 +state 3566 observe2Greater1 observeIGreater1 + action 0 + 4177 : 0.833 + 4178 : 0.167 +state 3567 observe2Greater1 observeIGreater1 + action 0 + 4179 : 1 +state 3568 observe2Greater1 observeIGreater1 + action 0 + 4180 : 0.833 + 4181 : 0.167 +state 3569 observe2Greater1 observeIGreater1 + action 0 + 4182 : 1 +state 3570 observe2Greater1 observeIGreater1 + action 0 + 4183 : 0.833 + 4184 : 0.167 +state 3571 observe2Greater1 observeIGreater1 + action 0 + 4185 : 1 +state 3572 observe2Greater1 observeIGreater1 + action 0 + 4186 : 0.833 + 4187 : 0.167 +state 3573 observe2Greater1 observeIGreater1 + action 0 + 4188 : 1 +state 3574 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3575 observe2Greater1 observeIGreater1 + action 0 + 4040 : 1 +state 3576 observe2Greater1 observeIGreater1 + action 0 + 4161 : 1 +state 3577 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3578 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3579 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4190 : 0.8 + 4191 : 0.2 +state 3580 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4192 : 0.8 + 4193 : 0.2 +state 3581 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4194 : 0.8 + 4195 : 0.2 +state 3582 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4196 : 0.8 + 4197 : 0.2 +state 3583 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4198 : 0.8 + 4199 : 0.2 +state 3584 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4200 : 1 +state 3585 observe3Greater1 observeIGreater1 + action 0 + 2549 : 0.833 + 2550 : 0.167 +state 3586 observe3Greater1 observeIGreater1 + action 0 + 4201 : 1 +state 3587 observe3Greater1 observeIGreater1 + action 0 + 4202 : 0.833 + 4203 : 0.167 +state 3588 observe3Greater1 observeIGreater1 + action 0 + 4204 : 1 +state 3589 observe3Greater1 observeIGreater1 + action 0 + 4205 : 0.833 + 4206 : 0.167 +state 3590 observe3Greater1 observeIGreater1 + action 0 + 4207 : 1 +state 3591 observe3Greater1 observeIGreater1 + action 0 + 4208 : 0.833 + 4209 : 0.167 +state 3592 observe3Greater1 observeIGreater1 + action 0 + 4210 : 1 +state 3593 observe3Greater1 observeIGreater1 + action 0 + 4211 : 0.833 + 4212 : 0.167 +state 3594 observe3Greater1 observeIGreater1 + action 0 + 4213 : 1 +state 3595 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3596 + action 0 + 2551 : 0.833 + 2552 : 0.167 +state 3597 + action 0 + 4215 : 1 +state 3598 + action 0 + 4216 : 0.833 + 4217 : 0.167 +state 3599 + action 0 + 4218 : 1 +state 3600 + action 0 + 4219 : 0.833 + 4220 : 0.167 +state 3601 + action 0 + 4221 : 1 +state 3602 + action 0 + 4222 : 0.833 + 4223 : 0.167 +state 3603 + action 0 + 4224 : 1 +state 3604 + action 0 + 4225 : 0.833 + 4226 : 0.167 +state 3605 + action 0 + 4227 : 1 +state 3606 + action 0 + 4228 : 1 +state 3607 + action 0 + 4054 : 1 +state 3608 observe2Greater1 observeIGreater1 + action 0 + 4175 : 1 +state 3609 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3610 + action 0 + 4228 : 1 +state 3611 observe0Greater1 observeOnlyTrueSender + action 0 + 4229 : 0.8 + 4230 : 0.2 +state 3612 observe0Greater1 observeOnlyTrueSender + action 0 + 4231 : 0.8 + 4232 : 0.2 +state 3613 observe0Greater1 observeOnlyTrueSender + action 0 + 4233 : 0.8 + 4234 : 0.2 +state 3614 observe0Greater1 observeOnlyTrueSender + action 0 + 4235 : 0.8 + 4236 : 0.2 +state 3615 observe0Greater1 observeOnlyTrueSender + action 0 + 4237 : 0.8 + 4238 : 0.2 +state 3616 observe0Greater1 observeOnlyTrueSender + action 0 + 4239 : 1 +state 3617 observe4Greater1 observeIGreater1 + action 0 + 2567 : 0.833 + 2568 : 0.167 +state 3618 observe4Greater1 observeIGreater1 + action 0 + 4240 : 1 +state 3619 observe4Greater1 observeIGreater1 + action 0 + 4241 : 0.833 + 4242 : 0.167 +state 3620 observe4Greater1 observeIGreater1 + action 0 + 4243 : 1 +state 3621 observe4Greater1 observeIGreater1 + action 0 + 4244 : 0.833 + 4245 : 0.167 +state 3622 observe4Greater1 observeIGreater1 + action 0 + 4246 : 1 +state 3623 observe4Greater1 observeIGreater1 + action 0 + 4247 : 0.833 + 4248 : 0.167 +state 3624 observe4Greater1 observeIGreater1 + action 0 + 4249 : 1 +state 3625 observe4Greater1 observeIGreater1 + action 0 + 4250 : 0.833 + 4251 : 0.167 +state 3626 observe4Greater1 observeIGreater1 + action 0 + 4252 : 1 +state 3627 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3628 + action 0 + 4068 : 1 +state 3629 observe2Greater1 observeIGreater1 + action 0 + 4189 : 1 +state 3630 + action 0 + 4228 : 1 +state 3631 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3632 observe0Greater1 observeOnlyTrueSender + action 0 + 4254 : 0.8 + 4255 : 0.2 +state 3633 observe0Greater1 observeOnlyTrueSender + action 0 + 4256 : 0.8 + 4257 : 0.2 +state 3634 observe0Greater1 observeOnlyTrueSender + action 0 + 4258 : 0.8 + 4259 : 0.2 +state 3635 observe0Greater1 observeOnlyTrueSender + action 0 + 4260 : 0.8 + 4261 : 0.2 +state 3636 observe0Greater1 observeOnlyTrueSender + action 0 + 4262 : 0.8 + 4263 : 0.2 +state 3637 observe0Greater1 observeOnlyTrueSender + action 0 + 4264 : 1 +state 3638 observe0Greater1 observeOnlyTrueSender + action 0 + 4265 : 1 +state 3639 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4266 : 1 +state 3640 observe0Greater1 observeOnlyTrueSender + action 0 + 4267 : 1 +state 3641 observe0Greater1 observeOnlyTrueSender + action 0 + 4268 : 1 +state 3642 observe3Greater1 observeIGreater1 + action 0 + 2594 : 0.833 + 2595 : 0.167 +state 3643 observe3Greater1 observeIGreater1 + action 0 + 4269 : 1 +state 3644 observe3Greater1 observeIGreater1 + action 0 + 4270 : 0.833 + 4271 : 0.167 +state 3645 observe3Greater1 observeIGreater1 + action 0 + 4272 : 1 +state 3646 observe3Greater1 observeIGreater1 + action 0 + 4273 : 0.833 + 4274 : 0.167 +state 3647 observe3Greater1 observeIGreater1 + action 0 + 4275 : 1 +state 3648 observe3Greater1 observeIGreater1 + action 0 + 4276 : 0.833 + 4277 : 0.167 +state 3649 observe3Greater1 observeIGreater1 + action 0 + 4278 : 1 +state 3650 observe3Greater1 observeIGreater1 + action 0 + 4279 : 0.833 + 4280 : 0.167 +state 3651 observe3Greater1 observeIGreater1 + action 0 + 4281 : 1 +state 3652 observe3Greater1 observeIGreater1 + action 0 + 4282 : 1 +state 3653 observe3Greater1 observeIGreater1 + action 0 + 2596 : 0.833 + 2597 : 0.167 +state 3654 observe3Greater1 observeIGreater1 + action 0 + 4283 : 1 +state 3655 observe3Greater1 observeIGreater1 + action 0 + 4284 : 0.833 + 4285 : 0.167 +state 3656 observe3Greater1 observeIGreater1 + action 0 + 4286 : 1 +state 3657 observe3Greater1 observeIGreater1 + action 0 + 4287 : 0.833 + 4288 : 0.167 +state 3658 observe3Greater1 observeIGreater1 + action 0 + 4289 : 1 +state 3659 observe3Greater1 observeIGreater1 + action 0 + 4290 : 0.833 + 4291 : 0.167 +state 3660 observe3Greater1 observeIGreater1 + action 0 + 4292 : 1 +state 3661 observe3Greater1 observeIGreater1 + action 0 + 4293 : 0.833 + 4294 : 0.167 +state 3662 observe3Greater1 observeIGreater1 + action 0 + 4295 : 1 +state 3663 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3664 observe3Greater1 observeIGreater1 + action 0 + 4093 : 1 +state 3665 observe3Greater1 observeIGreater1 + action 0 + 4214 : 1 +state 3666 observe3Greater1 observeIGreater1 + action 0 + 4282 : 1 +state 3667 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3668 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4297 : 0.8 + 4298 : 0.2 +state 3669 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4299 : 0.8 + 4300 : 0.2 +state 3670 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4301 : 0.8 + 4302 : 0.2 +state 3671 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4303 : 0.8 + 4304 : 0.2 +state 3672 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4305 : 0.8 + 4306 : 0.2 +state 3673 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4307 : 1 +state 3674 observe4Greater1 observeIGreater1 + action 0 + 2612 : 0.833 + 2613 : 0.167 +state 3675 observe4Greater1 observeIGreater1 + action 0 + 4308 : 1 +state 3676 observe4Greater1 observeIGreater1 + action 0 + 4309 : 0.833 + 4310 : 0.167 +state 3677 observe4Greater1 observeIGreater1 + action 0 + 4311 : 1 +state 3678 observe4Greater1 observeIGreater1 + action 0 + 4312 : 0.833 + 4313 : 0.167 +state 3679 observe4Greater1 observeIGreater1 + action 0 + 4314 : 1 +state 3680 observe4Greater1 observeIGreater1 + action 0 + 4315 : 0.833 + 4316 : 0.167 +state 3681 observe4Greater1 observeIGreater1 + action 0 + 4317 : 1 +state 3682 observe4Greater1 observeIGreater1 + action 0 + 4318 : 0.833 + 4319 : 0.167 +state 3683 observe4Greater1 observeIGreater1 + action 0 + 4320 : 1 +state 3684 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3685 + action 0 + 4107 : 1 +state 3686 + action 0 + 4228 : 1 +state 3687 observe3Greater1 observeIGreater1 + action 0 + 4296 : 1 +state 3688 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3689 observe0Greater1 observeOnlyTrueSender + action 0 + 4322 : 0.8 + 4323 : 0.2 +state 3690 observe0Greater1 observeOnlyTrueSender + action 0 + 4324 : 0.8 + 4325 : 0.2 +state 3691 observe0Greater1 observeOnlyTrueSender + action 0 + 4326 : 0.8 + 4327 : 0.2 +state 3692 observe0Greater1 observeOnlyTrueSender + action 0 + 4328 : 0.8 + 4329 : 0.2 +state 3693 observe0Greater1 observeOnlyTrueSender + action 0 + 4330 : 0.8 + 4331 : 0.2 +state 3694 observe0Greater1 observeOnlyTrueSender + action 0 + 4332 : 1 +state 3695 observe0Greater1 observeOnlyTrueSender + action 0 + 4333 : 1 +state 3696 observe0Greater1 observeOnlyTrueSender + action 0 + 4334 : 1 +state 3697 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4335 : 1 +state 3698 observe0Greater1 observeOnlyTrueSender + action 0 + 4336 : 1 +state 3699 observe4Greater1 observeIGreater1 + action 0 + 2639 : 0.833 + 2640 : 0.167 +state 3700 observe4Greater1 observeIGreater1 + action 0 + 4337 : 1 +state 3701 observe4Greater1 observeIGreater1 + action 0 + 4338 : 0.833 + 4339 : 0.167 +state 3702 observe4Greater1 observeIGreater1 + action 0 + 4340 : 1 +state 3703 observe4Greater1 observeIGreater1 + action 0 + 4341 : 0.833 + 4342 : 0.167 +state 3704 observe4Greater1 observeIGreater1 + action 0 + 4343 : 1 +state 3705 observe4Greater1 observeIGreater1 + action 0 + 4344 : 0.833 + 4345 : 0.167 +state 3706 observe4Greater1 observeIGreater1 + action 0 + 4346 : 1 +state 3707 observe4Greater1 observeIGreater1 + action 0 + 4347 : 0.833 + 4348 : 0.167 +state 3708 observe4Greater1 observeIGreater1 + action 0 + 4349 : 1 +state 3709 observe4Greater1 observeIGreater1 + action 0 + 4350 : 1 +state 3710 observe4Greater1 observeIGreater1 + action 0 + 4132 : 1 +state 3711 observe4Greater1 observeIGreater1 + action 0 + 4253 : 1 +state 3712 observe4Greater1 observeIGreater1 + action 0 + 4321 : 1 +state 3713 observe4Greater1 observeIGreater1 + action 0 + 4350 : 1 +state 3714 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4351 : 0.8 + 4352 : 0.2 +state 3715 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4353 : 0.8 + 4354 : 0.2 +state 3716 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4355 : 0.8 + 4356 : 0.2 +state 3717 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4357 : 0.8 + 4358 : 0.2 +state 3718 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4359 : 0.8 + 4360 : 0.2 +state 3719 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4361 : 1 +state 3720 observe0Greater1 observeOnlyTrueSender + action 0 + 4362 : 1 +state 3721 observe0Greater1 observeOnlyTrueSender + action 0 + 4363 : 1 +state 3722 observe0Greater1 observeOnlyTrueSender + action 0 + 4364 : 1 +state 3723 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4365 : 1 +state 3724 + action 0 + 4366 : 1 +state 3725 + action 0 + 4367 : 1 +state 3726 + action 0 + 4368 : 1 +state 3727 + action 0 + 4369 : 1 +state 3728 + action 0 + 4370 : 1 +state 3729 + action 0 + 4371 : 0.833 + 4372 : 0.167 +state 3730 + action 0 + 4373 : 1 +state 3731 + action 0 + 4374 : 0.833 + 4375 : 0.167 +state 3732 + action 0 + 4376 : 1 +state 3733 + action 0 + 4377 : 0.833 + 4378 : 0.167 +state 3734 + action 0 + 4379 : 1 +state 3735 + action 0 + 4380 : 0.833 + 4381 : 0.167 +state 3736 + action 0 + 4382 : 1 +state 3737 deadlock + action 0 + 3737 : 1 +state 3738 + action 0 + 4383 : 1 +state 3739 + action 0 + 4384 : 0.833 + 4385 : 0.167 +state 3740 + action 0 + 4386 : 1 +state 3741 + action 0 + 4387 : 0.833 + 4388 : 0.167 +state 3742 + action 0 + 4389 : 1 +state 3743 + action 0 + 4390 : 0.833 + 4391 : 0.167 +state 3744 + action 0 + 4392 : 1 +state 3745 + action 0 + 4393 : 0.833 + 4394 : 0.167 +state 3746 + action 0 + 4395 : 1 +state 3747 deadlock + action 0 + 3747 : 1 +state 3748 + action 0 + 4396 : 1 +state 3749 + action 0 + 4397 : 0.833 + 4398 : 0.167 +state 3750 + action 0 + 4399 : 1 +state 3751 + action 0 + 4400 : 0.833 + 4401 : 0.167 +state 3752 + action 0 + 4402 : 1 +state 3753 + action 0 + 4403 : 0.833 + 4404 : 0.167 +state 3754 + action 0 + 4405 : 1 +state 3755 + action 0 + 4406 : 0.833 + 4407 : 0.167 +state 3756 + action 0 + 4408 : 1 +state 3757 deadlock + action 0 + 3757 : 1 +state 3758 + action 0 + 4409 : 1 +state 3759 + action 0 + 4410 : 0.833 + 4411 : 0.167 +state 3760 + action 0 + 4412 : 1 +state 3761 + action 0 + 4413 : 0.833 + 4414 : 0.167 +state 3762 + action 0 + 4415 : 1 +state 3763 + action 0 + 4416 : 0.833 + 4417 : 0.167 +state 3764 + action 0 + 4418 : 1 +state 3765 + action 0 + 4419 : 0.833 + 4420 : 0.167 +state 3766 + action 0 + 4421 : 1 +state 3767 deadlock + action 0 + 3767 : 1 +state 3768 deadlock + action 0 + 3768 : 1 +state 3769 deadlock + action 0 + 3769 : 1 +state 3770 deadlock + action 0 + 3770 : 1 +state 3771 deadlock + action 0 + 3771 : 1 +state 3772 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 3773 observe1Greater1 observeIGreater1 + action 0 + 4427 : 1 +state 3774 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 3775 + action 0 + 4433 : 1 +state 3776 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 3777 + action 0 + 4439 : 1 +state 3778 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 3779 + action 0 + 4445 : 1 +state 3780 deadlock + action 0 + 3780 : 1 +state 3781 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3782 + action 0 + 4446 : 1 +state 3783 deadlock + action 0 + 3783 : 1 +state 3784 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3785 + action 0 + 4447 : 1 +state 3786 deadlock + action 0 + 3786 : 1 +state 3787 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3788 + action 0 + 4448 : 1 +state 3789 deadlock + action 0 + 3789 : 1 +state 3790 + action 0 + 2705 : 0.2 + 2706 : 0.2 + 2707 : 0.2 + 2708 : 0.2 + 2709 : 0.2 +state 3791 + action 0 + 4449 : 1 +state 3792 deadlock + action 0 + 3792 : 1 +state 3793 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 3794 observe2Greater1 observeIGreater1 + action 0 + 4455 : 1 +state 3795 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 3796 + action 0 + 4461 : 1 +state 3797 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 3798 + action 0 + 4467 : 1 +state 3799 deadlock + action 0 + 3799 : 1 +state 3800 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3801 + action 0 + 4468 : 1 +state 3802 deadlock + action 0 + 3802 : 1 +state 3803 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3804 + action 0 + 4469 : 1 +state 3805 deadlock + action 0 + 3805 : 1 +state 3806 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3807 + action 0 + 4470 : 1 +state 3808 deadlock + action 0 + 3808 : 1 +state 3809 + action 0 + 2715 : 0.2 + 2716 : 0.2 + 2717 : 0.2 + 2718 : 0.2 + 2719 : 0.2 +state 3810 + action 0 + 4471 : 1 +state 3811 deadlock + action 0 + 3811 : 1 +state 3812 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 3813 observe3Greater1 observeIGreater1 + action 0 + 4477 : 1 +state 3814 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 3815 + action 0 + 4483 : 1 +state 3816 deadlock + action 0 + 3816 : 1 +state 3817 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3818 + action 0 + 4484 : 1 +state 3819 deadlock + action 0 + 3819 : 1 +state 3820 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3821 + action 0 + 4485 : 1 +state 3822 deadlock + action 0 + 3822 : 1 +state 3823 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3824 + action 0 + 4486 : 1 +state 3825 deadlock + action 0 + 3825 : 1 +state 3826 + action 0 + 2725 : 0.2 + 2726 : 0.2 + 2727 : 0.2 + 2728 : 0.2 + 2729 : 0.2 +state 3827 + action 0 + 4487 : 1 +state 3828 deadlock + action 0 + 3828 : 1 +state 3829 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 3830 observe4Greater1 observeIGreater1 + action 0 + 4493 : 1 +state 3831 deadlock + action 0 + 3831 : 1 +state 3832 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3833 + action 0 + 4494 : 1 +state 3834 deadlock + action 0 + 3834 : 1 +state 3835 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3836 + action 0 + 4495 : 1 +state 3837 deadlock + action 0 + 3837 : 1 +state 3838 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3839 + action 0 + 4496 : 1 +state 3840 deadlock + action 0 + 3840 : 1 +state 3841 + action 0 + 2735 : 0.2 + 2736 : 0.2 + 2737 : 0.2 + 2738 : 0.2 + 2739 : 0.2 +state 3842 + action 0 + 4497 : 1 +state 3843 deadlock + action 0 + 3843 : 1 +state 3844 observe1Greater1 observeIGreater1 + action 0 + 4498 : 1 +state 3845 observe1Greater1 observeIGreater1 + action 0 + 4499 : 1 +state 3846 observe1Greater1 observeIGreater1 + action 0 + 4500 : 1 +state 3847 observe1Greater1 observeIGreater1 + action 0 + 4501 : 1 +state 3848 observe1Greater1 observeIGreater1 + action 0 + 2953 : 0.8 + 4502 : 0.2 +state 3849 observe1Greater1 observeIGreater1 + action 0 + 4503 : 0.8 + 4504 : 0.2 +state 3850 observe1Greater1 observeIGreater1 + action 0 + 4505 : 0.8 + 4506 : 0.2 +state 3851 observe1Greater1 observeIGreater1 + action 0 + 4507 : 0.8 + 4508 : 0.2 +state 3852 observe1Greater1 observeIGreater1 + action 0 + 4509 : 0.8 + 4510 : 0.2 +state 3853 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4511 : 1 +state 3854 observe1Greater1 observeIGreater1 + action 0 + 4499 : 1 +state 3855 observe2Greater1 observeIGreater1 + action 0 + 4512 : 1 +state 3856 + action 0 + 4513 : 1 +state 3857 + action 0 + 4514 : 1 +state 3858 + action 0 + 2978 : 0.8 + 4515 : 0.2 +state 3859 + action 0 + 4516 : 0.8 + 4517 : 0.2 +state 3860 + action 0 + 4518 : 0.8 + 4519 : 0.2 +state 3861 + action 0 + 4520 : 0.8 + 4521 : 0.2 +state 3862 + action 0 + 4522 : 0.8 + 4523 : 0.2 +state 3863 observe0Greater1 observeOnlyTrueSender + action 0 + 4524 : 1 +state 3864 observe1Greater1 observeIGreater1 + action 0 + 4500 : 1 +state 3865 + action 0 + 4513 : 1 +state 3866 observe3Greater1 observeIGreater1 + action 0 + 4525 : 1 +state 3867 + action 0 + 4526 : 1 +state 3868 + action 0 + 2997 : 0.8 + 4527 : 0.2 +state 3869 + action 0 + 4528 : 0.8 + 4529 : 0.2 +state 3870 + action 0 + 4530 : 0.8 + 4531 : 0.2 +state 3871 + action 0 + 4532 : 0.8 + 4533 : 0.2 +state 3872 + action 0 + 4534 : 0.8 + 4535 : 0.2 +state 3873 observe0Greater1 observeOnlyTrueSender + action 0 + 4536 : 1 +state 3874 observe1Greater1 observeIGreater1 + action 0 + 4501 : 1 +state 3875 + action 0 + 4514 : 1 +state 3876 + action 0 + 4526 : 1 +state 3877 observe4Greater1 observeIGreater1 + action 0 + 4537 : 1 +state 3878 + action 0 + 3010 : 0.8 + 4538 : 0.2 +state 3879 + action 0 + 4539 : 0.8 + 4540 : 0.2 +state 3880 + action 0 + 4541 : 0.8 + 4542 : 0.2 +state 3881 + action 0 + 4543 : 0.8 + 4544 : 0.2 +state 3882 + action 0 + 4545 : 0.8 + 4546 : 0.2 +state 3883 observe0Greater1 observeOnlyTrueSender + action 0 + 4547 : 1 +state 3884 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4548 : 1 +state 3885 observe0Greater1 observeOnlyTrueSender + action 0 + 4549 : 1 +state 3886 observe0Greater1 observeOnlyTrueSender + action 0 + 4550 : 1 +state 3887 observe0Greater1 observeOnlyTrueSender + action 0 + 4551 : 1 +state 3888 observe2Greater1 observeIGreater1 + action 0 + 4512 : 1 +state 3889 observe2Greater1 observeIGreater1 + action 0 + 4552 : 1 +state 3890 observe2Greater1 observeIGreater1 + action 0 + 4553 : 1 +state 3891 observe2Greater1 observeIGreater1 + action 0 + 4554 : 1 +state 3892 observe2Greater1 observeIGreater1 + action 0 + 3048 : 0.8 + 4555 : 0.2 +state 3893 observe2Greater1 observeIGreater1 + action 0 + 4556 : 0.8 + 4557 : 0.2 +state 3894 observe2Greater1 observeIGreater1 + action 0 + 4558 : 0.8 + 4559 : 0.2 +state 3895 observe2Greater1 observeIGreater1 + action 0 + 4560 : 0.8 + 4561 : 0.2 +state 3896 observe2Greater1 observeIGreater1 + action 0 + 4562 : 0.8 + 4563 : 0.2 +state 3897 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4564 : 1 +state 3898 + action 0 + 4513 : 1 +state 3899 observe2Greater1 observeIGreater1 + action 0 + 4553 : 1 +state 3900 observe3Greater1 observeIGreater1 + action 0 + 4565 : 1 +state 3901 + action 0 + 4566 : 1 +state 3902 + action 0 + 3067 : 0.8 + 4567 : 0.2 +state 3903 + action 0 + 4568 : 0.8 + 4569 : 0.2 +state 3904 + action 0 + 4570 : 0.8 + 4571 : 0.2 +state 3905 + action 0 + 4572 : 0.8 + 4573 : 0.2 +state 3906 + action 0 + 4574 : 0.8 + 4575 : 0.2 +state 3907 observe0Greater1 observeOnlyTrueSender + action 0 + 4576 : 1 +state 3908 + action 0 + 4514 : 1 +state 3909 observe2Greater1 observeIGreater1 + action 0 + 4554 : 1 +state 3910 + action 0 + 4566 : 1 +state 3911 observe4Greater1 observeIGreater1 + action 0 + 4577 : 1 +state 3912 + action 0 + 3080 : 0.8 + 4578 : 0.2 +state 3913 + action 0 + 4579 : 0.8 + 4580 : 0.2 +state 3914 + action 0 + 4581 : 0.8 + 4582 : 0.2 +state 3915 + action 0 + 4583 : 0.8 + 4584 : 0.2 +state 3916 + action 0 + 4585 : 0.8 + 4586 : 0.2 +state 3917 observe0Greater1 observeOnlyTrueSender + action 0 + 4587 : 1 +state 3918 observe0Greater1 observeOnlyTrueSender + action 0 + 4588 : 1 +state 3919 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4589 : 1 +state 3920 observe0Greater1 observeOnlyTrueSender + action 0 + 4590 : 1 +state 3921 observe0Greater1 observeOnlyTrueSender + action 0 + 4591 : 1 +state 3922 observe3Greater1 observeIGreater1 + action 0 + 4525 : 1 +state 3923 observe3Greater1 observeIGreater1 + action 0 + 4565 : 1 +state 3924 observe3Greater1 observeIGreater1 + action 0 + 4592 : 1 +state 3925 observe3Greater1 observeIGreater1 + action 0 + 4593 : 1 +state 3926 observe3Greater1 observeIGreater1 + action 0 + 3112 : 0.8 + 4594 : 0.2 +state 3927 observe3Greater1 observeIGreater1 + action 0 + 4595 : 0.8 + 4596 : 0.2 +state 3928 observe3Greater1 observeIGreater1 + action 0 + 4597 : 0.8 + 4598 : 0.2 +state 3929 observe3Greater1 observeIGreater1 + action 0 + 4599 : 0.8 + 4600 : 0.2 +state 3930 observe3Greater1 observeIGreater1 + action 0 + 4601 : 0.8 + 4602 : 0.2 +state 3931 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4603 : 1 +state 3932 + action 0 + 4526 : 1 +state 3933 + action 0 + 4566 : 1 +state 3934 observe3Greater1 observeIGreater1 + action 0 + 4593 : 1 +state 3935 observe4Greater1 observeIGreater1 + action 0 + 4604 : 1 +state 3936 + action 0 + 3125 : 0.8 + 4605 : 0.2 +state 3937 + action 0 + 4606 : 0.8 + 4607 : 0.2 +state 3938 + action 0 + 4608 : 0.8 + 4609 : 0.2 +state 3939 + action 0 + 4610 : 0.8 + 4611 : 0.2 +state 3940 + action 0 + 4612 : 0.8 + 4613 : 0.2 +state 3941 observe0Greater1 observeOnlyTrueSender + action 0 + 4614 : 1 +state 3942 observe0Greater1 observeOnlyTrueSender + action 0 + 4615 : 1 +state 3943 observe0Greater1 observeOnlyTrueSender + action 0 + 4616 : 1 +state 3944 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4617 : 1 +state 3945 observe0Greater1 observeOnlyTrueSender + action 0 + 4618 : 1 +state 3946 observe4Greater1 observeIGreater1 + action 0 + 4537 : 1 +state 3947 observe4Greater1 observeIGreater1 + action 0 + 4577 : 1 +state 3948 observe4Greater1 observeIGreater1 + action 0 + 4604 : 1 +state 3949 observe4Greater1 observeIGreater1 + action 0 + 4619 : 1 +state 3950 observe4Greater1 observeIGreater1 + action 0 + 3151 : 0.8 + 4620 : 0.2 +state 3951 observe4Greater1 observeIGreater1 + action 0 + 4621 : 0.8 + 4622 : 0.2 +state 3952 observe4Greater1 observeIGreater1 + action 0 + 4623 : 0.8 + 4624 : 0.2 +state 3953 observe4Greater1 observeIGreater1 + action 0 + 4625 : 0.8 + 4626 : 0.2 +state 3954 observe4Greater1 observeIGreater1 + action 0 + 4627 : 0.8 + 4628 : 0.2 +state 3955 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4629 : 1 +state 3956 observe0Greater1 observeOnlyTrueSender + action 0 + 4630 : 1 +state 3957 observe0Greater1 observeOnlyTrueSender + action 0 + 4631 : 1 +state 3958 observe0Greater1 observeOnlyTrueSender + action 0 + 4632 : 1 +state 3959 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4633 : 1 +state 3960 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3961 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3962 observe1Greater1 observeIGreater1 + action 0 + 4635 : 1 +state 3963 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3964 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3965 observe1Greater1 observeIGreater1 + action 0 + 4636 : 1 +state 3966 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3967 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3968 observe1Greater1 observeIGreater1 + action 0 + 4637 : 1 +state 3969 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3970 observe1Greater1 observeIGreater1 + action 0 + 2929 : 0.2 + 2930 : 0.2 + 2931 : 0.2 + 2932 : 0.2 + 2933 : 0.2 +state 3971 observe1Greater1 observeIGreater1 + action 0 + 4638 : 1 +state 3972 observe1Greater1 observeIGreater1 + action 0 + 4634 : 1 +state 3973 observe1Greater1 observeIGreater1 + action 0 + 4639 : 0.833 + 4640 : 0.167 +state 3974 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3975 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3976 observe1Greater1 observeIGreater1 + action 0 + 4642 : 1 +state 3977 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3978 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3979 observe1Greater1 observeIGreater1 + action 0 + 4643 : 1 +state 3980 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3981 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3982 observe1Greater1 observeIGreater1 + action 0 + 4644 : 1 +state 3983 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3984 observe1Greater1 observeIGreater1 + action 0 + 2935 : 0.2 + 2936 : 0.2 + 2937 : 0.2 + 2938 : 0.2 + 2939 : 0.2 +state 3985 observe1Greater1 observeIGreater1 + action 0 + 4645 : 1 +state 3986 observe1Greater1 observeIGreater1 + action 0 + 4641 : 1 +state 3987 observe1Greater1 observeIGreater1 + action 0 + 4646 : 0.833 + 4647 : 0.167 +state 3988 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3989 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3990 observe1Greater1 observeIGreater1 + action 0 + 4649 : 1 +state 3991 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3992 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3993 observe1Greater1 observeIGreater1 + action 0 + 4650 : 1 +state 3994 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3995 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3996 observe1Greater1 observeIGreater1 + action 0 + 4651 : 1 +state 3997 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 3998 observe1Greater1 observeIGreater1 + action 0 + 2941 : 0.2 + 2942 : 0.2 + 2943 : 0.2 + 2944 : 0.2 + 2945 : 0.2 +state 3999 observe1Greater1 observeIGreater1 + action 0 + 4652 : 1 +state 4000 observe1Greater1 observeIGreater1 + action 0 + 4648 : 1 +state 4001 observe1Greater1 observeIGreater1 + action 0 + 4653 : 0.833 + 4654 : 0.167 +state 4002 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4003 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4004 observe1Greater1 observeIGreater1 + action 0 + 4656 : 1 +state 4005 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4006 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4007 observe1Greater1 observeIGreater1 + action 0 + 4657 : 1 +state 4008 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4009 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4010 observe1Greater1 observeIGreater1 + action 0 + 4658 : 1 +state 4011 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4012 observe1Greater1 observeIGreater1 + action 0 + 2947 : 0.2 + 2948 : 0.2 + 2949 : 0.2 + 2950 : 0.2 + 2951 : 0.2 +state 4013 observe1Greater1 observeIGreater1 + action 0 + 4659 : 1 +state 4014 observe1Greater1 observeIGreater1 + action 0 + 4655 : 1 +state 4015 observe1Greater1 observeIGreater1 + action 0 + 4660 : 0.833 + 4661 : 0.167 +state 4016 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 2958 : 0.833 + 2959 : 0.167 +state 4017 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4662 : 1 +state 4018 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4663 : 0.833 + 4664 : 0.167 +state 4019 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4665 : 1 +state 4020 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4666 : 0.833 + 4667 : 0.167 +state 4021 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4668 : 1 +state 4022 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4669 : 0.833 + 4670 : 0.167 +state 4023 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4671 : 1 +state 4024 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4672 : 0.833 + 4673 : 0.167 +state 4025 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4674 : 1 +state 4026 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4026 : 1 +state 4027 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4028 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4029 observe2Greater1 observeIGreater1 + action 0 + 4676 : 1 +state 4030 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4031 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4032 observe2Greater1 observeIGreater1 + action 0 + 4677 : 1 +state 4033 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4034 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4035 observe2Greater1 observeIGreater1 + action 0 + 4678 : 1 +state 4036 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4037 observe2Greater1 observeIGreater1 + action 0 + 2960 : 0.2 + 2961 : 0.2 + 2962 : 0.2 + 2963 : 0.2 + 2964 : 0.2 +state 4038 observe2Greater1 observeIGreater1 + action 0 + 4679 : 1 +state 4039 observe2Greater1 observeIGreater1 + action 0 + 4675 : 1 +state 4040 observe2Greater1 observeIGreater1 + action 0 + 4680 : 0.833 + 4681 : 0.167 +state 4041 + action 0 + 4682 : 1 +state 4042 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4043 + action 0 + 4683 : 1 +state 4044 + action 0 + 4682 : 1 +state 4045 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4046 + action 0 + 4684 : 1 +state 4047 + action 0 + 4682 : 1 +state 4048 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4049 + action 0 + 4685 : 1 +state 4050 + action 0 + 4682 : 1 +state 4051 + action 0 + 2966 : 0.2 + 2967 : 0.2 + 2968 : 0.2 + 2969 : 0.2 + 2970 : 0.2 +state 4052 + action 0 + 4686 : 1 +state 4053 + action 0 + 4682 : 1 +state 4054 + action 0 + 4687 : 0.833 + 4688 : 0.167 +state 4055 + action 0 + 4689 : 1 +state 4056 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4057 + action 0 + 4690 : 1 +state 4058 + action 0 + 4689 : 1 +state 4059 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4060 + action 0 + 4691 : 1 +state 4061 + action 0 + 4689 : 1 +state 4062 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4063 + action 0 + 4692 : 1 +state 4064 + action 0 + 4689 : 1 +state 4065 + action 0 + 2972 : 0.2 + 2973 : 0.2 + 2974 : 0.2 + 2975 : 0.2 + 2976 : 0.2 +state 4066 + action 0 + 4693 : 1 +state 4067 + action 0 + 4689 : 1 +state 4068 + action 0 + 4694 : 0.833 + 4695 : 0.167 +state 4069 observe0Greater1 observeOnlyTrueSender + action 0 + 2983 : 0.833 + 2984 : 0.167 +state 4070 observe0Greater1 observeOnlyTrueSender + action 0 + 4696 : 1 +state 4071 observe0Greater1 observeOnlyTrueSender + action 0 + 4697 : 0.833 + 4698 : 0.167 +state 4072 observe0Greater1 observeOnlyTrueSender + action 0 + 4699 : 1 +state 4073 observe0Greater1 observeOnlyTrueSender + action 0 + 4700 : 0.833 + 4701 : 0.167 +state 4074 observe0Greater1 observeOnlyTrueSender + action 0 + 4702 : 1 +state 4075 observe0Greater1 observeOnlyTrueSender + action 0 + 4703 : 0.833 + 4704 : 0.167 +state 4076 observe0Greater1 observeOnlyTrueSender + action 0 + 4705 : 1 +state 4077 observe0Greater1 observeOnlyTrueSender + action 0 + 4706 : 0.833 + 4707 : 0.167 +state 4078 observe0Greater1 observeOnlyTrueSender + action 0 + 4708 : 1 +state 4079 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4079 : 1 +state 4080 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4081 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4082 observe3Greater1 observeIGreater1 + action 0 + 4710 : 1 +state 4083 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4084 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4085 observe3Greater1 observeIGreater1 + action 0 + 4711 : 1 +state 4086 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4087 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4088 observe3Greater1 observeIGreater1 + action 0 + 4712 : 1 +state 4089 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4090 observe3Greater1 observeIGreater1 + action 0 + 2985 : 0.2 + 2986 : 0.2 + 2987 : 0.2 + 2988 : 0.2 + 2989 : 0.2 +state 4091 observe3Greater1 observeIGreater1 + action 0 + 4713 : 1 +state 4092 observe3Greater1 observeIGreater1 + action 0 + 4709 : 1 +state 4093 observe3Greater1 observeIGreater1 + action 0 + 4714 : 0.833 + 4715 : 0.167 +state 4094 + action 0 + 4716 : 1 +state 4095 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4096 + action 0 + 4717 : 1 +state 4097 + action 0 + 4716 : 1 +state 4098 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4099 + action 0 + 4718 : 1 +state 4100 + action 0 + 4716 : 1 +state 4101 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4102 + action 0 + 4719 : 1 +state 4103 + action 0 + 4716 : 1 +state 4104 + action 0 + 2991 : 0.2 + 2992 : 0.2 + 2993 : 0.2 + 2994 : 0.2 + 2995 : 0.2 +state 4105 + action 0 + 4720 : 1 +state 4106 + action 0 + 4716 : 1 +state 4107 + action 0 + 4721 : 0.833 + 4722 : 0.167 +state 4108 observe0Greater1 observeOnlyTrueSender + action 0 + 3002 : 0.833 + 3003 : 0.167 +state 4109 observe0Greater1 observeOnlyTrueSender + action 0 + 4723 : 1 +state 4110 observe0Greater1 observeOnlyTrueSender + action 0 + 4724 : 0.833 + 4725 : 0.167 +state 4111 observe0Greater1 observeOnlyTrueSender + action 0 + 4726 : 1 +state 4112 observe0Greater1 observeOnlyTrueSender + action 0 + 4727 : 0.833 + 4728 : 0.167 +state 4113 observe0Greater1 observeOnlyTrueSender + action 0 + 4729 : 1 +state 4114 observe0Greater1 observeOnlyTrueSender + action 0 + 4730 : 0.833 + 4731 : 0.167 +state 4115 observe0Greater1 observeOnlyTrueSender + action 0 + 4732 : 1 +state 4116 observe0Greater1 observeOnlyTrueSender + action 0 + 4733 : 0.833 + 4734 : 0.167 +state 4117 observe0Greater1 observeOnlyTrueSender + action 0 + 4735 : 1 +state 4118 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4118 : 1 +state 4119 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4120 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4121 observe4Greater1 observeIGreater1 + action 0 + 4737 : 1 +state 4122 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4123 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4124 observe4Greater1 observeIGreater1 + action 0 + 4738 : 1 +state 4125 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4126 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4127 observe4Greater1 observeIGreater1 + action 0 + 4739 : 1 +state 4128 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4129 observe4Greater1 observeIGreater1 + action 0 + 3004 : 0.2 + 3005 : 0.2 + 3006 : 0.2 + 3007 : 0.2 + 3008 : 0.2 +state 4130 observe4Greater1 observeIGreater1 + action 0 + 4740 : 1 +state 4131 observe4Greater1 observeIGreater1 + action 0 + 4736 : 1 +state 4132 observe4Greater1 observeIGreater1 + action 0 + 4741 : 0.833 + 4742 : 0.167 +state 4133 observe0Greater1 observeOnlyTrueSender + action 0 + 3015 : 0.833 + 3016 : 0.167 +state 4134 observe0Greater1 observeOnlyTrueSender + action 0 + 4743 : 1 +state 4135 observe0Greater1 observeOnlyTrueSender + action 0 + 4744 : 0.833 + 4745 : 0.167 +state 4136 observe0Greater1 observeOnlyTrueSender + action 0 + 4746 : 1 +state 4137 observe0Greater1 observeOnlyTrueSender + action 0 + 4747 : 0.833 + 4748 : 0.167 +state 4138 observe0Greater1 observeOnlyTrueSender + action 0 + 4749 : 1 +state 4139 observe0Greater1 observeOnlyTrueSender + action 0 + 4750 : 0.833 + 4751 : 0.167 +state 4140 observe0Greater1 observeOnlyTrueSender + action 0 + 4752 : 1 +state 4141 observe0Greater1 observeOnlyTrueSender + action 0 + 4753 : 0.833 + 4754 : 0.167 +state 4142 observe0Greater1 observeOnlyTrueSender + action 0 + 4755 : 1 +state 4143 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4143 : 1 +state 4144 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4144 : 1 +state 4145 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4145 : 1 +state 4146 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4146 : 1 +state 4147 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4147 : 1 +state 4148 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4149 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4150 observe2Greater1 observeIGreater1 + action 0 + 4757 : 1 +state 4151 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4152 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4153 observe2Greater1 observeIGreater1 + action 0 + 4758 : 1 +state 4154 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4155 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4156 observe2Greater1 observeIGreater1 + action 0 + 4759 : 1 +state 4157 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4158 observe2Greater1 observeIGreater1 + action 0 + 3030 : 0.2 + 3031 : 0.2 + 3032 : 0.2 + 3033 : 0.2 + 3034 : 0.2 +state 4159 observe2Greater1 observeIGreater1 + action 0 + 4760 : 1 +state 4160 observe2Greater1 observeIGreater1 + action 0 + 4756 : 1 +state 4161 observe2Greater1 observeIGreater1 + action 0 + 4761 : 0.833 + 4762 : 0.167 +state 4162 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4163 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4164 observe2Greater1 observeIGreater1 + action 0 + 4764 : 1 +state 4165 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4166 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4167 observe2Greater1 observeIGreater1 + action 0 + 4765 : 1 +state 4168 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4169 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4170 observe2Greater1 observeIGreater1 + action 0 + 4766 : 1 +state 4171 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4172 observe2Greater1 observeIGreater1 + action 0 + 3036 : 0.2 + 3037 : 0.2 + 3038 : 0.2 + 3039 : 0.2 + 3040 : 0.2 +state 4173 observe2Greater1 observeIGreater1 + action 0 + 4767 : 1 +state 4174 observe2Greater1 observeIGreater1 + action 0 + 4763 : 1 +state 4175 observe2Greater1 observeIGreater1 + action 0 + 4768 : 0.833 + 4769 : 0.167 +state 4176 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4177 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4178 observe2Greater1 observeIGreater1 + action 0 + 4771 : 1 +state 4179 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4180 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4181 observe2Greater1 observeIGreater1 + action 0 + 4772 : 1 +state 4182 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4183 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4184 observe2Greater1 observeIGreater1 + action 0 + 4773 : 1 +state 4185 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4186 observe2Greater1 observeIGreater1 + action 0 + 3042 : 0.2 + 3043 : 0.2 + 3044 : 0.2 + 3045 : 0.2 + 3046 : 0.2 +state 4187 observe2Greater1 observeIGreater1 + action 0 + 4774 : 1 +state 4188 observe2Greater1 observeIGreater1 + action 0 + 4770 : 1 +state 4189 observe2Greater1 observeIGreater1 + action 0 + 4775 : 0.833 + 4776 : 0.167 +state 4190 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3053 : 0.833 + 3054 : 0.167 +state 4191 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4777 : 1 +state 4192 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4778 : 0.833 + 4779 : 0.167 +state 4193 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4780 : 1 +state 4194 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4781 : 0.833 + 4782 : 0.167 +state 4195 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4783 : 1 +state 4196 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4784 : 0.833 + 4785 : 0.167 +state 4197 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4786 : 1 +state 4198 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4787 : 0.833 + 4788 : 0.167 +state 4199 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4789 : 1 +state 4200 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4200 : 1 +state 4201 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4202 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4203 observe3Greater1 observeIGreater1 + action 0 + 4791 : 1 +state 4204 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4205 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4206 observe3Greater1 observeIGreater1 + action 0 + 4792 : 1 +state 4207 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4208 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4209 observe3Greater1 observeIGreater1 + action 0 + 4793 : 1 +state 4210 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4211 observe3Greater1 observeIGreater1 + action 0 + 3055 : 0.2 + 3056 : 0.2 + 3057 : 0.2 + 3058 : 0.2 + 3059 : 0.2 +state 4212 observe3Greater1 observeIGreater1 + action 0 + 4794 : 1 +state 4213 observe3Greater1 observeIGreater1 + action 0 + 4790 : 1 +state 4214 observe3Greater1 observeIGreater1 + action 0 + 4795 : 0.833 + 4796 : 0.167 +state 4215 + action 0 + 4797 : 1 +state 4216 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4217 + action 0 + 4798 : 1 +state 4218 + action 0 + 4797 : 1 +state 4219 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4220 + action 0 + 4799 : 1 +state 4221 + action 0 + 4797 : 1 +state 4222 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4223 + action 0 + 4800 : 1 +state 4224 + action 0 + 4797 : 1 +state 4225 + action 0 + 3061 : 0.2 + 3062 : 0.2 + 3063 : 0.2 + 3064 : 0.2 + 3065 : 0.2 +state 4226 + action 0 + 4801 : 1 +state 4227 + action 0 + 4797 : 1 +state 4228 + action 0 + 4802 : 0.833 + 4803 : 0.167 +state 4229 observe0Greater1 observeOnlyTrueSender + action 0 + 3072 : 0.833 + 3073 : 0.167 +state 4230 observe0Greater1 observeOnlyTrueSender + action 0 + 4804 : 1 +state 4231 observe0Greater1 observeOnlyTrueSender + action 0 + 4805 : 0.833 + 4806 : 0.167 +state 4232 observe0Greater1 observeOnlyTrueSender + action 0 + 4807 : 1 +state 4233 observe0Greater1 observeOnlyTrueSender + action 0 + 4808 : 0.833 + 4809 : 0.167 +state 4234 observe0Greater1 observeOnlyTrueSender + action 0 + 4810 : 1 +state 4235 observe0Greater1 observeOnlyTrueSender + action 0 + 4811 : 0.833 + 4812 : 0.167 +state 4236 observe0Greater1 observeOnlyTrueSender + action 0 + 4813 : 1 +state 4237 observe0Greater1 observeOnlyTrueSender + action 0 + 4814 : 0.833 + 4815 : 0.167 +state 4238 observe0Greater1 observeOnlyTrueSender + action 0 + 4816 : 1 +state 4239 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4239 : 1 +state 4240 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4241 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4242 observe4Greater1 observeIGreater1 + action 0 + 4818 : 1 +state 4243 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4244 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4245 observe4Greater1 observeIGreater1 + action 0 + 4819 : 1 +state 4246 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4247 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4248 observe4Greater1 observeIGreater1 + action 0 + 4820 : 1 +state 4249 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4250 observe4Greater1 observeIGreater1 + action 0 + 3074 : 0.2 + 3075 : 0.2 + 3076 : 0.2 + 3077 : 0.2 + 3078 : 0.2 +state 4251 observe4Greater1 observeIGreater1 + action 0 + 4821 : 1 +state 4252 observe4Greater1 observeIGreater1 + action 0 + 4817 : 1 +state 4253 observe4Greater1 observeIGreater1 + action 0 + 4822 : 0.833 + 4823 : 0.167 +state 4254 observe0Greater1 observeOnlyTrueSender + action 0 + 3085 : 0.833 + 3086 : 0.167 +state 4255 observe0Greater1 observeOnlyTrueSender + action 0 + 4824 : 1 +state 4256 observe0Greater1 observeOnlyTrueSender + action 0 + 4825 : 0.833 + 4826 : 0.167 +state 4257 observe0Greater1 observeOnlyTrueSender + action 0 + 4827 : 1 +state 4258 observe0Greater1 observeOnlyTrueSender + action 0 + 4828 : 0.833 + 4829 : 0.167 +state 4259 observe0Greater1 observeOnlyTrueSender + action 0 + 4830 : 1 +state 4260 observe0Greater1 observeOnlyTrueSender + action 0 + 4831 : 0.833 + 4832 : 0.167 +state 4261 observe0Greater1 observeOnlyTrueSender + action 0 + 4833 : 1 +state 4262 observe0Greater1 observeOnlyTrueSender + action 0 + 4834 : 0.833 + 4835 : 0.167 +state 4263 observe0Greater1 observeOnlyTrueSender + action 0 + 4836 : 1 +state 4264 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4264 : 1 +state 4265 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4265 : 1 +state 4266 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4266 : 1 +state 4267 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4267 : 1 +state 4268 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4268 : 1 +state 4269 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4270 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4271 observe3Greater1 observeIGreater1 + action 0 + 4838 : 1 +state 4272 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4273 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4274 observe3Greater1 observeIGreater1 + action 0 + 4839 : 1 +state 4275 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4276 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4277 observe3Greater1 observeIGreater1 + action 0 + 4840 : 1 +state 4278 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4279 observe3Greater1 observeIGreater1 + action 0 + 3100 : 0.2 + 3101 : 0.2 + 3102 : 0.2 + 3103 : 0.2 + 3104 : 0.2 +state 4280 observe3Greater1 observeIGreater1 + action 0 + 4841 : 1 +state 4281 observe3Greater1 observeIGreater1 + action 0 + 4837 : 1 +state 4282 observe3Greater1 observeIGreater1 + action 0 + 4842 : 0.833 + 4843 : 0.167 +state 4283 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4284 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4285 observe3Greater1 observeIGreater1 + action 0 + 4845 : 1 +state 4286 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4287 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4288 observe3Greater1 observeIGreater1 + action 0 + 4846 : 1 +state 4289 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4290 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4291 observe3Greater1 observeIGreater1 + action 0 + 4847 : 1 +state 4292 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4293 observe3Greater1 observeIGreater1 + action 0 + 3106 : 0.2 + 3107 : 0.2 + 3108 : 0.2 + 3109 : 0.2 + 3110 : 0.2 +state 4294 observe3Greater1 observeIGreater1 + action 0 + 4848 : 1 +state 4295 observe3Greater1 observeIGreater1 + action 0 + 4844 : 1 +state 4296 observe3Greater1 observeIGreater1 + action 0 + 4849 : 0.833 + 4850 : 0.167 +state 4297 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3117 : 0.833 + 3118 : 0.167 +state 4298 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4851 : 1 +state 4299 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4852 : 0.833 + 4853 : 0.167 +state 4300 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4854 : 1 +state 4301 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4855 : 0.833 + 4856 : 0.167 +state 4302 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4857 : 1 +state 4303 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4858 : 0.833 + 4859 : 0.167 +state 4304 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4860 : 1 +state 4305 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4861 : 0.833 + 4862 : 0.167 +state 4306 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4863 : 1 +state 4307 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4307 : 1 +state 4308 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4309 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4310 observe4Greater1 observeIGreater1 + action 0 + 4865 : 1 +state 4311 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4312 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4313 observe4Greater1 observeIGreater1 + action 0 + 4866 : 1 +state 4314 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4315 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4316 observe4Greater1 observeIGreater1 + action 0 + 4867 : 1 +state 4317 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4318 observe4Greater1 observeIGreater1 + action 0 + 3119 : 0.2 + 3120 : 0.2 + 3121 : 0.2 + 3122 : 0.2 + 3123 : 0.2 +state 4319 observe4Greater1 observeIGreater1 + action 0 + 4868 : 1 +state 4320 observe4Greater1 observeIGreater1 + action 0 + 4864 : 1 +state 4321 observe4Greater1 observeIGreater1 + action 0 + 4869 : 0.833 + 4870 : 0.167 +state 4322 observe0Greater1 observeOnlyTrueSender + action 0 + 3130 : 0.833 + 3131 : 0.167 +state 4323 observe0Greater1 observeOnlyTrueSender + action 0 + 4871 : 1 +state 4324 observe0Greater1 observeOnlyTrueSender + action 0 + 4872 : 0.833 + 4873 : 0.167 +state 4325 observe0Greater1 observeOnlyTrueSender + action 0 + 4874 : 1 +state 4326 observe0Greater1 observeOnlyTrueSender + action 0 + 4875 : 0.833 + 4876 : 0.167 +state 4327 observe0Greater1 observeOnlyTrueSender + action 0 + 4877 : 1 +state 4328 observe0Greater1 observeOnlyTrueSender + action 0 + 4878 : 0.833 + 4879 : 0.167 +state 4329 observe0Greater1 observeOnlyTrueSender + action 0 + 4880 : 1 +state 4330 observe0Greater1 observeOnlyTrueSender + action 0 + 4881 : 0.833 + 4882 : 0.167 +state 4331 observe0Greater1 observeOnlyTrueSender + action 0 + 4883 : 1 +state 4332 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4332 : 1 +state 4333 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4333 : 1 +state 4334 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4334 : 1 +state 4335 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4335 : 1 +state 4336 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4336 : 1 +state 4337 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4338 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4339 observe4Greater1 observeIGreater1 + action 0 + 4885 : 1 +state 4340 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4341 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4342 observe4Greater1 observeIGreater1 + action 0 + 4886 : 1 +state 4343 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4344 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4345 observe4Greater1 observeIGreater1 + action 0 + 4887 : 1 +state 4346 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4347 observe4Greater1 observeIGreater1 + action 0 + 3145 : 0.2 + 3146 : 0.2 + 3147 : 0.2 + 3148 : 0.2 + 3149 : 0.2 +state 4348 observe4Greater1 observeIGreater1 + action 0 + 4888 : 1 +state 4349 observe4Greater1 observeIGreater1 + action 0 + 4884 : 1 +state 4350 observe4Greater1 observeIGreater1 + action 0 + 4889 : 0.833 + 4890 : 0.167 +state 4351 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3156 : 0.833 + 3157 : 0.167 +state 4352 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4891 : 1 +state 4353 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4892 : 0.833 + 4893 : 0.167 +state 4354 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4894 : 1 +state 4355 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4895 : 0.833 + 4896 : 0.167 +state 4356 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4897 : 1 +state 4357 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4898 : 0.833 + 4899 : 0.167 +state 4358 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4900 : 1 +state 4359 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4901 : 0.833 + 4902 : 0.167 +state 4360 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4903 : 1 +state 4361 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4361 : 1 +state 4362 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4362 : 1 +state 4363 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4363 : 1 +state 4364 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4364 : 1 +state 4365 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4365 : 1 +state 4366 deadlock + action 0 + 4366 : 1 +state 4367 deadlock + action 0 + 4367 : 1 +state 4368 deadlock + action 0 + 4368 : 1 +state 4369 deadlock + action 0 + 4369 : 1 +state 4370 deadlock + action 0 + 4370 : 1 +state 4371 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4372 + action 0 + 4904 : 1 +state 4373 deadlock + action 0 + 4373 : 1 +state 4374 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4375 + action 0 + 4905 : 1 +state 4376 deadlock + action 0 + 4376 : 1 +state 4377 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4378 + action 0 + 4906 : 1 +state 4379 deadlock + action 0 + 4379 : 1 +state 4380 + action 0 + 3184 : 0.2 + 3185 : 0.2 + 3186 : 0.2 + 3187 : 0.2 + 3188 : 0.2 +state 4381 + action 0 + 4907 : 1 +state 4382 deadlock + action 0 + 4382 : 1 +state 4383 deadlock + action 0 + 4383 : 1 +state 4384 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4385 + action 0 + 4908 : 1 +state 4386 deadlock + action 0 + 4386 : 1 +state 4387 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4388 + action 0 + 4909 : 1 +state 4389 deadlock + action 0 + 4389 : 1 +state 4390 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4391 + action 0 + 4910 : 1 +state 4392 deadlock + action 0 + 4392 : 1 +state 4393 + action 0 + 3190 : 0.2 + 3191 : 0.2 + 3192 : 0.2 + 3193 : 0.2 + 3194 : 0.2 +state 4394 + action 0 + 4911 : 1 +state 4395 deadlock + action 0 + 4395 : 1 +state 4396 deadlock + action 0 + 4396 : 1 +state 4397 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4398 + action 0 + 4912 : 1 +state 4399 deadlock + action 0 + 4399 : 1 +state 4400 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4401 + action 0 + 4913 : 1 +state 4402 deadlock + action 0 + 4402 : 1 +state 4403 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4404 + action 0 + 4914 : 1 +state 4405 deadlock + action 0 + 4405 : 1 +state 4406 + action 0 + 3196 : 0.2 + 3197 : 0.2 + 3198 : 0.2 + 3199 : 0.2 + 3200 : 0.2 +state 4407 + action 0 + 4915 : 1 +state 4408 deadlock + action 0 + 4408 : 1 +state 4409 deadlock + action 0 + 4409 : 1 +state 4410 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4411 + action 0 + 4916 : 1 +state 4412 deadlock + action 0 + 4412 : 1 +state 4413 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4414 + action 0 + 4917 : 1 +state 4415 deadlock + action 0 + 4415 : 1 +state 4416 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4417 + action 0 + 4918 : 1 +state 4418 deadlock + action 0 + 4418 : 1 +state 4419 + action 0 + 3202 : 0.2 + 3203 : 0.2 + 3204 : 0.2 + 3205 : 0.2 + 3206 : 0.2 +state 4420 + action 0 + 4919 : 1 +state 4421 deadlock + action 0 + 4421 : 1 +state 4422 observe1Greater1 observeIGreater1 + action 0 + 3266 : 0.8 + 4920 : 0.2 +state 4423 observe1Greater1 observeIGreater1 + action 0 + 4921 : 0.8 + 4922 : 0.2 +state 4424 observe1Greater1 observeIGreater1 + action 0 + 4923 : 0.8 + 4924 : 0.2 +state 4425 observe1Greater1 observeIGreater1 + action 0 + 4925 : 0.8 + 4926 : 0.2 +state 4426 observe1Greater1 observeIGreater1 + action 0 + 4927 : 0.8 + 4928 : 0.2 +state 4427 observe1Greater1 observeIGreater1 + action 0 + 4929 : 1 +state 4428 + action 0 + 3273 : 0.8 + 4930 : 0.2 +state 4429 + action 0 + 4931 : 0.8 + 4932 : 0.2 +state 4430 + action 0 + 4933 : 0.8 + 4934 : 0.2 +state 4431 + action 0 + 4935 : 0.8 + 4936 : 0.2 +state 4432 + action 0 + 4937 : 0.8 + 4938 : 0.2 +state 4433 + action 0 + 4939 : 1 +state 4434 + action 0 + 3280 : 0.8 + 4940 : 0.2 +state 4435 + action 0 + 4941 : 0.8 + 4942 : 0.2 +state 4436 + action 0 + 4943 : 0.8 + 4944 : 0.2 +state 4437 + action 0 + 4945 : 0.8 + 4946 : 0.2 +state 4438 + action 0 + 4947 : 0.8 + 4948 : 0.2 +state 4439 + action 0 + 4949 : 1 +state 4440 + action 0 + 3287 : 0.8 + 4950 : 0.2 +state 4441 + action 0 + 4951 : 0.8 + 4952 : 0.2 +state 4442 + action 0 + 4953 : 0.8 + 4954 : 0.2 +state 4443 + action 0 + 4955 : 0.8 + 4956 : 0.2 +state 4444 + action 0 + 4957 : 0.8 + 4958 : 0.2 +state 4445 + action 0 + 4959 : 1 +state 4446 observe1Greater1 observeIGreater1 + action 0 + 4960 : 1 +state 4447 + action 0 + 4961 : 1 +state 4448 + action 0 + 4962 : 1 +state 4449 + action 0 + 4963 : 1 +state 4450 observe2Greater1 observeIGreater1 + action 0 + 3307 : 0.8 + 4964 : 0.2 +state 4451 observe2Greater1 observeIGreater1 + action 0 + 4965 : 0.8 + 4966 : 0.2 +state 4452 observe2Greater1 observeIGreater1 + action 0 + 4967 : 0.8 + 4968 : 0.2 +state 4453 observe2Greater1 observeIGreater1 + action 0 + 4969 : 0.8 + 4970 : 0.2 +state 4454 observe2Greater1 observeIGreater1 + action 0 + 4971 : 0.8 + 4972 : 0.2 +state 4455 observe2Greater1 observeIGreater1 + action 0 + 4973 : 1 +state 4456 + action 0 + 3314 : 0.8 + 4974 : 0.2 +state 4457 + action 0 + 4975 : 0.8 + 4976 : 0.2 +state 4458 + action 0 + 4977 : 0.8 + 4978 : 0.2 +state 4459 + action 0 + 4979 : 0.8 + 4980 : 0.2 +state 4460 + action 0 + 4981 : 0.8 + 4982 : 0.2 +state 4461 + action 0 + 4983 : 1 +state 4462 + action 0 + 3321 : 0.8 + 4984 : 0.2 +state 4463 + action 0 + 4985 : 0.8 + 4986 : 0.2 +state 4464 + action 0 + 4987 : 0.8 + 4988 : 0.2 +state 4465 + action 0 + 4989 : 0.8 + 4990 : 0.2 +state 4466 + action 0 + 4991 : 0.8 + 4992 : 0.2 +state 4467 + action 0 + 4993 : 1 +state 4468 + action 0 + 4994 : 1 +state 4469 observe2Greater1 observeIGreater1 + action 0 + 4995 : 1 +state 4470 + action 0 + 4996 : 1 +state 4471 + action 0 + 4997 : 1 +state 4472 observe3Greater1 observeIGreater1 + action 0 + 3341 : 0.8 + 4998 : 0.2 +state 4473 observe3Greater1 observeIGreater1 + action 0 + 4999 : 0.8 + 5000 : 0.2 +state 4474 observe3Greater1 observeIGreater1 + action 0 + 5001 : 0.8 + 5002 : 0.2 +state 4475 observe3Greater1 observeIGreater1 + action 0 + 5003 : 0.8 + 5004 : 0.2 +state 4476 observe3Greater1 observeIGreater1 + action 0 + 5005 : 0.8 + 5006 : 0.2 +state 4477 observe3Greater1 observeIGreater1 + action 0 + 5007 : 1 +state 4478 + action 0 + 3348 : 0.8 + 5008 : 0.2 +state 4479 + action 0 + 5009 : 0.8 + 5010 : 0.2 +state 4480 + action 0 + 5011 : 0.8 + 5012 : 0.2 +state 4481 + action 0 + 5013 : 0.8 + 5014 : 0.2 +state 4482 + action 0 + 5015 : 0.8 + 5016 : 0.2 +state 4483 + action 0 + 5017 : 1 +state 4484 + action 0 + 5018 : 1 +state 4485 + action 0 + 5019 : 1 +state 4486 observe3Greater1 observeIGreater1 + action 0 + 5020 : 1 +state 4487 + action 0 + 5021 : 1 +state 4488 observe4Greater1 observeIGreater1 + action 0 + 3368 : 0.8 + 5022 : 0.2 +state 4489 observe4Greater1 observeIGreater1 + action 0 + 5023 : 0.8 + 5024 : 0.2 +state 4490 observe4Greater1 observeIGreater1 + action 0 + 5025 : 0.8 + 5026 : 0.2 +state 4491 observe4Greater1 observeIGreater1 + action 0 + 5027 : 0.8 + 5028 : 0.2 +state 4492 observe4Greater1 observeIGreater1 + action 0 + 5029 : 0.8 + 5030 : 0.2 +state 4493 observe4Greater1 observeIGreater1 + action 0 + 5031 : 1 +state 4494 + action 0 + 5032 : 1 +state 4495 + action 0 + 5033 : 1 +state 4496 + action 0 + 5034 : 1 +state 4497 observe4Greater1 observeIGreater1 + action 0 + 5035 : 1 +state 4498 observe1Greater1 observeIGreater1 + action 0 + 5036 : 0.833 + 5037 : 0.167 +state 4499 observe1Greater1 observeIGreater1 + action 0 + 5038 : 0.833 + 5039 : 0.167 +state 4500 observe1Greater1 observeIGreater1 + action 0 + 5040 : 0.833 + 5041 : 0.167 +state 4501 observe1Greater1 observeIGreater1 + action 0 + 5042 : 0.833 + 5043 : 0.167 +state 4502 observe1Greater1 observeIGreater1 + action 0 + 5044 : 1 +state 4503 observe1Greater1 observeIGreater1 + action 0 + 5045 : 0.833 + 5046 : 0.167 +state 4504 observe1Greater1 observeIGreater1 + action 0 + 5047 : 1 +state 4505 observe1Greater1 observeIGreater1 + action 0 + 5048 : 0.833 + 5049 : 0.167 +state 4506 observe1Greater1 observeIGreater1 + action 0 + 5050 : 1 +state 4507 observe1Greater1 observeIGreater1 + action 0 + 5051 : 0.833 + 5052 : 0.167 +state 4508 observe1Greater1 observeIGreater1 + action 0 + 5053 : 1 +state 4509 observe1Greater1 observeIGreater1 + action 0 + 5054 : 0.833 + 5055 : 0.167 +state 4510 observe1Greater1 observeIGreater1 + action 0 + 5056 : 1 +state 4511 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4511 : 1 +state 4512 observe2Greater1 observeIGreater1 + action 0 + 5057 : 0.833 + 5058 : 0.167 +state 4513 + action 0 + 5059 : 0.833 + 5060 : 0.167 +state 4514 + action 0 + 5061 : 0.833 + 5062 : 0.167 +state 4515 + action 0 + 5063 : 1 +state 4516 + action 0 + 5064 : 0.833 + 5065 : 0.167 +state 4517 + action 0 + 5066 : 1 +state 4518 + action 0 + 5067 : 0.833 + 5068 : 0.167 +state 4519 + action 0 + 5069 : 1 +state 4520 + action 0 + 5070 : 0.833 + 5071 : 0.167 +state 4521 + action 0 + 5072 : 1 +state 4522 + action 0 + 5073 : 0.833 + 5074 : 0.167 +state 4523 + action 0 + 5075 : 1 +state 4524 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4524 : 1 +state 4525 observe3Greater1 observeIGreater1 + action 0 + 5076 : 0.833 + 5077 : 0.167 +state 4526 + action 0 + 5078 : 0.833 + 5079 : 0.167 +state 4527 + action 0 + 5080 : 1 +state 4528 + action 0 + 5081 : 0.833 + 5082 : 0.167 +state 4529 + action 0 + 5083 : 1 +state 4530 + action 0 + 5084 : 0.833 + 5085 : 0.167 +state 4531 + action 0 + 5086 : 1 +state 4532 + action 0 + 5087 : 0.833 + 5088 : 0.167 +state 4533 + action 0 + 5089 : 1 +state 4534 + action 0 + 5090 : 0.833 + 5091 : 0.167 +state 4535 + action 0 + 5092 : 1 +state 4536 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4536 : 1 +state 4537 observe4Greater1 observeIGreater1 + action 0 + 5093 : 0.833 + 5094 : 0.167 +state 4538 + action 0 + 5095 : 1 +state 4539 + action 0 + 5096 : 0.833 + 5097 : 0.167 +state 4540 + action 0 + 5098 : 1 +state 4541 + action 0 + 5099 : 0.833 + 5100 : 0.167 +state 4542 + action 0 + 5101 : 1 +state 4543 + action 0 + 5102 : 0.833 + 5103 : 0.167 +state 4544 + action 0 + 5104 : 1 +state 4545 + action 0 + 5105 : 0.833 + 5106 : 0.167 +state 4546 + action 0 + 5107 : 1 +state 4547 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4547 : 1 +state 4548 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4548 : 1 +state 4549 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4549 : 1 +state 4550 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4550 : 1 +state 4551 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4551 : 1 +state 4552 observe2Greater1 observeIGreater1 + action 0 + 5108 : 0.833 + 5109 : 0.167 +state 4553 observe2Greater1 observeIGreater1 + action 0 + 5110 : 0.833 + 5111 : 0.167 +state 4554 observe2Greater1 observeIGreater1 + action 0 + 5112 : 0.833 + 5113 : 0.167 +state 4555 observe2Greater1 observeIGreater1 + action 0 + 5114 : 1 +state 4556 observe2Greater1 observeIGreater1 + action 0 + 5115 : 0.833 + 5116 : 0.167 +state 4557 observe2Greater1 observeIGreater1 + action 0 + 5117 : 1 +state 4558 observe2Greater1 observeIGreater1 + action 0 + 5118 : 0.833 + 5119 : 0.167 +state 4559 observe2Greater1 observeIGreater1 + action 0 + 5120 : 1 +state 4560 observe2Greater1 observeIGreater1 + action 0 + 5121 : 0.833 + 5122 : 0.167 +state 4561 observe2Greater1 observeIGreater1 + action 0 + 5123 : 1 +state 4562 observe2Greater1 observeIGreater1 + action 0 + 5124 : 0.833 + 5125 : 0.167 +state 4563 observe2Greater1 observeIGreater1 + action 0 + 5126 : 1 +state 4564 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4564 : 1 +state 4565 observe3Greater1 observeIGreater1 + action 0 + 5127 : 0.833 + 5128 : 0.167 +state 4566 + action 0 + 5129 : 0.833 + 5130 : 0.167 +state 4567 + action 0 + 5131 : 1 +state 4568 + action 0 + 5132 : 0.833 + 5133 : 0.167 +state 4569 + action 0 + 5134 : 1 +state 4570 + action 0 + 5135 : 0.833 + 5136 : 0.167 +state 4571 + action 0 + 5137 : 1 +state 4572 + action 0 + 5138 : 0.833 + 5139 : 0.167 +state 4573 + action 0 + 5140 : 1 +state 4574 + action 0 + 5141 : 0.833 + 5142 : 0.167 +state 4575 + action 0 + 5143 : 1 +state 4576 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4576 : 1 +state 4577 observe4Greater1 observeIGreater1 + action 0 + 5144 : 0.833 + 5145 : 0.167 +state 4578 + action 0 + 5146 : 1 +state 4579 + action 0 + 5147 : 0.833 + 5148 : 0.167 +state 4580 + action 0 + 5149 : 1 +state 4581 + action 0 + 5150 : 0.833 + 5151 : 0.167 +state 4582 + action 0 + 5152 : 1 +state 4583 + action 0 + 5153 : 0.833 + 5154 : 0.167 +state 4584 + action 0 + 5155 : 1 +state 4585 + action 0 + 5156 : 0.833 + 5157 : 0.167 +state 4586 + action 0 + 5158 : 1 +state 4587 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4587 : 1 +state 4588 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4588 : 1 +state 4589 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4589 : 1 +state 4590 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4590 : 1 +state 4591 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4591 : 1 +state 4592 observe3Greater1 observeIGreater1 + action 0 + 5159 : 0.833 + 5160 : 0.167 +state 4593 observe3Greater1 observeIGreater1 + action 0 + 5161 : 0.833 + 5162 : 0.167 +state 4594 observe3Greater1 observeIGreater1 + action 0 + 5163 : 1 +state 4595 observe3Greater1 observeIGreater1 + action 0 + 5164 : 0.833 + 5165 : 0.167 +state 4596 observe3Greater1 observeIGreater1 + action 0 + 5166 : 1 +state 4597 observe3Greater1 observeIGreater1 + action 0 + 5167 : 0.833 + 5168 : 0.167 +state 4598 observe3Greater1 observeIGreater1 + action 0 + 5169 : 1 +state 4599 observe3Greater1 observeIGreater1 + action 0 + 5170 : 0.833 + 5171 : 0.167 +state 4600 observe3Greater1 observeIGreater1 + action 0 + 5172 : 1 +state 4601 observe3Greater1 observeIGreater1 + action 0 + 5173 : 0.833 + 5174 : 0.167 +state 4602 observe3Greater1 observeIGreater1 + action 0 + 5175 : 1 +state 4603 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4603 : 1 +state 4604 observe4Greater1 observeIGreater1 + action 0 + 5176 : 0.833 + 5177 : 0.167 +state 4605 + action 0 + 5178 : 1 +state 4606 + action 0 + 5179 : 0.833 + 5180 : 0.167 +state 4607 + action 0 + 5181 : 1 +state 4608 + action 0 + 5182 : 0.833 + 5183 : 0.167 +state 4609 + action 0 + 5184 : 1 +state 4610 + action 0 + 5185 : 0.833 + 5186 : 0.167 +state 4611 + action 0 + 5187 : 1 +state 4612 + action 0 + 5188 : 0.833 + 5189 : 0.167 +state 4613 + action 0 + 5190 : 1 +state 4614 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4614 : 1 +state 4615 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4615 : 1 +state 4616 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4616 : 1 +state 4617 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4617 : 1 +state 4618 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4618 : 1 +state 4619 observe4Greater1 observeIGreater1 + action 0 + 5191 : 0.833 + 5192 : 0.167 +state 4620 observe4Greater1 observeIGreater1 + action 0 + 5193 : 1 +state 4621 observe4Greater1 observeIGreater1 + action 0 + 5194 : 0.833 + 5195 : 0.167 +state 4622 observe4Greater1 observeIGreater1 + action 0 + 5196 : 1 +state 4623 observe4Greater1 observeIGreater1 + action 0 + 5197 : 0.833 + 5198 : 0.167 +state 4624 observe4Greater1 observeIGreater1 + action 0 + 5199 : 1 +state 4625 observe4Greater1 observeIGreater1 + action 0 + 5200 : 0.833 + 5201 : 0.167 +state 4626 observe4Greater1 observeIGreater1 + action 0 + 5202 : 1 +state 4627 observe4Greater1 observeIGreater1 + action 0 + 5203 : 0.833 + 5204 : 0.167 +state 4628 observe4Greater1 observeIGreater1 + action 0 + 5205 : 1 +state 4629 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4629 : 1 +state 4630 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4630 : 1 +state 4631 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4631 : 1 +state 4632 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4632 : 1 +state 4633 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4633 : 1 +state 4634 observe1Greater1 observeIGreater1 + action 0 + 5036 : 0.833 + 5037 : 0.167 +state 4635 observe1Greater1 observeIGreater1 + action 0 + 5206 : 1 +state 4636 observe1Greater1 observeIGreater1 + action 0 + 5207 : 1 +state 4637 observe1Greater1 observeIGreater1 + action 0 + 5208 : 1 +state 4638 observe1Greater1 observeIGreater1 + action 0 + 5209 : 1 +state 4639 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 4640 observe1Greater1 observeIGreater1 + action 0 + 5215 : 1 +state 4641 observe1Greater1 observeIGreater1 + action 0 + 5038 : 0.833 + 5039 : 0.167 +state 4642 observe1Greater1 observeIGreater1 + action 0 + 5216 : 1 +state 4643 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5217 : 1 +state 4644 observe1Greater1 observeIGreater1 + action 0 + 5218 : 1 +state 4645 observe1Greater1 observeIGreater1 + action 0 + 5219 : 1 +state 4646 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 4647 observe1Greater1 observeIGreater1 + action 0 + 5225 : 1 +state 4648 observe1Greater1 observeIGreater1 + action 0 + 5040 : 0.833 + 5041 : 0.167 +state 4649 observe1Greater1 observeIGreater1 + action 0 + 5226 : 1 +state 4650 observe1Greater1 observeIGreater1 + action 0 + 5227 : 1 +state 4651 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5228 : 1 +state 4652 observe1Greater1 observeIGreater1 + action 0 + 5229 : 1 +state 4653 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 4654 observe1Greater1 observeIGreater1 + action 0 + 5235 : 1 +state 4655 observe1Greater1 observeIGreater1 + action 0 + 5042 : 0.833 + 5043 : 0.167 +state 4656 observe1Greater1 observeIGreater1 + action 0 + 5236 : 1 +state 4657 observe1Greater1 observeIGreater1 + action 0 + 5237 : 1 +state 4658 observe1Greater1 observeIGreater1 + action 0 + 5238 : 1 +state 4659 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5239 : 1 +state 4660 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 4661 observe1Greater1 observeIGreater1 + action 0 + 5245 : 1 +state 4662 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4662 : 1 +state 4663 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4664 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5246 : 1 +state 4665 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4665 : 1 +state 4666 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4667 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5247 : 1 +state 4668 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4668 : 1 +state 4669 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4670 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5248 : 1 +state 4671 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4671 : 1 +state 4672 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 3436 : 0.2 + 3437 : 0.2 + 3438 : 0.2 + 3439 : 0.2 + 3440 : 0.2 +state 4673 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5249 : 1 +state 4674 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 4674 : 1 +state 4675 observe2Greater1 observeIGreater1 + action 0 + 5057 : 0.833 + 5058 : 0.167 +state 4676 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5250 : 1 +state 4677 observe2Greater1 observeIGreater1 + action 0 + 5251 : 1 +state 4678 observe2Greater1 observeIGreater1 + action 0 + 5252 : 1 +state 4679 observe2Greater1 observeIGreater1 + action 0 + 5253 : 1 +state 4680 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 4681 observe2Greater1 observeIGreater1 + action 0 + 5259 : 1 +state 4682 + action 0 + 5059 : 0.833 + 5060 : 0.167 +state 4683 observe1Greater1 observeIGreater1 + action 0 + 5260 : 1 +state 4684 observe2Greater1 observeIGreater1 + action 0 + 5261 : 1 +state 4685 observe3Greater1 observeIGreater1 + action 0 + 5262 : 1 +state 4686 + action 0 + 5263 : 1 +state 4687 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 4688 + action 0 + 5269 : 1 +state 4689 + action 0 + 5061 : 0.833 + 5062 : 0.167 +state 4690 observe1Greater1 observeIGreater1 + action 0 + 5270 : 1 +state 4691 observe2Greater1 observeIGreater1 + action 0 + 5271 : 1 +state 4692 + action 0 + 5272 : 1 +state 4693 observe4Greater1 observeIGreater1 + action 0 + 5273 : 1 +state 4694 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 4695 + action 0 + 5279 : 1 +state 4696 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4696 : 1 +state 4697 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4698 observe0Greater1 observeOnlyTrueSender + action 0 + 5280 : 1 +state 4699 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4699 : 1 +state 4700 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4701 observe0Greater1 observeOnlyTrueSender + action 0 + 5281 : 1 +state 4702 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4702 : 1 +state 4703 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4704 observe0Greater1 observeOnlyTrueSender + action 0 + 5282 : 1 +state 4705 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4705 : 1 +state 4706 observe0Greater1 observeOnlyTrueSender + action 0 + 3479 : 0.2 + 3480 : 0.2 + 3481 : 0.2 + 3482 : 0.2 + 3483 : 0.2 +state 4707 observe0Greater1 observeOnlyTrueSender + action 0 + 5283 : 1 +state 4708 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4708 : 1 +state 4709 observe3Greater1 observeIGreater1 + action 0 + 5076 : 0.833 + 5077 : 0.167 +state 4710 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5284 : 1 +state 4711 observe3Greater1 observeIGreater1 + action 0 + 5285 : 1 +state 4712 observe3Greater1 observeIGreater1 + action 0 + 5286 : 1 +state 4713 observe3Greater1 observeIGreater1 + action 0 + 5287 : 1 +state 4714 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 4715 observe3Greater1 observeIGreater1 + action 0 + 5293 : 1 +state 4716 + action 0 + 5078 : 0.833 + 5079 : 0.167 +state 4717 observe1Greater1 observeIGreater1 + action 0 + 5294 : 1 +state 4718 + action 0 + 5295 : 1 +state 4719 observe3Greater1 observeIGreater1 + action 0 + 5296 : 1 +state 4720 observe4Greater1 observeIGreater1 + action 0 + 5297 : 1 +state 4721 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 4722 + action 0 + 5303 : 1 +state 4723 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4723 : 1 +state 4724 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4725 observe0Greater1 observeOnlyTrueSender + action 0 + 5304 : 1 +state 4726 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4726 : 1 +state 4727 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4728 observe0Greater1 observeOnlyTrueSender + action 0 + 5305 : 1 +state 4729 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4729 : 1 +state 4730 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4731 observe0Greater1 observeOnlyTrueSender + action 0 + 5306 : 1 +state 4732 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4732 : 1 +state 4733 observe0Greater1 observeOnlyTrueSender + action 0 + 3511 : 0.2 + 3512 : 0.2 + 3513 : 0.2 + 3514 : 0.2 + 3515 : 0.2 +state 4734 observe0Greater1 observeOnlyTrueSender + action 0 + 5307 : 1 +state 4735 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4735 : 1 +state 4736 observe4Greater1 observeIGreater1 + action 0 + 5093 : 0.833 + 5094 : 0.167 +state 4737 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5308 : 1 +state 4738 observe4Greater1 observeIGreater1 + action 0 + 5309 : 1 +state 4739 observe4Greater1 observeIGreater1 + action 0 + 5310 : 1 +state 4740 observe4Greater1 observeIGreater1 + action 0 + 5311 : 1 +state 4741 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 4742 observe4Greater1 observeIGreater1 + action 0 + 5317 : 1 +state 4743 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4743 : 1 +state 4744 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4745 observe0Greater1 observeOnlyTrueSender + action 0 + 5318 : 1 +state 4746 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4746 : 1 +state 4747 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4748 observe0Greater1 observeOnlyTrueSender + action 0 + 5319 : 1 +state 4749 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4749 : 1 +state 4750 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4751 observe0Greater1 observeOnlyTrueSender + action 0 + 5320 : 1 +state 4752 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4752 : 1 +state 4753 observe0Greater1 observeOnlyTrueSender + action 0 + 3532 : 0.2 + 3533 : 0.2 + 3534 : 0.2 + 3535 : 0.2 + 3536 : 0.2 +state 4754 observe0Greater1 observeOnlyTrueSender + action 0 + 5321 : 1 +state 4755 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4755 : 1 +state 4756 observe2Greater1 observeIGreater1 + action 0 + 5108 : 0.833 + 5109 : 0.167 +state 4757 observe2Greater1 observeIGreater1 + action 0 + 5322 : 1 +state 4758 observe2Greater1 observeIGreater1 + action 0 + 5323 : 1 +state 4759 observe2Greater1 observeIGreater1 + action 0 + 5324 : 1 +state 4760 observe2Greater1 observeIGreater1 + action 0 + 5325 : 1 +state 4761 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 4762 observe2Greater1 observeIGreater1 + action 0 + 5331 : 1 +state 4763 observe2Greater1 observeIGreater1 + action 0 + 5110 : 0.833 + 5111 : 0.167 +state 4764 observe2Greater1 observeIGreater1 + action 0 + 5332 : 1 +state 4765 observe2Greater1 observeIGreater1 + action 0 + 5333 : 1 +state 4766 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5334 : 1 +state 4767 observe2Greater1 observeIGreater1 + action 0 + 5335 : 1 +state 4768 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 4769 observe2Greater1 observeIGreater1 + action 0 + 5341 : 1 +state 4770 observe2Greater1 observeIGreater1 + action 0 + 5112 : 0.833 + 5113 : 0.167 +state 4771 observe2Greater1 observeIGreater1 + action 0 + 5342 : 1 +state 4772 observe2Greater1 observeIGreater1 + action 0 + 5343 : 1 +state 4773 observe2Greater1 observeIGreater1 + action 0 + 5344 : 1 +state 4774 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5345 : 1 +state 4775 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 4776 observe2Greater1 observeIGreater1 + action 0 + 5351 : 1 +state 4777 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4777 : 1 +state 4778 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4779 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5352 : 1 +state 4780 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4780 : 1 +state 4781 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4782 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5353 : 1 +state 4783 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4783 : 1 +state 4784 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4785 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5354 : 1 +state 4786 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4786 : 1 +state 4787 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 3579 : 0.2 + 3580 : 0.2 + 3581 : 0.2 + 3582 : 0.2 + 3583 : 0.2 +state 4788 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5355 : 1 +state 4789 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 4789 : 1 +state 4790 observe3Greater1 observeIGreater1 + action 0 + 5127 : 0.833 + 5128 : 0.167 +state 4791 observe3Greater1 observeIGreater1 + action 0 + 5356 : 1 +state 4792 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5357 : 1 +state 4793 observe3Greater1 observeIGreater1 + action 0 + 5358 : 1 +state 4794 observe3Greater1 observeIGreater1 + action 0 + 5359 : 1 +state 4795 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 4796 observe3Greater1 observeIGreater1 + action 0 + 5365 : 1 +state 4797 + action 0 + 5129 : 0.833 + 5130 : 0.167 +state 4798 + action 0 + 5366 : 1 +state 4799 observe2Greater1 observeIGreater1 + action 0 + 5367 : 1 +state 4800 observe3Greater1 observeIGreater1 + action 0 + 5368 : 1 +state 4801 observe4Greater1 observeIGreater1 + action 0 + 5369 : 1 +state 4802 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 4803 + action 0 + 5375 : 1 +state 4804 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4804 : 1 +state 4805 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4806 observe0Greater1 observeOnlyTrueSender + action 0 + 5376 : 1 +state 4807 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4807 : 1 +state 4808 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4809 observe0Greater1 observeOnlyTrueSender + action 0 + 5377 : 1 +state 4810 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4810 : 1 +state 4811 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4812 observe0Greater1 observeOnlyTrueSender + action 0 + 5378 : 1 +state 4813 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4813 : 1 +state 4814 observe0Greater1 observeOnlyTrueSender + action 0 + 3611 : 0.2 + 3612 : 0.2 + 3613 : 0.2 + 3614 : 0.2 + 3615 : 0.2 +state 4815 observe0Greater1 observeOnlyTrueSender + action 0 + 5379 : 1 +state 4816 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4816 : 1 +state 4817 observe4Greater1 observeIGreater1 + action 0 + 5144 : 0.833 + 5145 : 0.167 +state 4818 observe4Greater1 observeIGreater1 + action 0 + 5380 : 1 +state 4819 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5381 : 1 +state 4820 observe4Greater1 observeIGreater1 + action 0 + 5382 : 1 +state 4821 observe4Greater1 observeIGreater1 + action 0 + 5383 : 1 +state 4822 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 4823 observe4Greater1 observeIGreater1 + action 0 + 5389 : 1 +state 4824 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4824 : 1 +state 4825 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4826 observe0Greater1 observeOnlyTrueSender + action 0 + 5390 : 1 +state 4827 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4827 : 1 +state 4828 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4829 observe0Greater1 observeOnlyTrueSender + action 0 + 5391 : 1 +state 4830 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4830 : 1 +state 4831 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4832 observe0Greater1 observeOnlyTrueSender + action 0 + 5392 : 1 +state 4833 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4833 : 1 +state 4834 observe0Greater1 observeOnlyTrueSender + action 0 + 3632 : 0.2 + 3633 : 0.2 + 3634 : 0.2 + 3635 : 0.2 + 3636 : 0.2 +state 4835 observe0Greater1 observeOnlyTrueSender + action 0 + 5393 : 1 +state 4836 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4836 : 1 +state 4837 observe3Greater1 observeIGreater1 + action 0 + 5159 : 0.833 + 5160 : 0.167 +state 4838 observe3Greater1 observeIGreater1 + action 0 + 5394 : 1 +state 4839 observe3Greater1 observeIGreater1 + action 0 + 5395 : 1 +state 4840 observe3Greater1 observeIGreater1 + action 0 + 5396 : 1 +state 4841 observe3Greater1 observeIGreater1 + action 0 + 5397 : 1 +state 4842 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 4843 observe3Greater1 observeIGreater1 + action 0 + 5403 : 1 +state 4844 observe3Greater1 observeIGreater1 + action 0 + 5161 : 0.833 + 5162 : 0.167 +state 4845 observe3Greater1 observeIGreater1 + action 0 + 5404 : 1 +state 4846 observe3Greater1 observeIGreater1 + action 0 + 5405 : 1 +state 4847 observe3Greater1 observeIGreater1 + action 0 + 5406 : 1 +state 4848 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5407 : 1 +state 4849 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 4850 observe3Greater1 observeIGreater1 + action 0 + 5413 : 1 +state 4851 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4851 : 1 +state 4852 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4853 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5414 : 1 +state 4854 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4854 : 1 +state 4855 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4856 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5415 : 1 +state 4857 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4857 : 1 +state 4858 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4859 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5416 : 1 +state 4860 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4860 : 1 +state 4861 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 3668 : 0.2 + 3669 : 0.2 + 3670 : 0.2 + 3671 : 0.2 + 3672 : 0.2 +state 4862 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5417 : 1 +state 4863 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 4863 : 1 +state 4864 observe4Greater1 observeIGreater1 + action 0 + 5176 : 0.833 + 5177 : 0.167 +state 4865 observe4Greater1 observeIGreater1 + action 0 + 5418 : 1 +state 4866 observe4Greater1 observeIGreater1 + action 0 + 5419 : 1 +state 4867 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5420 : 1 +state 4868 observe4Greater1 observeIGreater1 + action 0 + 5421 : 1 +state 4869 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 4870 observe4Greater1 observeIGreater1 + action 0 + 5427 : 1 +state 4871 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4871 : 1 +state 4872 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4873 observe0Greater1 observeOnlyTrueSender + action 0 + 5428 : 1 +state 4874 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4874 : 1 +state 4875 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4876 observe0Greater1 observeOnlyTrueSender + action 0 + 5429 : 1 +state 4877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4877 : 1 +state 4878 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4879 observe0Greater1 observeOnlyTrueSender + action 0 + 5430 : 1 +state 4880 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4880 : 1 +state 4881 observe0Greater1 observeOnlyTrueSender + action 0 + 3689 : 0.2 + 3690 : 0.2 + 3691 : 0.2 + 3692 : 0.2 + 3693 : 0.2 +state 4882 observe0Greater1 observeOnlyTrueSender + action 0 + 5431 : 1 +state 4883 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 4883 : 1 +state 4884 observe4Greater1 observeIGreater1 + action 0 + 5191 : 0.833 + 5192 : 0.167 +state 4885 observe4Greater1 observeIGreater1 + action 0 + 5432 : 1 +state 4886 observe4Greater1 observeIGreater1 + action 0 + 5433 : 1 +state 4887 observe4Greater1 observeIGreater1 + action 0 + 5434 : 1 +state 4888 observe4Greater1 observeIGreater1 + action 0 + 5435 : 1 +state 4889 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 4890 observe4Greater1 observeIGreater1 + action 0 + 5441 : 1 +state 4891 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4891 : 1 +state 4892 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4893 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5442 : 1 +state 4894 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4894 : 1 +state 4895 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4896 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5443 : 1 +state 4897 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4897 : 1 +state 4898 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4899 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5444 : 1 +state 4900 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4900 : 1 +state 4901 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 3714 : 0.2 + 3715 : 0.2 + 3716 : 0.2 + 3717 : 0.2 + 3718 : 0.2 +state 4902 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5445 : 1 +state 4903 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 4903 : 1 +state 4904 observe1Greater1 observeIGreater1 + action 0 + 5446 : 1 +state 4905 + action 0 + 5447 : 1 +state 4906 + action 0 + 5448 : 1 +state 4907 + action 0 + 5449 : 1 +state 4908 + action 0 + 5450 : 1 +state 4909 observe2Greater1 observeIGreater1 + action 0 + 5451 : 1 +state 4910 + action 0 + 5452 : 1 +state 4911 + action 0 + 5453 : 1 +state 4912 + action 0 + 5454 : 1 +state 4913 + action 0 + 5455 : 1 +state 4914 observe3Greater1 observeIGreater1 + action 0 + 5456 : 1 +state 4915 + action 0 + 5457 : 1 +state 4916 + action 0 + 5458 : 1 +state 4917 + action 0 + 5459 : 1 +state 4918 + action 0 + 5460 : 1 +state 4919 observe4Greater1 observeIGreater1 + action 0 + 5461 : 1 +state 4920 observe1Greater1 observeIGreater1 + action 0 + 5462 : 1 +state 4921 observe1Greater1 observeIGreater1 + action 0 + 5463 : 0.833 + 5464 : 0.167 +state 4922 observe1Greater1 observeIGreater1 + action 0 + 5465 : 1 +state 4923 observe1Greater1 observeIGreater1 + action 0 + 5466 : 0.833 + 5467 : 0.167 +state 4924 observe1Greater1 observeIGreater1 + action 0 + 5468 : 1 +state 4925 observe1Greater1 observeIGreater1 + action 0 + 5469 : 0.833 + 5470 : 0.167 +state 4926 observe1Greater1 observeIGreater1 + action 0 + 5471 : 1 +state 4927 observe1Greater1 observeIGreater1 + action 0 + 5472 : 0.833 + 5473 : 0.167 +state 4928 observe1Greater1 observeIGreater1 + action 0 + 5474 : 1 +state 4929 deadlock observe1Greater1 observeIGreater1 + action 0 + 4929 : 1 +state 4930 + action 0 + 5475 : 1 +state 4931 + action 0 + 5476 : 0.833 + 5477 : 0.167 +state 4932 + action 0 + 5478 : 1 +state 4933 + action 0 + 5479 : 0.833 + 5480 : 0.167 +state 4934 + action 0 + 5481 : 1 +state 4935 + action 0 + 5482 : 0.833 + 5483 : 0.167 +state 4936 + action 0 + 5484 : 1 +state 4937 + action 0 + 5485 : 0.833 + 5486 : 0.167 +state 4938 + action 0 + 5487 : 1 +state 4939 deadlock + action 0 + 4939 : 1 +state 4940 + action 0 + 5488 : 1 +state 4941 + action 0 + 5489 : 0.833 + 5490 : 0.167 +state 4942 + action 0 + 5491 : 1 +state 4943 + action 0 + 5492 : 0.833 + 5493 : 0.167 +state 4944 + action 0 + 5494 : 1 +state 4945 + action 0 + 5495 : 0.833 + 5496 : 0.167 +state 4946 + action 0 + 5497 : 1 +state 4947 + action 0 + 5498 : 0.833 + 5499 : 0.167 +state 4948 + action 0 + 5500 : 1 +state 4949 deadlock + action 0 + 4949 : 1 +state 4950 + action 0 + 5501 : 1 +state 4951 + action 0 + 5502 : 0.833 + 5503 : 0.167 +state 4952 + action 0 + 5504 : 1 +state 4953 + action 0 + 5505 : 0.833 + 5506 : 0.167 +state 4954 + action 0 + 5507 : 1 +state 4955 + action 0 + 5508 : 0.833 + 5509 : 0.167 +state 4956 + action 0 + 5510 : 1 +state 4957 + action 0 + 5511 : 0.833 + 5512 : 0.167 +state 4958 + action 0 + 5513 : 1 +state 4959 deadlock + action 0 + 4959 : 1 +state 4960 deadlock observe1Greater1 observeIGreater1 + action 0 + 4960 : 1 +state 4961 deadlock + action 0 + 4961 : 1 +state 4962 deadlock + action 0 + 4962 : 1 +state 4963 deadlock + action 0 + 4963 : 1 +state 4964 observe2Greater1 observeIGreater1 + action 0 + 5514 : 1 +state 4965 observe2Greater1 observeIGreater1 + action 0 + 5515 : 0.833 + 5516 : 0.167 +state 4966 observe2Greater1 observeIGreater1 + action 0 + 5517 : 1 +state 4967 observe2Greater1 observeIGreater1 + action 0 + 5518 : 0.833 + 5519 : 0.167 +state 4968 observe2Greater1 observeIGreater1 + action 0 + 5520 : 1 +state 4969 observe2Greater1 observeIGreater1 + action 0 + 5521 : 0.833 + 5522 : 0.167 +state 4970 observe2Greater1 observeIGreater1 + action 0 + 5523 : 1 +state 4971 observe2Greater1 observeIGreater1 + action 0 + 5524 : 0.833 + 5525 : 0.167 +state 4972 observe2Greater1 observeIGreater1 + action 0 + 5526 : 1 +state 4973 deadlock observe2Greater1 observeIGreater1 + action 0 + 4973 : 1 +state 4974 + action 0 + 5527 : 1 +state 4975 + action 0 + 5528 : 0.833 + 5529 : 0.167 +state 4976 + action 0 + 5530 : 1 +state 4977 + action 0 + 5531 : 0.833 + 5532 : 0.167 +state 4978 + action 0 + 5533 : 1 +state 4979 + action 0 + 5534 : 0.833 + 5535 : 0.167 +state 4980 + action 0 + 5536 : 1 +state 4981 + action 0 + 5537 : 0.833 + 5538 : 0.167 +state 4982 + action 0 + 5539 : 1 +state 4983 deadlock + action 0 + 4983 : 1 +state 4984 + action 0 + 5540 : 1 +state 4985 + action 0 + 5541 : 0.833 + 5542 : 0.167 +state 4986 + action 0 + 5543 : 1 +state 4987 + action 0 + 5544 : 0.833 + 5545 : 0.167 +state 4988 + action 0 + 5546 : 1 +state 4989 + action 0 + 5547 : 0.833 + 5548 : 0.167 +state 4990 + action 0 + 5549 : 1 +state 4991 + action 0 + 5550 : 0.833 + 5551 : 0.167 +state 4992 + action 0 + 5552 : 1 +state 4993 deadlock + action 0 + 4993 : 1 +state 4994 deadlock + action 0 + 4994 : 1 +state 4995 deadlock observe2Greater1 observeIGreater1 + action 0 + 4995 : 1 +state 4996 deadlock + action 0 + 4996 : 1 +state 4997 deadlock + action 0 + 4997 : 1 +state 4998 observe3Greater1 observeIGreater1 + action 0 + 5553 : 1 +state 4999 observe3Greater1 observeIGreater1 + action 0 + 5554 : 0.833 + 5555 : 0.167 +state 5000 observe3Greater1 observeIGreater1 + action 0 + 5556 : 1 +state 5001 observe3Greater1 observeIGreater1 + action 0 + 5557 : 0.833 + 5558 : 0.167 +state 5002 observe3Greater1 observeIGreater1 + action 0 + 5559 : 1 +state 5003 observe3Greater1 observeIGreater1 + action 0 + 5560 : 0.833 + 5561 : 0.167 +state 5004 observe3Greater1 observeIGreater1 + action 0 + 5562 : 1 +state 5005 observe3Greater1 observeIGreater1 + action 0 + 5563 : 0.833 + 5564 : 0.167 +state 5006 observe3Greater1 observeIGreater1 + action 0 + 5565 : 1 +state 5007 deadlock observe3Greater1 observeIGreater1 + action 0 + 5007 : 1 +state 5008 + action 0 + 5566 : 1 +state 5009 + action 0 + 5567 : 0.833 + 5568 : 0.167 +state 5010 + action 0 + 5569 : 1 +state 5011 + action 0 + 5570 : 0.833 + 5571 : 0.167 +state 5012 + action 0 + 5572 : 1 +state 5013 + action 0 + 5573 : 0.833 + 5574 : 0.167 +state 5014 + action 0 + 5575 : 1 +state 5015 + action 0 + 5576 : 0.833 + 5577 : 0.167 +state 5016 + action 0 + 5578 : 1 +state 5017 deadlock + action 0 + 5017 : 1 +state 5018 deadlock + action 0 + 5018 : 1 +state 5019 deadlock + action 0 + 5019 : 1 +state 5020 deadlock observe3Greater1 observeIGreater1 + action 0 + 5020 : 1 +state 5021 deadlock + action 0 + 5021 : 1 +state 5022 observe4Greater1 observeIGreater1 + action 0 + 5579 : 1 +state 5023 observe4Greater1 observeIGreater1 + action 0 + 5580 : 0.833 + 5581 : 0.167 +state 5024 observe4Greater1 observeIGreater1 + action 0 + 5582 : 1 +state 5025 observe4Greater1 observeIGreater1 + action 0 + 5583 : 0.833 + 5584 : 0.167 +state 5026 observe4Greater1 observeIGreater1 + action 0 + 5585 : 1 +state 5027 observe4Greater1 observeIGreater1 + action 0 + 5586 : 0.833 + 5587 : 0.167 +state 5028 observe4Greater1 observeIGreater1 + action 0 + 5588 : 1 +state 5029 observe4Greater1 observeIGreater1 + action 0 + 5589 : 0.833 + 5590 : 0.167 +state 5030 observe4Greater1 observeIGreater1 + action 0 + 5591 : 1 +state 5031 deadlock observe4Greater1 observeIGreater1 + action 0 + 5031 : 1 +state 5032 deadlock + action 0 + 5032 : 1 +state 5033 deadlock + action 0 + 5033 : 1 +state 5034 deadlock + action 0 + 5034 : 1 +state 5035 deadlock observe4Greater1 observeIGreater1 + action 0 + 5035 : 1 +state 5036 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 5037 observe1Greater1 observeIGreater1 + action 0 + 5597 : 1 +state 5038 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 5039 observe1Greater1 observeIGreater1 + action 0 + 5603 : 1 +state 5040 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 5041 observe1Greater1 observeIGreater1 + action 0 + 5609 : 1 +state 5042 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 5043 observe1Greater1 observeIGreater1 + action 0 + 5615 : 1 +state 5044 deadlock observe1Greater1 observeIGreater1 + action 0 + 5044 : 1 +state 5045 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5046 observe1Greater1 observeIGreater1 + action 0 + 5616 : 1 +state 5047 deadlock observe1Greater1 observeIGreater1 + action 0 + 5047 : 1 +state 5048 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5049 observe1Greater1 observeIGreater1 + action 0 + 5617 : 1 +state 5050 deadlock observe1Greater1 observeIGreater1 + action 0 + 5050 : 1 +state 5051 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5052 observe1Greater1 observeIGreater1 + action 0 + 5618 : 1 +state 5053 deadlock observe1Greater1 observeIGreater1 + action 0 + 5053 : 1 +state 5054 observe1Greater1 observeIGreater1 + action 0 + 3848 : 0.2 + 3849 : 0.2 + 3850 : 0.2 + 3851 : 0.2 + 3852 : 0.2 +state 5055 observe1Greater1 observeIGreater1 + action 0 + 5619 : 1 +state 5056 deadlock observe1Greater1 observeIGreater1 + action 0 + 5056 : 1 +state 5057 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 5058 observe2Greater1 observeIGreater1 + action 0 + 5625 : 1 +state 5059 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 5060 + action 0 + 5631 : 1 +state 5061 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 5062 + action 0 + 5637 : 1 +state 5063 deadlock + action 0 + 5063 : 1 +state 5064 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5065 + action 0 + 5638 : 1 +state 5066 deadlock + action 0 + 5066 : 1 +state 5067 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5068 + action 0 + 5639 : 1 +state 5069 deadlock + action 0 + 5069 : 1 +state 5070 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5071 + action 0 + 5640 : 1 +state 5072 deadlock + action 0 + 5072 : 1 +state 5073 + action 0 + 3858 : 0.2 + 3859 : 0.2 + 3860 : 0.2 + 3861 : 0.2 + 3862 : 0.2 +state 5074 + action 0 + 5641 : 1 +state 5075 deadlock + action 0 + 5075 : 1 +state 5076 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 5077 observe3Greater1 observeIGreater1 + action 0 + 5647 : 1 +state 5078 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 5079 + action 0 + 5653 : 1 +state 5080 deadlock + action 0 + 5080 : 1 +state 5081 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5082 + action 0 + 5654 : 1 +state 5083 deadlock + action 0 + 5083 : 1 +state 5084 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5085 + action 0 + 5655 : 1 +state 5086 deadlock + action 0 + 5086 : 1 +state 5087 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5088 + action 0 + 5656 : 1 +state 5089 deadlock + action 0 + 5089 : 1 +state 5090 + action 0 + 3868 : 0.2 + 3869 : 0.2 + 3870 : 0.2 + 3871 : 0.2 + 3872 : 0.2 +state 5091 + action 0 + 5657 : 1 +state 5092 deadlock + action 0 + 5092 : 1 +state 5093 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 5094 observe4Greater1 observeIGreater1 + action 0 + 5663 : 1 +state 5095 deadlock + action 0 + 5095 : 1 +state 5096 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5097 + action 0 + 5664 : 1 +state 5098 deadlock + action 0 + 5098 : 1 +state 5099 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5100 + action 0 + 5665 : 1 +state 5101 deadlock + action 0 + 5101 : 1 +state 5102 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5103 + action 0 + 5666 : 1 +state 5104 deadlock + action 0 + 5104 : 1 +state 5105 + action 0 + 3878 : 0.2 + 3879 : 0.2 + 3880 : 0.2 + 3881 : 0.2 + 3882 : 0.2 +state 5106 + action 0 + 5667 : 1 +state 5107 deadlock + action 0 + 5107 : 1 +state 5108 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 5109 observe2Greater1 observeIGreater1 + action 0 + 5673 : 1 +state 5110 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 5111 observe2Greater1 observeIGreater1 + action 0 + 5679 : 1 +state 5112 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 5113 observe2Greater1 observeIGreater1 + action 0 + 5685 : 1 +state 5114 deadlock observe2Greater1 observeIGreater1 + action 0 + 5114 : 1 +state 5115 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5116 observe2Greater1 observeIGreater1 + action 0 + 5686 : 1 +state 5117 deadlock observe2Greater1 observeIGreater1 + action 0 + 5117 : 1 +state 5118 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5119 observe2Greater1 observeIGreater1 + action 0 + 5687 : 1 +state 5120 deadlock observe2Greater1 observeIGreater1 + action 0 + 5120 : 1 +state 5121 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5122 observe2Greater1 observeIGreater1 + action 0 + 5688 : 1 +state 5123 deadlock observe2Greater1 observeIGreater1 + action 0 + 5123 : 1 +state 5124 observe2Greater1 observeIGreater1 + action 0 + 3892 : 0.2 + 3893 : 0.2 + 3894 : 0.2 + 3895 : 0.2 + 3896 : 0.2 +state 5125 observe2Greater1 observeIGreater1 + action 0 + 5689 : 1 +state 5126 deadlock observe2Greater1 observeIGreater1 + action 0 + 5126 : 1 +state 5127 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 5128 observe3Greater1 observeIGreater1 + action 0 + 5695 : 1 +state 5129 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 5130 + action 0 + 5701 : 1 +state 5131 deadlock + action 0 + 5131 : 1 +state 5132 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5133 + action 0 + 5702 : 1 +state 5134 deadlock + action 0 + 5134 : 1 +state 5135 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5136 + action 0 + 5703 : 1 +state 5137 deadlock + action 0 + 5137 : 1 +state 5138 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5139 + action 0 + 5704 : 1 +state 5140 deadlock + action 0 + 5140 : 1 +state 5141 + action 0 + 3902 : 0.2 + 3903 : 0.2 + 3904 : 0.2 + 3905 : 0.2 + 3906 : 0.2 +state 5142 + action 0 + 5705 : 1 +state 5143 deadlock + action 0 + 5143 : 1 +state 5144 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 5145 observe4Greater1 observeIGreater1 + action 0 + 5711 : 1 +state 5146 deadlock + action 0 + 5146 : 1 +state 5147 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5148 + action 0 + 5712 : 1 +state 5149 deadlock + action 0 + 5149 : 1 +state 5150 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5151 + action 0 + 5713 : 1 +state 5152 deadlock + action 0 + 5152 : 1 +state 5153 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5154 + action 0 + 5714 : 1 +state 5155 deadlock + action 0 + 5155 : 1 +state 5156 + action 0 + 3912 : 0.2 + 3913 : 0.2 + 3914 : 0.2 + 3915 : 0.2 + 3916 : 0.2 +state 5157 + action 0 + 5715 : 1 +state 5158 deadlock + action 0 + 5158 : 1 +state 5159 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 5160 observe3Greater1 observeIGreater1 + action 0 + 5721 : 1 +state 5161 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 5162 observe3Greater1 observeIGreater1 + action 0 + 5727 : 1 +state 5163 deadlock observe3Greater1 observeIGreater1 + action 0 + 5163 : 1 +state 5164 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5165 observe3Greater1 observeIGreater1 + action 0 + 5728 : 1 +state 5166 deadlock observe3Greater1 observeIGreater1 + action 0 + 5166 : 1 +state 5167 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5168 observe3Greater1 observeIGreater1 + action 0 + 5729 : 1 +state 5169 deadlock observe3Greater1 observeIGreater1 + action 0 + 5169 : 1 +state 5170 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5171 observe3Greater1 observeIGreater1 + action 0 + 5730 : 1 +state 5172 deadlock observe3Greater1 observeIGreater1 + action 0 + 5172 : 1 +state 5173 observe3Greater1 observeIGreater1 + action 0 + 3926 : 0.2 + 3927 : 0.2 + 3928 : 0.2 + 3929 : 0.2 + 3930 : 0.2 +state 5174 observe3Greater1 observeIGreater1 + action 0 + 5731 : 1 +state 5175 deadlock observe3Greater1 observeIGreater1 + action 0 + 5175 : 1 +state 5176 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 5177 observe4Greater1 observeIGreater1 + action 0 + 5737 : 1 +state 5178 deadlock + action 0 + 5178 : 1 +state 5179 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5180 + action 0 + 5738 : 1 +state 5181 deadlock + action 0 + 5181 : 1 +state 5182 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5183 + action 0 + 5739 : 1 +state 5184 deadlock + action 0 + 5184 : 1 +state 5185 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5186 + action 0 + 5740 : 1 +state 5187 deadlock + action 0 + 5187 : 1 +state 5188 + action 0 + 3936 : 0.2 + 3937 : 0.2 + 3938 : 0.2 + 3939 : 0.2 + 3940 : 0.2 +state 5189 + action 0 + 5741 : 1 +state 5190 deadlock + action 0 + 5190 : 1 +state 5191 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 5192 observe4Greater1 observeIGreater1 + action 0 + 5747 : 1 +state 5193 deadlock observe4Greater1 observeIGreater1 + action 0 + 5193 : 1 +state 5194 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5195 observe4Greater1 observeIGreater1 + action 0 + 5748 : 1 +state 5196 deadlock observe4Greater1 observeIGreater1 + action 0 + 5196 : 1 +state 5197 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5198 observe4Greater1 observeIGreater1 + action 0 + 5749 : 1 +state 5199 deadlock observe4Greater1 observeIGreater1 + action 0 + 5199 : 1 +state 5200 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5201 observe4Greater1 observeIGreater1 + action 0 + 5750 : 1 +state 5202 deadlock observe4Greater1 observeIGreater1 + action 0 + 5202 : 1 +state 5203 observe4Greater1 observeIGreater1 + action 0 + 3950 : 0.2 + 3951 : 0.2 + 3952 : 0.2 + 3953 : 0.2 + 3954 : 0.2 +state 5204 observe4Greater1 observeIGreater1 + action 0 + 5751 : 1 +state 5205 deadlock observe4Greater1 observeIGreater1 + action 0 + 5205 : 1 +state 5206 observe1Greater1 observeIGreater1 + action 0 + 5752 : 1 +state 5207 observe1Greater1 observeIGreater1 + action 0 + 5753 : 1 +state 5208 observe1Greater1 observeIGreater1 + action 0 + 5754 : 1 +state 5209 observe1Greater1 observeIGreater1 + action 0 + 5755 : 1 +state 5210 observe1Greater1 observeIGreater1 + action 0 + 5756 : 0.8 + 5757 : 0.2 +state 5211 observe1Greater1 observeIGreater1 + action 0 + 5758 : 0.8 + 5759 : 0.2 +state 5212 observe1Greater1 observeIGreater1 + action 0 + 5760 : 0.8 + 5761 : 0.2 +state 5213 observe1Greater1 observeIGreater1 + action 0 + 5762 : 0.8 + 5763 : 0.2 +state 5214 observe1Greater1 observeIGreater1 + action 0 + 5764 : 0.8 + 5765 : 0.2 +state 5215 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5766 : 1 +state 5216 observe1Greater1 observeIGreater1 + action 0 + 5753 : 1 +state 5217 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5767 : 1 +state 5218 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5219 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5220 observe1Greater1 observeIGreater1 + action 0 + 5770 : 0.8 + 5771 : 0.2 +state 5221 observe1Greater1 observeIGreater1 + action 0 + 5772 : 0.8 + 5773 : 0.2 +state 5222 observe1Greater1 observeIGreater1 + action 0 + 5774 : 0.8 + 5775 : 0.2 +state 5223 observe1Greater1 observeIGreater1 + action 0 + 5776 : 0.8 + 5777 : 0.2 +state 5224 observe1Greater1 observeIGreater1 + action 0 + 5778 : 0.8 + 5779 : 0.2 +state 5225 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5780 : 1 +state 5226 observe1Greater1 observeIGreater1 + action 0 + 5754 : 1 +state 5227 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5228 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5781 : 1 +state 5229 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5230 observe1Greater1 observeIGreater1 + action 0 + 5783 : 0.8 + 5784 : 0.2 +state 5231 observe1Greater1 observeIGreater1 + action 0 + 5785 : 0.8 + 5786 : 0.2 +state 5232 observe1Greater1 observeIGreater1 + action 0 + 5787 : 0.8 + 5788 : 0.2 +state 5233 observe1Greater1 observeIGreater1 + action 0 + 5789 : 0.8 + 5790 : 0.2 +state 5234 observe1Greater1 observeIGreater1 + action 0 + 5791 : 0.8 + 5792 : 0.2 +state 5235 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5793 : 1 +state 5236 observe1Greater1 observeIGreater1 + action 0 + 5755 : 1 +state 5237 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5238 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5239 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5794 : 1 +state 5240 observe1Greater1 observeIGreater1 + action 0 + 5795 : 0.8 + 5796 : 0.2 +state 5241 observe1Greater1 observeIGreater1 + action 0 + 5797 : 0.8 + 5798 : 0.2 +state 5242 observe1Greater1 observeIGreater1 + action 0 + 5799 : 0.8 + 5800 : 0.2 +state 5243 observe1Greater1 observeIGreater1 + action 0 + 5801 : 0.8 + 5802 : 0.2 +state 5244 observe1Greater1 observeIGreater1 + action 0 + 5803 : 0.8 + 5804 : 0.2 +state 5245 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5805 : 1 +state 5246 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5806 : 1 +state 5247 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5807 : 1 +state 5248 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5808 : 1 +state 5249 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5809 : 1 +state 5250 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 5767 : 1 +state 5251 observe2Greater1 observeIGreater1 + action 0 + 5810 : 1 +state 5252 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5253 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5254 observe2Greater1 observeIGreater1 + action 0 + 5813 : 0.8 + 5814 : 0.2 +state 5255 observe2Greater1 observeIGreater1 + action 0 + 5815 : 0.8 + 5816 : 0.2 +state 5256 observe2Greater1 observeIGreater1 + action 0 + 5817 : 0.8 + 5818 : 0.2 +state 5257 observe2Greater1 observeIGreater1 + action 0 + 5819 : 0.8 + 5820 : 0.2 +state 5258 observe2Greater1 observeIGreater1 + action 0 + 5821 : 0.8 + 5822 : 0.2 +state 5259 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5823 : 1 +state 5260 observe1Greater1 observeIGreater1 + action 0 + 5768 : 1 +state 5261 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5262 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5263 + action 0 + 5825 : 1 +state 5264 + action 0 + 5826 : 0.8 + 5827 : 0.2 +state 5265 + action 0 + 5828 : 0.8 + 5829 : 0.2 +state 5266 + action 0 + 5830 : 0.8 + 5831 : 0.2 +state 5267 + action 0 + 5832 : 0.8 + 5833 : 0.2 +state 5268 + action 0 + 5834 : 0.8 + 5835 : 0.2 +state 5269 observe0Greater1 observeOnlyTrueSender + action 0 + 5836 : 1 +state 5270 observe1Greater1 observeIGreater1 + action 0 + 5769 : 1 +state 5271 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5272 + action 0 + 5825 : 1 +state 5273 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5274 + action 0 + 5838 : 0.8 + 5839 : 0.2 +state 5275 + action 0 + 5840 : 0.8 + 5841 : 0.2 +state 5276 + action 0 + 5842 : 0.8 + 5843 : 0.2 +state 5277 + action 0 + 5844 : 0.8 + 5845 : 0.2 +state 5278 + action 0 + 5846 : 0.8 + 5847 : 0.2 +state 5279 observe0Greater1 observeOnlyTrueSender + action 0 + 5848 : 1 +state 5280 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5849 : 1 +state 5281 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5850 : 1 +state 5282 observe0Greater1 observeOnlyTrueSender + action 0 + 5851 : 1 +state 5283 observe0Greater1 observeOnlyTrueSender + action 0 + 5852 : 1 +state 5284 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 5781 : 1 +state 5285 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5286 observe3Greater1 observeIGreater1 + action 0 + 5853 : 1 +state 5287 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5288 observe3Greater1 observeIGreater1 + action 0 + 5855 : 0.8 + 5856 : 0.2 +state 5289 observe3Greater1 observeIGreater1 + action 0 + 5857 : 0.8 + 5858 : 0.2 +state 5290 observe3Greater1 observeIGreater1 + action 0 + 5859 : 0.8 + 5860 : 0.2 +state 5291 observe3Greater1 observeIGreater1 + action 0 + 5861 : 0.8 + 5862 : 0.2 +state 5292 observe3Greater1 observeIGreater1 + action 0 + 5863 : 0.8 + 5864 : 0.2 +state 5293 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5865 : 1 +state 5294 observe1Greater1 observeIGreater1 + action 0 + 5782 : 1 +state 5295 + action 0 + 5825 : 1 +state 5296 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5297 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5298 + action 0 + 5867 : 0.8 + 5868 : 0.2 +state 5299 + action 0 + 5869 : 0.8 + 5870 : 0.2 +state 5300 + action 0 + 5871 : 0.8 + 5872 : 0.2 +state 5301 + action 0 + 5873 : 0.8 + 5874 : 0.2 +state 5302 + action 0 + 5875 : 0.8 + 5876 : 0.2 +state 5303 observe0Greater1 observeOnlyTrueSender + action 0 + 5877 : 1 +state 5304 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5878 : 1 +state 5305 observe0Greater1 observeOnlyTrueSender + action 0 + 5879 : 1 +state 5306 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5880 : 1 +state 5307 observe0Greater1 observeOnlyTrueSender + action 0 + 5881 : 1 +state 5308 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 5794 : 1 +state 5309 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5310 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5311 observe4Greater1 observeIGreater1 + action 0 + 5882 : 1 +state 5312 observe4Greater1 observeIGreater1 + action 0 + 5883 : 0.8 + 5884 : 0.2 +state 5313 observe4Greater1 observeIGreater1 + action 0 + 5885 : 0.8 + 5886 : 0.2 +state 5314 observe4Greater1 observeIGreater1 + action 0 + 5887 : 0.8 + 5888 : 0.2 +state 5315 observe4Greater1 observeIGreater1 + action 0 + 5889 : 0.8 + 5890 : 0.2 +state 5316 observe4Greater1 observeIGreater1 + action 0 + 5891 : 0.8 + 5892 : 0.2 +state 5317 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5893 : 1 +state 5318 observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5894 : 1 +state 5319 observe0Greater1 observeOnlyTrueSender + action 0 + 5895 : 1 +state 5320 observe0Greater1 observeOnlyTrueSender + action 0 + 5896 : 1 +state 5321 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5897 : 1 +state 5322 observe2Greater1 observeIGreater1 + action 0 + 5810 : 1 +state 5323 observe2Greater1 observeIGreater1 + action 0 + 5898 : 1 +state 5324 observe2Greater1 observeIGreater1 + action 0 + 5899 : 1 +state 5325 observe2Greater1 observeIGreater1 + action 0 + 5900 : 1 +state 5326 observe2Greater1 observeIGreater1 + action 0 + 5901 : 0.8 + 5902 : 0.2 +state 5327 observe2Greater1 observeIGreater1 + action 0 + 5903 : 0.8 + 5904 : 0.2 +state 5328 observe2Greater1 observeIGreater1 + action 0 + 5905 : 0.8 + 5906 : 0.2 +state 5329 observe2Greater1 observeIGreater1 + action 0 + 5907 : 0.8 + 5908 : 0.2 +state 5330 observe2Greater1 observeIGreater1 + action 0 + 5909 : 0.8 + 5910 : 0.2 +state 5331 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5911 : 1 +state 5332 observe2Greater1 observeIGreater1 + action 0 + 5811 : 1 +state 5333 observe2Greater1 observeIGreater1 + action 0 + 5899 : 1 +state 5334 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5912 : 1 +state 5335 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5336 observe2Greater1 observeIGreater1 + action 0 + 5914 : 0.8 + 5915 : 0.2 +state 5337 observe2Greater1 observeIGreater1 + action 0 + 5916 : 0.8 + 5917 : 0.2 +state 5338 observe2Greater1 observeIGreater1 + action 0 + 5918 : 0.8 + 5919 : 0.2 +state 5339 observe2Greater1 observeIGreater1 + action 0 + 5920 : 0.8 + 5921 : 0.2 +state 5340 observe2Greater1 observeIGreater1 + action 0 + 5922 : 0.8 + 5923 : 0.2 +state 5341 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5924 : 1 +state 5342 observe2Greater1 observeIGreater1 + action 0 + 5812 : 1 +state 5343 observe2Greater1 observeIGreater1 + action 0 + 5900 : 1 +state 5344 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5345 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5925 : 1 +state 5346 observe2Greater1 observeIGreater1 + action 0 + 5926 : 0.8 + 5927 : 0.2 +state 5347 observe2Greater1 observeIGreater1 + action 0 + 5928 : 0.8 + 5929 : 0.2 +state 5348 observe2Greater1 observeIGreater1 + action 0 + 5930 : 0.8 + 5931 : 0.2 +state 5349 observe2Greater1 observeIGreater1 + action 0 + 5932 : 0.8 + 5933 : 0.2 +state 5350 observe2Greater1 observeIGreater1 + action 0 + 5934 : 0.8 + 5935 : 0.2 +state 5351 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5936 : 1 +state 5352 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5937 : 1 +state 5353 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5938 : 1 +state 5354 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5939 : 1 +state 5355 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5940 : 1 +state 5356 observe3Greater1 observeIGreater1 + action 0 + 5824 : 1 +state 5357 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 5912 : 1 +state 5358 observe3Greater1 observeIGreater1 + action 0 + 5941 : 1 +state 5359 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5360 observe3Greater1 observeIGreater1 + action 0 + 5943 : 0.8 + 5944 : 0.2 +state 5361 observe3Greater1 observeIGreater1 + action 0 + 5945 : 0.8 + 5946 : 0.2 +state 5362 observe3Greater1 observeIGreater1 + action 0 + 5947 : 0.8 + 5948 : 0.2 +state 5363 observe3Greater1 observeIGreater1 + action 0 + 5949 : 0.8 + 5950 : 0.2 +state 5364 observe3Greater1 observeIGreater1 + action 0 + 5951 : 0.8 + 5952 : 0.2 +state 5365 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5953 : 1 +state 5366 + action 0 + 5825 : 1 +state 5367 observe2Greater1 observeIGreater1 + action 0 + 5913 : 1 +state 5368 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5369 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5370 + action 0 + 5955 : 0.8 + 5956 : 0.2 +state 5371 + action 0 + 5957 : 0.8 + 5958 : 0.2 +state 5372 + action 0 + 5959 : 0.8 + 5960 : 0.2 +state 5373 + action 0 + 5961 : 0.8 + 5962 : 0.2 +state 5374 + action 0 + 5963 : 0.8 + 5964 : 0.2 +state 5375 observe0Greater1 observeOnlyTrueSender + action 0 + 5965 : 1 +state 5376 observe0Greater1 observeOnlyTrueSender + action 0 + 5966 : 1 +state 5377 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5967 : 1 +state 5378 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5968 : 1 +state 5379 observe0Greater1 observeOnlyTrueSender + action 0 + 5969 : 1 +state 5380 observe4Greater1 observeIGreater1 + action 0 + 5837 : 1 +state 5381 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 5925 : 1 +state 5382 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5383 observe4Greater1 observeIGreater1 + action 0 + 5970 : 1 +state 5384 observe4Greater1 observeIGreater1 + action 0 + 5971 : 0.8 + 5972 : 0.2 +state 5385 observe4Greater1 observeIGreater1 + action 0 + 5973 : 0.8 + 5974 : 0.2 +state 5386 observe4Greater1 observeIGreater1 + action 0 + 5975 : 0.8 + 5976 : 0.2 +state 5387 observe4Greater1 observeIGreater1 + action 0 + 5977 : 0.8 + 5978 : 0.2 +state 5388 observe4Greater1 observeIGreater1 + action 0 + 5979 : 0.8 + 5980 : 0.2 +state 5389 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5981 : 1 +state 5390 observe0Greater1 observeOnlyTrueSender + action 0 + 5982 : 1 +state 5391 observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5983 : 1 +state 5392 observe0Greater1 observeOnlyTrueSender + action 0 + 5984 : 1 +state 5393 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5985 : 1 +state 5394 observe3Greater1 observeIGreater1 + action 0 + 5853 : 1 +state 5395 observe3Greater1 observeIGreater1 + action 0 + 5941 : 1 +state 5396 observe3Greater1 observeIGreater1 + action 0 + 5986 : 1 +state 5397 observe3Greater1 observeIGreater1 + action 0 + 5987 : 1 +state 5398 observe3Greater1 observeIGreater1 + action 0 + 5988 : 0.8 + 5989 : 0.2 +state 5399 observe3Greater1 observeIGreater1 + action 0 + 5990 : 0.8 + 5991 : 0.2 +state 5400 observe3Greater1 observeIGreater1 + action 0 + 5992 : 0.8 + 5993 : 0.2 +state 5401 observe3Greater1 observeIGreater1 + action 0 + 5994 : 0.8 + 5995 : 0.2 +state 5402 observe3Greater1 observeIGreater1 + action 0 + 5996 : 0.8 + 5997 : 0.2 +state 5403 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5998 : 1 +state 5404 observe3Greater1 observeIGreater1 + action 0 + 5854 : 1 +state 5405 observe3Greater1 observeIGreater1 + action 0 + 5942 : 1 +state 5406 observe3Greater1 observeIGreater1 + action 0 + 5987 : 1 +state 5407 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5999 : 1 +state 5408 observe3Greater1 observeIGreater1 + action 0 + 6000 : 0.8 + 6001 : 0.2 +state 5409 observe3Greater1 observeIGreater1 + action 0 + 6002 : 0.8 + 6003 : 0.2 +state 5410 observe3Greater1 observeIGreater1 + action 0 + 6004 : 0.8 + 6005 : 0.2 +state 5411 observe3Greater1 observeIGreater1 + action 0 + 6006 : 0.8 + 6007 : 0.2 +state 5412 observe3Greater1 observeIGreater1 + action 0 + 6008 : 0.8 + 6009 : 0.2 +state 5413 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6010 : 1 +state 5414 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6011 : 1 +state 5415 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6012 : 1 +state 5416 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6013 : 1 +state 5417 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6014 : 1 +state 5418 observe4Greater1 observeIGreater1 + action 0 + 5866 : 1 +state 5419 observe4Greater1 observeIGreater1 + action 0 + 5954 : 1 +state 5420 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 5999 : 1 +state 5421 observe4Greater1 observeIGreater1 + action 0 + 6015 : 1 +state 5422 observe4Greater1 observeIGreater1 + action 0 + 6016 : 0.8 + 6017 : 0.2 +state 5423 observe4Greater1 observeIGreater1 + action 0 + 6018 : 0.8 + 6019 : 0.2 +state 5424 observe4Greater1 observeIGreater1 + action 0 + 6020 : 0.8 + 6021 : 0.2 +state 5425 observe4Greater1 observeIGreater1 + action 0 + 6022 : 0.8 + 6023 : 0.2 +state 5426 observe4Greater1 observeIGreater1 + action 0 + 6024 : 0.8 + 6025 : 0.2 +state 5427 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6026 : 1 +state 5428 observe0Greater1 observeOnlyTrueSender + action 0 + 6027 : 1 +state 5429 observe0Greater1 observeOnlyTrueSender + action 0 + 6028 : 1 +state 5430 observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6029 : 1 +state 5431 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6030 : 1 +state 5432 observe4Greater1 observeIGreater1 + action 0 + 5882 : 1 +state 5433 observe4Greater1 observeIGreater1 + action 0 + 5970 : 1 +state 5434 observe4Greater1 observeIGreater1 + action 0 + 6015 : 1 +state 5435 observe4Greater1 observeIGreater1 + action 0 + 6031 : 1 +state 5436 observe4Greater1 observeIGreater1 + action 0 + 6032 : 0.8 + 6033 : 0.2 +state 5437 observe4Greater1 observeIGreater1 + action 0 + 6034 : 0.8 + 6035 : 0.2 +state 5438 observe4Greater1 observeIGreater1 + action 0 + 6036 : 0.8 + 6037 : 0.2 +state 5439 observe4Greater1 observeIGreater1 + action 0 + 6038 : 0.8 + 6039 : 0.2 +state 5440 observe4Greater1 observeIGreater1 + action 0 + 6040 : 0.8 + 6041 : 0.2 +state 5441 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6042 : 1 +state 5442 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6043 : 1 +state 5443 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6044 : 1 +state 5444 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6045 : 1 +state 5445 observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6046 : 1 +state 5446 deadlock observe1Greater1 observeIGreater1 + action 0 + 5446 : 1 +state 5447 deadlock + action 0 + 5447 : 1 +state 5448 deadlock + action 0 + 5448 : 1 +state 5449 deadlock + action 0 + 5449 : 1 +state 5450 deadlock + action 0 + 5450 : 1 +state 5451 deadlock observe2Greater1 observeIGreater1 + action 0 + 5451 : 1 +state 5452 deadlock + action 0 + 5452 : 1 +state 5453 deadlock + action 0 + 5453 : 1 +state 5454 deadlock + action 0 + 5454 : 1 +state 5455 deadlock + action 0 + 5455 : 1 +state 5456 deadlock observe3Greater1 observeIGreater1 + action 0 + 5456 : 1 +state 5457 deadlock + action 0 + 5457 : 1 +state 5458 deadlock + action 0 + 5458 : 1 +state 5459 deadlock + action 0 + 5459 : 1 +state 5460 deadlock + action 0 + 5460 : 1 +state 5461 deadlock observe4Greater1 observeIGreater1 + action 0 + 5461 : 1 +state 5462 deadlock observe1Greater1 observeIGreater1 + action 0 + 5462 : 1 +state 5463 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5464 observe1Greater1 observeIGreater1 + action 0 + 6047 : 1 +state 5465 deadlock observe1Greater1 observeIGreater1 + action 0 + 5465 : 1 +state 5466 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5467 observe1Greater1 observeIGreater1 + action 0 + 6048 : 1 +state 5468 deadlock observe1Greater1 observeIGreater1 + action 0 + 5468 : 1 +state 5469 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5470 observe1Greater1 observeIGreater1 + action 0 + 6049 : 1 +state 5471 deadlock observe1Greater1 observeIGreater1 + action 0 + 5471 : 1 +state 5472 observe1Greater1 observeIGreater1 + action 0 + 4422 : 0.2 + 4423 : 0.2 + 4424 : 0.2 + 4425 : 0.2 + 4426 : 0.2 +state 5473 observe1Greater1 observeIGreater1 + action 0 + 6050 : 1 +state 5474 deadlock observe1Greater1 observeIGreater1 + action 0 + 5474 : 1 +state 5475 deadlock + action 0 + 5475 : 1 +state 5476 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5477 + action 0 + 6051 : 1 +state 5478 deadlock + action 0 + 5478 : 1 +state 5479 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5480 + action 0 + 6052 : 1 +state 5481 deadlock + action 0 + 5481 : 1 +state 5482 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5483 + action 0 + 6053 : 1 +state 5484 deadlock + action 0 + 5484 : 1 +state 5485 + action 0 + 4428 : 0.2 + 4429 : 0.2 + 4430 : 0.2 + 4431 : 0.2 + 4432 : 0.2 +state 5486 + action 0 + 6054 : 1 +state 5487 deadlock + action 0 + 5487 : 1 +state 5488 deadlock + action 0 + 5488 : 1 +state 5489 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5490 + action 0 + 6055 : 1 +state 5491 deadlock + action 0 + 5491 : 1 +state 5492 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5493 + action 0 + 6056 : 1 +state 5494 deadlock + action 0 + 5494 : 1 +state 5495 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5496 + action 0 + 6057 : 1 +state 5497 deadlock + action 0 + 5497 : 1 +state 5498 + action 0 + 4434 : 0.2 + 4435 : 0.2 + 4436 : 0.2 + 4437 : 0.2 + 4438 : 0.2 +state 5499 + action 0 + 6058 : 1 +state 5500 deadlock + action 0 + 5500 : 1 +state 5501 deadlock + action 0 + 5501 : 1 +state 5502 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5503 + action 0 + 6059 : 1 +state 5504 deadlock + action 0 + 5504 : 1 +state 5505 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5506 + action 0 + 6060 : 1 +state 5507 deadlock + action 0 + 5507 : 1 +state 5508 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5509 + action 0 + 6061 : 1 +state 5510 deadlock + action 0 + 5510 : 1 +state 5511 + action 0 + 4440 : 0.2 + 4441 : 0.2 + 4442 : 0.2 + 4443 : 0.2 + 4444 : 0.2 +state 5512 + action 0 + 6062 : 1 +state 5513 deadlock + action 0 + 5513 : 1 +state 5514 deadlock observe2Greater1 observeIGreater1 + action 0 + 5514 : 1 +state 5515 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5516 observe2Greater1 observeIGreater1 + action 0 + 6063 : 1 +state 5517 deadlock observe2Greater1 observeIGreater1 + action 0 + 5517 : 1 +state 5518 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5519 observe2Greater1 observeIGreater1 + action 0 + 6064 : 1 +state 5520 deadlock observe2Greater1 observeIGreater1 + action 0 + 5520 : 1 +state 5521 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5522 observe2Greater1 observeIGreater1 + action 0 + 6065 : 1 +state 5523 deadlock observe2Greater1 observeIGreater1 + action 0 + 5523 : 1 +state 5524 observe2Greater1 observeIGreater1 + action 0 + 4450 : 0.2 + 4451 : 0.2 + 4452 : 0.2 + 4453 : 0.2 + 4454 : 0.2 +state 5525 observe2Greater1 observeIGreater1 + action 0 + 6066 : 1 +state 5526 deadlock observe2Greater1 observeIGreater1 + action 0 + 5526 : 1 +state 5527 deadlock + action 0 + 5527 : 1 +state 5528 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5529 + action 0 + 6067 : 1 +state 5530 deadlock + action 0 + 5530 : 1 +state 5531 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5532 + action 0 + 6068 : 1 +state 5533 deadlock + action 0 + 5533 : 1 +state 5534 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5535 + action 0 + 6069 : 1 +state 5536 deadlock + action 0 + 5536 : 1 +state 5537 + action 0 + 4456 : 0.2 + 4457 : 0.2 + 4458 : 0.2 + 4459 : 0.2 + 4460 : 0.2 +state 5538 + action 0 + 6070 : 1 +state 5539 deadlock + action 0 + 5539 : 1 +state 5540 deadlock + action 0 + 5540 : 1 +state 5541 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5542 + action 0 + 6071 : 1 +state 5543 deadlock + action 0 + 5543 : 1 +state 5544 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5545 + action 0 + 6072 : 1 +state 5546 deadlock + action 0 + 5546 : 1 +state 5547 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5548 + action 0 + 6073 : 1 +state 5549 deadlock + action 0 + 5549 : 1 +state 5550 + action 0 + 4462 : 0.2 + 4463 : 0.2 + 4464 : 0.2 + 4465 : 0.2 + 4466 : 0.2 +state 5551 + action 0 + 6074 : 1 +state 5552 deadlock + action 0 + 5552 : 1 +state 5553 deadlock observe3Greater1 observeIGreater1 + action 0 + 5553 : 1 +state 5554 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5555 observe3Greater1 observeIGreater1 + action 0 + 6075 : 1 +state 5556 deadlock observe3Greater1 observeIGreater1 + action 0 + 5556 : 1 +state 5557 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5558 observe3Greater1 observeIGreater1 + action 0 + 6076 : 1 +state 5559 deadlock observe3Greater1 observeIGreater1 + action 0 + 5559 : 1 +state 5560 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5561 observe3Greater1 observeIGreater1 + action 0 + 6077 : 1 +state 5562 deadlock observe3Greater1 observeIGreater1 + action 0 + 5562 : 1 +state 5563 observe3Greater1 observeIGreater1 + action 0 + 4472 : 0.2 + 4473 : 0.2 + 4474 : 0.2 + 4475 : 0.2 + 4476 : 0.2 +state 5564 observe3Greater1 observeIGreater1 + action 0 + 6078 : 1 +state 5565 deadlock observe3Greater1 observeIGreater1 + action 0 + 5565 : 1 +state 5566 deadlock + action 0 + 5566 : 1 +state 5567 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5568 + action 0 + 6079 : 1 +state 5569 deadlock + action 0 + 5569 : 1 +state 5570 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5571 + action 0 + 6080 : 1 +state 5572 deadlock + action 0 + 5572 : 1 +state 5573 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5574 + action 0 + 6081 : 1 +state 5575 deadlock + action 0 + 5575 : 1 +state 5576 + action 0 + 4478 : 0.2 + 4479 : 0.2 + 4480 : 0.2 + 4481 : 0.2 + 4482 : 0.2 +state 5577 + action 0 + 6082 : 1 +state 5578 deadlock + action 0 + 5578 : 1 +state 5579 deadlock observe4Greater1 observeIGreater1 + action 0 + 5579 : 1 +state 5580 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5581 observe4Greater1 observeIGreater1 + action 0 + 6083 : 1 +state 5582 deadlock observe4Greater1 observeIGreater1 + action 0 + 5582 : 1 +state 5583 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5584 observe4Greater1 observeIGreater1 + action 0 + 6084 : 1 +state 5585 deadlock observe4Greater1 observeIGreater1 + action 0 + 5585 : 1 +state 5586 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5587 observe4Greater1 observeIGreater1 + action 0 + 6085 : 1 +state 5588 deadlock observe4Greater1 observeIGreater1 + action 0 + 5588 : 1 +state 5589 observe4Greater1 observeIGreater1 + action 0 + 4488 : 0.2 + 4489 : 0.2 + 4490 : 0.2 + 4491 : 0.2 + 4492 : 0.2 +state 5590 observe4Greater1 observeIGreater1 + action 0 + 6086 : 1 +state 5591 deadlock observe4Greater1 observeIGreater1 + action 0 + 5591 : 1 +state 5592 observe1Greater1 observeIGreater1 + action 0 + 4634 : 0.8 + 6087 : 0.2 +state 5593 observe1Greater1 observeIGreater1 + action 0 + 6088 : 0.8 + 6089 : 0.2 +state 5594 observe1Greater1 observeIGreater1 + action 0 + 6090 : 0.8 + 6091 : 0.2 +state 5595 observe1Greater1 observeIGreater1 + action 0 + 6092 : 0.8 + 6093 : 0.2 +state 5596 observe1Greater1 observeIGreater1 + action 0 + 6094 : 0.8 + 6095 : 0.2 +state 5597 observe1Greater1 observeIGreater1 + action 0 + 6096 : 1 +state 5598 observe1Greater1 observeIGreater1 + action 0 + 4641 : 0.8 + 6097 : 0.2 +state 5599 observe1Greater1 observeIGreater1 + action 0 + 6098 : 0.8 + 6099 : 0.2 +state 5600 observe1Greater1 observeIGreater1 + action 0 + 6100 : 0.8 + 6101 : 0.2 +state 5601 observe1Greater1 observeIGreater1 + action 0 + 6102 : 0.8 + 6103 : 0.2 +state 5602 observe1Greater1 observeIGreater1 + action 0 + 6104 : 0.8 + 6105 : 0.2 +state 5603 observe1Greater1 observeIGreater1 + action 0 + 6106 : 1 +state 5604 observe1Greater1 observeIGreater1 + action 0 + 4648 : 0.8 + 6107 : 0.2 +state 5605 observe1Greater1 observeIGreater1 + action 0 + 6108 : 0.8 + 6109 : 0.2 +state 5606 observe1Greater1 observeIGreater1 + action 0 + 6110 : 0.8 + 6111 : 0.2 +state 5607 observe1Greater1 observeIGreater1 + action 0 + 6112 : 0.8 + 6113 : 0.2 +state 5608 observe1Greater1 observeIGreater1 + action 0 + 6114 : 0.8 + 6115 : 0.2 +state 5609 observe1Greater1 observeIGreater1 + action 0 + 6116 : 1 +state 5610 observe1Greater1 observeIGreater1 + action 0 + 4655 : 0.8 + 6117 : 0.2 +state 5611 observe1Greater1 observeIGreater1 + action 0 + 6118 : 0.8 + 6119 : 0.2 +state 5612 observe1Greater1 observeIGreater1 + action 0 + 6120 : 0.8 + 6121 : 0.2 +state 5613 observe1Greater1 observeIGreater1 + action 0 + 6122 : 0.8 + 6123 : 0.2 +state 5614 observe1Greater1 observeIGreater1 + action 0 + 6124 : 0.8 + 6125 : 0.2 +state 5615 observe1Greater1 observeIGreater1 + action 0 + 6126 : 1 +state 5616 observe1Greater1 observeIGreater1 + action 0 + 6127 : 1 +state 5617 observe1Greater1 observeIGreater1 + action 0 + 6128 : 1 +state 5618 observe1Greater1 observeIGreater1 + action 0 + 6129 : 1 +state 5619 observe1Greater1 observeIGreater1 + action 0 + 6130 : 1 +state 5620 observe2Greater1 observeIGreater1 + action 0 + 4675 : 0.8 + 6131 : 0.2 +state 5621 observe2Greater1 observeIGreater1 + action 0 + 6132 : 0.8 + 6133 : 0.2 +state 5622 observe2Greater1 observeIGreater1 + action 0 + 6134 : 0.8 + 6135 : 0.2 +state 5623 observe2Greater1 observeIGreater1 + action 0 + 6136 : 0.8 + 6137 : 0.2 +state 5624 observe2Greater1 observeIGreater1 + action 0 + 6138 : 0.8 + 6139 : 0.2 +state 5625 observe2Greater1 observeIGreater1 + action 0 + 6140 : 1 +state 5626 + action 0 + 4682 : 0.8 + 6141 : 0.2 +state 5627 + action 0 + 6142 : 0.8 + 6143 : 0.2 +state 5628 + action 0 + 6144 : 0.8 + 6145 : 0.2 +state 5629 + action 0 + 6146 : 0.8 + 6147 : 0.2 +state 5630 + action 0 + 6148 : 0.8 + 6149 : 0.2 +state 5631 + action 0 + 6150 : 1 +state 5632 + action 0 + 4689 : 0.8 + 6151 : 0.2 +state 5633 + action 0 + 6152 : 0.8 + 6153 : 0.2 +state 5634 + action 0 + 6154 : 0.8 + 6155 : 0.2 +state 5635 + action 0 + 6156 : 0.8 + 6157 : 0.2 +state 5636 + action 0 + 6158 : 0.8 + 6159 : 0.2 +state 5637 + action 0 + 6160 : 1 +state 5638 observe1Greater1 observeIGreater1 + action 0 + 6161 : 1 +state 5639 observe2Greater1 observeIGreater1 + action 0 + 6162 : 1 +state 5640 + action 0 + 6163 : 1 +state 5641 + action 0 + 6164 : 1 +state 5642 observe3Greater1 observeIGreater1 + action 0 + 4709 : 0.8 + 6165 : 0.2 +state 5643 observe3Greater1 observeIGreater1 + action 0 + 6166 : 0.8 + 6167 : 0.2 +state 5644 observe3Greater1 observeIGreater1 + action 0 + 6168 : 0.8 + 6169 : 0.2 +state 5645 observe3Greater1 observeIGreater1 + action 0 + 6170 : 0.8 + 6171 : 0.2 +state 5646 observe3Greater1 observeIGreater1 + action 0 + 6172 : 0.8 + 6173 : 0.2 +state 5647 observe3Greater1 observeIGreater1 + action 0 + 6174 : 1 +state 5648 + action 0 + 4716 : 0.8 + 6175 : 0.2 +state 5649 + action 0 + 6176 : 0.8 + 6177 : 0.2 +state 5650 + action 0 + 6178 : 0.8 + 6179 : 0.2 +state 5651 + action 0 + 6180 : 0.8 + 6181 : 0.2 +state 5652 + action 0 + 6182 : 0.8 + 6183 : 0.2 +state 5653 + action 0 + 6184 : 1 +state 5654 observe1Greater1 observeIGreater1 + action 0 + 6185 : 1 +state 5655 + action 0 + 6186 : 1 +state 5656 observe3Greater1 observeIGreater1 + action 0 + 6187 : 1 +state 5657 + action 0 + 6188 : 1 +state 5658 observe4Greater1 observeIGreater1 + action 0 + 4736 : 0.8 + 6189 : 0.2 +state 5659 observe4Greater1 observeIGreater1 + action 0 + 6190 : 0.8 + 6191 : 0.2 +state 5660 observe4Greater1 observeIGreater1 + action 0 + 6192 : 0.8 + 6193 : 0.2 +state 5661 observe4Greater1 observeIGreater1 + action 0 + 6194 : 0.8 + 6195 : 0.2 +state 5662 observe4Greater1 observeIGreater1 + action 0 + 6196 : 0.8 + 6197 : 0.2 +state 5663 observe4Greater1 observeIGreater1 + action 0 + 6198 : 1 +state 5664 observe1Greater1 observeIGreater1 + action 0 + 6199 : 1 +state 5665 + action 0 + 6200 : 1 +state 5666 + action 0 + 6201 : 1 +state 5667 observe4Greater1 observeIGreater1 + action 0 + 6202 : 1 +state 5668 observe2Greater1 observeIGreater1 + action 0 + 4756 : 0.8 + 6203 : 0.2 +state 5669 observe2Greater1 observeIGreater1 + action 0 + 6204 : 0.8 + 6205 : 0.2 +state 5670 observe2Greater1 observeIGreater1 + action 0 + 6206 : 0.8 + 6207 : 0.2 +state 5671 observe2Greater1 observeIGreater1 + action 0 + 6208 : 0.8 + 6209 : 0.2 +state 5672 observe2Greater1 observeIGreater1 + action 0 + 6210 : 0.8 + 6211 : 0.2 +state 5673 observe2Greater1 observeIGreater1 + action 0 + 6212 : 1 +state 5674 observe2Greater1 observeIGreater1 + action 0 + 4763 : 0.8 + 6213 : 0.2 +state 5675 observe2Greater1 observeIGreater1 + action 0 + 6214 : 0.8 + 6215 : 0.2 +state 5676 observe2Greater1 observeIGreater1 + action 0 + 6216 : 0.8 + 6217 : 0.2 +state 5677 observe2Greater1 observeIGreater1 + action 0 + 6218 : 0.8 + 6219 : 0.2 +state 5678 observe2Greater1 observeIGreater1 + action 0 + 6220 : 0.8 + 6221 : 0.2 +state 5679 observe2Greater1 observeIGreater1 + action 0 + 6222 : 1 +state 5680 observe2Greater1 observeIGreater1 + action 0 + 4770 : 0.8 + 6223 : 0.2 +state 5681 observe2Greater1 observeIGreater1 + action 0 + 6224 : 0.8 + 6225 : 0.2 +state 5682 observe2Greater1 observeIGreater1 + action 0 + 6226 : 0.8 + 6227 : 0.2 +state 5683 observe2Greater1 observeIGreater1 + action 0 + 6228 : 0.8 + 6229 : 0.2 +state 5684 observe2Greater1 observeIGreater1 + action 0 + 6230 : 0.8 + 6231 : 0.2 +state 5685 observe2Greater1 observeIGreater1 + action 0 + 6232 : 1 +state 5686 observe2Greater1 observeIGreater1 + action 0 + 6233 : 1 +state 5687 observe2Greater1 observeIGreater1 + action 0 + 6234 : 1 +state 5688 observe2Greater1 observeIGreater1 + action 0 + 6235 : 1 +state 5689 observe2Greater1 observeIGreater1 + action 0 + 6236 : 1 +state 5690 observe3Greater1 observeIGreater1 + action 0 + 4790 : 0.8 + 6237 : 0.2 +state 5691 observe3Greater1 observeIGreater1 + action 0 + 6238 : 0.8 + 6239 : 0.2 +state 5692 observe3Greater1 observeIGreater1 + action 0 + 6240 : 0.8 + 6241 : 0.2 +state 5693 observe3Greater1 observeIGreater1 + action 0 + 6242 : 0.8 + 6243 : 0.2 +state 5694 observe3Greater1 observeIGreater1 + action 0 + 6244 : 0.8 + 6245 : 0.2 +state 5695 observe3Greater1 observeIGreater1 + action 0 + 6246 : 1 +state 5696 + action 0 + 4797 : 0.8 + 6247 : 0.2 +state 5697 + action 0 + 6248 : 0.8 + 6249 : 0.2 +state 5698 + action 0 + 6250 : 0.8 + 6251 : 0.2 +state 5699 + action 0 + 6252 : 0.8 + 6253 : 0.2 +state 5700 + action 0 + 6254 : 0.8 + 6255 : 0.2 +state 5701 + action 0 + 6256 : 1 +state 5702 + action 0 + 6257 : 1 +state 5703 observe2Greater1 observeIGreater1 + action 0 + 6258 : 1 +state 5704 observe3Greater1 observeIGreater1 + action 0 + 6259 : 1 +state 5705 + action 0 + 6260 : 1 +state 5706 observe4Greater1 observeIGreater1 + action 0 + 4817 : 0.8 + 6261 : 0.2 +state 5707 observe4Greater1 observeIGreater1 + action 0 + 6262 : 0.8 + 6263 : 0.2 +state 5708 observe4Greater1 observeIGreater1 + action 0 + 6264 : 0.8 + 6265 : 0.2 +state 5709 observe4Greater1 observeIGreater1 + action 0 + 6266 : 0.8 + 6267 : 0.2 +state 5710 observe4Greater1 observeIGreater1 + action 0 + 6268 : 0.8 + 6269 : 0.2 +state 5711 observe4Greater1 observeIGreater1 + action 0 + 6270 : 1 +state 5712 + action 0 + 6271 : 1 +state 5713 observe2Greater1 observeIGreater1 + action 0 + 6272 : 1 +state 5714 + action 0 + 6273 : 1 +state 5715 observe4Greater1 observeIGreater1 + action 0 + 6274 : 1 +state 5716 observe3Greater1 observeIGreater1 + action 0 + 4837 : 0.8 + 6275 : 0.2 +state 5717 observe3Greater1 observeIGreater1 + action 0 + 6276 : 0.8 + 6277 : 0.2 +state 5718 observe3Greater1 observeIGreater1 + action 0 + 6278 : 0.8 + 6279 : 0.2 +state 5719 observe3Greater1 observeIGreater1 + action 0 + 6280 : 0.8 + 6281 : 0.2 +state 5720 observe3Greater1 observeIGreater1 + action 0 + 6282 : 0.8 + 6283 : 0.2 +state 5721 observe3Greater1 observeIGreater1 + action 0 + 6284 : 1 +state 5722 observe3Greater1 observeIGreater1 + action 0 + 4844 : 0.8 + 6285 : 0.2 +state 5723 observe3Greater1 observeIGreater1 + action 0 + 6286 : 0.8 + 6287 : 0.2 +state 5724 observe3Greater1 observeIGreater1 + action 0 + 6288 : 0.8 + 6289 : 0.2 +state 5725 observe3Greater1 observeIGreater1 + action 0 + 6290 : 0.8 + 6291 : 0.2 +state 5726 observe3Greater1 observeIGreater1 + action 0 + 6292 : 0.8 + 6293 : 0.2 +state 5727 observe3Greater1 observeIGreater1 + action 0 + 6294 : 1 +state 5728 observe3Greater1 observeIGreater1 + action 0 + 6295 : 1 +state 5729 observe3Greater1 observeIGreater1 + action 0 + 6296 : 1 +state 5730 observe3Greater1 observeIGreater1 + action 0 + 6297 : 1 +state 5731 observe3Greater1 observeIGreater1 + action 0 + 6298 : 1 +state 5732 observe4Greater1 observeIGreater1 + action 0 + 4864 : 0.8 + 6299 : 0.2 +state 5733 observe4Greater1 observeIGreater1 + action 0 + 6300 : 0.8 + 6301 : 0.2 +state 5734 observe4Greater1 observeIGreater1 + action 0 + 6302 : 0.8 + 6303 : 0.2 +state 5735 observe4Greater1 observeIGreater1 + action 0 + 6304 : 0.8 + 6305 : 0.2 +state 5736 observe4Greater1 observeIGreater1 + action 0 + 6306 : 0.8 + 6307 : 0.2 +state 5737 observe4Greater1 observeIGreater1 + action 0 + 6308 : 1 +state 5738 + action 0 + 6309 : 1 +state 5739 + action 0 + 6310 : 1 +state 5740 observe3Greater1 observeIGreater1 + action 0 + 6311 : 1 +state 5741 observe4Greater1 observeIGreater1 + action 0 + 6312 : 1 +state 5742 observe4Greater1 observeIGreater1 + action 0 + 4884 : 0.8 + 6313 : 0.2 +state 5743 observe4Greater1 observeIGreater1 + action 0 + 6314 : 0.8 + 6315 : 0.2 +state 5744 observe4Greater1 observeIGreater1 + action 0 + 6316 : 0.8 + 6317 : 0.2 +state 5745 observe4Greater1 observeIGreater1 + action 0 + 6318 : 0.8 + 6319 : 0.2 +state 5746 observe4Greater1 observeIGreater1 + action 0 + 6320 : 0.8 + 6321 : 0.2 +state 5747 observe4Greater1 observeIGreater1 + action 0 + 6322 : 1 +state 5748 observe4Greater1 observeIGreater1 + action 0 + 6323 : 1 +state 5749 observe4Greater1 observeIGreater1 + action 0 + 6324 : 1 +state 5750 observe4Greater1 observeIGreater1 + action 0 + 6325 : 1 +state 5751 observe4Greater1 observeIGreater1 + action 0 + 6326 : 1 +state 5752 observe1Greater1 observeIGreater1 + action 0 + 6327 : 0.833 + 6328 : 0.167 +state 5753 observe1Greater1 observeIGreater1 + action 0 + 6329 : 0.833 + 6330 : 0.167 +state 5754 observe1Greater1 observeIGreater1 + action 0 + 6331 : 0.833 + 6332 : 0.167 +state 5755 observe1Greater1 observeIGreater1 + action 0 + 6333 : 0.833 + 6334 : 0.167 +state 5756 observe1Greater1 observeIGreater1 + action 0 + 4639 : 0.833 + 4640 : 0.167 +state 5757 observe1Greater1 observeIGreater1 + action 0 + 6335 : 1 +state 5758 observe1Greater1 observeIGreater1 + action 0 + 6336 : 0.833 + 6337 : 0.167 +state 5759 observe1Greater1 observeIGreater1 + action 0 + 6338 : 1 +state 5760 observe1Greater1 observeIGreater1 + action 0 + 6339 : 0.833 + 6340 : 0.167 +state 5761 observe1Greater1 observeIGreater1 + action 0 + 6341 : 1 +state 5762 observe1Greater1 observeIGreater1 + action 0 + 6342 : 0.833 + 6343 : 0.167 +state 5763 observe1Greater1 observeIGreater1 + action 0 + 6344 : 1 +state 5764 observe1Greater1 observeIGreater1 + action 0 + 6345 : 0.833 + 6346 : 0.167 +state 5765 observe1Greater1 observeIGreater1 + action 0 + 6347 : 1 +state 5766 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5766 : 1 +state 5767 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6348 : 0.833 + 6349 : 0.167 +state 5768 observe1Greater1 observeIGreater1 + action 0 + 6350 : 0.833 + 6351 : 0.167 +state 5769 observe1Greater1 observeIGreater1 + action 0 + 6352 : 0.833 + 6353 : 0.167 +state 5770 observe1Greater1 observeIGreater1 + action 0 + 4646 : 0.833 + 4647 : 0.167 +state 5771 observe1Greater1 observeIGreater1 + action 0 + 6354 : 1 +state 5772 observe1Greater1 observeIGreater1 + action 0 + 6355 : 0.833 + 6356 : 0.167 +state 5773 observe1Greater1 observeIGreater1 + action 0 + 6357 : 1 +state 5774 observe1Greater1 observeIGreater1 + action 0 + 6358 : 0.833 + 6359 : 0.167 +state 5775 observe1Greater1 observeIGreater1 + action 0 + 6360 : 1 +state 5776 observe1Greater1 observeIGreater1 + action 0 + 6361 : 0.833 + 6362 : 0.167 +state 5777 observe1Greater1 observeIGreater1 + action 0 + 6363 : 1 +state 5778 observe1Greater1 observeIGreater1 + action 0 + 6364 : 0.833 + 6365 : 0.167 +state 5779 observe1Greater1 observeIGreater1 + action 0 + 6366 : 1 +state 5780 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5780 : 1 +state 5781 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 6367 : 0.833 + 6368 : 0.167 +state 5782 observe1Greater1 observeIGreater1 + action 0 + 6369 : 0.833 + 6370 : 0.167 +state 5783 observe1Greater1 observeIGreater1 + action 0 + 4653 : 0.833 + 4654 : 0.167 +state 5784 observe1Greater1 observeIGreater1 + action 0 + 6371 : 1 +state 5785 observe1Greater1 observeIGreater1 + action 0 + 6372 : 0.833 + 6373 : 0.167 +state 5786 observe1Greater1 observeIGreater1 + action 0 + 6374 : 1 +state 5787 observe1Greater1 observeIGreater1 + action 0 + 6375 : 0.833 + 6376 : 0.167 +state 5788 observe1Greater1 observeIGreater1 + action 0 + 6377 : 1 +state 5789 observe1Greater1 observeIGreater1 + action 0 + 6378 : 0.833 + 6379 : 0.167 +state 5790 observe1Greater1 observeIGreater1 + action 0 + 6380 : 1 +state 5791 observe1Greater1 observeIGreater1 + action 0 + 6381 : 0.833 + 6382 : 0.167 +state 5792 observe1Greater1 observeIGreater1 + action 0 + 6383 : 1 +state 5793 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5793 : 1 +state 5794 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 6384 : 0.833 + 6385 : 0.167 +state 5795 observe1Greater1 observeIGreater1 + action 0 + 4660 : 0.833 + 4661 : 0.167 +state 5796 observe1Greater1 observeIGreater1 + action 0 + 6386 : 1 +state 5797 observe1Greater1 observeIGreater1 + action 0 + 6387 : 0.833 + 6388 : 0.167 +state 5798 observe1Greater1 observeIGreater1 + action 0 + 6389 : 1 +state 5799 observe1Greater1 observeIGreater1 + action 0 + 6390 : 0.833 + 6391 : 0.167 +state 5800 observe1Greater1 observeIGreater1 + action 0 + 6392 : 1 +state 5801 observe1Greater1 observeIGreater1 + action 0 + 6393 : 0.833 + 6394 : 0.167 +state 5802 observe1Greater1 observeIGreater1 + action 0 + 6395 : 1 +state 5803 observe1Greater1 observeIGreater1 + action 0 + 6396 : 0.833 + 6397 : 0.167 +state 5804 observe1Greater1 observeIGreater1 + action 0 + 6398 : 1 +state 5805 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5805 : 1 +state 5806 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5806 : 1 +state 5807 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5807 : 1 +state 5808 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5808 : 1 +state 5809 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5809 : 1 +state 5810 observe2Greater1 observeIGreater1 + action 0 + 6399 : 0.833 + 6400 : 0.167 +state 5811 observe2Greater1 observeIGreater1 + action 0 + 6401 : 0.833 + 6402 : 0.167 +state 5812 observe2Greater1 observeIGreater1 + action 0 + 6403 : 0.833 + 6404 : 0.167 +state 5813 observe2Greater1 observeIGreater1 + action 0 + 4680 : 0.833 + 4681 : 0.167 +state 5814 observe2Greater1 observeIGreater1 + action 0 + 6405 : 1 +state 5815 observe2Greater1 observeIGreater1 + action 0 + 6406 : 0.833 + 6407 : 0.167 +state 5816 observe2Greater1 observeIGreater1 + action 0 + 6408 : 1 +state 5817 observe2Greater1 observeIGreater1 + action 0 + 6409 : 0.833 + 6410 : 0.167 +state 5818 observe2Greater1 observeIGreater1 + action 0 + 6411 : 1 +state 5819 observe2Greater1 observeIGreater1 + action 0 + 6412 : 0.833 + 6413 : 0.167 +state 5820 observe2Greater1 observeIGreater1 + action 0 + 6414 : 1 +state 5821 observe2Greater1 observeIGreater1 + action 0 + 6415 : 0.833 + 6416 : 0.167 +state 5822 observe2Greater1 observeIGreater1 + action 0 + 6417 : 1 +state 5823 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5823 : 1 +state 5824 observe3Greater1 observeIGreater1 + action 0 + 6418 : 0.833 + 6419 : 0.167 +state 5825 + action 0 + 6420 : 0.833 + 6421 : 0.167 +state 5826 + action 0 + 4687 : 0.833 + 4688 : 0.167 +state 5827 + action 0 + 6422 : 1 +state 5828 + action 0 + 6423 : 0.833 + 6424 : 0.167 +state 5829 + action 0 + 6425 : 1 +state 5830 + action 0 + 6426 : 0.833 + 6427 : 0.167 +state 5831 + action 0 + 6428 : 1 +state 5832 + action 0 + 6429 : 0.833 + 6430 : 0.167 +state 5833 + action 0 + 6431 : 1 +state 5834 + action 0 + 6432 : 0.833 + 6433 : 0.167 +state 5835 + action 0 + 6434 : 1 +state 5836 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5836 : 1 +state 5837 observe4Greater1 observeIGreater1 + action 0 + 6435 : 0.833 + 6436 : 0.167 +state 5838 + action 0 + 4694 : 0.833 + 4695 : 0.167 +state 5839 + action 0 + 6437 : 1 +state 5840 + action 0 + 6438 : 0.833 + 6439 : 0.167 +state 5841 + action 0 + 6440 : 1 +state 5842 + action 0 + 6441 : 0.833 + 6442 : 0.167 +state 5843 + action 0 + 6443 : 1 +state 5844 + action 0 + 6444 : 0.833 + 6445 : 0.167 +state 5845 + action 0 + 6446 : 1 +state 5846 + action 0 + 6447 : 0.833 + 6448 : 0.167 +state 5847 + action 0 + 6449 : 1 +state 5848 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5848 : 1 +state 5849 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5849 : 1 +state 5850 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5850 : 1 +state 5851 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5851 : 1 +state 5852 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5852 : 1 +state 5853 observe3Greater1 observeIGreater1 + action 0 + 6450 : 0.833 + 6451 : 0.167 +state 5854 observe3Greater1 observeIGreater1 + action 0 + 6452 : 0.833 + 6453 : 0.167 +state 5855 observe3Greater1 observeIGreater1 + action 0 + 4714 : 0.833 + 4715 : 0.167 +state 5856 observe3Greater1 observeIGreater1 + action 0 + 6454 : 1 +state 5857 observe3Greater1 observeIGreater1 + action 0 + 6455 : 0.833 + 6456 : 0.167 +state 5858 observe3Greater1 observeIGreater1 + action 0 + 6457 : 1 +state 5859 observe3Greater1 observeIGreater1 + action 0 + 6458 : 0.833 + 6459 : 0.167 +state 5860 observe3Greater1 observeIGreater1 + action 0 + 6460 : 1 +state 5861 observe3Greater1 observeIGreater1 + action 0 + 6461 : 0.833 + 6462 : 0.167 +state 5862 observe3Greater1 observeIGreater1 + action 0 + 6463 : 1 +state 5863 observe3Greater1 observeIGreater1 + action 0 + 6464 : 0.833 + 6465 : 0.167 +state 5864 observe3Greater1 observeIGreater1 + action 0 + 6466 : 1 +state 5865 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5865 : 1 +state 5866 observe4Greater1 observeIGreater1 + action 0 + 6467 : 0.833 + 6468 : 0.167 +state 5867 + action 0 + 4721 : 0.833 + 4722 : 0.167 +state 5868 + action 0 + 6469 : 1 +state 5869 + action 0 + 6470 : 0.833 + 6471 : 0.167 +state 5870 + action 0 + 6472 : 1 +state 5871 + action 0 + 6473 : 0.833 + 6474 : 0.167 +state 5872 + action 0 + 6475 : 1 +state 5873 + action 0 + 6476 : 0.833 + 6477 : 0.167 +state 5874 + action 0 + 6478 : 1 +state 5875 + action 0 + 6479 : 0.833 + 6480 : 0.167 +state 5876 + action 0 + 6481 : 1 +state 5877 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5877 : 1 +state 5878 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5878 : 1 +state 5879 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5879 : 1 +state 5880 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5880 : 1 +state 5881 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5881 : 1 +state 5882 observe4Greater1 observeIGreater1 + action 0 + 6482 : 0.833 + 6483 : 0.167 +state 5883 observe4Greater1 observeIGreater1 + action 0 + 4741 : 0.833 + 4742 : 0.167 +state 5884 observe4Greater1 observeIGreater1 + action 0 + 6484 : 1 +state 5885 observe4Greater1 observeIGreater1 + action 0 + 6485 : 0.833 + 6486 : 0.167 +state 5886 observe4Greater1 observeIGreater1 + action 0 + 6487 : 1 +state 5887 observe4Greater1 observeIGreater1 + action 0 + 6488 : 0.833 + 6489 : 0.167 +state 5888 observe4Greater1 observeIGreater1 + action 0 + 6490 : 1 +state 5889 observe4Greater1 observeIGreater1 + action 0 + 6491 : 0.833 + 6492 : 0.167 +state 5890 observe4Greater1 observeIGreater1 + action 0 + 6493 : 1 +state 5891 observe4Greater1 observeIGreater1 + action 0 + 6494 : 0.833 + 6495 : 0.167 +state 5892 observe4Greater1 observeIGreater1 + action 0 + 6496 : 1 +state 5893 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5893 : 1 +state 5894 deadlock observe0Greater1 observe1Greater1 observeIGreater1 + action 0 + 5894 : 1 +state 5895 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5895 : 1 +state 5896 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5896 : 1 +state 5897 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5897 : 1 +state 5898 observe2Greater1 observeIGreater1 + action 0 + 6497 : 0.833 + 6498 : 0.167 +state 5899 observe2Greater1 observeIGreater1 + action 0 + 6499 : 0.833 + 6500 : 0.167 +state 5900 observe2Greater1 observeIGreater1 + action 0 + 6501 : 0.833 + 6502 : 0.167 +state 5901 observe2Greater1 observeIGreater1 + action 0 + 4761 : 0.833 + 4762 : 0.167 +state 5902 observe2Greater1 observeIGreater1 + action 0 + 6503 : 1 +state 5903 observe2Greater1 observeIGreater1 + action 0 + 6504 : 0.833 + 6505 : 0.167 +state 5904 observe2Greater1 observeIGreater1 + action 0 + 6506 : 1 +state 5905 observe2Greater1 observeIGreater1 + action 0 + 6507 : 0.833 + 6508 : 0.167 +state 5906 observe2Greater1 observeIGreater1 + action 0 + 6509 : 1 +state 5907 observe2Greater1 observeIGreater1 + action 0 + 6510 : 0.833 + 6511 : 0.167 +state 5908 observe2Greater1 observeIGreater1 + action 0 + 6512 : 1 +state 5909 observe2Greater1 observeIGreater1 + action 0 + 6513 : 0.833 + 6514 : 0.167 +state 5910 observe2Greater1 observeIGreater1 + action 0 + 6515 : 1 +state 5911 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5911 : 1 +state 5912 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 6516 : 0.833 + 6517 : 0.167 +state 5913 observe2Greater1 observeIGreater1 + action 0 + 6518 : 0.833 + 6519 : 0.167 +state 5914 observe2Greater1 observeIGreater1 + action 0 + 4768 : 0.833 + 4769 : 0.167 +state 5915 observe2Greater1 observeIGreater1 + action 0 + 6520 : 1 +state 5916 observe2Greater1 observeIGreater1 + action 0 + 6521 : 0.833 + 6522 : 0.167 +state 5917 observe2Greater1 observeIGreater1 + action 0 + 6523 : 1 +state 5918 observe2Greater1 observeIGreater1 + action 0 + 6524 : 0.833 + 6525 : 0.167 +state 5919 observe2Greater1 observeIGreater1 + action 0 + 6526 : 1 +state 5920 observe2Greater1 observeIGreater1 + action 0 + 6527 : 0.833 + 6528 : 0.167 +state 5921 observe2Greater1 observeIGreater1 + action 0 + 6529 : 1 +state 5922 observe2Greater1 observeIGreater1 + action 0 + 6530 : 0.833 + 6531 : 0.167 +state 5923 observe2Greater1 observeIGreater1 + action 0 + 6532 : 1 +state 5924 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5924 : 1 +state 5925 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 6533 : 0.833 + 6534 : 0.167 +state 5926 observe2Greater1 observeIGreater1 + action 0 + 4775 : 0.833 + 4776 : 0.167 +state 5927 observe2Greater1 observeIGreater1 + action 0 + 6535 : 1 +state 5928 observe2Greater1 observeIGreater1 + action 0 + 6536 : 0.833 + 6537 : 0.167 +state 5929 observe2Greater1 observeIGreater1 + action 0 + 6538 : 1 +state 5930 observe2Greater1 observeIGreater1 + action 0 + 6539 : 0.833 + 6540 : 0.167 +state 5931 observe2Greater1 observeIGreater1 + action 0 + 6541 : 1 +state 5932 observe2Greater1 observeIGreater1 + action 0 + 6542 : 0.833 + 6543 : 0.167 +state 5933 observe2Greater1 observeIGreater1 + action 0 + 6544 : 1 +state 5934 observe2Greater1 observeIGreater1 + action 0 + 6545 : 0.833 + 6546 : 0.167 +state 5935 observe2Greater1 observeIGreater1 + action 0 + 6547 : 1 +state 5936 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5936 : 1 +state 5937 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5937 : 1 +state 5938 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5938 : 1 +state 5939 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5939 : 1 +state 5940 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5940 : 1 +state 5941 observe3Greater1 observeIGreater1 + action 0 + 6548 : 0.833 + 6549 : 0.167 +state 5942 observe3Greater1 observeIGreater1 + action 0 + 6550 : 0.833 + 6551 : 0.167 +state 5943 observe3Greater1 observeIGreater1 + action 0 + 4795 : 0.833 + 4796 : 0.167 +state 5944 observe3Greater1 observeIGreater1 + action 0 + 6552 : 1 +state 5945 observe3Greater1 observeIGreater1 + action 0 + 6553 : 0.833 + 6554 : 0.167 +state 5946 observe3Greater1 observeIGreater1 + action 0 + 6555 : 1 +state 5947 observe3Greater1 observeIGreater1 + action 0 + 6556 : 0.833 + 6557 : 0.167 +state 5948 observe3Greater1 observeIGreater1 + action 0 + 6558 : 1 +state 5949 observe3Greater1 observeIGreater1 + action 0 + 6559 : 0.833 + 6560 : 0.167 +state 5950 observe3Greater1 observeIGreater1 + action 0 + 6561 : 1 +state 5951 observe3Greater1 observeIGreater1 + action 0 + 6562 : 0.833 + 6563 : 0.167 +state 5952 observe3Greater1 observeIGreater1 + action 0 + 6564 : 1 +state 5953 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5953 : 1 +state 5954 observe4Greater1 observeIGreater1 + action 0 + 6565 : 0.833 + 6566 : 0.167 +state 5955 + action 0 + 4802 : 0.833 + 4803 : 0.167 +state 5956 + action 0 + 6567 : 1 +state 5957 + action 0 + 6568 : 0.833 + 6569 : 0.167 +state 5958 + action 0 + 6570 : 1 +state 5959 + action 0 + 6571 : 0.833 + 6572 : 0.167 +state 5960 + action 0 + 6573 : 1 +state 5961 + action 0 + 6574 : 0.833 + 6575 : 0.167 +state 5962 + action 0 + 6576 : 1 +state 5963 + action 0 + 6577 : 0.833 + 6578 : 0.167 +state 5964 + action 0 + 6579 : 1 +state 5965 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5965 : 1 +state 5966 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5966 : 1 +state 5967 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5967 : 1 +state 5968 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5968 : 1 +state 5969 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5969 : 1 +state 5970 observe4Greater1 observeIGreater1 + action 0 + 6580 : 0.833 + 6581 : 0.167 +state 5971 observe4Greater1 observeIGreater1 + action 0 + 4822 : 0.833 + 4823 : 0.167 +state 5972 observe4Greater1 observeIGreater1 + action 0 + 6582 : 1 +state 5973 observe4Greater1 observeIGreater1 + action 0 + 6583 : 0.833 + 6584 : 0.167 +state 5974 observe4Greater1 observeIGreater1 + action 0 + 6585 : 1 +state 5975 observe4Greater1 observeIGreater1 + action 0 + 6586 : 0.833 + 6587 : 0.167 +state 5976 observe4Greater1 observeIGreater1 + action 0 + 6588 : 1 +state 5977 observe4Greater1 observeIGreater1 + action 0 + 6589 : 0.833 + 6590 : 0.167 +state 5978 observe4Greater1 observeIGreater1 + action 0 + 6591 : 1 +state 5979 observe4Greater1 observeIGreater1 + action 0 + 6592 : 0.833 + 6593 : 0.167 +state 5980 observe4Greater1 observeIGreater1 + action 0 + 6594 : 1 +state 5981 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5981 : 1 +state 5982 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5982 : 1 +state 5983 deadlock observe0Greater1 observe2Greater1 observeIGreater1 + action 0 + 5983 : 1 +state 5984 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 5984 : 1 +state 5985 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 5985 : 1 +state 5986 observe3Greater1 observeIGreater1 + action 0 + 6595 : 0.833 + 6596 : 0.167 +state 5987 observe3Greater1 observeIGreater1 + action 0 + 6597 : 0.833 + 6598 : 0.167 +state 5988 observe3Greater1 observeIGreater1 + action 0 + 4842 : 0.833 + 4843 : 0.167 +state 5989 observe3Greater1 observeIGreater1 + action 0 + 6599 : 1 +state 5990 observe3Greater1 observeIGreater1 + action 0 + 6600 : 0.833 + 6601 : 0.167 +state 5991 observe3Greater1 observeIGreater1 + action 0 + 6602 : 1 +state 5992 observe3Greater1 observeIGreater1 + action 0 + 6603 : 0.833 + 6604 : 0.167 +state 5993 observe3Greater1 observeIGreater1 + action 0 + 6605 : 1 +state 5994 observe3Greater1 observeIGreater1 + action 0 + 6606 : 0.833 + 6607 : 0.167 +state 5995 observe3Greater1 observeIGreater1 + action 0 + 6608 : 1 +state 5996 observe3Greater1 observeIGreater1 + action 0 + 6609 : 0.833 + 6610 : 0.167 +state 5997 observe3Greater1 observeIGreater1 + action 0 + 6611 : 1 +state 5998 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 5998 : 1 +state 5999 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 6612 : 0.833 + 6613 : 0.167 +state 6000 observe3Greater1 observeIGreater1 + action 0 + 4849 : 0.833 + 4850 : 0.167 +state 6001 observe3Greater1 observeIGreater1 + action 0 + 6614 : 1 +state 6002 observe3Greater1 observeIGreater1 + action 0 + 6615 : 0.833 + 6616 : 0.167 +state 6003 observe3Greater1 observeIGreater1 + action 0 + 6617 : 1 +state 6004 observe3Greater1 observeIGreater1 + action 0 + 6618 : 0.833 + 6619 : 0.167 +state 6005 observe3Greater1 observeIGreater1 + action 0 + 6620 : 1 +state 6006 observe3Greater1 observeIGreater1 + action 0 + 6621 : 0.833 + 6622 : 0.167 +state 6007 observe3Greater1 observeIGreater1 + action 0 + 6623 : 1 +state 6008 observe3Greater1 observeIGreater1 + action 0 + 6624 : 0.833 + 6625 : 0.167 +state 6009 observe3Greater1 observeIGreater1 + action 0 + 6626 : 1 +state 6010 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6010 : 1 +state 6011 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6011 : 1 +state 6012 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6012 : 1 +state 6013 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6013 : 1 +state 6014 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6014 : 1 +state 6015 observe4Greater1 observeIGreater1 + action 0 + 6627 : 0.833 + 6628 : 0.167 +state 6016 observe4Greater1 observeIGreater1 + action 0 + 4869 : 0.833 + 4870 : 0.167 +state 6017 observe4Greater1 observeIGreater1 + action 0 + 6629 : 1 +state 6018 observe4Greater1 observeIGreater1 + action 0 + 6630 : 0.833 + 6631 : 0.167 +state 6019 observe4Greater1 observeIGreater1 + action 0 + 6632 : 1 +state 6020 observe4Greater1 observeIGreater1 + action 0 + 6633 : 0.833 + 6634 : 0.167 +state 6021 observe4Greater1 observeIGreater1 + action 0 + 6635 : 1 +state 6022 observe4Greater1 observeIGreater1 + action 0 + 6636 : 0.833 + 6637 : 0.167 +state 6023 observe4Greater1 observeIGreater1 + action 0 + 6638 : 1 +state 6024 observe4Greater1 observeIGreater1 + action 0 + 6639 : 0.833 + 6640 : 0.167 +state 6025 observe4Greater1 observeIGreater1 + action 0 + 6641 : 1 +state 6026 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6026 : 1 +state 6027 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 6027 : 1 +state 6028 deadlock observe0Greater1 observeOnlyTrueSender + action 0 + 6028 : 1 +state 6029 deadlock observe0Greater1 observe3Greater1 observeIGreater1 + action 0 + 6029 : 1 +state 6030 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6030 : 1 +state 6031 observe4Greater1 observeIGreater1 + action 0 + 6642 : 0.833 + 6643 : 0.167 +state 6032 observe4Greater1 observeIGreater1 + action 0 + 4889 : 0.833 + 4890 : 0.167 +state 6033 observe4Greater1 observeIGreater1 + action 0 + 6644 : 1 +state 6034 observe4Greater1 observeIGreater1 + action 0 + 6645 : 0.833 + 6646 : 0.167 +state 6035 observe4Greater1 observeIGreater1 + action 0 + 6647 : 1 +state 6036 observe4Greater1 observeIGreater1 + action 0 + 6648 : 0.833 + 6649 : 0.167 +state 6037 observe4Greater1 observeIGreater1 + action 0 + 6650 : 1 +state 6038 observe4Greater1 observeIGreater1 + action 0 + 6651 : 0.833 + 6652 : 0.167 +state 6039 observe4Greater1 observeIGreater1 + action 0 + 6653 : 1 +state 6040 observe4Greater1 observeIGreater1 + action 0 + 6654 : 0.833 + 6655 : 0.167 +state 6041 observe4Greater1 observeIGreater1 + action 0 + 6656 : 1 +state 6042 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6042 : 1 +state 6043 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6043 : 1 +state 6044 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6044 : 1 +state 6045 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6045 : 1 +state 6046 deadlock observe0Greater1 observe4Greater1 observeIGreater1 + action 0 + 6046 : 1 +state 6047 observe1Greater1 observeIGreater1 + action 0 + 6657 : 1 +state 6048 observe1Greater1 observeIGreater1 + action 0 + 6658 : 1 +state 6049 observe1Greater1 observeIGreater1 + action 0 + 6659 : 1 +state 6050 observe1Greater1 observeIGreater1 + action 0 + 6660 : 1 +state 6051 observe1Greater1 observeIGreater1 + action 0 + 6661 : 1 +state 6052 observe2Greater1 observeIGreater1 + action 0 + 6662 : 1 +state 6053 + action 0 + 6663 : 1 +state 6054 + action 0 + 6664 : 1 +state 6055 observe1Greater1 observeIGreater1 + action 0 + 6665 : 1 +state 6056 + action 0 + 6666 : 1 +state 6057 observe3Greater1 observeIGreater1 + action 0 + 6667 : 1 +state 6058 + action 0 + 6668 : 1 +state 6059 observe1Greater1 observeIGreater1 + action 0 + 6669 : 1 +state 6060 + action 0 + 6670 : 1 +state 6061 + action 0 + 6671 : 1 +state 6062 observe4Greater1 observeIGreater1 + action 0 + 6672 : 1 +state 6063 observe2Greater1 observeIGreater1 + action 0 + 6673 : 1 +state 6064 observe2Greater1 observeIGreater1 + action 0 + 6674 : 1 +state 6065 observe2Greater1 observeIGreater1 + action 0 + 6675 : 1 +state 6066 observe2Greater1 observeIGreater1 + action 0 + 6676 : 1 +state 6067 + action 0 + 6677 : 1 +state 6068 observe2Greater1 observeIGreater1 + action 0 + 6678 : 1 +state 6069 observe3Greater1 observeIGreater1 + action 0 + 6679 : 1 +state 6070 + action 0 + 6680 : 1 +state 6071 + action 0 + 6681 : 1 +state 6072 observe2Greater1 observeIGreater1 + action 0 + 6682 : 1 +state 6073 + action 0 + 6683 : 1 +state 6074 observe4Greater1 observeIGreater1 + action 0 + 6684 : 1 +state 6075 observe3Greater1 observeIGreater1 + action 0 + 6685 : 1 +state 6076 observe3Greater1 observeIGreater1 + action 0 + 6686 : 1 +state 6077 observe3Greater1 observeIGreater1 + action 0 + 6687 : 1 +state 6078 observe3Greater1 observeIGreater1 + action 0 + 6688 : 1 +state 6079 + action 0 + 6689 : 1 +state 6080 + action 0 + 6690 : 1 +state 6081 observe3Greater1 observeIGreater1 + action 0 + 6691 : 1 +state 6082 observe4Greater1 observeIGreater1 + action 0 + 6692 : 1 +state 6083 observe4Greater1 observeIGreater1 + action 0 + 6693 : 1 +state 6084 observe4Greater1 observeIGreater1 + action 0 + 6694 : 1 +state 6085 observe4Greater1 observeIGreater1 + action 0 + 6695 : 1 +state 6086 observe4Greater1 observeIGreater1 + action 0 + 6696 : 1 +state 6087 observe1Greater1 observeIGreater1 + action 0 + 6697 : 1 +state 6088 observe1Greater1 observeIGreater1 + action 0 + 6698 : 0.833 + 6699 : 0.167 +state 6089 observe1Greater1 observeIGreater1 + action 0 + 6700 : 1 +state 6090 observe1Greater1 observeIGreater1 + action 0 + 6701 : 0.833 + 6702 : 0.167 +state 6091 observe1Greater1 observeIGreater1 + action 0 + 6703 : 1 +state 6092 observe1Greater1 observeIGreater1 + action 0 + 6704 : 0.833 + 6705 : 0.167 +state 6093 observe1Greater1 observeIGreater1 + action 0 + 6706 : 1 +state 6094 observe1Greater1 observeIGreater1 + action 0 + 6707 : 0.833 + 6708 : 0.167 +state 6095 observe1Greater1 observeIGreater1 + action 0 + 6709 : 1 +state 6096 deadlock observe1Greater1 observeIGreater1 + action 0 + 6096 : 1 +state 6097 observe1Greater1 observeIGreater1 + action 0 + 6710 : 1 +state 6098 observe1Greater1 observeIGreater1 + action 0 + 6711 : 0.833 + 6712 : 0.167 +state 6099 observe1Greater1 observeIGreater1 + action 0 + 6713 : 1 +state 6100 observe1Greater1 observeIGreater1 + action 0 + 6714 : 0.833 + 6715 : 0.167 +state 6101 observe1Greater1 observeIGreater1 + action 0 + 6716 : 1 +state 6102 observe1Greater1 observeIGreater1 + action 0 + 6717 : 0.833 + 6718 : 0.167 +state 6103 observe1Greater1 observeIGreater1 + action 0 + 6719 : 1 +state 6104 observe1Greater1 observeIGreater1 + action 0 + 6720 : 0.833 + 6721 : 0.167 +state 6105 observe1Greater1 observeIGreater1 + action 0 + 6722 : 1 +state 6106 deadlock observe1Greater1 observeIGreater1 + action 0 + 6106 : 1 +state 6107 observe1Greater1 observeIGreater1 + action 0 + 6723 : 1 +state 6108 observe1Greater1 observeIGreater1 + action 0 + 6724 : 0.833 + 6725 : 0.167 +state 6109 observe1Greater1 observeIGreater1 + action 0 + 6726 : 1 +state 6110 observe1Greater1 observeIGreater1 + action 0 + 6727 : 0.833 + 6728 : 0.167 +state 6111 observe1Greater1 observeIGreater1 + action 0 + 6729 : 1 +state 6112 observe1Greater1 observeIGreater1 + action 0 + 6730 : 0.833 + 6731 : 0.167 +state 6113 observe1Greater1 observeIGreater1 + action 0 + 6732 : 1 +state 6114 observe1Greater1 observeIGreater1 + action 0 + 6733 : 0.833 + 6734 : 0.167 +state 6115 observe1Greater1 observeIGreater1 + action 0 + 6735 : 1 +state 6116 deadlock observe1Greater1 observeIGreater1 + action 0 + 6116 : 1 +state 6117 observe1Greater1 observeIGreater1 + action 0 + 6736 : 1 +state 6118 observe1Greater1 observeIGreater1 + action 0 + 6737 : 0.833 + 6738 : 0.167 +state 6119 observe1Greater1 observeIGreater1 + action 0 + 6739 : 1 +state 6120 observe1Greater1 observeIGreater1 + action 0 + 6740 : 0.833 + 6741 : 0.167 +state 6121 observe1Greater1 observeIGreater1 + action 0 + 6742 : 1 +state 6122 observe1Greater1 observeIGreater1 + action 0 + 6743 : 0.833 + 6744 : 0.167 +state 6123 observe1Greater1 observeIGreater1 + action 0 + 6745 : 1 +state 6124 observe1Greater1 observeIGreater1 + action 0 + 6746 : 0.833 + 6747 : 0.167 +state 6125 observe1Greater1 observeIGreater1 + action 0 + 6748 : 1 +state 6126 deadlock observe1Greater1 observeIGreater1 + action 0 + 6126 : 1 +state 6127 deadlock observe1Greater1 observeIGreater1 + action 0 + 6127 : 1 +state 6128 deadlock observe1Greater1 observeIGreater1 + action 0 + 6128 : 1 +state 6129 deadlock observe1Greater1 observeIGreater1 + action 0 + 6129 : 1 +state 6130 deadlock observe1Greater1 observeIGreater1 + action 0 + 6130 : 1 +state 6131 observe2Greater1 observeIGreater1 + action 0 + 6749 : 1 +state 6132 observe2Greater1 observeIGreater1 + action 0 + 6750 : 0.833 + 6751 : 0.167 +state 6133 observe2Greater1 observeIGreater1 + action 0 + 6752 : 1 +state 6134 observe2Greater1 observeIGreater1 + action 0 + 6753 : 0.833 + 6754 : 0.167 +state 6135 observe2Greater1 observeIGreater1 + action 0 + 6755 : 1 +state 6136 observe2Greater1 observeIGreater1 + action 0 + 6756 : 0.833 + 6757 : 0.167 +state 6137 observe2Greater1 observeIGreater1 + action 0 + 6758 : 1 +state 6138 observe2Greater1 observeIGreater1 + action 0 + 6759 : 0.833 + 6760 : 0.167 +state 6139 observe2Greater1 observeIGreater1 + action 0 + 6761 : 1 +state 6140 deadlock observe2Greater1 observeIGreater1 + action 0 + 6140 : 1 +state 6141 + action 0 + 6762 : 1 +state 6142 + action 0 + 6763 : 0.833 + 6764 : 0.167 +state 6143 + action 0 + 6765 : 1 +state 6144 + action 0 + 6766 : 0.833 + 6767 : 0.167 +state 6145 + action 0 + 6768 : 1 +state 6146 + action 0 + 6769 : 0.833 + 6770 : 0.167 +state 6147 + action 0 + 6771 : 1 +state 6148 + action 0 + 6772 : 0.833 + 6773 : 0.167 +state 6149 + action 0 + 6774 : 1 +state 6150 deadlock + action 0 + 6150 : 1 +state 6151 + action 0 + 6775 : 1 +state 6152 + action 0 + 6776 : 0.833 + 6777 : 0.167 +state 6153 + action 0 + 6778 : 1 +state 6154 + action 0 + 6779 : 0.833 + 6780 : 0.167 +state 6155 + action 0 + 6781 : 1 +state 6156 + action 0 + 6782 : 0.833 + 6783 : 0.167 +state 6157 + action 0 + 6784 : 1 +state 6158 + action 0 + 6785 : 0.833 + 6786 : 0.167 +state 6159 + action 0 + 6787 : 1 +state 6160 deadlock + action 0 + 6160 : 1 +state 6161 deadlock observe1Greater1 observeIGreater1 + action 0 + 6161 : 1 +state 6162 deadlock observe2Greater1 observeIGreater1 + action 0 + 6162 : 1 +state 6163 deadlock + action 0 + 6163 : 1 +state 6164 deadlock + action 0 + 6164 : 1 +state 6165 observe3Greater1 observeIGreater1 + action 0 + 6788 : 1 +state 6166 observe3Greater1 observeIGreater1 + action 0 + 6789 : 0.833 + 6790 : 0.167 +state 6167 observe3Greater1 observeIGreater1 + action 0 + 6791 : 1 +state 6168 observe3Greater1 observeIGreater1 + action 0 + 6792 : 0.833 + 6793 : 0.167 +state 6169 observe3Greater1 observeIGreater1 + action 0 + 6794 : 1 +state 6170 observe3Greater1 observeIGreater1 + action 0 + 6795 : 0.833 + 6796 : 0.167 +state 6171 observe3Greater1 observeIGreater1 + action 0 + 6797 : 1 +state 6172 observe3Greater1 observeIGreater1 + action 0 + 6798 : 0.833 + 6799 : 0.167 +state 6173 observe3Greater1 observeIGreater1 + action 0 + 6800 : 1 +state 6174 deadlock observe3Greater1 observeIGreater1 + action 0 + 6174 : 1 +state 6175 + action 0 + 6801 : 1 +state 6176 + action 0 + 6802 : 0.833 + 6803 : 0.167 +state 6177 + action 0 + 6804 : 1 +state 6178 + action 0 + 6805 : 0.833 + 6806 : 0.167 +state 6179 + action 0 + 6807 : 1 +state 6180 + action 0 + 6808 : 0.833 + 6809 : 0.167 +state 6181 + action 0 + 6810 : 1 +state 6182 + action 0 + 6811 : 0.833 + 6812 : 0.167 +state 6183 + action 0 + 6813 : 1 +state 6184 deadlock + action 0 + 6184 : 1 +state 6185 deadlock observe1Greater1 observeIGreater1 + action 0 + 6185 : 1 +state 6186 deadlock + action 0 + 6186 : 1 +state 6187 deadlock observe3Greater1 observeIGreater1 + action 0 + 6187 : 1 +state 6188 deadlock + action 0 + 6188 : 1 +state 6189 observe4Greater1 observeIGreater1 + action 0 + 6814 : 1 +state 6190 observe4Greater1 observeIGreater1 + action 0 + 6815 : 0.833 + 6816 : 0.167 +state 6191 observe4Greater1 observeIGreater1 + action 0 + 6817 : 1 +state 6192 observe4Greater1 observeIGreater1 + action 0 + 6818 : 0.833 + 6819 : 0.167 +state 6193 observe4Greater1 observeIGreater1 + action 0 + 6820 : 1 +state 6194 observe4Greater1 observeIGreater1 + action 0 + 6821 : 0.833 + 6822 : 0.167 +state 6195 observe4Greater1 observeIGreater1 + action 0 + 6823 : 1 +state 6196 observe4Greater1 observeIGreater1 + action 0 + 6824 : 0.833 + 6825 : 0.167 +state 6197 observe4Greater1 observeIGreater1 + action 0 + 6826 : 1 +state 6198 deadlock observe4Greater1 observeIGreater1 + action 0 + 6198 : 1 +state 6199 deadlock observe1Greater1 observeIGreater1 + action 0 + 6199 : 1 +state 6200 deadlock + action 0 + 6200 : 1 +state 6201 deadlock + action 0 + 6201 : 1 +state 6202 deadlock observe4Greater1 observeIGreater1 + action 0 + 6202 : 1 +state 6203 observe2Greater1 observeIGreater1 + action 0 + 6827 : 1 +state 6204 observe2Greater1 observeIGreater1 + action 0 + 6828 : 0.833 + 6829 : 0.167 +state 6205 observe2Greater1 observeIGreater1 + action 0 + 6830 : 1 +state 6206 observe2Greater1 observeIGreater1 + action 0 + 6831 : 0.833 + 6832 : 0.167 +state 6207 observe2Greater1 observeIGreater1 + action 0 + 6833 : 1 +state 6208 observe2Greater1 observeIGreater1 + action 0 + 6834 : 0.833 + 6835 : 0.167 +state 6209 observe2Greater1 observeIGreater1 + action 0 + 6836 : 1 +state 6210 observe2Greater1 observeIGreater1 + action 0 + 6837 : 0.833 + 6838 : 0.167 +state 6211 observe2Greater1 observeIGreater1 + action 0 + 6839 : 1 +state 6212 deadlock observe2Greater1 observeIGreater1 + action 0 + 6212 : 1 +state 6213 observe2Greater1 observeIGreater1 + action 0 + 6840 : 1 +state 6214 observe2Greater1 observeIGreater1 + action 0 + 6841 : 0.833 + 6842 : 0.167 +state 6215 observe2Greater1 observeIGreater1 + action 0 + 6843 : 1 +state 6216 observe2Greater1 observeIGreater1 + action 0 + 6844 : 0.833 + 6845 : 0.167 +state 6217 observe2Greater1 observeIGreater1 + action 0 + 6846 : 1 +state 6218 observe2Greater1 observeIGreater1 + action 0 + 6847 : 0.833 + 6848 : 0.167 +state 6219 observe2Greater1 observeIGreater1 + action 0 + 6849 : 1 +state 6220 observe2Greater1 observeIGreater1 + action 0 + 6850 : 0.833 + 6851 : 0.167 +state 6221 observe2Greater1 observeIGreater1 + action 0 + 6852 : 1 +state 6222 deadlock observe2Greater1 observeIGreater1 + action 0 + 6222 : 1 +state 6223 observe2Greater1 observeIGreater1 + action 0 + 6853 : 1 +state 6224 observe2Greater1 observeIGreater1 + action 0 + 6854 : 0.833 + 6855 : 0.167 +state 6225 observe2Greater1 observeIGreater1 + action 0 + 6856 : 1 +state 6226 observe2Greater1 observeIGreater1 + action 0 + 6857 : 0.833 + 6858 : 0.167 +state 6227 observe2Greater1 observeIGreater1 + action 0 + 6859 : 1 +state 6228 observe2Greater1 observeIGreater1 + action 0 + 6860 : 0.833 + 6861 : 0.167 +state 6229 observe2Greater1 observeIGreater1 + action 0 + 6862 : 1 +state 6230 observe2Greater1 observeIGreater1 + action 0 + 6863 : 0.833 + 6864 : 0.167 +state 6231 observe2Greater1 observeIGreater1 + action 0 + 6865 : 1 +state 6232 deadlock observe2Greater1 observeIGreater1 + action 0 + 6232 : 1 +state 6233 deadlock observe2Greater1 observeIGreater1 + action 0 + 6233 : 1 +state 6234 deadlock observe2Greater1 observeIGreater1 + action 0 + 6234 : 1 +state 6235 deadlock observe2Greater1 observeIGreater1 + action 0 + 6235 : 1 +state 6236 deadlock observe2Greater1 observeIGreater1 + action 0 + 6236 : 1 +state 6237 observe3Greater1 observeIGreater1 + action 0 + 6866 : 1 +state 6238 observe3Greater1 observeIGreater1 + action 0 + 6867 : 0.833 + 6868 : 0.167 +state 6239 observe3Greater1 observeIGreater1 + action 0 + 6869 : 1 +state 6240 observe3Greater1 observeIGreater1 + action 0 + 6870 : 0.833 + 6871 : 0.167 +state 6241 observe3Greater1 observeIGreater1 + action 0 + 6872 : 1 +state 6242 observe3Greater1 observeIGreater1 + action 0 + 6873 : 0.833 + 6874 : 0.167 +state 6243 observe3Greater1 observeIGreater1 + action 0 + 6875 : 1 +state 6244 observe3Greater1 observeIGreater1 + action 0 + 6876 : 0.833 + 6877 : 0.167 +state 6245 observe3Greater1 observeIGreater1 + action 0 + 6878 : 1 +state 6246 deadlock observe3Greater1 observeIGreater1 + action 0 + 6246 : 1 +state 6247 + action 0 + 6879 : 1 +state 6248 + action 0 + 6880 : 0.833 + 6881 : 0.167 +state 6249 + action 0 + 6882 : 1 +state 6250 + action 0 + 6883 : 0.833 + 6884 : 0.167 +state 6251 + action 0 + 6885 : 1 +state 6252 + action 0 + 6886 : 0.833 + 6887 : 0.167 +state 6253 + action 0 + 6888 : 1 +state 6254 + action 0 + 6889 : 0.833 + 6890 : 0.167 +state 6255 + action 0 + 6891 : 1 +state 6256 deadlock + action 0 + 6256 : 1 +state 6257 deadlock + action 0 + 6257 : 1 +state 6258 deadlock observe2Greater1 observeIGreater1 + action 0 + 6258 : 1 +state 6259 deadlock observe3Greater1 observeIGreater1 + action 0 + 6259 : 1 +state 6260 deadlock + action 0 + 6260 : 1 +state 6261 observe4Greater1 observeIGreater1 + action 0 + 6892 : 1 +state 6262 observe4Greater1 observeIGreater1 + action 0 + 6893 : 0.833 + 6894 : 0.167 +state 6263 observe4Greater1 observeIGreater1 + action 0 + 6895 : 1 +state 6264 observe4Greater1 observeIGreater1 + action 0 + 6896 : 0.833 + 6897 : 0.167 +state 6265 observe4Greater1 observeIGreater1 + action 0 + 6898 : 1 +state 6266 observe4Greater1 observeIGreater1 + action 0 + 6899 : 0.833 + 6900 : 0.167 +state 6267 observe4Greater1 observeIGreater1 + action 0 + 6901 : 1 +state 6268 observe4Greater1 observeIGreater1 + action 0 + 6902 : 0.833 + 6903 : 0.167 +state 6269 observe4Greater1 observeIGreater1 + action 0 + 6904 : 1 +state 6270 deadlock observe4Greater1 observeIGreater1 + action 0 + 6270 : 1 +state 6271 deadlock + action 0 + 6271 : 1 +state 6272 deadlock observe2Greater1 observeIGreater1 + action 0 + 6272 : 1 +state 6273 deadlock + action 0 + 6273 : 1 +state 6274 deadlock observe4Greater1 observeIGreater1 + action 0 + 6274 : 1 +state 6275 observe3Greater1 observeIGreater1 + action 0 + 6905 : 1 +state 6276 observe3Greater1 observeIGreater1 + action 0 + 6906 : 0.833 + 6907 : 0.167 +state 6277 observe3Greater1 observeIGreater1 + action 0 + 6908 : 1 +state 6278 observe3Greater1 observeIGreater1 + action 0 + 6909 : 0.833 + 6910 : 0.167 +state 6279 observe3Greater1 observeIGreater1 + action 0 + 6911 : 1 +state 6280 observe3Greater1 observeIGreater1 + action 0 + 6912 : 0.833 + 6913 : 0.167 +state 6281 observe3Greater1 observeIGreater1 + action 0 + 6914 : 1 +state 6282 observe3Greater1 observeIGreater1 + action 0 + 6915 : 0.833 + 6916 : 0.167 +state 6283 observe3Greater1 observeIGreater1 + action 0 + 6917 : 1 +state 6284 deadlock observe3Greater1 observeIGreater1 + action 0 + 6284 : 1 +state 6285 observe3Greater1 observeIGreater1 + action 0 + 6918 : 1 +state 6286 observe3Greater1 observeIGreater1 + action 0 + 6919 : 0.833 + 6920 : 0.167 +state 6287 observe3Greater1 observeIGreater1 + action 0 + 6921 : 1 +state 6288 observe3Greater1 observeIGreater1 + action 0 + 6922 : 0.833 + 6923 : 0.167 +state 6289 observe3Greater1 observeIGreater1 + action 0 + 6924 : 1 +state 6290 observe3Greater1 observeIGreater1 + action 0 + 6925 : 0.833 + 6926 : 0.167 +state 6291 observe3Greater1 observeIGreater1 + action 0 + 6927 : 1 +state 6292 observe3Greater1 observeIGreater1 + action 0 + 6928 : 0.833 + 6929 : 0.167 +state 6293 observe3Greater1 observeIGreater1 + action 0 + 6930 : 1 +state 6294 deadlock observe3Greater1 observeIGreater1 + action 0 + 6294 : 1 +state 6295 deadlock observe3Greater1 observeIGreater1 + action 0 + 6295 : 1 +state 6296 deadlock observe3Greater1 observeIGreater1 + action 0 + 6296 : 1 +state 6297 deadlock observe3Greater1 observeIGreater1 + action 0 + 6297 : 1 +state 6298 deadlock observe3Greater1 observeIGreater1 + action 0 + 6298 : 1 +state 6299 observe4Greater1 observeIGreater1 + action 0 + 6931 : 1 +state 6300 observe4Greater1 observeIGreater1 + action 0 + 6932 : 0.833 + 6933 : 0.167 +state 6301 observe4Greater1 observeIGreater1 + action 0 + 6934 : 1 +state 6302 observe4Greater1 observeIGreater1 + action 0 + 6935 : 0.833 + 6936 : 0.167 +state 6303 observe4Greater1 observeIGreater1 + action 0 + 6937 : 1 +state 6304 observe4Greater1 observeIGreater1 + action 0 + 6938 : 0.833 + 6939 : 0.167 +state 6305 observe4Greater1 observeIGreater1 + action 0 + 6940 : 1 +state 6306 observe4Greater1 observeIGreater1 + action 0 + 6941 : 0.833 + 6942 : 0.167 +state 6307 observe4Greater1 observeIGreater1 + action 0 + 6943 : 1 +state 6308 deadlock observe4Greater1 observeIGreater1 + action 0 + 6308 : 1 +state 6309 deadlock + action 0 + 6309 : 1 +state 6310 deadlock + action 0 + 6310 : 1 +state 6311 deadlock observe3Greater1 observeIGreater1 + action 0 + 6311 : 1 +state 6312 deadlock observe4Greater1 observeIGreater1 + action 0 + 6312 : 1 +state 6313 observe4Greater1 observeIGreater1 + action 0 + 6944 : 1 +state 6314 observe4Greater1 observeIGreater1 + action 0 + 6945 : 0.833 + 6946 : 0.167 +state 6315 observe4Greater1 observeIGreater1 + action 0 + 6947 : 1 +state 6316 observe4Greater1 observeIGreater1 + action 0 + 6948 : 0.833 + 6949 : 0.167 +state 6317 observe4Greater1 observeIGreater1 + action 0 + 6950 : 1 +state 6318 observe4Greater1 observeIGreater1 + action 0 + 6951 : 0.833 + 6952 : 0.167 +state 6319 observe4Greater1 observeIGreater1 + action 0 + 6953 : 1 +state 6320 observe4Greater1 observeIGreater1 + action 0 + 6954 : 0.833 + 6955 : 0.167 +state 6321 observe4Greater1 observeIGreater1 + action 0 + 6956 : 1 +state 6322 deadlock observe4Greater1 observeIGreater1 + action 0 + 6322 : 1 +state 6323 deadlock observe4Greater1 observeIGreater1 + action 0 + 6323 : 1 +state 6324 deadlock observe4Greater1 observeIGreater1 + action 0 + 6324 : 1 +state 6325 deadlock observe4Greater1 observeIGreater1 + action 0 + 6325 : 1 +state 6326 deadlock observe4Greater1 observeIGreater1 + action 0 + 6326 : 1 +state 6327 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 6328 observe1Greater1 observeIGreater1 + action 0 + 6962 : 1 +state 6329 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 6330 observe1Greater1 observeIGreater1 + action 0 + 6968 : 1 +state 6331 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 6332 observe1Greater1 observeIGreater1 + action 0 + 6974 : 1 +state 6333 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 6334 observe1Greater1 observeIGreater1 + action 0 + 6980 : 1 +state 6335 deadlock observe1Greater1 observeIGreater1 + action 0 + 6335 : 1 +state 6336 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6337 observe1Greater1 observeIGreater1 + action 0 + 6981 : 1 +state 6338 deadlock observe1Greater1 observeIGreater1 + action 0 + 6338 : 1 +state 6339 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6340 observe1Greater1 observeIGreater1 + action 0 + 6982 : 1 +state 6341 deadlock observe1Greater1 observeIGreater1 + action 0 + 6341 : 1 +state 6342 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6343 observe1Greater1 observeIGreater1 + action 0 + 6983 : 1 +state 6344 deadlock observe1Greater1 observeIGreater1 + action 0 + 6344 : 1 +state 6345 observe1Greater1 observeIGreater1 + action 0 + 5210 : 0.2 + 5211 : 0.2 + 5212 : 0.2 + 5213 : 0.2 + 5214 : 0.2 +state 6346 observe1Greater1 observeIGreater1 + action 0 + 6984 : 1 +state 6347 deadlock observe1Greater1 observeIGreater1 + action 0 + 6347 : 1 +state 6348 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 6349 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6990 : 1 +state 6350 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 6351 observe1Greater1 observeIGreater1 + action 0 + 6996 : 1 +state 6352 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 6353 observe1Greater1 observeIGreater1 + action 0 + 7002 : 1 +state 6354 deadlock observe1Greater1 observeIGreater1 + action 0 + 6354 : 1 +state 6355 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6356 observe1Greater1 observeIGreater1 + action 0 + 7003 : 1 +state 6357 deadlock observe1Greater1 observeIGreater1 + action 0 + 6357 : 1 +state 6358 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6359 observe1Greater1 observeIGreater1 + action 0 + 7004 : 1 +state 6360 deadlock observe1Greater1 observeIGreater1 + action 0 + 6360 : 1 +state 6361 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6362 observe1Greater1 observeIGreater1 + action 0 + 7005 : 1 +state 6363 deadlock observe1Greater1 observeIGreater1 + action 0 + 6363 : 1 +state 6364 observe1Greater1 observeIGreater1 + action 0 + 5220 : 0.2 + 5221 : 0.2 + 5222 : 0.2 + 5223 : 0.2 + 5224 : 0.2 +state 6365 observe1Greater1 observeIGreater1 + action 0 + 7006 : 1 +state 6366 deadlock observe1Greater1 observeIGreater1 + action 0 + 6366 : 1 +state 6367 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 6368 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7012 : 1 +state 6369 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 6370 observe1Greater1 observeIGreater1 + action 0 + 7018 : 1 +state 6371 deadlock observe1Greater1 observeIGreater1 + action 0 + 6371 : 1 +state 6372 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6373 observe1Greater1 observeIGreater1 + action 0 + 7019 : 1 +state 6374 deadlock observe1Greater1 observeIGreater1 + action 0 + 6374 : 1 +state 6375 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6376 observe1Greater1 observeIGreater1 + action 0 + 7020 : 1 +state 6377 deadlock observe1Greater1 observeIGreater1 + action 0 + 6377 : 1 +state 6378 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6379 observe1Greater1 observeIGreater1 + action 0 + 7021 : 1 +state 6380 deadlock observe1Greater1 observeIGreater1 + action 0 + 6380 : 1 +state 6381 observe1Greater1 observeIGreater1 + action 0 + 5230 : 0.2 + 5231 : 0.2 + 5232 : 0.2 + 5233 : 0.2 + 5234 : 0.2 +state 6382 observe1Greater1 observeIGreater1 + action 0 + 7022 : 1 +state 6383 deadlock observe1Greater1 observeIGreater1 + action 0 + 6383 : 1 +state 6384 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 6385 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7028 : 1 +state 6386 deadlock observe1Greater1 observeIGreater1 + action 0 + 6386 : 1 +state 6387 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6388 observe1Greater1 observeIGreater1 + action 0 + 7029 : 1 +state 6389 deadlock observe1Greater1 observeIGreater1 + action 0 + 6389 : 1 +state 6390 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6391 observe1Greater1 observeIGreater1 + action 0 + 7030 : 1 +state 6392 deadlock observe1Greater1 observeIGreater1 + action 0 + 6392 : 1 +state 6393 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6394 observe1Greater1 observeIGreater1 + action 0 + 7031 : 1 +state 6395 deadlock observe1Greater1 observeIGreater1 + action 0 + 6395 : 1 +state 6396 observe1Greater1 observeIGreater1 + action 0 + 5240 : 0.2 + 5241 : 0.2 + 5242 : 0.2 + 5243 : 0.2 + 5244 : 0.2 +state 6397 observe1Greater1 observeIGreater1 + action 0 + 7032 : 1 +state 6398 deadlock observe1Greater1 observeIGreater1 + action 0 + 6398 : 1 +state 6399 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 6400 observe2Greater1 observeIGreater1 + action 0 + 7038 : 1 +state 6401 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 6402 observe2Greater1 observeIGreater1 + action 0 + 7044 : 1 +state 6403 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 6404 observe2Greater1 observeIGreater1 + action 0 + 7050 : 1 +state 6405 deadlock observe2Greater1 observeIGreater1 + action 0 + 6405 : 1 +state 6406 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6407 observe2Greater1 observeIGreater1 + action 0 + 7051 : 1 +state 6408 deadlock observe2Greater1 observeIGreater1 + action 0 + 6408 : 1 +state 6409 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6410 observe2Greater1 observeIGreater1 + action 0 + 7052 : 1 +state 6411 deadlock observe2Greater1 observeIGreater1 + action 0 + 6411 : 1 +state 6412 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6413 observe2Greater1 observeIGreater1 + action 0 + 7053 : 1 +state 6414 deadlock observe2Greater1 observeIGreater1 + action 0 + 6414 : 1 +state 6415 observe2Greater1 observeIGreater1 + action 0 + 5254 : 0.2 + 5255 : 0.2 + 5256 : 0.2 + 5257 : 0.2 + 5258 : 0.2 +state 6416 observe2Greater1 observeIGreater1 + action 0 + 7054 : 1 +state 6417 deadlock observe2Greater1 observeIGreater1 + action 0 + 6417 : 1 +state 6418 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 6419 observe3Greater1 observeIGreater1 + action 0 + 7060 : 1 +state 6420 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 6421 + action 0 + 7066 : 1 +state 6422 deadlock + action 0 + 6422 : 1 +state 6423 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6424 + action 0 + 7067 : 1 +state 6425 deadlock + action 0 + 6425 : 1 +state 6426 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6427 + action 0 + 7068 : 1 +state 6428 deadlock + action 0 + 6428 : 1 +state 6429 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6430 + action 0 + 7069 : 1 +state 6431 deadlock + action 0 + 6431 : 1 +state 6432 + action 0 + 5264 : 0.2 + 5265 : 0.2 + 5266 : 0.2 + 5267 : 0.2 + 5268 : 0.2 +state 6433 + action 0 + 7070 : 1 +state 6434 deadlock + action 0 + 6434 : 1 +state 6435 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 6436 observe4Greater1 observeIGreater1 + action 0 + 7076 : 1 +state 6437 deadlock + action 0 + 6437 : 1 +state 6438 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6439 + action 0 + 7077 : 1 +state 6440 deadlock + action 0 + 6440 : 1 +state 6441 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6442 + action 0 + 7078 : 1 +state 6443 deadlock + action 0 + 6443 : 1 +state 6444 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6445 + action 0 + 7079 : 1 +state 6446 deadlock + action 0 + 6446 : 1 +state 6447 + action 0 + 5274 : 0.2 + 5275 : 0.2 + 5276 : 0.2 + 5277 : 0.2 + 5278 : 0.2 +state 6448 + action 0 + 7080 : 1 +state 6449 deadlock + action 0 + 6449 : 1 +state 6450 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 6451 observe3Greater1 observeIGreater1 + action 0 + 7086 : 1 +state 6452 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 6453 observe3Greater1 observeIGreater1 + action 0 + 7092 : 1 +state 6454 deadlock observe3Greater1 observeIGreater1 + action 0 + 6454 : 1 +state 6455 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6456 observe3Greater1 observeIGreater1 + action 0 + 7093 : 1 +state 6457 deadlock observe3Greater1 observeIGreater1 + action 0 + 6457 : 1 +state 6458 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6459 observe3Greater1 observeIGreater1 + action 0 + 7094 : 1 +state 6460 deadlock observe3Greater1 observeIGreater1 + action 0 + 6460 : 1 +state 6461 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6462 observe3Greater1 observeIGreater1 + action 0 + 7095 : 1 +state 6463 deadlock observe3Greater1 observeIGreater1 + action 0 + 6463 : 1 +state 6464 observe3Greater1 observeIGreater1 + action 0 + 5288 : 0.2 + 5289 : 0.2 + 5290 : 0.2 + 5291 : 0.2 + 5292 : 0.2 +state 6465 observe3Greater1 observeIGreater1 + action 0 + 7096 : 1 +state 6466 deadlock observe3Greater1 observeIGreater1 + action 0 + 6466 : 1 +state 6467 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 6468 observe4Greater1 observeIGreater1 + action 0 + 7102 : 1 +state 6469 deadlock + action 0 + 6469 : 1 +state 6470 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6471 + action 0 + 7103 : 1 +state 6472 deadlock + action 0 + 6472 : 1 +state 6473 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6474 + action 0 + 7104 : 1 +state 6475 deadlock + action 0 + 6475 : 1 +state 6476 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6477 + action 0 + 7105 : 1 +state 6478 deadlock + action 0 + 6478 : 1 +state 6479 + action 0 + 5298 : 0.2 + 5299 : 0.2 + 5300 : 0.2 + 5301 : 0.2 + 5302 : 0.2 +state 6480 + action 0 + 7106 : 1 +state 6481 deadlock + action 0 + 6481 : 1 +state 6482 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 6483 observe4Greater1 observeIGreater1 + action 0 + 7112 : 1 +state 6484 deadlock observe4Greater1 observeIGreater1 + action 0 + 6484 : 1 +state 6485 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6486 observe4Greater1 observeIGreater1 + action 0 + 7113 : 1 +state 6487 deadlock observe4Greater1 observeIGreater1 + action 0 + 6487 : 1 +state 6488 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6489 observe4Greater1 observeIGreater1 + action 0 + 7114 : 1 +state 6490 deadlock observe4Greater1 observeIGreater1 + action 0 + 6490 : 1 +state 6491 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6492 observe4Greater1 observeIGreater1 + action 0 + 7115 : 1 +state 6493 deadlock observe4Greater1 observeIGreater1 + action 0 + 6493 : 1 +state 6494 observe4Greater1 observeIGreater1 + action 0 + 5312 : 0.2 + 5313 : 0.2 + 5314 : 0.2 + 5315 : 0.2 + 5316 : 0.2 +state 6495 observe4Greater1 observeIGreater1 + action 0 + 7116 : 1 +state 6496 deadlock observe4Greater1 observeIGreater1 + action 0 + 6496 : 1 +state 6497 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 6498 observe2Greater1 observeIGreater1 + action 0 + 7122 : 1 +state 6499 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 6500 observe2Greater1 observeIGreater1 + action 0 + 7128 : 1 +state 6501 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 6502 observe2Greater1 observeIGreater1 + action 0 + 7134 : 1 +state 6503 deadlock observe2Greater1 observeIGreater1 + action 0 + 6503 : 1 +state 6504 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6505 observe2Greater1 observeIGreater1 + action 0 + 7135 : 1 +state 6506 deadlock observe2Greater1 observeIGreater1 + action 0 + 6506 : 1 +state 6507 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6508 observe2Greater1 observeIGreater1 + action 0 + 7136 : 1 +state 6509 deadlock observe2Greater1 observeIGreater1 + action 0 + 6509 : 1 +state 6510 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6511 observe2Greater1 observeIGreater1 + action 0 + 7137 : 1 +state 6512 deadlock observe2Greater1 observeIGreater1 + action 0 + 6512 : 1 +state 6513 observe2Greater1 observeIGreater1 + action 0 + 5326 : 0.2 + 5327 : 0.2 + 5328 : 0.2 + 5329 : 0.2 + 5330 : 0.2 +state 6514 observe2Greater1 observeIGreater1 + action 0 + 7138 : 1 +state 6515 deadlock observe2Greater1 observeIGreater1 + action 0 + 6515 : 1 +state 6516 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 6517 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7144 : 1 +state 6518 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 6519 observe2Greater1 observeIGreater1 + action 0 + 7150 : 1 +state 6520 deadlock observe2Greater1 observeIGreater1 + action 0 + 6520 : 1 +state 6521 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6522 observe2Greater1 observeIGreater1 + action 0 + 7151 : 1 +state 6523 deadlock observe2Greater1 observeIGreater1 + action 0 + 6523 : 1 +state 6524 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6525 observe2Greater1 observeIGreater1 + action 0 + 7152 : 1 +state 6526 deadlock observe2Greater1 observeIGreater1 + action 0 + 6526 : 1 +state 6527 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6528 observe2Greater1 observeIGreater1 + action 0 + 7153 : 1 +state 6529 deadlock observe2Greater1 observeIGreater1 + action 0 + 6529 : 1 +state 6530 observe2Greater1 observeIGreater1 + action 0 + 5336 : 0.2 + 5337 : 0.2 + 5338 : 0.2 + 5339 : 0.2 + 5340 : 0.2 +state 6531 observe2Greater1 observeIGreater1 + action 0 + 7154 : 1 +state 6532 deadlock observe2Greater1 observeIGreater1 + action 0 + 6532 : 1 +state 6533 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 6534 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7160 : 1 +state 6535 deadlock observe2Greater1 observeIGreater1 + action 0 + 6535 : 1 +state 6536 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6537 observe2Greater1 observeIGreater1 + action 0 + 7161 : 1 +state 6538 deadlock observe2Greater1 observeIGreater1 + action 0 + 6538 : 1 +state 6539 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6540 observe2Greater1 observeIGreater1 + action 0 + 7162 : 1 +state 6541 deadlock observe2Greater1 observeIGreater1 + action 0 + 6541 : 1 +state 6542 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6543 observe2Greater1 observeIGreater1 + action 0 + 7163 : 1 +state 6544 deadlock observe2Greater1 observeIGreater1 + action 0 + 6544 : 1 +state 6545 observe2Greater1 observeIGreater1 + action 0 + 5346 : 0.2 + 5347 : 0.2 + 5348 : 0.2 + 5349 : 0.2 + 5350 : 0.2 +state 6546 observe2Greater1 observeIGreater1 + action 0 + 7164 : 1 +state 6547 deadlock observe2Greater1 observeIGreater1 + action 0 + 6547 : 1 +state 6548 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 6549 observe3Greater1 observeIGreater1 + action 0 + 7170 : 1 +state 6550 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 6551 observe3Greater1 observeIGreater1 + action 0 + 7176 : 1 +state 6552 deadlock observe3Greater1 observeIGreater1 + action 0 + 6552 : 1 +state 6553 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6554 observe3Greater1 observeIGreater1 + action 0 + 7177 : 1 +state 6555 deadlock observe3Greater1 observeIGreater1 + action 0 + 6555 : 1 +state 6556 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6557 observe3Greater1 observeIGreater1 + action 0 + 7178 : 1 +state 6558 deadlock observe3Greater1 observeIGreater1 + action 0 + 6558 : 1 +state 6559 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6560 observe3Greater1 observeIGreater1 + action 0 + 7179 : 1 +state 6561 deadlock observe3Greater1 observeIGreater1 + action 0 + 6561 : 1 +state 6562 observe3Greater1 observeIGreater1 + action 0 + 5360 : 0.2 + 5361 : 0.2 + 5362 : 0.2 + 5363 : 0.2 + 5364 : 0.2 +state 6563 observe3Greater1 observeIGreater1 + action 0 + 7180 : 1 +state 6564 deadlock observe3Greater1 observeIGreater1 + action 0 + 6564 : 1 +state 6565 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 6566 observe4Greater1 observeIGreater1 + action 0 + 7186 : 1 +state 6567 deadlock + action 0 + 6567 : 1 +state 6568 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6569 + action 0 + 7187 : 1 +state 6570 deadlock + action 0 + 6570 : 1 +state 6571 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6572 + action 0 + 7188 : 1 +state 6573 deadlock + action 0 + 6573 : 1 +state 6574 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6575 + action 0 + 7189 : 1 +state 6576 deadlock + action 0 + 6576 : 1 +state 6577 + action 0 + 5370 : 0.2 + 5371 : 0.2 + 5372 : 0.2 + 5373 : 0.2 + 5374 : 0.2 +state 6578 + action 0 + 7190 : 1 +state 6579 deadlock + action 0 + 6579 : 1 +state 6580 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 6581 observe4Greater1 observeIGreater1 + action 0 + 7196 : 1 +state 6582 deadlock observe4Greater1 observeIGreater1 + action 0 + 6582 : 1 +state 6583 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6584 observe4Greater1 observeIGreater1 + action 0 + 7197 : 1 +state 6585 deadlock observe4Greater1 observeIGreater1 + action 0 + 6585 : 1 +state 6586 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6587 observe4Greater1 observeIGreater1 + action 0 + 7198 : 1 +state 6588 deadlock observe4Greater1 observeIGreater1 + action 0 + 6588 : 1 +state 6589 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6590 observe4Greater1 observeIGreater1 + action 0 + 7199 : 1 +state 6591 deadlock observe4Greater1 observeIGreater1 + action 0 + 6591 : 1 +state 6592 observe4Greater1 observeIGreater1 + action 0 + 5384 : 0.2 + 5385 : 0.2 + 5386 : 0.2 + 5387 : 0.2 + 5388 : 0.2 +state 6593 observe4Greater1 observeIGreater1 + action 0 + 7200 : 1 +state 6594 deadlock observe4Greater1 observeIGreater1 + action 0 + 6594 : 1 +state 6595 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 6596 observe3Greater1 observeIGreater1 + action 0 + 7206 : 1 +state 6597 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 6598 observe3Greater1 observeIGreater1 + action 0 + 7212 : 1 +state 6599 deadlock observe3Greater1 observeIGreater1 + action 0 + 6599 : 1 +state 6600 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6601 observe3Greater1 observeIGreater1 + action 0 + 7213 : 1 +state 6602 deadlock observe3Greater1 observeIGreater1 + action 0 + 6602 : 1 +state 6603 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6604 observe3Greater1 observeIGreater1 + action 0 + 7214 : 1 +state 6605 deadlock observe3Greater1 observeIGreater1 + action 0 + 6605 : 1 +state 6606 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6607 observe3Greater1 observeIGreater1 + action 0 + 7215 : 1 +state 6608 deadlock observe3Greater1 observeIGreater1 + action 0 + 6608 : 1 +state 6609 observe3Greater1 observeIGreater1 + action 0 + 5398 : 0.2 + 5399 : 0.2 + 5400 : 0.2 + 5401 : 0.2 + 5402 : 0.2 +state 6610 observe3Greater1 observeIGreater1 + action 0 + 7216 : 1 +state 6611 deadlock observe3Greater1 observeIGreater1 + action 0 + 6611 : 1 +state 6612 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 6613 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7222 : 1 +state 6614 deadlock observe3Greater1 observeIGreater1 + action 0 + 6614 : 1 +state 6615 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6616 observe3Greater1 observeIGreater1 + action 0 + 7223 : 1 +state 6617 deadlock observe3Greater1 observeIGreater1 + action 0 + 6617 : 1 +state 6618 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6619 observe3Greater1 observeIGreater1 + action 0 + 7224 : 1 +state 6620 deadlock observe3Greater1 observeIGreater1 + action 0 + 6620 : 1 +state 6621 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6622 observe3Greater1 observeIGreater1 + action 0 + 7225 : 1 +state 6623 deadlock observe3Greater1 observeIGreater1 + action 0 + 6623 : 1 +state 6624 observe3Greater1 observeIGreater1 + action 0 + 5408 : 0.2 + 5409 : 0.2 + 5410 : 0.2 + 5411 : 0.2 + 5412 : 0.2 +state 6625 observe3Greater1 observeIGreater1 + action 0 + 7226 : 1 +state 6626 deadlock observe3Greater1 observeIGreater1 + action 0 + 6626 : 1 +state 6627 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 6628 observe4Greater1 observeIGreater1 + action 0 + 7232 : 1 +state 6629 deadlock observe4Greater1 observeIGreater1 + action 0 + 6629 : 1 +state 6630 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6631 observe4Greater1 observeIGreater1 + action 0 + 7233 : 1 +state 6632 deadlock observe4Greater1 observeIGreater1 + action 0 + 6632 : 1 +state 6633 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6634 observe4Greater1 observeIGreater1 + action 0 + 7234 : 1 +state 6635 deadlock observe4Greater1 observeIGreater1 + action 0 + 6635 : 1 +state 6636 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6637 observe4Greater1 observeIGreater1 + action 0 + 7235 : 1 +state 6638 deadlock observe4Greater1 observeIGreater1 + action 0 + 6638 : 1 +state 6639 observe4Greater1 observeIGreater1 + action 0 + 5422 : 0.2 + 5423 : 0.2 + 5424 : 0.2 + 5425 : 0.2 + 5426 : 0.2 +state 6640 observe4Greater1 observeIGreater1 + action 0 + 7236 : 1 +state 6641 deadlock observe4Greater1 observeIGreater1 + action 0 + 6641 : 1 +state 6642 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 6643 observe4Greater1 observeIGreater1 + action 0 + 7242 : 1 +state 6644 deadlock observe4Greater1 observeIGreater1 + action 0 + 6644 : 1 +state 6645 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6646 observe4Greater1 observeIGreater1 + action 0 + 7243 : 1 +state 6647 deadlock observe4Greater1 observeIGreater1 + action 0 + 6647 : 1 +state 6648 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6649 observe4Greater1 observeIGreater1 + action 0 + 7244 : 1 +state 6650 deadlock observe4Greater1 observeIGreater1 + action 0 + 6650 : 1 +state 6651 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6652 observe4Greater1 observeIGreater1 + action 0 + 7245 : 1 +state 6653 deadlock observe4Greater1 observeIGreater1 + action 0 + 6653 : 1 +state 6654 observe4Greater1 observeIGreater1 + action 0 + 5436 : 0.2 + 5437 : 0.2 + 5438 : 0.2 + 5439 : 0.2 + 5440 : 0.2 +state 6655 observe4Greater1 observeIGreater1 + action 0 + 7246 : 1 +state 6656 deadlock observe4Greater1 observeIGreater1 + action 0 + 6656 : 1 +state 6657 deadlock observe1Greater1 observeIGreater1 + action 0 + 6657 : 1 +state 6658 deadlock observe1Greater1 observeIGreater1 + action 0 + 6658 : 1 +state 6659 deadlock observe1Greater1 observeIGreater1 + action 0 + 6659 : 1 +state 6660 deadlock observe1Greater1 observeIGreater1 + action 0 + 6660 : 1 +state 6661 deadlock observe1Greater1 observeIGreater1 + action 0 + 6661 : 1 +state 6662 deadlock observe2Greater1 observeIGreater1 + action 0 + 6662 : 1 +state 6663 deadlock + action 0 + 6663 : 1 +state 6664 deadlock + action 0 + 6664 : 1 +state 6665 deadlock observe1Greater1 observeIGreater1 + action 0 + 6665 : 1 +state 6666 deadlock + action 0 + 6666 : 1 +state 6667 deadlock observe3Greater1 observeIGreater1 + action 0 + 6667 : 1 +state 6668 deadlock + action 0 + 6668 : 1 +state 6669 deadlock observe1Greater1 observeIGreater1 + action 0 + 6669 : 1 +state 6670 deadlock + action 0 + 6670 : 1 +state 6671 deadlock + action 0 + 6671 : 1 +state 6672 deadlock observe4Greater1 observeIGreater1 + action 0 + 6672 : 1 +state 6673 deadlock observe2Greater1 observeIGreater1 + action 0 + 6673 : 1 +state 6674 deadlock observe2Greater1 observeIGreater1 + action 0 + 6674 : 1 +state 6675 deadlock observe2Greater1 observeIGreater1 + action 0 + 6675 : 1 +state 6676 deadlock observe2Greater1 observeIGreater1 + action 0 + 6676 : 1 +state 6677 deadlock + action 0 + 6677 : 1 +state 6678 deadlock observe2Greater1 observeIGreater1 + action 0 + 6678 : 1 +state 6679 deadlock observe3Greater1 observeIGreater1 + action 0 + 6679 : 1 +state 6680 deadlock + action 0 + 6680 : 1 +state 6681 deadlock + action 0 + 6681 : 1 +state 6682 deadlock observe2Greater1 observeIGreater1 + action 0 + 6682 : 1 +state 6683 deadlock + action 0 + 6683 : 1 +state 6684 deadlock observe4Greater1 observeIGreater1 + action 0 + 6684 : 1 +state 6685 deadlock observe3Greater1 observeIGreater1 + action 0 + 6685 : 1 +state 6686 deadlock observe3Greater1 observeIGreater1 + action 0 + 6686 : 1 +state 6687 deadlock observe3Greater1 observeIGreater1 + action 0 + 6687 : 1 +state 6688 deadlock observe3Greater1 observeIGreater1 + action 0 + 6688 : 1 +state 6689 deadlock + action 0 + 6689 : 1 +state 6690 deadlock + action 0 + 6690 : 1 +state 6691 deadlock observe3Greater1 observeIGreater1 + action 0 + 6691 : 1 +state 6692 deadlock observe4Greater1 observeIGreater1 + action 0 + 6692 : 1 +state 6693 deadlock observe4Greater1 observeIGreater1 + action 0 + 6693 : 1 +state 6694 deadlock observe4Greater1 observeIGreater1 + action 0 + 6694 : 1 +state 6695 deadlock observe4Greater1 observeIGreater1 + action 0 + 6695 : 1 +state 6696 deadlock observe4Greater1 observeIGreater1 + action 0 + 6696 : 1 +state 6697 deadlock observe1Greater1 observeIGreater1 + action 0 + 6697 : 1 +state 6698 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6699 observe1Greater1 observeIGreater1 + action 0 + 7247 : 1 +state 6700 deadlock observe1Greater1 observeIGreater1 + action 0 + 6700 : 1 +state 6701 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6702 observe1Greater1 observeIGreater1 + action 0 + 7248 : 1 +state 6703 deadlock observe1Greater1 observeIGreater1 + action 0 + 6703 : 1 +state 6704 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6705 observe1Greater1 observeIGreater1 + action 0 + 7249 : 1 +state 6706 deadlock observe1Greater1 observeIGreater1 + action 0 + 6706 : 1 +state 6707 observe1Greater1 observeIGreater1 + action 0 + 5592 : 0.2 + 5593 : 0.2 + 5594 : 0.2 + 5595 : 0.2 + 5596 : 0.2 +state 6708 observe1Greater1 observeIGreater1 + action 0 + 7250 : 1 +state 6709 deadlock observe1Greater1 observeIGreater1 + action 0 + 6709 : 1 +state 6710 deadlock observe1Greater1 observeIGreater1 + action 0 + 6710 : 1 +state 6711 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6712 observe1Greater1 observeIGreater1 + action 0 + 7251 : 1 +state 6713 deadlock observe1Greater1 observeIGreater1 + action 0 + 6713 : 1 +state 6714 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6715 observe1Greater1 observeIGreater1 + action 0 + 7252 : 1 +state 6716 deadlock observe1Greater1 observeIGreater1 + action 0 + 6716 : 1 +state 6717 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6718 observe1Greater1 observeIGreater1 + action 0 + 7253 : 1 +state 6719 deadlock observe1Greater1 observeIGreater1 + action 0 + 6719 : 1 +state 6720 observe1Greater1 observeIGreater1 + action 0 + 5598 : 0.2 + 5599 : 0.2 + 5600 : 0.2 + 5601 : 0.2 + 5602 : 0.2 +state 6721 observe1Greater1 observeIGreater1 + action 0 + 7254 : 1 +state 6722 deadlock observe1Greater1 observeIGreater1 + action 0 + 6722 : 1 +state 6723 deadlock observe1Greater1 observeIGreater1 + action 0 + 6723 : 1 +state 6724 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6725 observe1Greater1 observeIGreater1 + action 0 + 7255 : 1 +state 6726 deadlock observe1Greater1 observeIGreater1 + action 0 + 6726 : 1 +state 6727 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6728 observe1Greater1 observeIGreater1 + action 0 + 7256 : 1 +state 6729 deadlock observe1Greater1 observeIGreater1 + action 0 + 6729 : 1 +state 6730 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6731 observe1Greater1 observeIGreater1 + action 0 + 7257 : 1 +state 6732 deadlock observe1Greater1 observeIGreater1 + action 0 + 6732 : 1 +state 6733 observe1Greater1 observeIGreater1 + action 0 + 5604 : 0.2 + 5605 : 0.2 + 5606 : 0.2 + 5607 : 0.2 + 5608 : 0.2 +state 6734 observe1Greater1 observeIGreater1 + action 0 + 7258 : 1 +state 6735 deadlock observe1Greater1 observeIGreater1 + action 0 + 6735 : 1 +state 6736 deadlock observe1Greater1 observeIGreater1 + action 0 + 6736 : 1 +state 6737 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6738 observe1Greater1 observeIGreater1 + action 0 + 7259 : 1 +state 6739 deadlock observe1Greater1 observeIGreater1 + action 0 + 6739 : 1 +state 6740 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6741 observe1Greater1 observeIGreater1 + action 0 + 7260 : 1 +state 6742 deadlock observe1Greater1 observeIGreater1 + action 0 + 6742 : 1 +state 6743 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6744 observe1Greater1 observeIGreater1 + action 0 + 7261 : 1 +state 6745 deadlock observe1Greater1 observeIGreater1 + action 0 + 6745 : 1 +state 6746 observe1Greater1 observeIGreater1 + action 0 + 5610 : 0.2 + 5611 : 0.2 + 5612 : 0.2 + 5613 : 0.2 + 5614 : 0.2 +state 6747 observe1Greater1 observeIGreater1 + action 0 + 7262 : 1 +state 6748 deadlock observe1Greater1 observeIGreater1 + action 0 + 6748 : 1 +state 6749 deadlock observe2Greater1 observeIGreater1 + action 0 + 6749 : 1 +state 6750 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6751 observe2Greater1 observeIGreater1 + action 0 + 7263 : 1 +state 6752 deadlock observe2Greater1 observeIGreater1 + action 0 + 6752 : 1 +state 6753 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6754 observe2Greater1 observeIGreater1 + action 0 + 7264 : 1 +state 6755 deadlock observe2Greater1 observeIGreater1 + action 0 + 6755 : 1 +state 6756 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6757 observe2Greater1 observeIGreater1 + action 0 + 7265 : 1 +state 6758 deadlock observe2Greater1 observeIGreater1 + action 0 + 6758 : 1 +state 6759 observe2Greater1 observeIGreater1 + action 0 + 5620 : 0.2 + 5621 : 0.2 + 5622 : 0.2 + 5623 : 0.2 + 5624 : 0.2 +state 6760 observe2Greater1 observeIGreater1 + action 0 + 7266 : 1 +state 6761 deadlock observe2Greater1 observeIGreater1 + action 0 + 6761 : 1 +state 6762 deadlock + action 0 + 6762 : 1 +state 6763 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6764 + action 0 + 7267 : 1 +state 6765 deadlock + action 0 + 6765 : 1 +state 6766 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6767 + action 0 + 7268 : 1 +state 6768 deadlock + action 0 + 6768 : 1 +state 6769 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6770 + action 0 + 7269 : 1 +state 6771 deadlock + action 0 + 6771 : 1 +state 6772 + action 0 + 5626 : 0.2 + 5627 : 0.2 + 5628 : 0.2 + 5629 : 0.2 + 5630 : 0.2 +state 6773 + action 0 + 7270 : 1 +state 6774 deadlock + action 0 + 6774 : 1 +state 6775 deadlock + action 0 + 6775 : 1 +state 6776 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6777 + action 0 + 7271 : 1 +state 6778 deadlock + action 0 + 6778 : 1 +state 6779 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6780 + action 0 + 7272 : 1 +state 6781 deadlock + action 0 + 6781 : 1 +state 6782 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6783 + action 0 + 7273 : 1 +state 6784 deadlock + action 0 + 6784 : 1 +state 6785 + action 0 + 5632 : 0.2 + 5633 : 0.2 + 5634 : 0.2 + 5635 : 0.2 + 5636 : 0.2 +state 6786 + action 0 + 7274 : 1 +state 6787 deadlock + action 0 + 6787 : 1 +state 6788 deadlock observe3Greater1 observeIGreater1 + action 0 + 6788 : 1 +state 6789 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6790 observe3Greater1 observeIGreater1 + action 0 + 7275 : 1 +state 6791 deadlock observe3Greater1 observeIGreater1 + action 0 + 6791 : 1 +state 6792 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6793 observe3Greater1 observeIGreater1 + action 0 + 7276 : 1 +state 6794 deadlock observe3Greater1 observeIGreater1 + action 0 + 6794 : 1 +state 6795 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6796 observe3Greater1 observeIGreater1 + action 0 + 7277 : 1 +state 6797 deadlock observe3Greater1 observeIGreater1 + action 0 + 6797 : 1 +state 6798 observe3Greater1 observeIGreater1 + action 0 + 5642 : 0.2 + 5643 : 0.2 + 5644 : 0.2 + 5645 : 0.2 + 5646 : 0.2 +state 6799 observe3Greater1 observeIGreater1 + action 0 + 7278 : 1 +state 6800 deadlock observe3Greater1 observeIGreater1 + action 0 + 6800 : 1 +state 6801 deadlock + action 0 + 6801 : 1 +state 6802 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6803 + action 0 + 7279 : 1 +state 6804 deadlock + action 0 + 6804 : 1 +state 6805 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6806 + action 0 + 7280 : 1 +state 6807 deadlock + action 0 + 6807 : 1 +state 6808 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6809 + action 0 + 7281 : 1 +state 6810 deadlock + action 0 + 6810 : 1 +state 6811 + action 0 + 5648 : 0.2 + 5649 : 0.2 + 5650 : 0.2 + 5651 : 0.2 + 5652 : 0.2 +state 6812 + action 0 + 7282 : 1 +state 6813 deadlock + action 0 + 6813 : 1 +state 6814 deadlock observe4Greater1 observeIGreater1 + action 0 + 6814 : 1 +state 6815 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6816 observe4Greater1 observeIGreater1 + action 0 + 7283 : 1 +state 6817 deadlock observe4Greater1 observeIGreater1 + action 0 + 6817 : 1 +state 6818 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6819 observe4Greater1 observeIGreater1 + action 0 + 7284 : 1 +state 6820 deadlock observe4Greater1 observeIGreater1 + action 0 + 6820 : 1 +state 6821 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6822 observe4Greater1 observeIGreater1 + action 0 + 7285 : 1 +state 6823 deadlock observe4Greater1 observeIGreater1 + action 0 + 6823 : 1 +state 6824 observe4Greater1 observeIGreater1 + action 0 + 5658 : 0.2 + 5659 : 0.2 + 5660 : 0.2 + 5661 : 0.2 + 5662 : 0.2 +state 6825 observe4Greater1 observeIGreater1 + action 0 + 7286 : 1 +state 6826 deadlock observe4Greater1 observeIGreater1 + action 0 + 6826 : 1 +state 6827 deadlock observe2Greater1 observeIGreater1 + action 0 + 6827 : 1 +state 6828 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6829 observe2Greater1 observeIGreater1 + action 0 + 7287 : 1 +state 6830 deadlock observe2Greater1 observeIGreater1 + action 0 + 6830 : 1 +state 6831 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6832 observe2Greater1 observeIGreater1 + action 0 + 7288 : 1 +state 6833 deadlock observe2Greater1 observeIGreater1 + action 0 + 6833 : 1 +state 6834 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6835 observe2Greater1 observeIGreater1 + action 0 + 7289 : 1 +state 6836 deadlock observe2Greater1 observeIGreater1 + action 0 + 6836 : 1 +state 6837 observe2Greater1 observeIGreater1 + action 0 + 5668 : 0.2 + 5669 : 0.2 + 5670 : 0.2 + 5671 : 0.2 + 5672 : 0.2 +state 6838 observe2Greater1 observeIGreater1 + action 0 + 7290 : 1 +state 6839 deadlock observe2Greater1 observeIGreater1 + action 0 + 6839 : 1 +state 6840 deadlock observe2Greater1 observeIGreater1 + action 0 + 6840 : 1 +state 6841 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6842 observe2Greater1 observeIGreater1 + action 0 + 7291 : 1 +state 6843 deadlock observe2Greater1 observeIGreater1 + action 0 + 6843 : 1 +state 6844 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6845 observe2Greater1 observeIGreater1 + action 0 + 7292 : 1 +state 6846 deadlock observe2Greater1 observeIGreater1 + action 0 + 6846 : 1 +state 6847 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6848 observe2Greater1 observeIGreater1 + action 0 + 7293 : 1 +state 6849 deadlock observe2Greater1 observeIGreater1 + action 0 + 6849 : 1 +state 6850 observe2Greater1 observeIGreater1 + action 0 + 5674 : 0.2 + 5675 : 0.2 + 5676 : 0.2 + 5677 : 0.2 + 5678 : 0.2 +state 6851 observe2Greater1 observeIGreater1 + action 0 + 7294 : 1 +state 6852 deadlock observe2Greater1 observeIGreater1 + action 0 + 6852 : 1 +state 6853 deadlock observe2Greater1 observeIGreater1 + action 0 + 6853 : 1 +state 6854 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6855 observe2Greater1 observeIGreater1 + action 0 + 7295 : 1 +state 6856 deadlock observe2Greater1 observeIGreater1 + action 0 + 6856 : 1 +state 6857 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6858 observe2Greater1 observeIGreater1 + action 0 + 7296 : 1 +state 6859 deadlock observe2Greater1 observeIGreater1 + action 0 + 6859 : 1 +state 6860 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6861 observe2Greater1 observeIGreater1 + action 0 + 7297 : 1 +state 6862 deadlock observe2Greater1 observeIGreater1 + action 0 + 6862 : 1 +state 6863 observe2Greater1 observeIGreater1 + action 0 + 5680 : 0.2 + 5681 : 0.2 + 5682 : 0.2 + 5683 : 0.2 + 5684 : 0.2 +state 6864 observe2Greater1 observeIGreater1 + action 0 + 7298 : 1 +state 6865 deadlock observe2Greater1 observeIGreater1 + action 0 + 6865 : 1 +state 6866 deadlock observe3Greater1 observeIGreater1 + action 0 + 6866 : 1 +state 6867 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6868 observe3Greater1 observeIGreater1 + action 0 + 7299 : 1 +state 6869 deadlock observe3Greater1 observeIGreater1 + action 0 + 6869 : 1 +state 6870 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6871 observe3Greater1 observeIGreater1 + action 0 + 7300 : 1 +state 6872 deadlock observe3Greater1 observeIGreater1 + action 0 + 6872 : 1 +state 6873 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6874 observe3Greater1 observeIGreater1 + action 0 + 7301 : 1 +state 6875 deadlock observe3Greater1 observeIGreater1 + action 0 + 6875 : 1 +state 6876 observe3Greater1 observeIGreater1 + action 0 + 5690 : 0.2 + 5691 : 0.2 + 5692 : 0.2 + 5693 : 0.2 + 5694 : 0.2 +state 6877 observe3Greater1 observeIGreater1 + action 0 + 7302 : 1 +state 6878 deadlock observe3Greater1 observeIGreater1 + action 0 + 6878 : 1 +state 6879 deadlock + action 0 + 6879 : 1 +state 6880 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6881 + action 0 + 7303 : 1 +state 6882 deadlock + action 0 + 6882 : 1 +state 6883 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6884 + action 0 + 7304 : 1 +state 6885 deadlock + action 0 + 6885 : 1 +state 6886 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6887 + action 0 + 7305 : 1 +state 6888 deadlock + action 0 + 6888 : 1 +state 6889 + action 0 + 5696 : 0.2 + 5697 : 0.2 + 5698 : 0.2 + 5699 : 0.2 + 5700 : 0.2 +state 6890 + action 0 + 7306 : 1 +state 6891 deadlock + action 0 + 6891 : 1 +state 6892 deadlock observe4Greater1 observeIGreater1 + action 0 + 6892 : 1 +state 6893 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6894 observe4Greater1 observeIGreater1 + action 0 + 7307 : 1 +state 6895 deadlock observe4Greater1 observeIGreater1 + action 0 + 6895 : 1 +state 6896 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6897 observe4Greater1 observeIGreater1 + action 0 + 7308 : 1 +state 6898 deadlock observe4Greater1 observeIGreater1 + action 0 + 6898 : 1 +state 6899 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6900 observe4Greater1 observeIGreater1 + action 0 + 7309 : 1 +state 6901 deadlock observe4Greater1 observeIGreater1 + action 0 + 6901 : 1 +state 6902 observe4Greater1 observeIGreater1 + action 0 + 5706 : 0.2 + 5707 : 0.2 + 5708 : 0.2 + 5709 : 0.2 + 5710 : 0.2 +state 6903 observe4Greater1 observeIGreater1 + action 0 + 7310 : 1 +state 6904 deadlock observe4Greater1 observeIGreater1 + action 0 + 6904 : 1 +state 6905 deadlock observe3Greater1 observeIGreater1 + action 0 + 6905 : 1 +state 6906 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6907 observe3Greater1 observeIGreater1 + action 0 + 7311 : 1 +state 6908 deadlock observe3Greater1 observeIGreater1 + action 0 + 6908 : 1 +state 6909 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6910 observe3Greater1 observeIGreater1 + action 0 + 7312 : 1 +state 6911 deadlock observe3Greater1 observeIGreater1 + action 0 + 6911 : 1 +state 6912 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6913 observe3Greater1 observeIGreater1 + action 0 + 7313 : 1 +state 6914 deadlock observe3Greater1 observeIGreater1 + action 0 + 6914 : 1 +state 6915 observe3Greater1 observeIGreater1 + action 0 + 5716 : 0.2 + 5717 : 0.2 + 5718 : 0.2 + 5719 : 0.2 + 5720 : 0.2 +state 6916 observe3Greater1 observeIGreater1 + action 0 + 7314 : 1 +state 6917 deadlock observe3Greater1 observeIGreater1 + action 0 + 6917 : 1 +state 6918 deadlock observe3Greater1 observeIGreater1 + action 0 + 6918 : 1 +state 6919 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6920 observe3Greater1 observeIGreater1 + action 0 + 7315 : 1 +state 6921 deadlock observe3Greater1 observeIGreater1 + action 0 + 6921 : 1 +state 6922 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6923 observe3Greater1 observeIGreater1 + action 0 + 7316 : 1 +state 6924 deadlock observe3Greater1 observeIGreater1 + action 0 + 6924 : 1 +state 6925 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6926 observe3Greater1 observeIGreater1 + action 0 + 7317 : 1 +state 6927 deadlock observe3Greater1 observeIGreater1 + action 0 + 6927 : 1 +state 6928 observe3Greater1 observeIGreater1 + action 0 + 5722 : 0.2 + 5723 : 0.2 + 5724 : 0.2 + 5725 : 0.2 + 5726 : 0.2 +state 6929 observe3Greater1 observeIGreater1 + action 0 + 7318 : 1 +state 6930 deadlock observe3Greater1 observeIGreater1 + action 0 + 6930 : 1 +state 6931 deadlock observe4Greater1 observeIGreater1 + action 0 + 6931 : 1 +state 6932 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6933 observe4Greater1 observeIGreater1 + action 0 + 7319 : 1 +state 6934 deadlock observe4Greater1 observeIGreater1 + action 0 + 6934 : 1 +state 6935 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6936 observe4Greater1 observeIGreater1 + action 0 + 7320 : 1 +state 6937 deadlock observe4Greater1 observeIGreater1 + action 0 + 6937 : 1 +state 6938 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6939 observe4Greater1 observeIGreater1 + action 0 + 7321 : 1 +state 6940 deadlock observe4Greater1 observeIGreater1 + action 0 + 6940 : 1 +state 6941 observe4Greater1 observeIGreater1 + action 0 + 5732 : 0.2 + 5733 : 0.2 + 5734 : 0.2 + 5735 : 0.2 + 5736 : 0.2 +state 6942 observe4Greater1 observeIGreater1 + action 0 + 7322 : 1 +state 6943 deadlock observe4Greater1 observeIGreater1 + action 0 + 6943 : 1 +state 6944 deadlock observe4Greater1 observeIGreater1 + action 0 + 6944 : 1 +state 6945 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6946 observe4Greater1 observeIGreater1 + action 0 + 7323 : 1 +state 6947 deadlock observe4Greater1 observeIGreater1 + action 0 + 6947 : 1 +state 6948 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6949 observe4Greater1 observeIGreater1 + action 0 + 7324 : 1 +state 6950 deadlock observe4Greater1 observeIGreater1 + action 0 + 6950 : 1 +state 6951 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6952 observe4Greater1 observeIGreater1 + action 0 + 7325 : 1 +state 6953 deadlock observe4Greater1 observeIGreater1 + action 0 + 6953 : 1 +state 6954 observe4Greater1 observeIGreater1 + action 0 + 5742 : 0.2 + 5743 : 0.2 + 5744 : 0.2 + 5745 : 0.2 + 5746 : 0.2 +state 6955 observe4Greater1 observeIGreater1 + action 0 + 7326 : 1 +state 6956 deadlock observe4Greater1 observeIGreater1 + action 0 + 6956 : 1 +state 6957 observe1Greater1 observeIGreater1 + action 0 + 7327 : 0.8 + 7328 : 0.2 +state 6958 observe1Greater1 observeIGreater1 + action 0 + 7329 : 0.8 + 7330 : 0.2 +state 6959 observe1Greater1 observeIGreater1 + action 0 + 7331 : 0.8 + 7332 : 0.2 +state 6960 observe1Greater1 observeIGreater1 + action 0 + 7333 : 0.8 + 7334 : 0.2 +state 6961 observe1Greater1 observeIGreater1 + action 0 + 7335 : 0.8 + 7336 : 0.2 +state 6962 observe1Greater1 observeIGreater1 + action 0 + 7337 : 1 +state 6963 observe1Greater1 observeIGreater1 + action 0 + 7338 : 0.8 + 7339 : 0.2 +state 6964 observe1Greater1 observeIGreater1 + action 0 + 7340 : 0.8 + 7341 : 0.2 +state 6965 observe1Greater1 observeIGreater1 + action 0 + 7342 : 0.8 + 7343 : 0.2 +state 6966 observe1Greater1 observeIGreater1 + action 0 + 7344 : 0.8 + 7345 : 0.2 +state 6967 observe1Greater1 observeIGreater1 + action 0 + 7346 : 0.8 + 7347 : 0.2 +state 6968 observe1Greater1 observeIGreater1 + action 0 + 7348 : 1 +state 6969 observe1Greater1 observeIGreater1 + action 0 + 7349 : 0.8 + 7350 : 0.2 +state 6970 observe1Greater1 observeIGreater1 + action 0 + 7351 : 0.8 + 7352 : 0.2 +state 6971 observe1Greater1 observeIGreater1 + action 0 + 7353 : 0.8 + 7354 : 0.2 +state 6972 observe1Greater1 observeIGreater1 + action 0 + 7355 : 0.8 + 7356 : 0.2 +state 6973 observe1Greater1 observeIGreater1 + action 0 + 7357 : 0.8 + 7358 : 0.2 +state 6974 observe1Greater1 observeIGreater1 + action 0 + 7359 : 1 +state 6975 observe1Greater1 observeIGreater1 + action 0 + 7360 : 0.8 + 7361 : 0.2 +state 6976 observe1Greater1 observeIGreater1 + action 0 + 7362 : 0.8 + 7363 : 0.2 +state 6977 observe1Greater1 observeIGreater1 + action 0 + 7364 : 0.8 + 7365 : 0.2 +state 6978 observe1Greater1 observeIGreater1 + action 0 + 7366 : 0.8 + 7367 : 0.2 +state 6979 observe1Greater1 observeIGreater1 + action 0 + 7368 : 0.8 + 7369 : 0.2 +state 6980 observe1Greater1 observeIGreater1 + action 0 + 7370 : 1 +state 6981 observe1Greater1 observeIGreater1 + action 0 + 7371 : 1 +state 6982 observe1Greater1 observeIGreater1 + action 0 + 7372 : 1 +state 6983 observe1Greater1 observeIGreater1 + action 0 + 7373 : 1 +state 6984 observe1Greater1 observeIGreater1 + action 0 + 7374 : 1 +state 6985 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7375 : 0.8 + 7376 : 0.2 +state 6986 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7377 : 0.8 + 7378 : 0.2 +state 6987 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7379 : 0.8 + 7380 : 0.2 +state 6988 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7381 : 0.8 + 7382 : 0.2 +state 6989 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7383 : 0.8 + 7384 : 0.2 +state 6990 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7385 : 1 +state 6991 observe1Greater1 observeIGreater1 + action 0 + 7386 : 0.8 + 7387 : 0.2 +state 6992 observe1Greater1 observeIGreater1 + action 0 + 7388 : 0.8 + 7389 : 0.2 +state 6993 observe1Greater1 observeIGreater1 + action 0 + 7390 : 0.8 + 7391 : 0.2 +state 6994 observe1Greater1 observeIGreater1 + action 0 + 7392 : 0.8 + 7393 : 0.2 +state 6995 observe1Greater1 observeIGreater1 + action 0 + 7394 : 0.8 + 7395 : 0.2 +state 6996 observe1Greater1 observeIGreater1 + action 0 + 7396 : 1 +state 6997 observe1Greater1 observeIGreater1 + action 0 + 7397 : 0.8 + 7398 : 0.2 +state 6998 observe1Greater1 observeIGreater1 + action 0 + 7399 : 0.8 + 7400 : 0.2 +state 6999 observe1Greater1 observeIGreater1 + action 0 + 7401 : 0.8 + 7402 : 0.2 +state 7000 observe1Greater1 observeIGreater1 + action 0 + 7403 : 0.8 + 7404 : 0.2 +state 7001 observe1Greater1 observeIGreater1 + action 0 + 7405 : 0.8 + 7406 : 0.2 +state 7002 observe1Greater1 observeIGreater1 + action 0 + 7407 : 1 +state 7003 observe1Greater1 observeIGreater1 + action 0 + 7408 : 1 +state 7004 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7409 : 1 +state 7005 observe1Greater1 observeIGreater1 + action 0 + 7410 : 1 +state 7006 observe1Greater1 observeIGreater1 + action 0 + 7411 : 1 +state 7007 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7412 : 0.8 + 7413 : 0.2 +state 7008 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7414 : 0.8 + 7415 : 0.2 +state 7009 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7416 : 0.8 + 7417 : 0.2 +state 7010 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7418 : 0.8 + 7419 : 0.2 +state 7011 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7420 : 0.8 + 7421 : 0.2 +state 7012 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7422 : 1 +state 7013 observe1Greater1 observeIGreater1 + action 0 + 7423 : 0.8 + 7424 : 0.2 +state 7014 observe1Greater1 observeIGreater1 + action 0 + 7425 : 0.8 + 7426 : 0.2 +state 7015 observe1Greater1 observeIGreater1 + action 0 + 7427 : 0.8 + 7428 : 0.2 +state 7016 observe1Greater1 observeIGreater1 + action 0 + 7429 : 0.8 + 7430 : 0.2 +state 7017 observe1Greater1 observeIGreater1 + action 0 + 7431 : 0.8 + 7432 : 0.2 +state 7018 observe1Greater1 observeIGreater1 + action 0 + 7433 : 1 +state 7019 observe1Greater1 observeIGreater1 + action 0 + 7434 : 1 +state 7020 observe1Greater1 observeIGreater1 + action 0 + 7435 : 1 +state 7021 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7436 : 1 +state 7022 observe1Greater1 observeIGreater1 + action 0 + 7437 : 1 +state 7023 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7438 : 0.8 + 7439 : 0.2 +state 7024 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7440 : 0.8 + 7441 : 0.2 +state 7025 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7442 : 0.8 + 7443 : 0.2 +state 7026 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7444 : 0.8 + 7445 : 0.2 +state 7027 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7446 : 0.8 + 7447 : 0.2 +state 7028 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7448 : 1 +state 7029 observe1Greater1 observeIGreater1 + action 0 + 7449 : 1 +state 7030 observe1Greater1 observeIGreater1 + action 0 + 7450 : 1 +state 7031 observe1Greater1 observeIGreater1 + action 0 + 7451 : 1 +state 7032 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7452 : 1 +state 7033 observe2Greater1 observeIGreater1 + action 0 + 7453 : 0.8 + 7454 : 0.2 +state 7034 observe2Greater1 observeIGreater1 + action 0 + 7455 : 0.8 + 7456 : 0.2 +state 7035 observe2Greater1 observeIGreater1 + action 0 + 7457 : 0.8 + 7458 : 0.2 +state 7036 observe2Greater1 observeIGreater1 + action 0 + 7459 : 0.8 + 7460 : 0.2 +state 7037 observe2Greater1 observeIGreater1 + action 0 + 7461 : 0.8 + 7462 : 0.2 +state 7038 observe2Greater1 observeIGreater1 + action 0 + 7463 : 1 +state 7039 observe2Greater1 observeIGreater1 + action 0 + 7464 : 0.8 + 7465 : 0.2 +state 7040 observe2Greater1 observeIGreater1 + action 0 + 7466 : 0.8 + 7467 : 0.2 +state 7041 observe2Greater1 observeIGreater1 + action 0 + 7468 : 0.8 + 7469 : 0.2 +state 7042 observe2Greater1 observeIGreater1 + action 0 + 7470 : 0.8 + 7471 : 0.2 +state 7043 observe2Greater1 observeIGreater1 + action 0 + 7472 : 0.8 + 7473 : 0.2 +state 7044 observe2Greater1 observeIGreater1 + action 0 + 7474 : 1 +state 7045 observe2Greater1 observeIGreater1 + action 0 + 7475 : 0.8 + 7476 : 0.2 +state 7046 observe2Greater1 observeIGreater1 + action 0 + 7477 : 0.8 + 7478 : 0.2 +state 7047 observe2Greater1 observeIGreater1 + action 0 + 7479 : 0.8 + 7480 : 0.2 +state 7048 observe2Greater1 observeIGreater1 + action 0 + 7481 : 0.8 + 7482 : 0.2 +state 7049 observe2Greater1 observeIGreater1 + action 0 + 7483 : 0.8 + 7484 : 0.2 +state 7050 observe2Greater1 observeIGreater1 + action 0 + 7485 : 1 +state 7051 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7486 : 1 +state 7052 observe2Greater1 observeIGreater1 + action 0 + 7487 : 1 +state 7053 observe2Greater1 observeIGreater1 + action 0 + 7488 : 1 +state 7054 observe2Greater1 observeIGreater1 + action 0 + 7489 : 1 +state 7055 observe3Greater1 observeIGreater1 + action 0 + 7490 : 0.8 + 7491 : 0.2 +state 7056 observe3Greater1 observeIGreater1 + action 0 + 7492 : 0.8 + 7493 : 0.2 +state 7057 observe3Greater1 observeIGreater1 + action 0 + 7494 : 0.8 + 7495 : 0.2 +state 7058 observe3Greater1 observeIGreater1 + action 0 + 7496 : 0.8 + 7497 : 0.2 +state 7059 observe3Greater1 observeIGreater1 + action 0 + 7498 : 0.8 + 7499 : 0.2 +state 7060 observe3Greater1 observeIGreater1 + action 0 + 7500 : 1 +state 7061 + action 0 + 7501 : 0.8 + 7502 : 0.2 +state 7062 + action 0 + 7503 : 0.8 + 7504 : 0.2 +state 7063 + action 0 + 7505 : 0.8 + 7506 : 0.2 +state 7064 + action 0 + 7507 : 0.8 + 7508 : 0.2 +state 7065 + action 0 + 7509 : 0.8 + 7510 : 0.2 +state 7066 + action 0 + 7511 : 1 +state 7067 observe1Greater1 observeIGreater1 + action 0 + 7512 : 1 +state 7068 observe2Greater1 observeIGreater1 + action 0 + 7513 : 1 +state 7069 observe3Greater1 observeIGreater1 + action 0 + 7514 : 1 +state 7070 + action 0 + 7515 : 1 +state 7071 observe4Greater1 observeIGreater1 + action 0 + 7516 : 0.8 + 7517 : 0.2 +state 7072 observe4Greater1 observeIGreater1 + action 0 + 7518 : 0.8 + 7519 : 0.2 +state 7073 observe4Greater1 observeIGreater1 + action 0 + 7520 : 0.8 + 7521 : 0.2 +state 7074 observe4Greater1 observeIGreater1 + action 0 + 7522 : 0.8 + 7523 : 0.2 +state 7075 observe4Greater1 observeIGreater1 + action 0 + 7524 : 0.8 + 7525 : 0.2 +state 7076 observe4Greater1 observeIGreater1 + action 0 + 7526 : 1 +state 7077 observe1Greater1 observeIGreater1 + action 0 + 7527 : 1 +state 7078 observe2Greater1 observeIGreater1 + action 0 + 7528 : 1 +state 7079 + action 0 + 7529 : 1 +state 7080 observe4Greater1 observeIGreater1 + action 0 + 7530 : 1 +state 7081 observe3Greater1 observeIGreater1 + action 0 + 7531 : 0.8 + 7532 : 0.2 +state 7082 observe3Greater1 observeIGreater1 + action 0 + 7533 : 0.8 + 7534 : 0.2 +state 7083 observe3Greater1 observeIGreater1 + action 0 + 7535 : 0.8 + 7536 : 0.2 +state 7084 observe3Greater1 observeIGreater1 + action 0 + 7537 : 0.8 + 7538 : 0.2 +state 7085 observe3Greater1 observeIGreater1 + action 0 + 7539 : 0.8 + 7540 : 0.2 +state 7086 observe3Greater1 observeIGreater1 + action 0 + 7541 : 1 +state 7087 observe3Greater1 observeIGreater1 + action 0 + 7542 : 0.8 + 7543 : 0.2 +state 7088 observe3Greater1 observeIGreater1 + action 0 + 7544 : 0.8 + 7545 : 0.2 +state 7089 observe3Greater1 observeIGreater1 + action 0 + 7546 : 0.8 + 7547 : 0.2 +state 7090 observe3Greater1 observeIGreater1 + action 0 + 7548 : 0.8 + 7549 : 0.2 +state 7091 observe3Greater1 observeIGreater1 + action 0 + 7550 : 0.8 + 7551 : 0.2 +state 7092 observe3Greater1 observeIGreater1 + action 0 + 7552 : 1 +state 7093 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7553 : 1 +state 7094 observe3Greater1 observeIGreater1 + action 0 + 7554 : 1 +state 7095 observe3Greater1 observeIGreater1 + action 0 + 7555 : 1 +state 7096 observe3Greater1 observeIGreater1 + action 0 + 7556 : 1 +state 7097 observe4Greater1 observeIGreater1 + action 0 + 7557 : 0.8 + 7558 : 0.2 +state 7098 observe4Greater1 observeIGreater1 + action 0 + 7559 : 0.8 + 7560 : 0.2 +state 7099 observe4Greater1 observeIGreater1 + action 0 + 7561 : 0.8 + 7562 : 0.2 +state 7100 observe4Greater1 observeIGreater1 + action 0 + 7563 : 0.8 + 7564 : 0.2 +state 7101 observe4Greater1 observeIGreater1 + action 0 + 7565 : 0.8 + 7566 : 0.2 +state 7102 observe4Greater1 observeIGreater1 + action 0 + 7567 : 1 +state 7103 observe1Greater1 observeIGreater1 + action 0 + 7568 : 1 +state 7104 + action 0 + 7569 : 1 +state 7105 observe3Greater1 observeIGreater1 + action 0 + 7570 : 1 +state 7106 observe4Greater1 observeIGreater1 + action 0 + 7571 : 1 +state 7107 observe4Greater1 observeIGreater1 + action 0 + 7572 : 0.8 + 7573 : 0.2 +state 7108 observe4Greater1 observeIGreater1 + action 0 + 7574 : 0.8 + 7575 : 0.2 +state 7109 observe4Greater1 observeIGreater1 + action 0 + 7576 : 0.8 + 7577 : 0.2 +state 7110 observe4Greater1 observeIGreater1 + action 0 + 7578 : 0.8 + 7579 : 0.2 +state 7111 observe4Greater1 observeIGreater1 + action 0 + 7580 : 0.8 + 7581 : 0.2 +state 7112 observe4Greater1 observeIGreater1 + action 0 + 7582 : 1 +state 7113 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7583 : 1 +state 7114 observe4Greater1 observeIGreater1 + action 0 + 7584 : 1 +state 7115 observe4Greater1 observeIGreater1 + action 0 + 7585 : 1 +state 7116 observe4Greater1 observeIGreater1 + action 0 + 7586 : 1 +state 7117 observe2Greater1 observeIGreater1 + action 0 + 7587 : 0.8 + 7588 : 0.2 +state 7118 observe2Greater1 observeIGreater1 + action 0 + 7589 : 0.8 + 7590 : 0.2 +state 7119 observe2Greater1 observeIGreater1 + action 0 + 7591 : 0.8 + 7592 : 0.2 +state 7120 observe2Greater1 observeIGreater1 + action 0 + 7593 : 0.8 + 7594 : 0.2 +state 7121 observe2Greater1 observeIGreater1 + action 0 + 7595 : 0.8 + 7596 : 0.2 +state 7122 observe2Greater1 observeIGreater1 + action 0 + 7597 : 1 +state 7123 observe2Greater1 observeIGreater1 + action 0 + 7598 : 0.8 + 7599 : 0.2 +state 7124 observe2Greater1 observeIGreater1 + action 0 + 7600 : 0.8 + 7601 : 0.2 +state 7125 observe2Greater1 observeIGreater1 + action 0 + 7602 : 0.8 + 7603 : 0.2 +state 7126 observe2Greater1 observeIGreater1 + action 0 + 7604 : 0.8 + 7605 : 0.2 +state 7127 observe2Greater1 observeIGreater1 + action 0 + 7606 : 0.8 + 7607 : 0.2 +state 7128 observe2Greater1 observeIGreater1 + action 0 + 7608 : 1 +state 7129 observe2Greater1 observeIGreater1 + action 0 + 7609 : 0.8 + 7610 : 0.2 +state 7130 observe2Greater1 observeIGreater1 + action 0 + 7611 : 0.8 + 7612 : 0.2 +state 7131 observe2Greater1 observeIGreater1 + action 0 + 7613 : 0.8 + 7614 : 0.2 +state 7132 observe2Greater1 observeIGreater1 + action 0 + 7615 : 0.8 + 7616 : 0.2 +state 7133 observe2Greater1 observeIGreater1 + action 0 + 7617 : 0.8 + 7618 : 0.2 +state 7134 observe2Greater1 observeIGreater1 + action 0 + 7619 : 1 +state 7135 observe2Greater1 observeIGreater1 + action 0 + 7620 : 1 +state 7136 observe2Greater1 observeIGreater1 + action 0 + 7621 : 1 +state 7137 observe2Greater1 observeIGreater1 + action 0 + 7622 : 1 +state 7138 observe2Greater1 observeIGreater1 + action 0 + 7623 : 1 +state 7139 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7624 : 0.8 + 7625 : 0.2 +state 7140 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7626 : 0.8 + 7627 : 0.2 +state 7141 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7628 : 0.8 + 7629 : 0.2 +state 7142 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7630 : 0.8 + 7631 : 0.2 +state 7143 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7632 : 0.8 + 7633 : 0.2 +state 7144 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7634 : 1 +state 7145 observe2Greater1 observeIGreater1 + action 0 + 7635 : 0.8 + 7636 : 0.2 +state 7146 observe2Greater1 observeIGreater1 + action 0 + 7637 : 0.8 + 7638 : 0.2 +state 7147 observe2Greater1 observeIGreater1 + action 0 + 7639 : 0.8 + 7640 : 0.2 +state 7148 observe2Greater1 observeIGreater1 + action 0 + 7641 : 0.8 + 7642 : 0.2 +state 7149 observe2Greater1 observeIGreater1 + action 0 + 7643 : 0.8 + 7644 : 0.2 +state 7150 observe2Greater1 observeIGreater1 + action 0 + 7645 : 1 +state 7151 observe2Greater1 observeIGreater1 + action 0 + 7646 : 1 +state 7152 observe2Greater1 observeIGreater1 + action 0 + 7647 : 1 +state 7153 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7648 : 1 +state 7154 observe2Greater1 observeIGreater1 + action 0 + 7649 : 1 +state 7155 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7650 : 0.8 + 7651 : 0.2 +state 7156 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7652 : 0.8 + 7653 : 0.2 +state 7157 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7654 : 0.8 + 7655 : 0.2 +state 7158 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7656 : 0.8 + 7657 : 0.2 +state 7159 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7658 : 0.8 + 7659 : 0.2 +state 7160 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7660 : 1 +state 7161 observe2Greater1 observeIGreater1 + action 0 + 7661 : 1 +state 7162 observe2Greater1 observeIGreater1 + action 0 + 7662 : 1 +state 7163 observe2Greater1 observeIGreater1 + action 0 + 7663 : 1 +state 7164 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7664 : 1 +state 7165 observe3Greater1 observeIGreater1 + action 0 + 7665 : 0.8 + 7666 : 0.2 +state 7166 observe3Greater1 observeIGreater1 + action 0 + 7667 : 0.8 + 7668 : 0.2 +state 7167 observe3Greater1 observeIGreater1 + action 0 + 7669 : 0.8 + 7670 : 0.2 +state 7168 observe3Greater1 observeIGreater1 + action 0 + 7671 : 0.8 + 7672 : 0.2 +state 7169 observe3Greater1 observeIGreater1 + action 0 + 7673 : 0.8 + 7674 : 0.2 +state 7170 observe3Greater1 observeIGreater1 + action 0 + 7675 : 1 +state 7171 observe3Greater1 observeIGreater1 + action 0 + 7676 : 0.8 + 7677 : 0.2 +state 7172 observe3Greater1 observeIGreater1 + action 0 + 7678 : 0.8 + 7679 : 0.2 +state 7173 observe3Greater1 observeIGreater1 + action 0 + 7680 : 0.8 + 7681 : 0.2 +state 7174 observe3Greater1 observeIGreater1 + action 0 + 7682 : 0.8 + 7683 : 0.2 +state 7175 observe3Greater1 observeIGreater1 + action 0 + 7684 : 0.8 + 7685 : 0.2 +state 7176 observe3Greater1 observeIGreater1 + action 0 + 7686 : 1 +state 7177 observe3Greater1 observeIGreater1 + action 0 + 7687 : 1 +state 7178 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7688 : 1 +state 7179 observe3Greater1 observeIGreater1 + action 0 + 7689 : 1 +state 7180 observe3Greater1 observeIGreater1 + action 0 + 7690 : 1 +state 7181 observe4Greater1 observeIGreater1 + action 0 + 7691 : 0.8 + 7692 : 0.2 +state 7182 observe4Greater1 observeIGreater1 + action 0 + 7693 : 0.8 + 7694 : 0.2 +state 7183 observe4Greater1 observeIGreater1 + action 0 + 7695 : 0.8 + 7696 : 0.2 +state 7184 observe4Greater1 observeIGreater1 + action 0 + 7697 : 0.8 + 7698 : 0.2 +state 7185 observe4Greater1 observeIGreater1 + action 0 + 7699 : 0.8 + 7700 : 0.2 +state 7186 observe4Greater1 observeIGreater1 + action 0 + 7701 : 1 +state 7187 + action 0 + 7702 : 1 +state 7188 observe2Greater1 observeIGreater1 + action 0 + 7703 : 1 +state 7189 observe3Greater1 observeIGreater1 + action 0 + 7704 : 1 +state 7190 observe4Greater1 observeIGreater1 + action 0 + 7705 : 1 +state 7191 observe4Greater1 observeIGreater1 + action 0 + 7706 : 0.8 + 7707 : 0.2 +state 7192 observe4Greater1 observeIGreater1 + action 0 + 7708 : 0.8 + 7709 : 0.2 +state 7193 observe4Greater1 observeIGreater1 + action 0 + 7710 : 0.8 + 7711 : 0.2 +state 7194 observe4Greater1 observeIGreater1 + action 0 + 7712 : 0.8 + 7713 : 0.2 +state 7195 observe4Greater1 observeIGreater1 + action 0 + 7714 : 0.8 + 7715 : 0.2 +state 7196 observe4Greater1 observeIGreater1 + action 0 + 7716 : 1 +state 7197 observe4Greater1 observeIGreater1 + action 0 + 7717 : 1 +state 7198 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7718 : 1 +state 7199 observe4Greater1 observeIGreater1 + action 0 + 7719 : 1 +state 7200 observe4Greater1 observeIGreater1 + action 0 + 7720 : 1 +state 7201 observe3Greater1 observeIGreater1 + action 0 + 7721 : 0.8 + 7722 : 0.2 +state 7202 observe3Greater1 observeIGreater1 + action 0 + 7723 : 0.8 + 7724 : 0.2 +state 7203 observe3Greater1 observeIGreater1 + action 0 + 7725 : 0.8 + 7726 : 0.2 +state 7204 observe3Greater1 observeIGreater1 + action 0 + 7727 : 0.8 + 7728 : 0.2 +state 7205 observe3Greater1 observeIGreater1 + action 0 + 7729 : 0.8 + 7730 : 0.2 +state 7206 observe3Greater1 observeIGreater1 + action 0 + 7731 : 1 +state 7207 observe3Greater1 observeIGreater1 + action 0 + 7732 : 0.8 + 7733 : 0.2 +state 7208 observe3Greater1 observeIGreater1 + action 0 + 7734 : 0.8 + 7735 : 0.2 +state 7209 observe3Greater1 observeIGreater1 + action 0 + 7736 : 0.8 + 7737 : 0.2 +state 7210 observe3Greater1 observeIGreater1 + action 0 + 7738 : 0.8 + 7739 : 0.2 +state 7211 observe3Greater1 observeIGreater1 + action 0 + 7740 : 0.8 + 7741 : 0.2 +state 7212 observe3Greater1 observeIGreater1 + action 0 + 7742 : 1 +state 7213 observe3Greater1 observeIGreater1 + action 0 + 7743 : 1 +state 7214 observe3Greater1 observeIGreater1 + action 0 + 7744 : 1 +state 7215 observe3Greater1 observeIGreater1 + action 0 + 7745 : 1 +state 7216 observe3Greater1 observeIGreater1 + action 0 + 7746 : 1 +state 7217 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7747 : 0.8 + 7748 : 0.2 +state 7218 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7749 : 0.8 + 7750 : 0.2 +state 7219 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7751 : 0.8 + 7752 : 0.2 +state 7220 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7753 : 0.8 + 7754 : 0.2 +state 7221 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7755 : 0.8 + 7756 : 0.2 +state 7222 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7757 : 1 +state 7223 observe3Greater1 observeIGreater1 + action 0 + 7758 : 1 +state 7224 observe3Greater1 observeIGreater1 + action 0 + 7759 : 1 +state 7225 observe3Greater1 observeIGreater1 + action 0 + 7760 : 1 +state 7226 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7761 : 1 +state 7227 observe4Greater1 observeIGreater1 + action 0 + 7762 : 0.8 + 7763 : 0.2 +state 7228 observe4Greater1 observeIGreater1 + action 0 + 7764 : 0.8 + 7765 : 0.2 +state 7229 observe4Greater1 observeIGreater1 + action 0 + 7766 : 0.8 + 7767 : 0.2 +state 7230 observe4Greater1 observeIGreater1 + action 0 + 7768 : 0.8 + 7769 : 0.2 +state 7231 observe4Greater1 observeIGreater1 + action 0 + 7770 : 0.8 + 7771 : 0.2 +state 7232 observe4Greater1 observeIGreater1 + action 0 + 7772 : 1 +state 7233 observe4Greater1 observeIGreater1 + action 0 + 7773 : 1 +state 7234 observe4Greater1 observeIGreater1 + action 0 + 7774 : 1 +state 7235 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7775 : 1 +state 7236 observe4Greater1 observeIGreater1 + action 0 + 7776 : 1 +state 7237 observe4Greater1 observeIGreater1 + action 0 + 7777 : 0.8 + 7778 : 0.2 +state 7238 observe4Greater1 observeIGreater1 + action 0 + 7779 : 0.8 + 7780 : 0.2 +state 7239 observe4Greater1 observeIGreater1 + action 0 + 7781 : 0.8 + 7782 : 0.2 +state 7240 observe4Greater1 observeIGreater1 + action 0 + 7783 : 0.8 + 7784 : 0.2 +state 7241 observe4Greater1 observeIGreater1 + action 0 + 7785 : 0.8 + 7786 : 0.2 +state 7242 observe4Greater1 observeIGreater1 + action 0 + 7787 : 1 +state 7243 observe4Greater1 observeIGreater1 + action 0 + 7788 : 1 +state 7244 observe4Greater1 observeIGreater1 + action 0 + 7789 : 1 +state 7245 observe4Greater1 observeIGreater1 + action 0 + 7790 : 1 +state 7246 observe4Greater1 observeIGreater1 + action 0 + 7791 : 1 +state 7247 observe1Greater1 observeIGreater1 + action 0 + 7792 : 1 +state 7248 observe1Greater1 observeIGreater1 + action 0 + 7793 : 1 +state 7249 observe1Greater1 observeIGreater1 + action 0 + 7794 : 1 +state 7250 observe1Greater1 observeIGreater1 + action 0 + 7795 : 1 +state 7251 observe1Greater1 observeIGreater1 + action 0 + 7796 : 1 +state 7252 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7797 : 1 +state 7253 observe1Greater1 observeIGreater1 + action 0 + 7798 : 1 +state 7254 observe1Greater1 observeIGreater1 + action 0 + 7799 : 1 +state 7255 observe1Greater1 observeIGreater1 + action 0 + 7800 : 1 +state 7256 observe1Greater1 observeIGreater1 + action 0 + 7801 : 1 +state 7257 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7802 : 1 +state 7258 observe1Greater1 observeIGreater1 + action 0 + 7803 : 1 +state 7259 observe1Greater1 observeIGreater1 + action 0 + 7804 : 1 +state 7260 observe1Greater1 observeIGreater1 + action 0 + 7805 : 1 +state 7261 observe1Greater1 observeIGreater1 + action 0 + 7806 : 1 +state 7262 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7807 : 1 +state 7263 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7808 : 1 +state 7264 observe2Greater1 observeIGreater1 + action 0 + 7809 : 1 +state 7265 observe2Greater1 observeIGreater1 + action 0 + 7810 : 1 +state 7266 observe2Greater1 observeIGreater1 + action 0 + 7811 : 1 +state 7267 observe1Greater1 observeIGreater1 + action 0 + 7812 : 1 +state 7268 observe2Greater1 observeIGreater1 + action 0 + 7813 : 1 +state 7269 observe3Greater1 observeIGreater1 + action 0 + 7814 : 1 +state 7270 + action 0 + 7815 : 1 +state 7271 observe1Greater1 observeIGreater1 + action 0 + 7816 : 1 +state 7272 observe2Greater1 observeIGreater1 + action 0 + 7817 : 1 +state 7273 + action 0 + 7818 : 1 +state 7274 observe4Greater1 observeIGreater1 + action 0 + 7819 : 1 +state 7275 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7820 : 1 +state 7276 observe3Greater1 observeIGreater1 + action 0 + 7821 : 1 +state 7277 observe3Greater1 observeIGreater1 + action 0 + 7822 : 1 +state 7278 observe3Greater1 observeIGreater1 + action 0 + 7823 : 1 +state 7279 observe1Greater1 observeIGreater1 + action 0 + 7824 : 1 +state 7280 + action 0 + 7825 : 1 +state 7281 observe3Greater1 observeIGreater1 + action 0 + 7826 : 1 +state 7282 observe4Greater1 observeIGreater1 + action 0 + 7827 : 1 +state 7283 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7828 : 1 +state 7284 observe4Greater1 observeIGreater1 + action 0 + 7829 : 1 +state 7285 observe4Greater1 observeIGreater1 + action 0 + 7830 : 1 +state 7286 observe4Greater1 observeIGreater1 + action 0 + 7831 : 1 +state 7287 observe2Greater1 observeIGreater1 + action 0 + 7832 : 1 +state 7288 observe2Greater1 observeIGreater1 + action 0 + 7833 : 1 +state 7289 observe2Greater1 observeIGreater1 + action 0 + 7834 : 1 +state 7290 observe2Greater1 observeIGreater1 + action 0 + 7835 : 1 +state 7291 observe2Greater1 observeIGreater1 + action 0 + 7836 : 1 +state 7292 observe2Greater1 observeIGreater1 + action 0 + 7837 : 1 +state 7293 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7838 : 1 +state 7294 observe2Greater1 observeIGreater1 + action 0 + 7839 : 1 +state 7295 observe2Greater1 observeIGreater1 + action 0 + 7840 : 1 +state 7296 observe2Greater1 observeIGreater1 + action 0 + 7841 : 1 +state 7297 observe2Greater1 observeIGreater1 + action 0 + 7842 : 1 +state 7298 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7843 : 1 +state 7299 observe3Greater1 observeIGreater1 + action 0 + 7844 : 1 +state 7300 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7845 : 1 +state 7301 observe3Greater1 observeIGreater1 + action 0 + 7846 : 1 +state 7302 observe3Greater1 observeIGreater1 + action 0 + 7847 : 1 +state 7303 + action 0 + 7848 : 1 +state 7304 observe2Greater1 observeIGreater1 + action 0 + 7849 : 1 +state 7305 observe3Greater1 observeIGreater1 + action 0 + 7850 : 1 +state 7306 observe4Greater1 observeIGreater1 + action 0 + 7851 : 1 +state 7307 observe4Greater1 observeIGreater1 + action 0 + 7852 : 1 +state 7308 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7853 : 1 +state 7309 observe4Greater1 observeIGreater1 + action 0 + 7854 : 1 +state 7310 observe4Greater1 observeIGreater1 + action 0 + 7855 : 1 +state 7311 observe3Greater1 observeIGreater1 + action 0 + 7856 : 1 +state 7312 observe3Greater1 observeIGreater1 + action 0 + 7857 : 1 +state 7313 observe3Greater1 observeIGreater1 + action 0 + 7858 : 1 +state 7314 observe3Greater1 observeIGreater1 + action 0 + 7859 : 1 +state 7315 observe3Greater1 observeIGreater1 + action 0 + 7860 : 1 +state 7316 observe3Greater1 observeIGreater1 + action 0 + 7861 : 1 +state 7317 observe3Greater1 observeIGreater1 + action 0 + 7862 : 1 +state 7318 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7863 : 1 +state 7319 observe4Greater1 observeIGreater1 + action 0 + 7864 : 1 +state 7320 observe4Greater1 observeIGreater1 + action 0 + 7865 : 1 +state 7321 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7866 : 1 +state 7322 observe4Greater1 observeIGreater1 + action 0 + 7867 : 1 +state 7323 observe4Greater1 observeIGreater1 + action 0 + 7868 : 1 +state 7324 observe4Greater1 observeIGreater1 + action 0 + 7869 : 1 +state 7325 observe4Greater1 observeIGreater1 + action 0 + 7870 : 1 +state 7326 observe4Greater1 observeIGreater1 + action 0 + 7871 : 1 +state 7327 observe1Greater1 observeIGreater1 + action 0 + 6327 : 0.833 + 6328 : 0.167 +state 7328 observe1Greater1 observeIGreater1 + action 0 + 7872 : 1 +state 7329 observe1Greater1 observeIGreater1 + action 0 + 7873 : 0.833 + 7874 : 0.167 +state 7330 observe1Greater1 observeIGreater1 + action 0 + 7875 : 1 +state 7331 observe1Greater1 observeIGreater1 + action 0 + 7876 : 0.833 + 7877 : 0.167 +state 7332 observe1Greater1 observeIGreater1 + action 0 + 7878 : 1 +state 7333 observe1Greater1 observeIGreater1 + action 0 + 7879 : 0.833 + 7880 : 0.167 +state 7334 observe1Greater1 observeIGreater1 + action 0 + 7881 : 1 +state 7335 observe1Greater1 observeIGreater1 + action 0 + 7882 : 0.833 + 7883 : 0.167 +state 7336 observe1Greater1 observeIGreater1 + action 0 + 7884 : 1 +state 7337 deadlock observe1Greater1 observeIGreater1 + action 0 + 7337 : 1 +state 7338 observe1Greater1 observeIGreater1 + action 0 + 6329 : 0.833 + 6330 : 0.167 +state 7339 observe1Greater1 observeIGreater1 + action 0 + 7885 : 1 +state 7340 observe1Greater1 observeIGreater1 + action 0 + 7886 : 0.833 + 7887 : 0.167 +state 7341 observe1Greater1 observeIGreater1 + action 0 + 7888 : 1 +state 7342 observe1Greater1 observeIGreater1 + action 0 + 7889 : 0.833 + 7890 : 0.167 +state 7343 observe1Greater1 observeIGreater1 + action 0 + 7891 : 1 +state 7344 observe1Greater1 observeIGreater1 + action 0 + 7892 : 0.833 + 7893 : 0.167 +state 7345 observe1Greater1 observeIGreater1 + action 0 + 7894 : 1 +state 7346 observe1Greater1 observeIGreater1 + action 0 + 7895 : 0.833 + 7896 : 0.167 +state 7347 observe1Greater1 observeIGreater1 + action 0 + 7897 : 1 +state 7348 deadlock observe1Greater1 observeIGreater1 + action 0 + 7348 : 1 +state 7349 observe1Greater1 observeIGreater1 + action 0 + 6331 : 0.833 + 6332 : 0.167 +state 7350 observe1Greater1 observeIGreater1 + action 0 + 7898 : 1 +state 7351 observe1Greater1 observeIGreater1 + action 0 + 7899 : 0.833 + 7900 : 0.167 +state 7352 observe1Greater1 observeIGreater1 + action 0 + 7901 : 1 +state 7353 observe1Greater1 observeIGreater1 + action 0 + 7902 : 0.833 + 7903 : 0.167 +state 7354 observe1Greater1 observeIGreater1 + action 0 + 7904 : 1 +state 7355 observe1Greater1 observeIGreater1 + action 0 + 7905 : 0.833 + 7906 : 0.167 +state 7356 observe1Greater1 observeIGreater1 + action 0 + 7907 : 1 +state 7357 observe1Greater1 observeIGreater1 + action 0 + 7908 : 0.833 + 7909 : 0.167 +state 7358 observe1Greater1 observeIGreater1 + action 0 + 7910 : 1 +state 7359 deadlock observe1Greater1 observeIGreater1 + action 0 + 7359 : 1 +state 7360 observe1Greater1 observeIGreater1 + action 0 + 6333 : 0.833 + 6334 : 0.167 +state 7361 observe1Greater1 observeIGreater1 + action 0 + 7911 : 1 +state 7362 observe1Greater1 observeIGreater1 + action 0 + 7912 : 0.833 + 7913 : 0.167 +state 7363 observe1Greater1 observeIGreater1 + action 0 + 7914 : 1 +state 7364 observe1Greater1 observeIGreater1 + action 0 + 7915 : 0.833 + 7916 : 0.167 +state 7365 observe1Greater1 observeIGreater1 + action 0 + 7917 : 1 +state 7366 observe1Greater1 observeIGreater1 + action 0 + 7918 : 0.833 + 7919 : 0.167 +state 7367 observe1Greater1 observeIGreater1 + action 0 + 7920 : 1 +state 7368 observe1Greater1 observeIGreater1 + action 0 + 7921 : 0.833 + 7922 : 0.167 +state 7369 observe1Greater1 observeIGreater1 + action 0 + 7923 : 1 +state 7370 deadlock observe1Greater1 observeIGreater1 + action 0 + 7370 : 1 +state 7371 deadlock observe1Greater1 observeIGreater1 + action 0 + 7371 : 1 +state 7372 deadlock observe1Greater1 observeIGreater1 + action 0 + 7372 : 1 +state 7373 deadlock observe1Greater1 observeIGreater1 + action 0 + 7373 : 1 +state 7374 deadlock observe1Greater1 observeIGreater1 + action 0 + 7374 : 1 +state 7375 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6348 : 0.833 + 6349 : 0.167 +state 7376 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7924 : 1 +state 7377 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7925 : 0.833 + 7926 : 0.167 +state 7378 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7927 : 1 +state 7379 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7928 : 0.833 + 7929 : 0.167 +state 7380 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7930 : 1 +state 7381 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7931 : 0.833 + 7932 : 0.167 +state 7382 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7933 : 1 +state 7383 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7934 : 0.833 + 7935 : 0.167 +state 7384 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7936 : 1 +state 7385 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7385 : 1 +state 7386 observe1Greater1 observeIGreater1 + action 0 + 6350 : 0.833 + 6351 : 0.167 +state 7387 observe1Greater1 observeIGreater1 + action 0 + 7937 : 1 +state 7388 observe1Greater1 observeIGreater1 + action 0 + 7938 : 0.833 + 7939 : 0.167 +state 7389 observe1Greater1 observeIGreater1 + action 0 + 7940 : 1 +state 7390 observe1Greater1 observeIGreater1 + action 0 + 7941 : 0.833 + 7942 : 0.167 +state 7391 observe1Greater1 observeIGreater1 + action 0 + 7943 : 1 +state 7392 observe1Greater1 observeIGreater1 + action 0 + 7944 : 0.833 + 7945 : 0.167 +state 7393 observe1Greater1 observeIGreater1 + action 0 + 7946 : 1 +state 7394 observe1Greater1 observeIGreater1 + action 0 + 7947 : 0.833 + 7948 : 0.167 +state 7395 observe1Greater1 observeIGreater1 + action 0 + 7949 : 1 +state 7396 deadlock observe1Greater1 observeIGreater1 + action 0 + 7396 : 1 +state 7397 observe1Greater1 observeIGreater1 + action 0 + 6352 : 0.833 + 6353 : 0.167 +state 7398 observe1Greater1 observeIGreater1 + action 0 + 7950 : 1 +state 7399 observe1Greater1 observeIGreater1 + action 0 + 7951 : 0.833 + 7952 : 0.167 +state 7400 observe1Greater1 observeIGreater1 + action 0 + 7953 : 1 +state 7401 observe1Greater1 observeIGreater1 + action 0 + 7954 : 0.833 + 7955 : 0.167 +state 7402 observe1Greater1 observeIGreater1 + action 0 + 7956 : 1 +state 7403 observe1Greater1 observeIGreater1 + action 0 + 7957 : 0.833 + 7958 : 0.167 +state 7404 observe1Greater1 observeIGreater1 + action 0 + 7959 : 1 +state 7405 observe1Greater1 observeIGreater1 + action 0 + 7960 : 0.833 + 7961 : 0.167 +state 7406 observe1Greater1 observeIGreater1 + action 0 + 7962 : 1 +state 7407 deadlock observe1Greater1 observeIGreater1 + action 0 + 7407 : 1 +state 7408 deadlock observe1Greater1 observeIGreater1 + action 0 + 7408 : 1 +state 7409 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7409 : 1 +state 7410 deadlock observe1Greater1 observeIGreater1 + action 0 + 7410 : 1 +state 7411 deadlock observe1Greater1 observeIGreater1 + action 0 + 7411 : 1 +state 7412 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 6367 : 0.833 + 6368 : 0.167 +state 7413 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7963 : 1 +state 7414 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7964 : 0.833 + 7965 : 0.167 +state 7415 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7966 : 1 +state 7416 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7967 : 0.833 + 7968 : 0.167 +state 7417 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7969 : 1 +state 7418 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7970 : 0.833 + 7971 : 0.167 +state 7419 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7972 : 1 +state 7420 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7973 : 0.833 + 7974 : 0.167 +state 7421 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7975 : 1 +state 7422 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7422 : 1 +state 7423 observe1Greater1 observeIGreater1 + action 0 + 6369 : 0.833 + 6370 : 0.167 +state 7424 observe1Greater1 observeIGreater1 + action 0 + 7976 : 1 +state 7425 observe1Greater1 observeIGreater1 + action 0 + 7977 : 0.833 + 7978 : 0.167 +state 7426 observe1Greater1 observeIGreater1 + action 0 + 7979 : 1 +state 7427 observe1Greater1 observeIGreater1 + action 0 + 7980 : 0.833 + 7981 : 0.167 +state 7428 observe1Greater1 observeIGreater1 + action 0 + 7982 : 1 +state 7429 observe1Greater1 observeIGreater1 + action 0 + 7983 : 0.833 + 7984 : 0.167 +state 7430 observe1Greater1 observeIGreater1 + action 0 + 7985 : 1 +state 7431 observe1Greater1 observeIGreater1 + action 0 + 7986 : 0.833 + 7987 : 0.167 +state 7432 observe1Greater1 observeIGreater1 + action 0 + 7988 : 1 +state 7433 deadlock observe1Greater1 observeIGreater1 + action 0 + 7433 : 1 +state 7434 deadlock observe1Greater1 observeIGreater1 + action 0 + 7434 : 1 +state 7435 deadlock observe1Greater1 observeIGreater1 + action 0 + 7435 : 1 +state 7436 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7436 : 1 +state 7437 deadlock observe1Greater1 observeIGreater1 + action 0 + 7437 : 1 +state 7438 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 6384 : 0.833 + 6385 : 0.167 +state 7439 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7989 : 1 +state 7440 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7990 : 0.833 + 7991 : 0.167 +state 7441 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7992 : 1 +state 7442 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7993 : 0.833 + 7994 : 0.167 +state 7443 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7995 : 1 +state 7444 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7996 : 0.833 + 7997 : 0.167 +state 7445 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7998 : 1 +state 7446 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7999 : 0.833 + 8000 : 0.167 +state 7447 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8001 : 1 +state 7448 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7448 : 1 +state 7449 deadlock observe1Greater1 observeIGreater1 + action 0 + 7449 : 1 +state 7450 deadlock observe1Greater1 observeIGreater1 + action 0 + 7450 : 1 +state 7451 deadlock observe1Greater1 observeIGreater1 + action 0 + 7451 : 1 +state 7452 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7452 : 1 +state 7453 observe2Greater1 observeIGreater1 + action 0 + 6399 : 0.833 + 6400 : 0.167 +state 7454 observe2Greater1 observeIGreater1 + action 0 + 8002 : 1 +state 7455 observe2Greater1 observeIGreater1 + action 0 + 8003 : 0.833 + 8004 : 0.167 +state 7456 observe2Greater1 observeIGreater1 + action 0 + 8005 : 1 +state 7457 observe2Greater1 observeIGreater1 + action 0 + 8006 : 0.833 + 8007 : 0.167 +state 7458 observe2Greater1 observeIGreater1 + action 0 + 8008 : 1 +state 7459 observe2Greater1 observeIGreater1 + action 0 + 8009 : 0.833 + 8010 : 0.167 +state 7460 observe2Greater1 observeIGreater1 + action 0 + 8011 : 1 +state 7461 observe2Greater1 observeIGreater1 + action 0 + 8012 : 0.833 + 8013 : 0.167 +state 7462 observe2Greater1 observeIGreater1 + action 0 + 8014 : 1 +state 7463 deadlock observe2Greater1 observeIGreater1 + action 0 + 7463 : 1 +state 7464 observe2Greater1 observeIGreater1 + action 0 + 6401 : 0.833 + 6402 : 0.167 +state 7465 observe2Greater1 observeIGreater1 + action 0 + 8015 : 1 +state 7466 observe2Greater1 observeIGreater1 + action 0 + 8016 : 0.833 + 8017 : 0.167 +state 7467 observe2Greater1 observeIGreater1 + action 0 + 8018 : 1 +state 7468 observe2Greater1 observeIGreater1 + action 0 + 8019 : 0.833 + 8020 : 0.167 +state 7469 observe2Greater1 observeIGreater1 + action 0 + 8021 : 1 +state 7470 observe2Greater1 observeIGreater1 + action 0 + 8022 : 0.833 + 8023 : 0.167 +state 7471 observe2Greater1 observeIGreater1 + action 0 + 8024 : 1 +state 7472 observe2Greater1 observeIGreater1 + action 0 + 8025 : 0.833 + 8026 : 0.167 +state 7473 observe2Greater1 observeIGreater1 + action 0 + 8027 : 1 +state 7474 deadlock observe2Greater1 observeIGreater1 + action 0 + 7474 : 1 +state 7475 observe2Greater1 observeIGreater1 + action 0 + 6403 : 0.833 + 6404 : 0.167 +state 7476 observe2Greater1 observeIGreater1 + action 0 + 8028 : 1 +state 7477 observe2Greater1 observeIGreater1 + action 0 + 8029 : 0.833 + 8030 : 0.167 +state 7478 observe2Greater1 observeIGreater1 + action 0 + 8031 : 1 +state 7479 observe2Greater1 observeIGreater1 + action 0 + 8032 : 0.833 + 8033 : 0.167 +state 7480 observe2Greater1 observeIGreater1 + action 0 + 8034 : 1 +state 7481 observe2Greater1 observeIGreater1 + action 0 + 8035 : 0.833 + 8036 : 0.167 +state 7482 observe2Greater1 observeIGreater1 + action 0 + 8037 : 1 +state 7483 observe2Greater1 observeIGreater1 + action 0 + 8038 : 0.833 + 8039 : 0.167 +state 7484 observe2Greater1 observeIGreater1 + action 0 + 8040 : 1 +state 7485 deadlock observe2Greater1 observeIGreater1 + action 0 + 7485 : 1 +state 7486 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7486 : 1 +state 7487 deadlock observe2Greater1 observeIGreater1 + action 0 + 7487 : 1 +state 7488 deadlock observe2Greater1 observeIGreater1 + action 0 + 7488 : 1 +state 7489 deadlock observe2Greater1 observeIGreater1 + action 0 + 7489 : 1 +state 7490 observe3Greater1 observeIGreater1 + action 0 + 6418 : 0.833 + 6419 : 0.167 +state 7491 observe3Greater1 observeIGreater1 + action 0 + 8041 : 1 +state 7492 observe3Greater1 observeIGreater1 + action 0 + 8042 : 0.833 + 8043 : 0.167 +state 7493 observe3Greater1 observeIGreater1 + action 0 + 8044 : 1 +state 7494 observe3Greater1 observeIGreater1 + action 0 + 8045 : 0.833 + 8046 : 0.167 +state 7495 observe3Greater1 observeIGreater1 + action 0 + 8047 : 1 +state 7496 observe3Greater1 observeIGreater1 + action 0 + 8048 : 0.833 + 8049 : 0.167 +state 7497 observe3Greater1 observeIGreater1 + action 0 + 8050 : 1 +state 7498 observe3Greater1 observeIGreater1 + action 0 + 8051 : 0.833 + 8052 : 0.167 +state 7499 observe3Greater1 observeIGreater1 + action 0 + 8053 : 1 +state 7500 deadlock observe3Greater1 observeIGreater1 + action 0 + 7500 : 1 +state 7501 + action 0 + 6420 : 0.833 + 6421 : 0.167 +state 7502 + action 0 + 8054 : 1 +state 7503 + action 0 + 8055 : 0.833 + 8056 : 0.167 +state 7504 + action 0 + 8057 : 1 +state 7505 + action 0 + 8058 : 0.833 + 8059 : 0.167 +state 7506 + action 0 + 8060 : 1 +state 7507 + action 0 + 8061 : 0.833 + 8062 : 0.167 +state 7508 + action 0 + 8063 : 1 +state 7509 + action 0 + 8064 : 0.833 + 8065 : 0.167 +state 7510 + action 0 + 8066 : 1 +state 7511 deadlock + action 0 + 7511 : 1 +state 7512 deadlock observe1Greater1 observeIGreater1 + action 0 + 7512 : 1 +state 7513 deadlock observe2Greater1 observeIGreater1 + action 0 + 7513 : 1 +state 7514 deadlock observe3Greater1 observeIGreater1 + action 0 + 7514 : 1 +state 7515 deadlock + action 0 + 7515 : 1 +state 7516 observe4Greater1 observeIGreater1 + action 0 + 6435 : 0.833 + 6436 : 0.167 +state 7517 observe4Greater1 observeIGreater1 + action 0 + 8067 : 1 +state 7518 observe4Greater1 observeIGreater1 + action 0 + 8068 : 0.833 + 8069 : 0.167 +state 7519 observe4Greater1 observeIGreater1 + action 0 + 8070 : 1 +state 7520 observe4Greater1 observeIGreater1 + action 0 + 8071 : 0.833 + 8072 : 0.167 +state 7521 observe4Greater1 observeIGreater1 + action 0 + 8073 : 1 +state 7522 observe4Greater1 observeIGreater1 + action 0 + 8074 : 0.833 + 8075 : 0.167 +state 7523 observe4Greater1 observeIGreater1 + action 0 + 8076 : 1 +state 7524 observe4Greater1 observeIGreater1 + action 0 + 8077 : 0.833 + 8078 : 0.167 +state 7525 observe4Greater1 observeIGreater1 + action 0 + 8079 : 1 +state 7526 deadlock observe4Greater1 observeIGreater1 + action 0 + 7526 : 1 +state 7527 deadlock observe1Greater1 observeIGreater1 + action 0 + 7527 : 1 +state 7528 deadlock observe2Greater1 observeIGreater1 + action 0 + 7528 : 1 +state 7529 deadlock + action 0 + 7529 : 1 +state 7530 deadlock observe4Greater1 observeIGreater1 + action 0 + 7530 : 1 +state 7531 observe3Greater1 observeIGreater1 + action 0 + 6450 : 0.833 + 6451 : 0.167 +state 7532 observe3Greater1 observeIGreater1 + action 0 + 8080 : 1 +state 7533 observe3Greater1 observeIGreater1 + action 0 + 8081 : 0.833 + 8082 : 0.167 +state 7534 observe3Greater1 observeIGreater1 + action 0 + 8083 : 1 +state 7535 observe3Greater1 observeIGreater1 + action 0 + 8084 : 0.833 + 8085 : 0.167 +state 7536 observe3Greater1 observeIGreater1 + action 0 + 8086 : 1 +state 7537 observe3Greater1 observeIGreater1 + action 0 + 8087 : 0.833 + 8088 : 0.167 +state 7538 observe3Greater1 observeIGreater1 + action 0 + 8089 : 1 +state 7539 observe3Greater1 observeIGreater1 + action 0 + 8090 : 0.833 + 8091 : 0.167 +state 7540 observe3Greater1 observeIGreater1 + action 0 + 8092 : 1 +state 7541 deadlock observe3Greater1 observeIGreater1 + action 0 + 7541 : 1 +state 7542 observe3Greater1 observeIGreater1 + action 0 + 6452 : 0.833 + 6453 : 0.167 +state 7543 observe3Greater1 observeIGreater1 + action 0 + 8093 : 1 +state 7544 observe3Greater1 observeIGreater1 + action 0 + 8094 : 0.833 + 8095 : 0.167 +state 7545 observe3Greater1 observeIGreater1 + action 0 + 8096 : 1 +state 7546 observe3Greater1 observeIGreater1 + action 0 + 8097 : 0.833 + 8098 : 0.167 +state 7547 observe3Greater1 observeIGreater1 + action 0 + 8099 : 1 +state 7548 observe3Greater1 observeIGreater1 + action 0 + 8100 : 0.833 + 8101 : 0.167 +state 7549 observe3Greater1 observeIGreater1 + action 0 + 8102 : 1 +state 7550 observe3Greater1 observeIGreater1 + action 0 + 8103 : 0.833 + 8104 : 0.167 +state 7551 observe3Greater1 observeIGreater1 + action 0 + 8105 : 1 +state 7552 deadlock observe3Greater1 observeIGreater1 + action 0 + 7552 : 1 +state 7553 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7553 : 1 +state 7554 deadlock observe3Greater1 observeIGreater1 + action 0 + 7554 : 1 +state 7555 deadlock observe3Greater1 observeIGreater1 + action 0 + 7555 : 1 +state 7556 deadlock observe3Greater1 observeIGreater1 + action 0 + 7556 : 1 +state 7557 observe4Greater1 observeIGreater1 + action 0 + 6467 : 0.833 + 6468 : 0.167 +state 7558 observe4Greater1 observeIGreater1 + action 0 + 8106 : 1 +state 7559 observe4Greater1 observeIGreater1 + action 0 + 8107 : 0.833 + 8108 : 0.167 +state 7560 observe4Greater1 observeIGreater1 + action 0 + 8109 : 1 +state 7561 observe4Greater1 observeIGreater1 + action 0 + 8110 : 0.833 + 8111 : 0.167 +state 7562 observe4Greater1 observeIGreater1 + action 0 + 8112 : 1 +state 7563 observe4Greater1 observeIGreater1 + action 0 + 8113 : 0.833 + 8114 : 0.167 +state 7564 observe4Greater1 observeIGreater1 + action 0 + 8115 : 1 +state 7565 observe4Greater1 observeIGreater1 + action 0 + 8116 : 0.833 + 8117 : 0.167 +state 7566 observe4Greater1 observeIGreater1 + action 0 + 8118 : 1 +state 7567 deadlock observe4Greater1 observeIGreater1 + action 0 + 7567 : 1 +state 7568 deadlock observe1Greater1 observeIGreater1 + action 0 + 7568 : 1 +state 7569 deadlock + action 0 + 7569 : 1 +state 7570 deadlock observe3Greater1 observeIGreater1 + action 0 + 7570 : 1 +state 7571 deadlock observe4Greater1 observeIGreater1 + action 0 + 7571 : 1 +state 7572 observe4Greater1 observeIGreater1 + action 0 + 6482 : 0.833 + 6483 : 0.167 +state 7573 observe4Greater1 observeIGreater1 + action 0 + 8119 : 1 +state 7574 observe4Greater1 observeIGreater1 + action 0 + 8120 : 0.833 + 8121 : 0.167 +state 7575 observe4Greater1 observeIGreater1 + action 0 + 8122 : 1 +state 7576 observe4Greater1 observeIGreater1 + action 0 + 8123 : 0.833 + 8124 : 0.167 +state 7577 observe4Greater1 observeIGreater1 + action 0 + 8125 : 1 +state 7578 observe4Greater1 observeIGreater1 + action 0 + 8126 : 0.833 + 8127 : 0.167 +state 7579 observe4Greater1 observeIGreater1 + action 0 + 8128 : 1 +state 7580 observe4Greater1 observeIGreater1 + action 0 + 8129 : 0.833 + 8130 : 0.167 +state 7581 observe4Greater1 observeIGreater1 + action 0 + 8131 : 1 +state 7582 deadlock observe4Greater1 observeIGreater1 + action 0 + 7582 : 1 +state 7583 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7583 : 1 +state 7584 deadlock observe4Greater1 observeIGreater1 + action 0 + 7584 : 1 +state 7585 deadlock observe4Greater1 observeIGreater1 + action 0 + 7585 : 1 +state 7586 deadlock observe4Greater1 observeIGreater1 + action 0 + 7586 : 1 +state 7587 observe2Greater1 observeIGreater1 + action 0 + 6497 : 0.833 + 6498 : 0.167 +state 7588 observe2Greater1 observeIGreater1 + action 0 + 8132 : 1 +state 7589 observe2Greater1 observeIGreater1 + action 0 + 8133 : 0.833 + 8134 : 0.167 +state 7590 observe2Greater1 observeIGreater1 + action 0 + 8135 : 1 +state 7591 observe2Greater1 observeIGreater1 + action 0 + 8136 : 0.833 + 8137 : 0.167 +state 7592 observe2Greater1 observeIGreater1 + action 0 + 8138 : 1 +state 7593 observe2Greater1 observeIGreater1 + action 0 + 8139 : 0.833 + 8140 : 0.167 +state 7594 observe2Greater1 observeIGreater1 + action 0 + 8141 : 1 +state 7595 observe2Greater1 observeIGreater1 + action 0 + 8142 : 0.833 + 8143 : 0.167 +state 7596 observe2Greater1 observeIGreater1 + action 0 + 8144 : 1 +state 7597 deadlock observe2Greater1 observeIGreater1 + action 0 + 7597 : 1 +state 7598 observe2Greater1 observeIGreater1 + action 0 + 6499 : 0.833 + 6500 : 0.167 +state 7599 observe2Greater1 observeIGreater1 + action 0 + 8145 : 1 +state 7600 observe2Greater1 observeIGreater1 + action 0 + 8146 : 0.833 + 8147 : 0.167 +state 7601 observe2Greater1 observeIGreater1 + action 0 + 8148 : 1 +state 7602 observe2Greater1 observeIGreater1 + action 0 + 8149 : 0.833 + 8150 : 0.167 +state 7603 observe2Greater1 observeIGreater1 + action 0 + 8151 : 1 +state 7604 observe2Greater1 observeIGreater1 + action 0 + 8152 : 0.833 + 8153 : 0.167 +state 7605 observe2Greater1 observeIGreater1 + action 0 + 8154 : 1 +state 7606 observe2Greater1 observeIGreater1 + action 0 + 8155 : 0.833 + 8156 : 0.167 +state 7607 observe2Greater1 observeIGreater1 + action 0 + 8157 : 1 +state 7608 deadlock observe2Greater1 observeIGreater1 + action 0 + 7608 : 1 +state 7609 observe2Greater1 observeIGreater1 + action 0 + 6501 : 0.833 + 6502 : 0.167 +state 7610 observe2Greater1 observeIGreater1 + action 0 + 8158 : 1 +state 7611 observe2Greater1 observeIGreater1 + action 0 + 8159 : 0.833 + 8160 : 0.167 +state 7612 observe2Greater1 observeIGreater1 + action 0 + 8161 : 1 +state 7613 observe2Greater1 observeIGreater1 + action 0 + 8162 : 0.833 + 8163 : 0.167 +state 7614 observe2Greater1 observeIGreater1 + action 0 + 8164 : 1 +state 7615 observe2Greater1 observeIGreater1 + action 0 + 8165 : 0.833 + 8166 : 0.167 +state 7616 observe2Greater1 observeIGreater1 + action 0 + 8167 : 1 +state 7617 observe2Greater1 observeIGreater1 + action 0 + 8168 : 0.833 + 8169 : 0.167 +state 7618 observe2Greater1 observeIGreater1 + action 0 + 8170 : 1 +state 7619 deadlock observe2Greater1 observeIGreater1 + action 0 + 7619 : 1 +state 7620 deadlock observe2Greater1 observeIGreater1 + action 0 + 7620 : 1 +state 7621 deadlock observe2Greater1 observeIGreater1 + action 0 + 7621 : 1 +state 7622 deadlock observe2Greater1 observeIGreater1 + action 0 + 7622 : 1 +state 7623 deadlock observe2Greater1 observeIGreater1 + action 0 + 7623 : 1 +state 7624 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 6516 : 0.833 + 6517 : 0.167 +state 7625 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8171 : 1 +state 7626 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8172 : 0.833 + 8173 : 0.167 +state 7627 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8174 : 1 +state 7628 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8175 : 0.833 + 8176 : 0.167 +state 7629 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8177 : 1 +state 7630 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8178 : 0.833 + 8179 : 0.167 +state 7631 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8180 : 1 +state 7632 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8181 : 0.833 + 8182 : 0.167 +state 7633 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8183 : 1 +state 7634 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7634 : 1 +state 7635 observe2Greater1 observeIGreater1 + action 0 + 6518 : 0.833 + 6519 : 0.167 +state 7636 observe2Greater1 observeIGreater1 + action 0 + 8184 : 1 +state 7637 observe2Greater1 observeIGreater1 + action 0 + 8185 : 0.833 + 8186 : 0.167 +state 7638 observe2Greater1 observeIGreater1 + action 0 + 8187 : 1 +state 7639 observe2Greater1 observeIGreater1 + action 0 + 8188 : 0.833 + 8189 : 0.167 +state 7640 observe2Greater1 observeIGreater1 + action 0 + 8190 : 1 +state 7641 observe2Greater1 observeIGreater1 + action 0 + 8191 : 0.833 + 8192 : 0.167 +state 7642 observe2Greater1 observeIGreater1 + action 0 + 8193 : 1 +state 7643 observe2Greater1 observeIGreater1 + action 0 + 8194 : 0.833 + 8195 : 0.167 +state 7644 observe2Greater1 observeIGreater1 + action 0 + 8196 : 1 +state 7645 deadlock observe2Greater1 observeIGreater1 + action 0 + 7645 : 1 +state 7646 deadlock observe2Greater1 observeIGreater1 + action 0 + 7646 : 1 +state 7647 deadlock observe2Greater1 observeIGreater1 + action 0 + 7647 : 1 +state 7648 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7648 : 1 +state 7649 deadlock observe2Greater1 observeIGreater1 + action 0 + 7649 : 1 +state 7650 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 6533 : 0.833 + 6534 : 0.167 +state 7651 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8197 : 1 +state 7652 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8198 : 0.833 + 8199 : 0.167 +state 7653 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8200 : 1 +state 7654 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8201 : 0.833 + 8202 : 0.167 +state 7655 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8203 : 1 +state 7656 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8204 : 0.833 + 8205 : 0.167 +state 7657 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8206 : 1 +state 7658 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8207 : 0.833 + 8208 : 0.167 +state 7659 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8209 : 1 +state 7660 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7660 : 1 +state 7661 deadlock observe2Greater1 observeIGreater1 + action 0 + 7661 : 1 +state 7662 deadlock observe2Greater1 observeIGreater1 + action 0 + 7662 : 1 +state 7663 deadlock observe2Greater1 observeIGreater1 + action 0 + 7663 : 1 +state 7664 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7664 : 1 +state 7665 observe3Greater1 observeIGreater1 + action 0 + 6548 : 0.833 + 6549 : 0.167 +state 7666 observe3Greater1 observeIGreater1 + action 0 + 8210 : 1 +state 7667 observe3Greater1 observeIGreater1 + action 0 + 8211 : 0.833 + 8212 : 0.167 +state 7668 observe3Greater1 observeIGreater1 + action 0 + 8213 : 1 +state 7669 observe3Greater1 observeIGreater1 + action 0 + 8214 : 0.833 + 8215 : 0.167 +state 7670 observe3Greater1 observeIGreater1 + action 0 + 8216 : 1 +state 7671 observe3Greater1 observeIGreater1 + action 0 + 8217 : 0.833 + 8218 : 0.167 +state 7672 observe3Greater1 observeIGreater1 + action 0 + 8219 : 1 +state 7673 observe3Greater1 observeIGreater1 + action 0 + 8220 : 0.833 + 8221 : 0.167 +state 7674 observe3Greater1 observeIGreater1 + action 0 + 8222 : 1 +state 7675 deadlock observe3Greater1 observeIGreater1 + action 0 + 7675 : 1 +state 7676 observe3Greater1 observeIGreater1 + action 0 + 6550 : 0.833 + 6551 : 0.167 +state 7677 observe3Greater1 observeIGreater1 + action 0 + 8223 : 1 +state 7678 observe3Greater1 observeIGreater1 + action 0 + 8224 : 0.833 + 8225 : 0.167 +state 7679 observe3Greater1 observeIGreater1 + action 0 + 8226 : 1 +state 7680 observe3Greater1 observeIGreater1 + action 0 + 8227 : 0.833 + 8228 : 0.167 +state 7681 observe3Greater1 observeIGreater1 + action 0 + 8229 : 1 +state 7682 observe3Greater1 observeIGreater1 + action 0 + 8230 : 0.833 + 8231 : 0.167 +state 7683 observe3Greater1 observeIGreater1 + action 0 + 8232 : 1 +state 7684 observe3Greater1 observeIGreater1 + action 0 + 8233 : 0.833 + 8234 : 0.167 +state 7685 observe3Greater1 observeIGreater1 + action 0 + 8235 : 1 +state 7686 deadlock observe3Greater1 observeIGreater1 + action 0 + 7686 : 1 +state 7687 deadlock observe3Greater1 observeIGreater1 + action 0 + 7687 : 1 +state 7688 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7688 : 1 +state 7689 deadlock observe3Greater1 observeIGreater1 + action 0 + 7689 : 1 +state 7690 deadlock observe3Greater1 observeIGreater1 + action 0 + 7690 : 1 +state 7691 observe4Greater1 observeIGreater1 + action 0 + 6565 : 0.833 + 6566 : 0.167 +state 7692 observe4Greater1 observeIGreater1 + action 0 + 8236 : 1 +state 7693 observe4Greater1 observeIGreater1 + action 0 + 8237 : 0.833 + 8238 : 0.167 +state 7694 observe4Greater1 observeIGreater1 + action 0 + 8239 : 1 +state 7695 observe4Greater1 observeIGreater1 + action 0 + 8240 : 0.833 + 8241 : 0.167 +state 7696 observe4Greater1 observeIGreater1 + action 0 + 8242 : 1 +state 7697 observe4Greater1 observeIGreater1 + action 0 + 8243 : 0.833 + 8244 : 0.167 +state 7698 observe4Greater1 observeIGreater1 + action 0 + 8245 : 1 +state 7699 observe4Greater1 observeIGreater1 + action 0 + 8246 : 0.833 + 8247 : 0.167 +state 7700 observe4Greater1 observeIGreater1 + action 0 + 8248 : 1 +state 7701 deadlock observe4Greater1 observeIGreater1 + action 0 + 7701 : 1 +state 7702 deadlock + action 0 + 7702 : 1 +state 7703 deadlock observe2Greater1 observeIGreater1 + action 0 + 7703 : 1 +state 7704 deadlock observe3Greater1 observeIGreater1 + action 0 + 7704 : 1 +state 7705 deadlock observe4Greater1 observeIGreater1 + action 0 + 7705 : 1 +state 7706 observe4Greater1 observeIGreater1 + action 0 + 6580 : 0.833 + 6581 : 0.167 +state 7707 observe4Greater1 observeIGreater1 + action 0 + 8249 : 1 +state 7708 observe4Greater1 observeIGreater1 + action 0 + 8250 : 0.833 + 8251 : 0.167 +state 7709 observe4Greater1 observeIGreater1 + action 0 + 8252 : 1 +state 7710 observe4Greater1 observeIGreater1 + action 0 + 8253 : 0.833 + 8254 : 0.167 +state 7711 observe4Greater1 observeIGreater1 + action 0 + 8255 : 1 +state 7712 observe4Greater1 observeIGreater1 + action 0 + 8256 : 0.833 + 8257 : 0.167 +state 7713 observe4Greater1 observeIGreater1 + action 0 + 8258 : 1 +state 7714 observe4Greater1 observeIGreater1 + action 0 + 8259 : 0.833 + 8260 : 0.167 +state 7715 observe4Greater1 observeIGreater1 + action 0 + 8261 : 1 +state 7716 deadlock observe4Greater1 observeIGreater1 + action 0 + 7716 : 1 +state 7717 deadlock observe4Greater1 observeIGreater1 + action 0 + 7717 : 1 +state 7718 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7718 : 1 +state 7719 deadlock observe4Greater1 observeIGreater1 + action 0 + 7719 : 1 +state 7720 deadlock observe4Greater1 observeIGreater1 + action 0 + 7720 : 1 +state 7721 observe3Greater1 observeIGreater1 + action 0 + 6595 : 0.833 + 6596 : 0.167 +state 7722 observe3Greater1 observeIGreater1 + action 0 + 8262 : 1 +state 7723 observe3Greater1 observeIGreater1 + action 0 + 8263 : 0.833 + 8264 : 0.167 +state 7724 observe3Greater1 observeIGreater1 + action 0 + 8265 : 1 +state 7725 observe3Greater1 observeIGreater1 + action 0 + 8266 : 0.833 + 8267 : 0.167 +state 7726 observe3Greater1 observeIGreater1 + action 0 + 8268 : 1 +state 7727 observe3Greater1 observeIGreater1 + action 0 + 8269 : 0.833 + 8270 : 0.167 +state 7728 observe3Greater1 observeIGreater1 + action 0 + 8271 : 1 +state 7729 observe3Greater1 observeIGreater1 + action 0 + 8272 : 0.833 + 8273 : 0.167 +state 7730 observe3Greater1 observeIGreater1 + action 0 + 8274 : 1 +state 7731 deadlock observe3Greater1 observeIGreater1 + action 0 + 7731 : 1 +state 7732 observe3Greater1 observeIGreater1 + action 0 + 6597 : 0.833 + 6598 : 0.167 +state 7733 observe3Greater1 observeIGreater1 + action 0 + 8275 : 1 +state 7734 observe3Greater1 observeIGreater1 + action 0 + 8276 : 0.833 + 8277 : 0.167 +state 7735 observe3Greater1 observeIGreater1 + action 0 + 8278 : 1 +state 7736 observe3Greater1 observeIGreater1 + action 0 + 8279 : 0.833 + 8280 : 0.167 +state 7737 observe3Greater1 observeIGreater1 + action 0 + 8281 : 1 +state 7738 observe3Greater1 observeIGreater1 + action 0 + 8282 : 0.833 + 8283 : 0.167 +state 7739 observe3Greater1 observeIGreater1 + action 0 + 8284 : 1 +state 7740 observe3Greater1 observeIGreater1 + action 0 + 8285 : 0.833 + 8286 : 0.167 +state 7741 observe3Greater1 observeIGreater1 + action 0 + 8287 : 1 +state 7742 deadlock observe3Greater1 observeIGreater1 + action 0 + 7742 : 1 +state 7743 deadlock observe3Greater1 observeIGreater1 + action 0 + 7743 : 1 +state 7744 deadlock observe3Greater1 observeIGreater1 + action 0 + 7744 : 1 +state 7745 deadlock observe3Greater1 observeIGreater1 + action 0 + 7745 : 1 +state 7746 deadlock observe3Greater1 observeIGreater1 + action 0 + 7746 : 1 +state 7747 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 6612 : 0.833 + 6613 : 0.167 +state 7748 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8288 : 1 +state 7749 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8289 : 0.833 + 8290 : 0.167 +state 7750 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8291 : 1 +state 7751 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8292 : 0.833 + 8293 : 0.167 +state 7752 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8294 : 1 +state 7753 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8295 : 0.833 + 8296 : 0.167 +state 7754 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8297 : 1 +state 7755 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8298 : 0.833 + 8299 : 0.167 +state 7756 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8300 : 1 +state 7757 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7757 : 1 +state 7758 deadlock observe3Greater1 observeIGreater1 + action 0 + 7758 : 1 +state 7759 deadlock observe3Greater1 observeIGreater1 + action 0 + 7759 : 1 +state 7760 deadlock observe3Greater1 observeIGreater1 + action 0 + 7760 : 1 +state 7761 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7761 : 1 +state 7762 observe4Greater1 observeIGreater1 + action 0 + 6627 : 0.833 + 6628 : 0.167 +state 7763 observe4Greater1 observeIGreater1 + action 0 + 8301 : 1 +state 7764 observe4Greater1 observeIGreater1 + action 0 + 8302 : 0.833 + 8303 : 0.167 +state 7765 observe4Greater1 observeIGreater1 + action 0 + 8304 : 1 +state 7766 observe4Greater1 observeIGreater1 + action 0 + 8305 : 0.833 + 8306 : 0.167 +state 7767 observe4Greater1 observeIGreater1 + action 0 + 8307 : 1 +state 7768 observe4Greater1 observeIGreater1 + action 0 + 8308 : 0.833 + 8309 : 0.167 +state 7769 observe4Greater1 observeIGreater1 + action 0 + 8310 : 1 +state 7770 observe4Greater1 observeIGreater1 + action 0 + 8311 : 0.833 + 8312 : 0.167 +state 7771 observe4Greater1 observeIGreater1 + action 0 + 8313 : 1 +state 7772 deadlock observe4Greater1 observeIGreater1 + action 0 + 7772 : 1 +state 7773 deadlock observe4Greater1 observeIGreater1 + action 0 + 7773 : 1 +state 7774 deadlock observe4Greater1 observeIGreater1 + action 0 + 7774 : 1 +state 7775 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7775 : 1 +state 7776 deadlock observe4Greater1 observeIGreater1 + action 0 + 7776 : 1 +state 7777 observe4Greater1 observeIGreater1 + action 0 + 6642 : 0.833 + 6643 : 0.167 +state 7778 observe4Greater1 observeIGreater1 + action 0 + 8314 : 1 +state 7779 observe4Greater1 observeIGreater1 + action 0 + 8315 : 0.833 + 8316 : 0.167 +state 7780 observe4Greater1 observeIGreater1 + action 0 + 8317 : 1 +state 7781 observe4Greater1 observeIGreater1 + action 0 + 8318 : 0.833 + 8319 : 0.167 +state 7782 observe4Greater1 observeIGreater1 + action 0 + 8320 : 1 +state 7783 observe4Greater1 observeIGreater1 + action 0 + 8321 : 0.833 + 8322 : 0.167 +state 7784 observe4Greater1 observeIGreater1 + action 0 + 8323 : 1 +state 7785 observe4Greater1 observeIGreater1 + action 0 + 8324 : 0.833 + 8325 : 0.167 +state 7786 observe4Greater1 observeIGreater1 + action 0 + 8326 : 1 +state 7787 deadlock observe4Greater1 observeIGreater1 + action 0 + 7787 : 1 +state 7788 deadlock observe4Greater1 observeIGreater1 + action 0 + 7788 : 1 +state 7789 deadlock observe4Greater1 observeIGreater1 + action 0 + 7789 : 1 +state 7790 deadlock observe4Greater1 observeIGreater1 + action 0 + 7790 : 1 +state 7791 deadlock observe4Greater1 observeIGreater1 + action 0 + 7791 : 1 +state 7792 deadlock observe1Greater1 observeIGreater1 + action 0 + 7792 : 1 +state 7793 deadlock observe1Greater1 observeIGreater1 + action 0 + 7793 : 1 +state 7794 deadlock observe1Greater1 observeIGreater1 + action 0 + 7794 : 1 +state 7795 deadlock observe1Greater1 observeIGreater1 + action 0 + 7795 : 1 +state 7796 deadlock observe1Greater1 observeIGreater1 + action 0 + 7796 : 1 +state 7797 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7797 : 1 +state 7798 deadlock observe1Greater1 observeIGreater1 + action 0 + 7798 : 1 +state 7799 deadlock observe1Greater1 observeIGreater1 + action 0 + 7799 : 1 +state 7800 deadlock observe1Greater1 observeIGreater1 + action 0 + 7800 : 1 +state 7801 deadlock observe1Greater1 observeIGreater1 + action 0 + 7801 : 1 +state 7802 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7802 : 1 +state 7803 deadlock observe1Greater1 observeIGreater1 + action 0 + 7803 : 1 +state 7804 deadlock observe1Greater1 observeIGreater1 + action 0 + 7804 : 1 +state 7805 deadlock observe1Greater1 observeIGreater1 + action 0 + 7805 : 1 +state 7806 deadlock observe1Greater1 observeIGreater1 + action 0 + 7806 : 1 +state 7807 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7807 : 1 +state 7808 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7808 : 1 +state 7809 deadlock observe2Greater1 observeIGreater1 + action 0 + 7809 : 1 +state 7810 deadlock observe2Greater1 observeIGreater1 + action 0 + 7810 : 1 +state 7811 deadlock observe2Greater1 observeIGreater1 + action 0 + 7811 : 1 +state 7812 deadlock observe1Greater1 observeIGreater1 + action 0 + 7812 : 1 +state 7813 deadlock observe2Greater1 observeIGreater1 + action 0 + 7813 : 1 +state 7814 deadlock observe3Greater1 observeIGreater1 + action 0 + 7814 : 1 +state 7815 deadlock + action 0 + 7815 : 1 +state 7816 deadlock observe1Greater1 observeIGreater1 + action 0 + 7816 : 1 +state 7817 deadlock observe2Greater1 observeIGreater1 + action 0 + 7817 : 1 +state 7818 deadlock + action 0 + 7818 : 1 +state 7819 deadlock observe4Greater1 observeIGreater1 + action 0 + 7819 : 1 +state 7820 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7820 : 1 +state 7821 deadlock observe3Greater1 observeIGreater1 + action 0 + 7821 : 1 +state 7822 deadlock observe3Greater1 observeIGreater1 + action 0 + 7822 : 1 +state 7823 deadlock observe3Greater1 observeIGreater1 + action 0 + 7823 : 1 +state 7824 deadlock observe1Greater1 observeIGreater1 + action 0 + 7824 : 1 +state 7825 deadlock + action 0 + 7825 : 1 +state 7826 deadlock observe3Greater1 observeIGreater1 + action 0 + 7826 : 1 +state 7827 deadlock observe4Greater1 observeIGreater1 + action 0 + 7827 : 1 +state 7828 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7828 : 1 +state 7829 deadlock observe4Greater1 observeIGreater1 + action 0 + 7829 : 1 +state 7830 deadlock observe4Greater1 observeIGreater1 + action 0 + 7830 : 1 +state 7831 deadlock observe4Greater1 observeIGreater1 + action 0 + 7831 : 1 +state 7832 deadlock observe2Greater1 observeIGreater1 + action 0 + 7832 : 1 +state 7833 deadlock observe2Greater1 observeIGreater1 + action 0 + 7833 : 1 +state 7834 deadlock observe2Greater1 observeIGreater1 + action 0 + 7834 : 1 +state 7835 deadlock observe2Greater1 observeIGreater1 + action 0 + 7835 : 1 +state 7836 deadlock observe2Greater1 observeIGreater1 + action 0 + 7836 : 1 +state 7837 deadlock observe2Greater1 observeIGreater1 + action 0 + 7837 : 1 +state 7838 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7838 : 1 +state 7839 deadlock observe2Greater1 observeIGreater1 + action 0 + 7839 : 1 +state 7840 deadlock observe2Greater1 observeIGreater1 + action 0 + 7840 : 1 +state 7841 deadlock observe2Greater1 observeIGreater1 + action 0 + 7841 : 1 +state 7842 deadlock observe2Greater1 observeIGreater1 + action 0 + 7842 : 1 +state 7843 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7843 : 1 +state 7844 deadlock observe3Greater1 observeIGreater1 + action 0 + 7844 : 1 +state 7845 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7845 : 1 +state 7846 deadlock observe3Greater1 observeIGreater1 + action 0 + 7846 : 1 +state 7847 deadlock observe3Greater1 observeIGreater1 + action 0 + 7847 : 1 +state 7848 deadlock + action 0 + 7848 : 1 +state 7849 deadlock observe2Greater1 observeIGreater1 + action 0 + 7849 : 1 +state 7850 deadlock observe3Greater1 observeIGreater1 + action 0 + 7850 : 1 +state 7851 deadlock observe4Greater1 observeIGreater1 + action 0 + 7851 : 1 +state 7852 deadlock observe4Greater1 observeIGreater1 + action 0 + 7852 : 1 +state 7853 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7853 : 1 +state 7854 deadlock observe4Greater1 observeIGreater1 + action 0 + 7854 : 1 +state 7855 deadlock observe4Greater1 observeIGreater1 + action 0 + 7855 : 1 +state 7856 deadlock observe3Greater1 observeIGreater1 + action 0 + 7856 : 1 +state 7857 deadlock observe3Greater1 observeIGreater1 + action 0 + 7857 : 1 +state 7858 deadlock observe3Greater1 observeIGreater1 + action 0 + 7858 : 1 +state 7859 deadlock observe3Greater1 observeIGreater1 + action 0 + 7859 : 1 +state 7860 deadlock observe3Greater1 observeIGreater1 + action 0 + 7860 : 1 +state 7861 deadlock observe3Greater1 observeIGreater1 + action 0 + 7861 : 1 +state 7862 deadlock observe3Greater1 observeIGreater1 + action 0 + 7862 : 1 +state 7863 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7863 : 1 +state 7864 deadlock observe4Greater1 observeIGreater1 + action 0 + 7864 : 1 +state 7865 deadlock observe4Greater1 observeIGreater1 + action 0 + 7865 : 1 +state 7866 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7866 : 1 +state 7867 deadlock observe4Greater1 observeIGreater1 + action 0 + 7867 : 1 +state 7868 deadlock observe4Greater1 observeIGreater1 + action 0 + 7868 : 1 +state 7869 deadlock observe4Greater1 observeIGreater1 + action 0 + 7869 : 1 +state 7870 deadlock observe4Greater1 observeIGreater1 + action 0 + 7870 : 1 +state 7871 deadlock observe4Greater1 observeIGreater1 + action 0 + 7871 : 1 +state 7872 deadlock observe1Greater1 observeIGreater1 + action 0 + 7872 : 1 +state 7873 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7874 observe1Greater1 observeIGreater1 + action 0 + 8327 : 1 +state 7875 deadlock observe1Greater1 observeIGreater1 + action 0 + 7875 : 1 +state 7876 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7877 observe1Greater1 observeIGreater1 + action 0 + 8328 : 1 +state 7878 deadlock observe1Greater1 observeIGreater1 + action 0 + 7878 : 1 +state 7879 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7880 observe1Greater1 observeIGreater1 + action 0 + 8329 : 1 +state 7881 deadlock observe1Greater1 observeIGreater1 + action 0 + 7881 : 1 +state 7882 observe1Greater1 observeIGreater1 + action 0 + 6957 : 0.2 + 6958 : 0.2 + 6959 : 0.2 + 6960 : 0.2 + 6961 : 0.2 +state 7883 observe1Greater1 observeIGreater1 + action 0 + 8330 : 1 +state 7884 deadlock observe1Greater1 observeIGreater1 + action 0 + 7884 : 1 +state 7885 deadlock observe1Greater1 observeIGreater1 + action 0 + 7885 : 1 +state 7886 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7887 observe1Greater1 observeIGreater1 + action 0 + 8331 : 1 +state 7888 deadlock observe1Greater1 observeIGreater1 + action 0 + 7888 : 1 +state 7889 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7890 observe1Greater1 observeIGreater1 + action 0 + 8332 : 1 +state 7891 deadlock observe1Greater1 observeIGreater1 + action 0 + 7891 : 1 +state 7892 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7893 observe1Greater1 observeIGreater1 + action 0 + 8333 : 1 +state 7894 deadlock observe1Greater1 observeIGreater1 + action 0 + 7894 : 1 +state 7895 observe1Greater1 observeIGreater1 + action 0 + 6963 : 0.2 + 6964 : 0.2 + 6965 : 0.2 + 6966 : 0.2 + 6967 : 0.2 +state 7896 observe1Greater1 observeIGreater1 + action 0 + 8334 : 1 +state 7897 deadlock observe1Greater1 observeIGreater1 + action 0 + 7897 : 1 +state 7898 deadlock observe1Greater1 observeIGreater1 + action 0 + 7898 : 1 +state 7899 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7900 observe1Greater1 observeIGreater1 + action 0 + 8335 : 1 +state 7901 deadlock observe1Greater1 observeIGreater1 + action 0 + 7901 : 1 +state 7902 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7903 observe1Greater1 observeIGreater1 + action 0 + 8336 : 1 +state 7904 deadlock observe1Greater1 observeIGreater1 + action 0 + 7904 : 1 +state 7905 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7906 observe1Greater1 observeIGreater1 + action 0 + 8337 : 1 +state 7907 deadlock observe1Greater1 observeIGreater1 + action 0 + 7907 : 1 +state 7908 observe1Greater1 observeIGreater1 + action 0 + 6969 : 0.2 + 6970 : 0.2 + 6971 : 0.2 + 6972 : 0.2 + 6973 : 0.2 +state 7909 observe1Greater1 observeIGreater1 + action 0 + 8338 : 1 +state 7910 deadlock observe1Greater1 observeIGreater1 + action 0 + 7910 : 1 +state 7911 deadlock observe1Greater1 observeIGreater1 + action 0 + 7911 : 1 +state 7912 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7913 observe1Greater1 observeIGreater1 + action 0 + 8339 : 1 +state 7914 deadlock observe1Greater1 observeIGreater1 + action 0 + 7914 : 1 +state 7915 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7916 observe1Greater1 observeIGreater1 + action 0 + 8340 : 1 +state 7917 deadlock observe1Greater1 observeIGreater1 + action 0 + 7917 : 1 +state 7918 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7919 observe1Greater1 observeIGreater1 + action 0 + 8341 : 1 +state 7920 deadlock observe1Greater1 observeIGreater1 + action 0 + 7920 : 1 +state 7921 observe1Greater1 observeIGreater1 + action 0 + 6975 : 0.2 + 6976 : 0.2 + 6977 : 0.2 + 6978 : 0.2 + 6979 : 0.2 +state 7922 observe1Greater1 observeIGreater1 + action 0 + 8342 : 1 +state 7923 deadlock observe1Greater1 observeIGreater1 + action 0 + 7923 : 1 +state 7924 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7924 : 1 +state 7925 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7926 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8343 : 1 +state 7927 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7927 : 1 +state 7928 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7929 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8344 : 1 +state 7930 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7930 : 1 +state 7931 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7932 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8345 : 1 +state 7933 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7933 : 1 +state 7934 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 6985 : 0.2 + 6986 : 0.2 + 6987 : 0.2 + 6988 : 0.2 + 6989 : 0.2 +state 7935 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8346 : 1 +state 7936 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 7936 : 1 +state 7937 deadlock observe1Greater1 observeIGreater1 + action 0 + 7937 : 1 +state 7938 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7939 observe1Greater1 observeIGreater1 + action 0 + 8347 : 1 +state 7940 deadlock observe1Greater1 observeIGreater1 + action 0 + 7940 : 1 +state 7941 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7942 observe1Greater1 observeIGreater1 + action 0 + 8348 : 1 +state 7943 deadlock observe1Greater1 observeIGreater1 + action 0 + 7943 : 1 +state 7944 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7945 observe1Greater1 observeIGreater1 + action 0 + 8349 : 1 +state 7946 deadlock observe1Greater1 observeIGreater1 + action 0 + 7946 : 1 +state 7947 observe1Greater1 observeIGreater1 + action 0 + 6991 : 0.2 + 6992 : 0.2 + 6993 : 0.2 + 6994 : 0.2 + 6995 : 0.2 +state 7948 observe1Greater1 observeIGreater1 + action 0 + 8350 : 1 +state 7949 deadlock observe1Greater1 observeIGreater1 + action 0 + 7949 : 1 +state 7950 deadlock observe1Greater1 observeIGreater1 + action 0 + 7950 : 1 +state 7951 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7952 observe1Greater1 observeIGreater1 + action 0 + 8351 : 1 +state 7953 deadlock observe1Greater1 observeIGreater1 + action 0 + 7953 : 1 +state 7954 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7955 observe1Greater1 observeIGreater1 + action 0 + 8352 : 1 +state 7956 deadlock observe1Greater1 observeIGreater1 + action 0 + 7956 : 1 +state 7957 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7958 observe1Greater1 observeIGreater1 + action 0 + 8353 : 1 +state 7959 deadlock observe1Greater1 observeIGreater1 + action 0 + 7959 : 1 +state 7960 observe1Greater1 observeIGreater1 + action 0 + 6997 : 0.2 + 6998 : 0.2 + 6999 : 0.2 + 7000 : 0.2 + 7001 : 0.2 +state 7961 observe1Greater1 observeIGreater1 + action 0 + 8354 : 1 +state 7962 deadlock observe1Greater1 observeIGreater1 + action 0 + 7962 : 1 +state 7963 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7963 : 1 +state 7964 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7965 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8355 : 1 +state 7966 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7966 : 1 +state 7967 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7968 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8356 : 1 +state 7969 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7969 : 1 +state 7970 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7971 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8357 : 1 +state 7972 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7972 : 1 +state 7973 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7007 : 0.2 + 7008 : 0.2 + 7009 : 0.2 + 7010 : 0.2 + 7011 : 0.2 +state 7974 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8358 : 1 +state 7975 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 7975 : 1 +state 7976 deadlock observe1Greater1 observeIGreater1 + action 0 + 7976 : 1 +state 7977 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7978 observe1Greater1 observeIGreater1 + action 0 + 8359 : 1 +state 7979 deadlock observe1Greater1 observeIGreater1 + action 0 + 7979 : 1 +state 7980 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7981 observe1Greater1 observeIGreater1 + action 0 + 8360 : 1 +state 7982 deadlock observe1Greater1 observeIGreater1 + action 0 + 7982 : 1 +state 7983 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7984 observe1Greater1 observeIGreater1 + action 0 + 8361 : 1 +state 7985 deadlock observe1Greater1 observeIGreater1 + action 0 + 7985 : 1 +state 7986 observe1Greater1 observeIGreater1 + action 0 + 7013 : 0.2 + 7014 : 0.2 + 7015 : 0.2 + 7016 : 0.2 + 7017 : 0.2 +state 7987 observe1Greater1 observeIGreater1 + action 0 + 8362 : 1 +state 7988 deadlock observe1Greater1 observeIGreater1 + action 0 + 7988 : 1 +state 7989 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7989 : 1 +state 7990 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7991 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8363 : 1 +state 7992 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7992 : 1 +state 7993 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7994 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8364 : 1 +state 7995 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7995 : 1 +state 7996 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 7997 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8365 : 1 +state 7998 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7998 : 1 +state 7999 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 7023 : 0.2 + 7024 : 0.2 + 7025 : 0.2 + 7026 : 0.2 + 7027 : 0.2 +state 8000 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8366 : 1 +state 8001 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8001 : 1 +state 8002 deadlock observe2Greater1 observeIGreater1 + action 0 + 8002 : 1 +state 8003 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8004 observe2Greater1 observeIGreater1 + action 0 + 8367 : 1 +state 8005 deadlock observe2Greater1 observeIGreater1 + action 0 + 8005 : 1 +state 8006 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8007 observe2Greater1 observeIGreater1 + action 0 + 8368 : 1 +state 8008 deadlock observe2Greater1 observeIGreater1 + action 0 + 8008 : 1 +state 8009 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8010 observe2Greater1 observeIGreater1 + action 0 + 8369 : 1 +state 8011 deadlock observe2Greater1 observeIGreater1 + action 0 + 8011 : 1 +state 8012 observe2Greater1 observeIGreater1 + action 0 + 7033 : 0.2 + 7034 : 0.2 + 7035 : 0.2 + 7036 : 0.2 + 7037 : 0.2 +state 8013 observe2Greater1 observeIGreater1 + action 0 + 8370 : 1 +state 8014 deadlock observe2Greater1 observeIGreater1 + action 0 + 8014 : 1 +state 8015 deadlock observe2Greater1 observeIGreater1 + action 0 + 8015 : 1 +state 8016 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8017 observe2Greater1 observeIGreater1 + action 0 + 8371 : 1 +state 8018 deadlock observe2Greater1 observeIGreater1 + action 0 + 8018 : 1 +state 8019 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8020 observe2Greater1 observeIGreater1 + action 0 + 8372 : 1 +state 8021 deadlock observe2Greater1 observeIGreater1 + action 0 + 8021 : 1 +state 8022 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8023 observe2Greater1 observeIGreater1 + action 0 + 8373 : 1 +state 8024 deadlock observe2Greater1 observeIGreater1 + action 0 + 8024 : 1 +state 8025 observe2Greater1 observeIGreater1 + action 0 + 7039 : 0.2 + 7040 : 0.2 + 7041 : 0.2 + 7042 : 0.2 + 7043 : 0.2 +state 8026 observe2Greater1 observeIGreater1 + action 0 + 8374 : 1 +state 8027 deadlock observe2Greater1 observeIGreater1 + action 0 + 8027 : 1 +state 8028 deadlock observe2Greater1 observeIGreater1 + action 0 + 8028 : 1 +state 8029 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8030 observe2Greater1 observeIGreater1 + action 0 + 8375 : 1 +state 8031 deadlock observe2Greater1 observeIGreater1 + action 0 + 8031 : 1 +state 8032 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8033 observe2Greater1 observeIGreater1 + action 0 + 8376 : 1 +state 8034 deadlock observe2Greater1 observeIGreater1 + action 0 + 8034 : 1 +state 8035 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8036 observe2Greater1 observeIGreater1 + action 0 + 8377 : 1 +state 8037 deadlock observe2Greater1 observeIGreater1 + action 0 + 8037 : 1 +state 8038 observe2Greater1 observeIGreater1 + action 0 + 7045 : 0.2 + 7046 : 0.2 + 7047 : 0.2 + 7048 : 0.2 + 7049 : 0.2 +state 8039 observe2Greater1 observeIGreater1 + action 0 + 8378 : 1 +state 8040 deadlock observe2Greater1 observeIGreater1 + action 0 + 8040 : 1 +state 8041 deadlock observe3Greater1 observeIGreater1 + action 0 + 8041 : 1 +state 8042 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8043 observe3Greater1 observeIGreater1 + action 0 + 8379 : 1 +state 8044 deadlock observe3Greater1 observeIGreater1 + action 0 + 8044 : 1 +state 8045 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8046 observe3Greater1 observeIGreater1 + action 0 + 8380 : 1 +state 8047 deadlock observe3Greater1 observeIGreater1 + action 0 + 8047 : 1 +state 8048 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8049 observe3Greater1 observeIGreater1 + action 0 + 8381 : 1 +state 8050 deadlock observe3Greater1 observeIGreater1 + action 0 + 8050 : 1 +state 8051 observe3Greater1 observeIGreater1 + action 0 + 7055 : 0.2 + 7056 : 0.2 + 7057 : 0.2 + 7058 : 0.2 + 7059 : 0.2 +state 8052 observe3Greater1 observeIGreater1 + action 0 + 8382 : 1 +state 8053 deadlock observe3Greater1 observeIGreater1 + action 0 + 8053 : 1 +state 8054 deadlock + action 0 + 8054 : 1 +state 8055 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8056 + action 0 + 8383 : 1 +state 8057 deadlock + action 0 + 8057 : 1 +state 8058 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8059 + action 0 + 8384 : 1 +state 8060 deadlock + action 0 + 8060 : 1 +state 8061 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8062 + action 0 + 8385 : 1 +state 8063 deadlock + action 0 + 8063 : 1 +state 8064 + action 0 + 7061 : 0.2 + 7062 : 0.2 + 7063 : 0.2 + 7064 : 0.2 + 7065 : 0.2 +state 8065 + action 0 + 8386 : 1 +state 8066 deadlock + action 0 + 8066 : 1 +state 8067 deadlock observe4Greater1 observeIGreater1 + action 0 + 8067 : 1 +state 8068 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8069 observe4Greater1 observeIGreater1 + action 0 + 8387 : 1 +state 8070 deadlock observe4Greater1 observeIGreater1 + action 0 + 8070 : 1 +state 8071 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8072 observe4Greater1 observeIGreater1 + action 0 + 8388 : 1 +state 8073 deadlock observe4Greater1 observeIGreater1 + action 0 + 8073 : 1 +state 8074 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8075 observe4Greater1 observeIGreater1 + action 0 + 8389 : 1 +state 8076 deadlock observe4Greater1 observeIGreater1 + action 0 + 8076 : 1 +state 8077 observe4Greater1 observeIGreater1 + action 0 + 7071 : 0.2 + 7072 : 0.2 + 7073 : 0.2 + 7074 : 0.2 + 7075 : 0.2 +state 8078 observe4Greater1 observeIGreater1 + action 0 + 8390 : 1 +state 8079 deadlock observe4Greater1 observeIGreater1 + action 0 + 8079 : 1 +state 8080 deadlock observe3Greater1 observeIGreater1 + action 0 + 8080 : 1 +state 8081 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8082 observe3Greater1 observeIGreater1 + action 0 + 8391 : 1 +state 8083 deadlock observe3Greater1 observeIGreater1 + action 0 + 8083 : 1 +state 8084 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8085 observe3Greater1 observeIGreater1 + action 0 + 8392 : 1 +state 8086 deadlock observe3Greater1 observeIGreater1 + action 0 + 8086 : 1 +state 8087 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8088 observe3Greater1 observeIGreater1 + action 0 + 8393 : 1 +state 8089 deadlock observe3Greater1 observeIGreater1 + action 0 + 8089 : 1 +state 8090 observe3Greater1 observeIGreater1 + action 0 + 7081 : 0.2 + 7082 : 0.2 + 7083 : 0.2 + 7084 : 0.2 + 7085 : 0.2 +state 8091 observe3Greater1 observeIGreater1 + action 0 + 8394 : 1 +state 8092 deadlock observe3Greater1 observeIGreater1 + action 0 + 8092 : 1 +state 8093 deadlock observe3Greater1 observeIGreater1 + action 0 + 8093 : 1 +state 8094 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8095 observe3Greater1 observeIGreater1 + action 0 + 8395 : 1 +state 8096 deadlock observe3Greater1 observeIGreater1 + action 0 + 8096 : 1 +state 8097 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8098 observe3Greater1 observeIGreater1 + action 0 + 8396 : 1 +state 8099 deadlock observe3Greater1 observeIGreater1 + action 0 + 8099 : 1 +state 8100 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8101 observe3Greater1 observeIGreater1 + action 0 + 8397 : 1 +state 8102 deadlock observe3Greater1 observeIGreater1 + action 0 + 8102 : 1 +state 8103 observe3Greater1 observeIGreater1 + action 0 + 7087 : 0.2 + 7088 : 0.2 + 7089 : 0.2 + 7090 : 0.2 + 7091 : 0.2 +state 8104 observe3Greater1 observeIGreater1 + action 0 + 8398 : 1 +state 8105 deadlock observe3Greater1 observeIGreater1 + action 0 + 8105 : 1 +state 8106 deadlock observe4Greater1 observeIGreater1 + action 0 + 8106 : 1 +state 8107 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8108 observe4Greater1 observeIGreater1 + action 0 + 8399 : 1 +state 8109 deadlock observe4Greater1 observeIGreater1 + action 0 + 8109 : 1 +state 8110 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8111 observe4Greater1 observeIGreater1 + action 0 + 8400 : 1 +state 8112 deadlock observe4Greater1 observeIGreater1 + action 0 + 8112 : 1 +state 8113 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8114 observe4Greater1 observeIGreater1 + action 0 + 8401 : 1 +state 8115 deadlock observe4Greater1 observeIGreater1 + action 0 + 8115 : 1 +state 8116 observe4Greater1 observeIGreater1 + action 0 + 7097 : 0.2 + 7098 : 0.2 + 7099 : 0.2 + 7100 : 0.2 + 7101 : 0.2 +state 8117 observe4Greater1 observeIGreater1 + action 0 + 8402 : 1 +state 8118 deadlock observe4Greater1 observeIGreater1 + action 0 + 8118 : 1 +state 8119 deadlock observe4Greater1 observeIGreater1 + action 0 + 8119 : 1 +state 8120 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8121 observe4Greater1 observeIGreater1 + action 0 + 8403 : 1 +state 8122 deadlock observe4Greater1 observeIGreater1 + action 0 + 8122 : 1 +state 8123 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8124 observe4Greater1 observeIGreater1 + action 0 + 8404 : 1 +state 8125 deadlock observe4Greater1 observeIGreater1 + action 0 + 8125 : 1 +state 8126 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8127 observe4Greater1 observeIGreater1 + action 0 + 8405 : 1 +state 8128 deadlock observe4Greater1 observeIGreater1 + action 0 + 8128 : 1 +state 8129 observe4Greater1 observeIGreater1 + action 0 + 7107 : 0.2 + 7108 : 0.2 + 7109 : 0.2 + 7110 : 0.2 + 7111 : 0.2 +state 8130 observe4Greater1 observeIGreater1 + action 0 + 8406 : 1 +state 8131 deadlock observe4Greater1 observeIGreater1 + action 0 + 8131 : 1 +state 8132 deadlock observe2Greater1 observeIGreater1 + action 0 + 8132 : 1 +state 8133 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8134 observe2Greater1 observeIGreater1 + action 0 + 8407 : 1 +state 8135 deadlock observe2Greater1 observeIGreater1 + action 0 + 8135 : 1 +state 8136 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8137 observe2Greater1 observeIGreater1 + action 0 + 8408 : 1 +state 8138 deadlock observe2Greater1 observeIGreater1 + action 0 + 8138 : 1 +state 8139 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8140 observe2Greater1 observeIGreater1 + action 0 + 8409 : 1 +state 8141 deadlock observe2Greater1 observeIGreater1 + action 0 + 8141 : 1 +state 8142 observe2Greater1 observeIGreater1 + action 0 + 7117 : 0.2 + 7118 : 0.2 + 7119 : 0.2 + 7120 : 0.2 + 7121 : 0.2 +state 8143 observe2Greater1 observeIGreater1 + action 0 + 8410 : 1 +state 8144 deadlock observe2Greater1 observeIGreater1 + action 0 + 8144 : 1 +state 8145 deadlock observe2Greater1 observeIGreater1 + action 0 + 8145 : 1 +state 8146 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8147 observe2Greater1 observeIGreater1 + action 0 + 8411 : 1 +state 8148 deadlock observe2Greater1 observeIGreater1 + action 0 + 8148 : 1 +state 8149 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8150 observe2Greater1 observeIGreater1 + action 0 + 8412 : 1 +state 8151 deadlock observe2Greater1 observeIGreater1 + action 0 + 8151 : 1 +state 8152 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8153 observe2Greater1 observeIGreater1 + action 0 + 8413 : 1 +state 8154 deadlock observe2Greater1 observeIGreater1 + action 0 + 8154 : 1 +state 8155 observe2Greater1 observeIGreater1 + action 0 + 7123 : 0.2 + 7124 : 0.2 + 7125 : 0.2 + 7126 : 0.2 + 7127 : 0.2 +state 8156 observe2Greater1 observeIGreater1 + action 0 + 8414 : 1 +state 8157 deadlock observe2Greater1 observeIGreater1 + action 0 + 8157 : 1 +state 8158 deadlock observe2Greater1 observeIGreater1 + action 0 + 8158 : 1 +state 8159 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8160 observe2Greater1 observeIGreater1 + action 0 + 8415 : 1 +state 8161 deadlock observe2Greater1 observeIGreater1 + action 0 + 8161 : 1 +state 8162 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8163 observe2Greater1 observeIGreater1 + action 0 + 8416 : 1 +state 8164 deadlock observe2Greater1 observeIGreater1 + action 0 + 8164 : 1 +state 8165 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8166 observe2Greater1 observeIGreater1 + action 0 + 8417 : 1 +state 8167 deadlock observe2Greater1 observeIGreater1 + action 0 + 8167 : 1 +state 8168 observe2Greater1 observeIGreater1 + action 0 + 7129 : 0.2 + 7130 : 0.2 + 7131 : 0.2 + 7132 : 0.2 + 7133 : 0.2 +state 8169 observe2Greater1 observeIGreater1 + action 0 + 8418 : 1 +state 8170 deadlock observe2Greater1 observeIGreater1 + action 0 + 8170 : 1 +state 8171 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8171 : 1 +state 8172 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8173 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8419 : 1 +state 8174 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8174 : 1 +state 8175 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8176 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8420 : 1 +state 8177 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8177 : 1 +state 8178 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8179 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8421 : 1 +state 8180 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8180 : 1 +state 8181 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 7139 : 0.2 + 7140 : 0.2 + 7141 : 0.2 + 7142 : 0.2 + 7143 : 0.2 +state 8182 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8422 : 1 +state 8183 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8183 : 1 +state 8184 deadlock observe2Greater1 observeIGreater1 + action 0 + 8184 : 1 +state 8185 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8186 observe2Greater1 observeIGreater1 + action 0 + 8423 : 1 +state 8187 deadlock observe2Greater1 observeIGreater1 + action 0 + 8187 : 1 +state 8188 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8189 observe2Greater1 observeIGreater1 + action 0 + 8424 : 1 +state 8190 deadlock observe2Greater1 observeIGreater1 + action 0 + 8190 : 1 +state 8191 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8192 observe2Greater1 observeIGreater1 + action 0 + 8425 : 1 +state 8193 deadlock observe2Greater1 observeIGreater1 + action 0 + 8193 : 1 +state 8194 observe2Greater1 observeIGreater1 + action 0 + 7145 : 0.2 + 7146 : 0.2 + 7147 : 0.2 + 7148 : 0.2 + 7149 : 0.2 +state 8195 observe2Greater1 observeIGreater1 + action 0 + 8426 : 1 +state 8196 deadlock observe2Greater1 observeIGreater1 + action 0 + 8196 : 1 +state 8197 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8197 : 1 +state 8198 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8199 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8427 : 1 +state 8200 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8200 : 1 +state 8201 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8202 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8428 : 1 +state 8203 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8203 : 1 +state 8204 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8205 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8429 : 1 +state 8206 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8206 : 1 +state 8207 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 7155 : 0.2 + 7156 : 0.2 + 7157 : 0.2 + 7158 : 0.2 + 7159 : 0.2 +state 8208 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8430 : 1 +state 8209 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8209 : 1 +state 8210 deadlock observe3Greater1 observeIGreater1 + action 0 + 8210 : 1 +state 8211 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8212 observe3Greater1 observeIGreater1 + action 0 + 8431 : 1 +state 8213 deadlock observe3Greater1 observeIGreater1 + action 0 + 8213 : 1 +state 8214 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8215 observe3Greater1 observeIGreater1 + action 0 + 8432 : 1 +state 8216 deadlock observe3Greater1 observeIGreater1 + action 0 + 8216 : 1 +state 8217 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8218 observe3Greater1 observeIGreater1 + action 0 + 8433 : 1 +state 8219 deadlock observe3Greater1 observeIGreater1 + action 0 + 8219 : 1 +state 8220 observe3Greater1 observeIGreater1 + action 0 + 7165 : 0.2 + 7166 : 0.2 + 7167 : 0.2 + 7168 : 0.2 + 7169 : 0.2 +state 8221 observe3Greater1 observeIGreater1 + action 0 + 8434 : 1 +state 8222 deadlock observe3Greater1 observeIGreater1 + action 0 + 8222 : 1 +state 8223 deadlock observe3Greater1 observeIGreater1 + action 0 + 8223 : 1 +state 8224 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8225 observe3Greater1 observeIGreater1 + action 0 + 8435 : 1 +state 8226 deadlock observe3Greater1 observeIGreater1 + action 0 + 8226 : 1 +state 8227 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8228 observe3Greater1 observeIGreater1 + action 0 + 8436 : 1 +state 8229 deadlock observe3Greater1 observeIGreater1 + action 0 + 8229 : 1 +state 8230 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8231 observe3Greater1 observeIGreater1 + action 0 + 8437 : 1 +state 8232 deadlock observe3Greater1 observeIGreater1 + action 0 + 8232 : 1 +state 8233 observe3Greater1 observeIGreater1 + action 0 + 7171 : 0.2 + 7172 : 0.2 + 7173 : 0.2 + 7174 : 0.2 + 7175 : 0.2 +state 8234 observe3Greater1 observeIGreater1 + action 0 + 8438 : 1 +state 8235 deadlock observe3Greater1 observeIGreater1 + action 0 + 8235 : 1 +state 8236 deadlock observe4Greater1 observeIGreater1 + action 0 + 8236 : 1 +state 8237 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8238 observe4Greater1 observeIGreater1 + action 0 + 8439 : 1 +state 8239 deadlock observe4Greater1 observeIGreater1 + action 0 + 8239 : 1 +state 8240 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8241 observe4Greater1 observeIGreater1 + action 0 + 8440 : 1 +state 8242 deadlock observe4Greater1 observeIGreater1 + action 0 + 8242 : 1 +state 8243 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8244 observe4Greater1 observeIGreater1 + action 0 + 8441 : 1 +state 8245 deadlock observe4Greater1 observeIGreater1 + action 0 + 8245 : 1 +state 8246 observe4Greater1 observeIGreater1 + action 0 + 7181 : 0.2 + 7182 : 0.2 + 7183 : 0.2 + 7184 : 0.2 + 7185 : 0.2 +state 8247 observe4Greater1 observeIGreater1 + action 0 + 8442 : 1 +state 8248 deadlock observe4Greater1 observeIGreater1 + action 0 + 8248 : 1 +state 8249 deadlock observe4Greater1 observeIGreater1 + action 0 + 8249 : 1 +state 8250 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8251 observe4Greater1 observeIGreater1 + action 0 + 8443 : 1 +state 8252 deadlock observe4Greater1 observeIGreater1 + action 0 + 8252 : 1 +state 8253 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8254 observe4Greater1 observeIGreater1 + action 0 + 8444 : 1 +state 8255 deadlock observe4Greater1 observeIGreater1 + action 0 + 8255 : 1 +state 8256 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8257 observe4Greater1 observeIGreater1 + action 0 + 8445 : 1 +state 8258 deadlock observe4Greater1 observeIGreater1 + action 0 + 8258 : 1 +state 8259 observe4Greater1 observeIGreater1 + action 0 + 7191 : 0.2 + 7192 : 0.2 + 7193 : 0.2 + 7194 : 0.2 + 7195 : 0.2 +state 8260 observe4Greater1 observeIGreater1 + action 0 + 8446 : 1 +state 8261 deadlock observe4Greater1 observeIGreater1 + action 0 + 8261 : 1 +state 8262 deadlock observe3Greater1 observeIGreater1 + action 0 + 8262 : 1 +state 8263 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8264 observe3Greater1 observeIGreater1 + action 0 + 8447 : 1 +state 8265 deadlock observe3Greater1 observeIGreater1 + action 0 + 8265 : 1 +state 8266 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8267 observe3Greater1 observeIGreater1 + action 0 + 8448 : 1 +state 8268 deadlock observe3Greater1 observeIGreater1 + action 0 + 8268 : 1 +state 8269 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8270 observe3Greater1 observeIGreater1 + action 0 + 8449 : 1 +state 8271 deadlock observe3Greater1 observeIGreater1 + action 0 + 8271 : 1 +state 8272 observe3Greater1 observeIGreater1 + action 0 + 7201 : 0.2 + 7202 : 0.2 + 7203 : 0.2 + 7204 : 0.2 + 7205 : 0.2 +state 8273 observe3Greater1 observeIGreater1 + action 0 + 8450 : 1 +state 8274 deadlock observe3Greater1 observeIGreater1 + action 0 + 8274 : 1 +state 8275 deadlock observe3Greater1 observeIGreater1 + action 0 + 8275 : 1 +state 8276 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8277 observe3Greater1 observeIGreater1 + action 0 + 8451 : 1 +state 8278 deadlock observe3Greater1 observeIGreater1 + action 0 + 8278 : 1 +state 8279 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8280 observe3Greater1 observeIGreater1 + action 0 + 8452 : 1 +state 8281 deadlock observe3Greater1 observeIGreater1 + action 0 + 8281 : 1 +state 8282 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8283 observe3Greater1 observeIGreater1 + action 0 + 8453 : 1 +state 8284 deadlock observe3Greater1 observeIGreater1 + action 0 + 8284 : 1 +state 8285 observe3Greater1 observeIGreater1 + action 0 + 7207 : 0.2 + 7208 : 0.2 + 7209 : 0.2 + 7210 : 0.2 + 7211 : 0.2 +state 8286 observe3Greater1 observeIGreater1 + action 0 + 8454 : 1 +state 8287 deadlock observe3Greater1 observeIGreater1 + action 0 + 8287 : 1 +state 8288 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8288 : 1 +state 8289 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8290 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8455 : 1 +state 8291 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8291 : 1 +state 8292 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8293 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8456 : 1 +state 8294 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8294 : 1 +state 8295 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8296 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8457 : 1 +state 8297 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8297 : 1 +state 8298 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 7217 : 0.2 + 7218 : 0.2 + 7219 : 0.2 + 7220 : 0.2 + 7221 : 0.2 +state 8299 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8458 : 1 +state 8300 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8300 : 1 +state 8301 deadlock observe4Greater1 observeIGreater1 + action 0 + 8301 : 1 +state 8302 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8303 observe4Greater1 observeIGreater1 + action 0 + 8459 : 1 +state 8304 deadlock observe4Greater1 observeIGreater1 + action 0 + 8304 : 1 +state 8305 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8306 observe4Greater1 observeIGreater1 + action 0 + 8460 : 1 +state 8307 deadlock observe4Greater1 observeIGreater1 + action 0 + 8307 : 1 +state 8308 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8309 observe4Greater1 observeIGreater1 + action 0 + 8461 : 1 +state 8310 deadlock observe4Greater1 observeIGreater1 + action 0 + 8310 : 1 +state 8311 observe4Greater1 observeIGreater1 + action 0 + 7227 : 0.2 + 7228 : 0.2 + 7229 : 0.2 + 7230 : 0.2 + 7231 : 0.2 +state 8312 observe4Greater1 observeIGreater1 + action 0 + 8462 : 1 +state 8313 deadlock observe4Greater1 observeIGreater1 + action 0 + 8313 : 1 +state 8314 deadlock observe4Greater1 observeIGreater1 + action 0 + 8314 : 1 +state 8315 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8316 observe4Greater1 observeIGreater1 + action 0 + 8463 : 1 +state 8317 deadlock observe4Greater1 observeIGreater1 + action 0 + 8317 : 1 +state 8318 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8319 observe4Greater1 observeIGreater1 + action 0 + 8464 : 1 +state 8320 deadlock observe4Greater1 observeIGreater1 + action 0 + 8320 : 1 +state 8321 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8322 observe4Greater1 observeIGreater1 + action 0 + 8465 : 1 +state 8323 deadlock observe4Greater1 observeIGreater1 + action 0 + 8323 : 1 +state 8324 observe4Greater1 observeIGreater1 + action 0 + 7237 : 0.2 + 7238 : 0.2 + 7239 : 0.2 + 7240 : 0.2 + 7241 : 0.2 +state 8325 observe4Greater1 observeIGreater1 + action 0 + 8466 : 1 +state 8326 deadlock observe4Greater1 observeIGreater1 + action 0 + 8326 : 1 +state 8327 observe1Greater1 observeIGreater1 + action 0 + 8467 : 1 +state 8328 observe1Greater1 observeIGreater1 + action 0 + 8468 : 1 +state 8329 observe1Greater1 observeIGreater1 + action 0 + 8469 : 1 +state 8330 observe1Greater1 observeIGreater1 + action 0 + 8470 : 1 +state 8331 observe1Greater1 observeIGreater1 + action 0 + 8471 : 1 +state 8332 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8472 : 1 +state 8333 observe1Greater1 observeIGreater1 + action 0 + 8473 : 1 +state 8334 observe1Greater1 observeIGreater1 + action 0 + 8474 : 1 +state 8335 observe1Greater1 observeIGreater1 + action 0 + 8475 : 1 +state 8336 observe1Greater1 observeIGreater1 + action 0 + 8476 : 1 +state 8337 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8477 : 1 +state 8338 observe1Greater1 observeIGreater1 + action 0 + 8478 : 1 +state 8339 observe1Greater1 observeIGreater1 + action 0 + 8479 : 1 +state 8340 observe1Greater1 observeIGreater1 + action 0 + 8480 : 1 +state 8341 observe1Greater1 observeIGreater1 + action 0 + 8481 : 1 +state 8342 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8482 : 1 +state 8343 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8483 : 1 +state 8344 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8484 : 1 +state 8345 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8485 : 1 +state 8346 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8486 : 1 +state 8347 observe1Greater1 observeIGreater1 + action 0 + 8487 : 1 +state 8348 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8488 : 1 +state 8349 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8489 : 1 +state 8350 observe1Greater1 observeIGreater1 + action 0 + 8490 : 1 +state 8351 observe1Greater1 observeIGreater1 + action 0 + 8491 : 1 +state 8352 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8492 : 1 +state 8353 observe1Greater1 observeIGreater1 + action 0 + 8493 : 1 +state 8354 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8494 : 1 +state 8355 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8495 : 1 +state 8356 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8496 : 1 +state 8357 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8497 : 1 +state 8358 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8498 : 1 +state 8359 observe1Greater1 observeIGreater1 + action 0 + 8499 : 1 +state 8360 observe1Greater1 observeIGreater1 + action 0 + 8500 : 1 +state 8361 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8501 : 1 +state 8362 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8502 : 1 +state 8363 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8503 : 1 +state 8364 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8504 : 1 +state 8365 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8505 : 1 +state 8366 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8506 : 1 +state 8367 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8507 : 1 +state 8368 observe2Greater1 observeIGreater1 + action 0 + 8508 : 1 +state 8369 observe2Greater1 observeIGreater1 + action 0 + 8509 : 1 +state 8370 observe2Greater1 observeIGreater1 + action 0 + 8510 : 1 +state 8371 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8511 : 1 +state 8372 observe2Greater1 observeIGreater1 + action 0 + 8512 : 1 +state 8373 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8513 : 1 +state 8374 observe2Greater1 observeIGreater1 + action 0 + 8514 : 1 +state 8375 observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8515 : 1 +state 8376 observe2Greater1 observeIGreater1 + action 0 + 8516 : 1 +state 8377 observe2Greater1 observeIGreater1 + action 0 + 8517 : 1 +state 8378 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8518 : 1 +state 8379 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8519 : 1 +state 8380 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8520 : 1 +state 8381 observe3Greater1 observeIGreater1 + action 0 + 8521 : 1 +state 8382 observe3Greater1 observeIGreater1 + action 0 + 8522 : 1 +state 8383 observe1Greater1 observeIGreater1 + action 0 + 8523 : 1 +state 8384 observe2Greater1 observeIGreater1 + action 0 + 8524 : 1 +state 8385 observe3Greater1 observeIGreater1 + action 0 + 8525 : 1 +state 8386 observe4Greater1 observeIGreater1 + action 0 + 8526 : 1 +state 8387 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8527 : 1 +state 8388 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8528 : 1 +state 8389 observe4Greater1 observeIGreater1 + action 0 + 8529 : 1 +state 8390 observe4Greater1 observeIGreater1 + action 0 + 8530 : 1 +state 8391 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8531 : 1 +state 8392 observe3Greater1 observeIGreater1 + action 0 + 8532 : 1 +state 8393 observe3Greater1 observeIGreater1 + action 0 + 8533 : 1 +state 8394 observe3Greater1 observeIGreater1 + action 0 + 8534 : 1 +state 8395 observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8535 : 1 +state 8396 observe3Greater1 observeIGreater1 + action 0 + 8536 : 1 +state 8397 observe3Greater1 observeIGreater1 + action 0 + 8537 : 1 +state 8398 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8538 : 1 +state 8399 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8539 : 1 +state 8400 observe4Greater1 observeIGreater1 + action 0 + 8540 : 1 +state 8401 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8541 : 1 +state 8402 observe4Greater1 observeIGreater1 + action 0 + 8542 : 1 +state 8403 observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8543 : 1 +state 8404 observe4Greater1 observeIGreater1 + action 0 + 8544 : 1 +state 8405 observe4Greater1 observeIGreater1 + action 0 + 8545 : 1 +state 8406 observe4Greater1 observeIGreater1 + action 0 + 8546 : 1 +state 8407 observe2Greater1 observeIGreater1 + action 0 + 8547 : 1 +state 8408 observe2Greater1 observeIGreater1 + action 0 + 8548 : 1 +state 8409 observe2Greater1 observeIGreater1 + action 0 + 8549 : 1 +state 8410 observe2Greater1 observeIGreater1 + action 0 + 8550 : 1 +state 8411 observe2Greater1 observeIGreater1 + action 0 + 8551 : 1 +state 8412 observe2Greater1 observeIGreater1 + action 0 + 8552 : 1 +state 8413 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8553 : 1 +state 8414 observe2Greater1 observeIGreater1 + action 0 + 8554 : 1 +state 8415 observe2Greater1 observeIGreater1 + action 0 + 8555 : 1 +state 8416 observe2Greater1 observeIGreater1 + action 0 + 8556 : 1 +state 8417 observe2Greater1 observeIGreater1 + action 0 + 8557 : 1 +state 8418 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8558 : 1 +state 8419 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8559 : 1 +state 8420 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8560 : 1 +state 8421 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8561 : 1 +state 8422 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8562 : 1 +state 8423 observe2Greater1 observeIGreater1 + action 0 + 8563 : 1 +state 8424 observe2Greater1 observeIGreater1 + action 0 + 8564 : 1 +state 8425 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8565 : 1 +state 8426 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8566 : 1 +state 8427 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8567 : 1 +state 8428 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8568 : 1 +state 8429 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8569 : 1 +state 8430 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8570 : 1 +state 8431 observe3Greater1 observeIGreater1 + action 0 + 8571 : 1 +state 8432 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8572 : 1 +state 8433 observe3Greater1 observeIGreater1 + action 0 + 8573 : 1 +state 8434 observe3Greater1 observeIGreater1 + action 0 + 8574 : 1 +state 8435 observe3Greater1 observeIGreater1 + action 0 + 8575 : 1 +state 8436 observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8576 : 1 +state 8437 observe3Greater1 observeIGreater1 + action 0 + 8577 : 1 +state 8438 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8578 : 1 +state 8439 observe4Greater1 observeIGreater1 + action 0 + 8579 : 1 +state 8440 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8580 : 1 +state 8441 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8581 : 1 +state 8442 observe4Greater1 observeIGreater1 + action 0 + 8582 : 1 +state 8443 observe4Greater1 observeIGreater1 + action 0 + 8583 : 1 +state 8444 observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8584 : 1 +state 8445 observe4Greater1 observeIGreater1 + action 0 + 8585 : 1 +state 8446 observe4Greater1 observeIGreater1 + action 0 + 8586 : 1 +state 8447 observe3Greater1 observeIGreater1 + action 0 + 8587 : 1 +state 8448 observe3Greater1 observeIGreater1 + action 0 + 8588 : 1 +state 8449 observe3Greater1 observeIGreater1 + action 0 + 8589 : 1 +state 8450 observe3Greater1 observeIGreater1 + action 0 + 8590 : 1 +state 8451 observe3Greater1 observeIGreater1 + action 0 + 8591 : 1 +state 8452 observe3Greater1 observeIGreater1 + action 0 + 8592 : 1 +state 8453 observe3Greater1 observeIGreater1 + action 0 + 8593 : 1 +state 8454 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8594 : 1 +state 8455 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8595 : 1 +state 8456 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8596 : 1 +state 8457 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8597 : 1 +state 8458 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8598 : 1 +state 8459 observe4Greater1 observeIGreater1 + action 0 + 8599 : 1 +state 8460 observe4Greater1 observeIGreater1 + action 0 + 8600 : 1 +state 8461 observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8601 : 1 +state 8462 observe4Greater1 observeIGreater1 + action 0 + 8602 : 1 +state 8463 observe4Greater1 observeIGreater1 + action 0 + 8603 : 1 +state 8464 observe4Greater1 observeIGreater1 + action 0 + 8604 : 1 +state 8465 observe4Greater1 observeIGreater1 + action 0 + 8605 : 1 +state 8466 observe4Greater1 observeIGreater1 + action 0 + 8606 : 1 +state 8467 deadlock observe1Greater1 observeIGreater1 + action 0 + 8467 : 1 +state 8468 deadlock observe1Greater1 observeIGreater1 + action 0 + 8468 : 1 +state 8469 deadlock observe1Greater1 observeIGreater1 + action 0 + 8469 : 1 +state 8470 deadlock observe1Greater1 observeIGreater1 + action 0 + 8470 : 1 +state 8471 deadlock observe1Greater1 observeIGreater1 + action 0 + 8471 : 1 +state 8472 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8472 : 1 +state 8473 deadlock observe1Greater1 observeIGreater1 + action 0 + 8473 : 1 +state 8474 deadlock observe1Greater1 observeIGreater1 + action 0 + 8474 : 1 +state 8475 deadlock observe1Greater1 observeIGreater1 + action 0 + 8475 : 1 +state 8476 deadlock observe1Greater1 observeIGreater1 + action 0 + 8476 : 1 +state 8477 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8477 : 1 +state 8478 deadlock observe1Greater1 observeIGreater1 + action 0 + 8478 : 1 +state 8479 deadlock observe1Greater1 observeIGreater1 + action 0 + 8479 : 1 +state 8480 deadlock observe1Greater1 observeIGreater1 + action 0 + 8480 : 1 +state 8481 deadlock observe1Greater1 observeIGreater1 + action 0 + 8481 : 1 +state 8482 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8482 : 1 +state 8483 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8483 : 1 +state 8484 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8484 : 1 +state 8485 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8485 : 1 +state 8486 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8486 : 1 +state 8487 deadlock observe1Greater1 observeIGreater1 + action 0 + 8487 : 1 +state 8488 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8488 : 1 +state 8489 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8489 : 1 +state 8490 deadlock observe1Greater1 observeIGreater1 + action 0 + 8490 : 1 +state 8491 deadlock observe1Greater1 observeIGreater1 + action 0 + 8491 : 1 +state 8492 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8492 : 1 +state 8493 deadlock observe1Greater1 observeIGreater1 + action 0 + 8493 : 1 +state 8494 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8494 : 1 +state 8495 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8495 : 1 +state 8496 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8496 : 1 +state 8497 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8497 : 1 +state 8498 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8498 : 1 +state 8499 deadlock observe1Greater1 observeIGreater1 + action 0 + 8499 : 1 +state 8500 deadlock observe1Greater1 observeIGreater1 + action 0 + 8500 : 1 +state 8501 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8501 : 1 +state 8502 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8502 : 1 +state 8503 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8503 : 1 +state 8504 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8504 : 1 +state 8505 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8505 : 1 +state 8506 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8506 : 1 +state 8507 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8507 : 1 +state 8508 deadlock observe2Greater1 observeIGreater1 + action 0 + 8508 : 1 +state 8509 deadlock observe2Greater1 observeIGreater1 + action 0 + 8509 : 1 +state 8510 deadlock observe2Greater1 observeIGreater1 + action 0 + 8510 : 1 +state 8511 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8511 : 1 +state 8512 deadlock observe2Greater1 observeIGreater1 + action 0 + 8512 : 1 +state 8513 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8513 : 1 +state 8514 deadlock observe2Greater1 observeIGreater1 + action 0 + 8514 : 1 +state 8515 deadlock observe1Greater1 observe2Greater1 observeIGreater1 + action 0 + 8515 : 1 +state 8516 deadlock observe2Greater1 observeIGreater1 + action 0 + 8516 : 1 +state 8517 deadlock observe2Greater1 observeIGreater1 + action 0 + 8517 : 1 +state 8518 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8518 : 1 +state 8519 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8519 : 1 +state 8520 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8520 : 1 +state 8521 deadlock observe3Greater1 observeIGreater1 + action 0 + 8521 : 1 +state 8522 deadlock observe3Greater1 observeIGreater1 + action 0 + 8522 : 1 +state 8523 deadlock observe1Greater1 observeIGreater1 + action 0 + 8523 : 1 +state 8524 deadlock observe2Greater1 observeIGreater1 + action 0 + 8524 : 1 +state 8525 deadlock observe3Greater1 observeIGreater1 + action 0 + 8525 : 1 +state 8526 deadlock observe4Greater1 observeIGreater1 + action 0 + 8526 : 1 +state 8527 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8527 : 1 +state 8528 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8528 : 1 +state 8529 deadlock observe4Greater1 observeIGreater1 + action 0 + 8529 : 1 +state 8530 deadlock observe4Greater1 observeIGreater1 + action 0 + 8530 : 1 +state 8531 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8531 : 1 +state 8532 deadlock observe3Greater1 observeIGreater1 + action 0 + 8532 : 1 +state 8533 deadlock observe3Greater1 observeIGreater1 + action 0 + 8533 : 1 +state 8534 deadlock observe3Greater1 observeIGreater1 + action 0 + 8534 : 1 +state 8535 deadlock observe1Greater1 observe3Greater1 observeIGreater1 + action 0 + 8535 : 1 +state 8536 deadlock observe3Greater1 observeIGreater1 + action 0 + 8536 : 1 +state 8537 deadlock observe3Greater1 observeIGreater1 + action 0 + 8537 : 1 +state 8538 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8538 : 1 +state 8539 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8539 : 1 +state 8540 deadlock observe4Greater1 observeIGreater1 + action 0 + 8540 : 1 +state 8541 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8541 : 1 +state 8542 deadlock observe4Greater1 observeIGreater1 + action 0 + 8542 : 1 +state 8543 deadlock observe1Greater1 observe4Greater1 observeIGreater1 + action 0 + 8543 : 1 +state 8544 deadlock observe4Greater1 observeIGreater1 + action 0 + 8544 : 1 +state 8545 deadlock observe4Greater1 observeIGreater1 + action 0 + 8545 : 1 +state 8546 deadlock observe4Greater1 observeIGreater1 + action 0 + 8546 : 1 +state 8547 deadlock observe2Greater1 observeIGreater1 + action 0 + 8547 : 1 +state 8548 deadlock observe2Greater1 observeIGreater1 + action 0 + 8548 : 1 +state 8549 deadlock observe2Greater1 observeIGreater1 + action 0 + 8549 : 1 +state 8550 deadlock observe2Greater1 observeIGreater1 + action 0 + 8550 : 1 +state 8551 deadlock observe2Greater1 observeIGreater1 + action 0 + 8551 : 1 +state 8552 deadlock observe2Greater1 observeIGreater1 + action 0 + 8552 : 1 +state 8553 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8553 : 1 +state 8554 deadlock observe2Greater1 observeIGreater1 + action 0 + 8554 : 1 +state 8555 deadlock observe2Greater1 observeIGreater1 + action 0 + 8555 : 1 +state 8556 deadlock observe2Greater1 observeIGreater1 + action 0 + 8556 : 1 +state 8557 deadlock observe2Greater1 observeIGreater1 + action 0 + 8557 : 1 +state 8558 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8558 : 1 +state 8559 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8559 : 1 +state 8560 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8560 : 1 +state 8561 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8561 : 1 +state 8562 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8562 : 1 +state 8563 deadlock observe2Greater1 observeIGreater1 + action 0 + 8563 : 1 +state 8564 deadlock observe2Greater1 observeIGreater1 + action 0 + 8564 : 1 +state 8565 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8565 : 1 +state 8566 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8566 : 1 +state 8567 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8567 : 1 +state 8568 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8568 : 1 +state 8569 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8569 : 1 +state 8570 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8570 : 1 +state 8571 deadlock observe3Greater1 observeIGreater1 + action 0 + 8571 : 1 +state 8572 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8572 : 1 +state 8573 deadlock observe3Greater1 observeIGreater1 + action 0 + 8573 : 1 +state 8574 deadlock observe3Greater1 observeIGreater1 + action 0 + 8574 : 1 +state 8575 deadlock observe3Greater1 observeIGreater1 + action 0 + 8575 : 1 +state 8576 deadlock observe2Greater1 observe3Greater1 observeIGreater1 + action 0 + 8576 : 1 +state 8577 deadlock observe3Greater1 observeIGreater1 + action 0 + 8577 : 1 +state 8578 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8578 : 1 +state 8579 deadlock observe4Greater1 observeIGreater1 + action 0 + 8579 : 1 +state 8580 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8580 : 1 +state 8581 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8581 : 1 +state 8582 deadlock observe4Greater1 observeIGreater1 + action 0 + 8582 : 1 +state 8583 deadlock observe4Greater1 observeIGreater1 + action 0 + 8583 : 1 +state 8584 deadlock observe2Greater1 observe4Greater1 observeIGreater1 + action 0 + 8584 : 1 +state 8585 deadlock observe4Greater1 observeIGreater1 + action 0 + 8585 : 1 +state 8586 deadlock observe4Greater1 observeIGreater1 + action 0 + 8586 : 1 +state 8587 deadlock observe3Greater1 observeIGreater1 + action 0 + 8587 : 1 +state 8588 deadlock observe3Greater1 observeIGreater1 + action 0 + 8588 : 1 +state 8589 deadlock observe3Greater1 observeIGreater1 + action 0 + 8589 : 1 +state 8590 deadlock observe3Greater1 observeIGreater1 + action 0 + 8590 : 1 +state 8591 deadlock observe3Greater1 observeIGreater1 + action 0 + 8591 : 1 +state 8592 deadlock observe3Greater1 observeIGreater1 + action 0 + 8592 : 1 +state 8593 deadlock observe3Greater1 observeIGreater1 + action 0 + 8593 : 1 +state 8594 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8594 : 1 +state 8595 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8595 : 1 +state 8596 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8596 : 1 +state 8597 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8597 : 1 +state 8598 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8598 : 1 +state 8599 deadlock observe4Greater1 observeIGreater1 + action 0 + 8599 : 1 +state 8600 deadlock observe4Greater1 observeIGreater1 + action 0 + 8600 : 1 +state 8601 deadlock observe3Greater1 observe4Greater1 observeIGreater1 + action 0 + 8601 : 1 +state 8602 deadlock observe4Greater1 observeIGreater1 + action 0 + 8602 : 1 +state 8603 deadlock observe4Greater1 observeIGreater1 + action 0 + 8603 : 1 +state 8604 deadlock observe4Greater1 observeIGreater1 + action 0 + 8604 : 1 +state 8605 deadlock observe4Greater1 observeIGreater1 + action 0 + 8605 : 1 +state 8606 deadlock observe4Greater1 observeIGreater1 + action 0 + 8606 : 1 diff --git a/resources/examples/testfiles/ma/jobscheduler.drn b/resources/examples/testfiles/ma/jobscheduler.drn new file mode 100644 index 000000000..6f2e61a39 --- /dev/null +++ b/resources/examples/testfiles/ma/jobscheduler.drn @@ -0,0 +1,71 @@ +// Exported by storm +// Original model type: Markov Automaton +@type: Markov Automaton +@parameters + +@reward_models +avg_waiting_time +@nr_states +17 +@model +state 0 !0 [1] init + action 0 [0] + 1 : 1 + action 1 [0] + 2 : 1 + action 2 [0] + 3 : 1 +state 1 !3 [1] + action 0 [0] + 4 : 0.333333 + 5 : 0.666667 +state 2 !4 [1] + action 0 [0] + 4 : 0.25 + 6 : 0.75 +state 3 !5 [1] + action 0 [0] + 5 : 0.4 + 6 : 0.6 +state 4 !0 [0.666667] one_job_finished slowest_before_fastest + action 0 [0] + 7 : 1 +state 5 !0 [0.666667] one_job_finished + action 0 [0] + 8 : 1 +state 6 !0 [0.666667] one_job_finished + action 0 [0] + 9 : 1 +state 7 !5 [0.666667] one_job_finished slowest_before_fastest + action 0 [0] + 10 : 0.4 + 11 : 0.6 +state 8 !4 [0.666667] one_job_finished + action 0 [0] + 10 : 0.25 + 12 : 0.75 +state 9 !3 [0.666667] one_job_finished + action 0 [0] + 11 : 0.333333 + 12 : 0.666667 +state 10 !0 [0.333333] half_of_jobs_finished slowest_before_fastest + action 0 [0] + 13 : 1 +state 11 !0 [0.333333] half_of_jobs_finished + action 0 [0] + 14 : 1 +state 12 !0 [0.333333] half_of_jobs_finished + action 0 [0] + 15 : 1 +state 13 !3 [0.333333] half_of_jobs_finished slowest_before_fastest + action 0 [0] + 16 : 1 +state 14 !2 [0.333333] half_of_jobs_finished + action 0 [0] + 16 : 1 +state 15 !1 [0.333333] half_of_jobs_finished + action 0 [0] + 16 : 1 +state 16 !1 [0] all_jobs_finished deadlock + action 0 [0] + 16 : 1 diff --git a/resources/examples/testfiles/mdp/prism-mec-example1.nm b/resources/examples/testfiles/mdp/prism-mec-example1.nm new file mode 100644 index 000000000..bb8ec7d17 --- /dev/null +++ b/resources/examples/testfiles/mdp/prism-mec-example1.nm @@ -0,0 +1,12 @@ +mdp + +module test + + x : [0..2]; + + [] x=0 -> true; + [] x=0 -> 0.5 : (x'=1) + 0.5: (x'=2); + [] x=1 -> (x'=0); + [] x=2 -> true; + +endmodule diff --git a/resources/examples/testfiles/mdp/prism-mec-example2.nm b/resources/examples/testfiles/mdp/prism-mec-example2.nm new file mode 100644 index 000000000..7ef54d4b2 --- /dev/null +++ b/resources/examples/testfiles/mdp/prism-mec-example2.nm @@ -0,0 +1,13 @@ +mdp + +module test + + x : [0..2]; + + [] x=0 -> true; + [] x=0 -> 0.5 : (x'=1) + 0.5: (x'=1); + [] x=0 -> (x'=2); + [] x=1 -> (x'=0); + [] x=2 -> true; + +endmodule diff --git a/resources/examples/testfiles/mdp/two_dice.drn b/resources/examples/testfiles/mdp/two_dice.drn index 74d13d03b..7e88bc459 100644 --- a/resources/examples/testfiles/mdp/two_dice.drn +++ b/resources/examples/testfiles/mdp/two_dice.drn @@ -3,6 +3,8 @@ @type: MDP @parameters +@reward_models +coinflips @nr_states 169 @model diff --git a/src/storm-cli-utilities/CMakeLists.txt b/src/storm-cli-utilities/CMakeLists.txt index 64c2848c7..84819b72b 100644 --- a/src/storm-cli-utilities/CMakeLists.txt +++ b/src/storm-cli-utilities/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_cli_util_headers DEPENDS ${STORM_CLI_UTIL_OUTPUT_HE add_dependencies(storm-cli-utilities copy_storm_pars_headers) # installation -install(TARGETS storm-cli-utilities RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-cli-utilities EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-cli-utilities/cli.cpp b/src/storm-cli-utilities/cli.cpp index dfc3065b8..4d44454c8 100644 --- a/src/storm-cli-utilities/cli.cpp +++ b/src/storm-cli-utilities/cli.cpp @@ -11,6 +11,7 @@ #include <type_traits> #include <ctime> +#include <boost/algorithm/string/replace.hpp> #include "storm-cli-utilities/model-handling.h" @@ -63,7 +64,27 @@ namespace storm { storm::utility::cleanUp(); return 0; } - + + std::string shellQuoteSingleIfNecessary(const std::string& arg) { + // quote empty argument + if (arg.empty()) { + return "''"; + } + + if (arg.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./=") != std::string::npos) { + // contains potentially unsafe character, needs quoting + if (arg.find('\'') != std::string::npos) { + // contains ', we have to replace all ' with '\'' + std::string escaped(arg); + boost::replace_all(escaped, "'", "'\\''"); + return "'" + escaped + "'"; + } else { + return "'" + arg + "'"; + } + } + + return arg; + } void printHeader(std::string const& name, const int argc, const char** argv) { STORM_PRINT(name << " " << storm::utility::StormVersion::shortVersionString() << std::endl << std::endl); @@ -71,7 +92,7 @@ namespace storm { // "Compute" the command line argument string with which storm was invoked. std::stringstream commandStream; for (int i = 1; i < argc; ++i) { - commandStream << argv[i] << " "; + commandStream << " " << shellQuoteSingleIfNecessary(argv[i]); } std::string command = commandStream.str(); @@ -79,7 +100,7 @@ namespace storm { if (!command.empty()) { std::time_t result = std::time(nullptr); STORM_PRINT("Date: " << std::ctime(&result)); - STORM_PRINT("Command line arguments: " << commandStream.str() << std::endl); + STORM_PRINT("Command line arguments:" << commandStream.str() << std::endl); STORM_PRINT("Current working directory: " << storm::utility::cli::getCurrentWorkingDirectory() << std::endl << std::endl); } } diff --git a/src/storm-cli-utilities/cli.h b/src/storm-cli-utilities/cli.h index e8d8601e9..66c51bad6 100644 --- a/src/storm-cli-utilities/cli.h +++ b/src/storm-cli-utilities/cli.h @@ -11,6 +11,13 @@ namespace storm { */ int64_t process(const int argc, const char** argv); + /*! + * For a command-line argument, returns a quoted version + * with single quotes if it contains unsafe characters. + * Otherwise, just returns the unquoted argument. + */ + std::string shellQuoteSingleIfNecessary(const std::string& arg); + void printHeader(std::string const& name, const int argc, const char** argv); void printVersion(std::string const& name); diff --git a/src/storm-cli-utilities/model-handling.h b/src/storm-cli-utilities/model-handling.h index 4180bdc33..d03cfe630 100644 --- a/src/storm-cli-utilities/model-handling.h +++ b/src/storm-cli-utilities/model-handling.h @@ -23,6 +23,7 @@ #include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/ResourceSettings.h" @@ -189,6 +190,7 @@ namespace storm { options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet()); options.setBuildAllLabels(buildSettings.isBuildFullModelSet()); options.setBuildAllRewardModels(buildSettings.isBuildFullModelSet()); + options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet()); if (buildSettings.isBuildFullModelSet()) { options.clearTerminalStates(); } @@ -216,7 +218,7 @@ namespace storm { auto buildSettings = storm::settings::getModule<storm::settings::modules::BuildSettings>(); std::shared_ptr<storm::models::ModelBase> result; if (input.model) { - if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid || engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) { + if (engine == storm::settings::modules::CoreSettings::Engine::Dd || engine == storm::settings::modules::CoreSettings::Engine::Hybrid || engine == storm::settings::modules::CoreSettings::Engine::DdSparse || engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) { result = buildModelDd<DdType, ValueType>(input); } else if (engine == storm::settings::modules::CoreSettings::Engine::Sparse) { result = buildModelSparse<ValueType>(input, buildSettings); @@ -305,37 +307,82 @@ namespace storm { } template <storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { + typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type + preprocessDdMarkovAutomaton(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model) { + return model; + } + + template <storm::dd::DdType DdType, typename ValueType> + typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type + preprocessDdMarkovAutomaton(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model) { + auto ma = model->template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(); + if (!ma->isClosed()) { + return std::make_shared<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(ma->close()); + } else { + return model; + } + } + + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) { STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(), "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation."); STORM_LOG_INFO("Performing bisimulation minimization..."); - return storm::api::performBisimulationMinimization<DdType, ValueType>(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); + return storm::api::performBisimulationMinimization<DdType, ValueType, ExportValueType>(model, createFormulasToRespect(input.properties), storm::storage::BisimulationType::Strong, bisimulationSettings.getSignatureMode()); } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessDdModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input) { auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); - std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> result = std::make_pair(model, false); + std::pair<std::shared_ptr<storm::models::Model<ValueType>>, bool> intermediateResult = std::make_pair(model, false); + + if (model->isOfType(storm::models::ModelType::MarkovAutomaton)) { + intermediateResult.first = preprocessDdMarkovAutomaton(intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>()); + intermediateResult.second = true; + } + std::unique_ptr<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>> result; + auto symbolicModel = intermediateResult.first->template as<storm::models::symbolic::Model<DdType, ValueType>>(); if (generalSettings.isBisimulationSet()) { - result.first = preprocessDdModelBisimulation(model, input, bisimulationSettings); - result.second = true; + std::shared_ptr<storm::models::Model<ExportValueType>> newModel = preprocessDdModelBisimulation<DdType, ValueType, ExportValueType>(symbolicModel, input, bisimulationSettings); + result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(newModel, true); + } else { + result = std::make_unique<std::pair<std::shared_ptr<storm::models::Model<ExportValueType>>, bool>>(symbolicModel->template toValueType<ExportValueType>(), !std::is_same<ValueType, ExportValueType>::value); } - return result; + if (result && result->first->isSymbolicModel() && storm::settings::getModule<storm::settings::modules::CoreSettings>().getEngine() == storm::settings::modules::CoreSettings::Engine::DdSparse) { + // Mark as changed. + result->second = true; + + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> symbolicModel = result->first->template as<storm::models::symbolic::Model<DdType, ExportValueType>>(); + if (symbolicModel->isOfType(storm::models::ModelType::Dtmc)) { + storm::transformer::SymbolicDtmcToSparseDtmcTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Dtmc<DdType, ExportValueType>>()); + } else if (symbolicModel->isOfType(storm::models::ModelType::Ctmc)) { + storm::transformer::SymbolicCtmcToSparseCtmcTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Ctmc<DdType, ExportValueType>>()); + } else if (symbolicModel->isOfType(storm::models::ModelType::Mdp)) { + storm::transformer::SymbolicMdpToSparseMdpTransformer<DdType, ExportValueType> transformer; + result->first = transformer.translate(*symbolicModel->template as<storm::models::symbolic::Mdp<DdType, ExportValueType>>()); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The translation to a sparse model is not supported for the given model type."); + } + } + + return *result; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename ExportValueType = BuildValueType> std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) { storm::utility::Stopwatch preprocessingWatch(true); std::pair<std::shared_ptr<storm::models::ModelBase>, bool> result = std::make_pair(model, false); if (model->isSparseModel()) { - result = preprocessSparseModel<ValueType>(result.first->as<storm::models::sparse::Model<ValueType>>(), input); + result = preprocessSparseModel<BuildValueType>(result.first->as<storm::models::sparse::Model<BuildValueType>>(), input); } else { STORM_LOG_ASSERT(model->isSymbolicModel(), "Unexpected model type."); - result = preprocessDdModel<DdType, ValueType>(result.first->as<storm::models::symbolic::Model<DdType, ValueType>>(), input); + result = preprocessDdModel<DdType, BuildValueType, ExportValueType>(result.first->as<storm::models::symbolic::Model<DdType, BuildValueType>>(), input); } preprocessingWatch.stop(); @@ -377,8 +424,6 @@ namespace storm { auto counterexampleSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>(); if (counterexampleSettings.isMinimalCommandSetGenerationSet()) { - STORM_LOG_THROW(input.model && input.model.get().isPrismProgram(), storm::exceptions::NotSupportedException, "Minimal command set counterexamples are only supported for PRISM model input."); - storm::prism::Program const& program = input.model.get().asPrismProgram(); bool useMilp = counterexampleSettings.isUseMilpBasedMinimalCommandSetGenerationSet(); for (auto const& property : input.properties) { @@ -387,13 +432,14 @@ namespace storm { storm::utility::Stopwatch watch(true); if (useMilp) { STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample generation using MILP is currently only supported for MDPs."); - counterexample = storm::api::computePrismHighLevelCounterexampleMilp(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMilp(input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); } else { STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample generation using MaxSAT is currently only supported for discrete-time models."); + if (sparseModel->isOfType(storm::models::ModelType::Dtmc)) { - counterexample = storm::api::computePrismHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(input.model.get(), sparseModel->template as<storm::models::sparse::Dtmc<ValueType>>(), property.getRawFormula()); } else { - counterexample = storm::api::computePrismHighLevelCounterexampleMaxSmt(program, sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); + counterexample = storm::api::computeHighLevelCounterexampleMaxSmt(input.model.get(), sparseModel->template as<storm::models::sparse::Mdp<ValueType>>(), property.getRawFormula()); } } watch.stop(); @@ -617,13 +663,13 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename VerificationValueType = BuildValueType> std::shared_ptr<storm::models::ModelBase> buildPreprocessExportModelWithValueTypeAndDdlib(SymbolicInput const& input, storm::settings::modules::CoreSettings::Engine engine) { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); auto buildSettings = storm::settings::getModule<storm::settings::modules::BuildSettings>(); std::shared_ptr<storm::models::ModelBase> model; if (!buildSettings.isNoBuildModelSet()) { - model = buildModel<DdType, ValueType>(engine, input, ioSettings); + model = buildModel<DdType, BuildValueType>(engine, input, ioSettings); } if (model) { @@ -633,17 +679,17 @@ namespace storm { STORM_LOG_THROW(model || input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model."); if (model) { - auto preprocessingResult = preprocessModel<DdType, ValueType>(model, input); + auto preprocessingResult = preprocessModel<DdType, BuildValueType, VerificationValueType>(model, input); if (preprocessingResult.second) { model = preprocessingResult.first; model->printModelInformationToStream(std::cout); } - exportModel<DdType, ValueType>(model, input); + exportModel<DdType, BuildValueType>(model, input); } return model; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename BuildValueType, typename VerificationValueType = BuildValueType> void processInputWithValueTypeAndDdlib(SymbolicInput const& input) { auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>(); auto abstractionSettings = storm::settings::getModule<storm::settings::modules::AbstractionSettings>(); @@ -652,19 +698,19 @@ namespace storm { storm::settings::modules::CoreSettings::Engine engine = coreSettings.getEngine(); if (engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement && abstractionSettings.getAbstractionRefinementMethod() == storm::settings::modules::AbstractionSettings::Method::Games) { - verifyWithAbstractionRefinementEngine<DdType, ValueType>(input); + verifyWithAbstractionRefinementEngine<DdType, VerificationValueType>(input); } else if (engine == storm::settings::modules::CoreSettings::Engine::Exploration) { - verifyWithExplorationEngine<ValueType>(input); + verifyWithExplorationEngine<VerificationValueType>(input); } else { - std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, ValueType>(input, engine); - + std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, BuildValueType, VerificationValueType>(input, engine); + if (model) { if (coreSettings.isCounterexampleSet()) { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); - generateCounterexamples<ValueType>(model, input); + generateCounterexamples<VerificationValueType>(model, input); } else { auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); - verifyModel<DdType, ValueType>(model, input, coreSettings); + verifyModel<DdType, VerificationValueType>(model, input, coreSettings); } } } @@ -674,12 +720,16 @@ namespace storm { void processInputWithValueType(SymbolicInput const& input) { auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>(); auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); + auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue() && generalSettings.isExactSet()) { STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); - processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, ValueType>(input); + processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber>(input); + } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD && coreSettings.isDdLibraryTypeSetFromDefaultValue() && std::is_same<ValueType, double>::value && generalSettings.isBisimulationSet() && bisimulationSettings.useExactArithmeticInDdBisimulation()) { + STORM_LOG_INFO("Switching to DD library sylvan to allow for rational arithmetic."); + processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber, double>(input); } else if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD) { - processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, ValueType>(input); + processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, double>(input); } else { STORM_LOG_ASSERT(coreSettings.getDdLibraryType() == storm::dd::DdType::Sylvan, "Unknown DD library."); processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, ValueType>(input); diff --git a/src/storm-dft-cli/CMakeLists.txt b/src/storm-dft-cli/CMakeLists.txt index 4780eef4d..5886ac0a0 100644 --- a/src/storm-dft-cli/CMakeLists.txt +++ b/src/storm-dft-cli/CMakeLists.txt @@ -6,4 +6,4 @@ set_target_properties(storm-dft-cli PROPERTIES OUTPUT_NAME "storm-dft") add_dependencies(binaries storm-dft-cli) # installation -install(TARGETS storm-dft-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-dft-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-dft-cli/storm-dft.cpp b/src/storm-dft-cli/storm-dft.cpp index e68c853c3..9923330d0 100644 --- a/src/storm-dft-cli/storm-dft.cpp +++ b/src/storm-dft-cli/storm-dft.cpp @@ -1,166 +1,65 @@ -#include "storm-dft/settings/DftSettings.h" +#include "storm-dft/api/storm-dft.h" +#include "storm-dft/settings/DftSettings.h" #include "storm-dft/settings/modules/DftIOSettings.h" #include "storm-dft/settings/modules/FaultTreeSettings.h" #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/utility/initialize.h" -#include "storm/api/storm.h" #include "storm-cli-utilities/cli.h" -#include "storm-dft/parser/DFTGalileoParser.h" -#include "storm-dft/parser/DFTJsonParser.h" -#include "storm-dft/modelchecker/dft/DFTModelChecker.h" -#include "storm-dft/modelchecker/dft/DFTASFChecker.h" -#include "storm-dft/transformations/DftToGspnTransformator.h" -#include "storm-dft/storage/dft/DftJsonExporter.h" - -#include "storm-gspn/storage/gspn/GSPN.h" -#include "storm-gspn/storm-gspn.h" - -#include <boost/lexical_cast.hpp> -#include <memory> - -/*! - * Analyse the given DFT according to the given properties. - * We first load the DFT from the given file, then build the corresponding model and last check against the given properties. - * - * @param properties PCTL formulas capturing the properties to check. - * @param symred Flag whether symmetry reduction should be used. - * @param allowModularisation Flag whether modularisation should be applied if possible. - * @param enableDC Flag whether Don't Care propagation should be used. - * @param approximationError Allowed approximation error. - */ -template <typename ValueType> -void analyzeDFT(std::vector<std::string> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { - storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); - std::shared_ptr<storm::storage::DFT<ValueType>> dft; - - // Build DFT from given file. - if (dftIOSettings.isDftJsonFileSet()) { - storm::parser::DFTJsonParser<ValueType> parser; - std::cout << "Loading DFT from file " << dftIOSettings.getDftJsonFilename() << std::endl; - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); - } else { - storm::parser::DFTGalileoParser<ValueType> parser; - std::cout << "Loading DFT from file " << dftIOSettings.getDftFilename() << std::endl; - dft = std::make_shared<storm::storage::DFT<ValueType>>(parser.parseDFT(dftIOSettings.getDftFilename())); - } - - // Build properties - std::string propString = properties[0]; - for (size_t i = 1; i < properties.size(); ++i) { - propString += ";" + properties[i]; - } - std::vector<std::shared_ptr<storm::logic::Formula const>> props = storm::api::extractFormulasFromProperties(storm::api::parseProperties(propString)); - STORM_LOG_ASSERT(props.size() > 0, "No properties found."); - - // Check model - storm::modelchecker::DFTModelChecker<ValueType> modelChecker; - modelChecker.check(*dft, props, symred, allowModularisation, enableDC, approximationError); - modelChecker.printTimings(); - modelChecker.printResults(); -} - /*! - * Analyze the DFT with use of SMT solving. - * - * @param filename Path to DFT file in Galileo format. + * Process commandline options and start computations. */ template<typename ValueType> -void analyzeWithSMT(std::string filename) { - std::cout << "Running DFT analysis on file " << filename << " with use of SMT" << std::endl; - - storm::parser::DFTGalileoParser<ValueType> parser; - storm::storage::DFT<ValueType> dft = parser.parseDFT(filename); - storm::modelchecker::DFTASFChecker asfChecker(dft); - asfChecker.convert(); - asfChecker.toFile("test.smt2"); - //bool sat = dftSmtBuilder.check(); - //std::cout << "SMT result: " << sat << std::endl; -} - void processOptions() { // Start by setting some urgent options (log levels, resources, etc.) storm::cli::setUrgentOptions(); - // storm::cli::processOptions(); - storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); storm::settings::modules::FaultTreeSettings const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>(); - storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); storm::settings::modules::IOSettings const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); + if (!dftIOSettings.isDftFileSet() && !dftIOSettings.isDftJsonFileSet()) { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model."); } + // Build DFT from given file + std::shared_ptr<storm::storage::DFT<ValueType>> dft; + if (dftIOSettings.isDftJsonFileSet()) { + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); + dft = storm::api::loadDFTJson<ValueType>(dftIOSettings.getDftJsonFilename()); + } else { + STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); + dft = storm::api::loadDFTGalileo<ValueType>(dftIOSettings.getDftFilename()); + } + + if (dftIOSettings.isDisplayStatsSet()) { + std::cout << "=============DFT Statistics==============" << std::endl; + dft->writeStatsToStream(std::cout); + std::cout << "=========================================" << std::endl; + } + if (dftIOSettings.isExportToJson()) { - STORM_LOG_THROW(dftIOSettings.isDftFileSet(), storm::exceptions::InvalidSettingsException, "No input model in Galileo format given."); - storm::parser::DFTGalileoParser<double> parser; - storm::storage::DFT<double> dft = parser.parseDFT(dftIOSettings.getDftFilename()); // Export to json - storm::storage::DftJsonExporter<double>::toFile(dft, dftIOSettings.getExportJsonFilename()); - storm::utility::cleanUp(); + storm::api::exportDFTToJson<ValueType>(*dft, dftIOSettings.getExportJsonFilename()); return; } - if (dftIOSettings.isTransformToGspn()) { - std::shared_ptr<storm::storage::DFT<double>> dft; - if (dftIOSettings.isDftJsonFileSet()) { - storm::parser::DFTJsonParser<double> parser; - dft = std::make_shared<storm::storage::DFT<double>>(parser.parseJson(dftIOSettings.getDftJsonFilename())); - } else { - storm::parser::DFTGalileoParser<double> parser(true, false); - dft = std::make_shared<storm::storage::DFT<double>>(parser.parseDFT(dftIOSettings.getDftFilename())); - } - storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(*dft); - gspnTransformator.transform(); - storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); - uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); - - storm::handleGSPNExportSettings(*gspn); - - std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); - storm::builder::JaniGSPNBuilder builder(*gspn); - storm::jani::Model* model = builder.build(); - storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); - - - storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); - auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); - auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); - auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); - - auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); - auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); - - storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); - if (janiSettings.isJaniFileSet()) { - storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); - } - - delete model; - delete gspn; - storm::utility::cleanUp(); + // Transform to GSPN + storm::api::transformToGSPN(*dft); return; } - bool parametric = false; -#ifdef STORM_HAVE_CARL - parametric = generalSettings.isParametricSet(); -#endif - + #ifdef STORM_HAVE_Z3 if (faultTreeSettings.solveWithSMT()) { // Solve with SMT - if (parametric) { - // analyzeWithSMT<storm::RationalFunction>(dftSettings.getDftFilename()); - } else { - analyzeWithSMT<double>(dftIOSettings.getDftFilename()); - } - storm::utility::cleanUp(); + STORM_LOG_DEBUG("Running DFT analysis with use of SMT"); + storm::api::exportDFTToSMT(*dft, "test.smt2"); + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only exported to SMT file 'test.smt2' but analysis is not supported."); return; } #endif @@ -172,9 +71,8 @@ void processOptions() { optimizationDirection = "max"; } - // Construct properties to check for + // Construct properties to analyse std::vector<std::string> properties; - if (ioSettings.isPropertySet()) { properties.push_back(ioSettings.getProperty()); } @@ -197,38 +95,31 @@ void processOptions() { } } - if (properties.empty()) { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No property given."); + // Build properties + STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidSettingsException, "No property given."); + std::string propString = properties[0]; + for (size_t i = 1; i < properties.size(); ++i) { + propString += ";" + properties[i]; } + std::vector<std::shared_ptr<storm::logic::Formula const>> props = storm::api::extractFormulasFromProperties(storm::api::parseProperties(propString)); + STORM_LOG_ASSERT(props.size() > 0, "No properties found."); - // Set possible approximation error - double approximationError = 0.0; + // Carry out the actual analysis if (faultTreeSettings.isApproximationErrorSet()) { - approximationError = faultTreeSettings.getApproximationError(); - } - - // From this point on we are ready to carry out the actual computations. - if (parametric) { -#ifdef STORM_HAVE_CARL - analyzeDFT<storm::RationalFunction>(properties, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); -#endif + // Approximate analysis + storm::api::analyzeDFTApprox<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), faultTreeSettings.getApproximationError(), true); } else { - analyzeDFT<double>(properties, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), approximationError); + storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), !faultTreeSettings.isDisableDC(), true); } } /*! - * Entry point for the DyFTeE backend. + * Entry point for Storm-DFT. * * @param argc The argc argument of main(). * @param argv The argv argument of main(). * @return Return code, 0 if successfull, not 0 otherwise. */ -/*! - * Main entry point of the executable storm-pars. - */ int main(const int argc, const char** argv) { try { storm::utility::setUp(); @@ -240,8 +131,12 @@ int main(const int argc, const char** argv) { return -1; } - processOptions(); - //storm::pars::processOptions(); + storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); + if (generalSettings.isParametricSet()) { + processOptions<storm::RationalFunction>(); + } else { + processOptions<double>(); + } totalTimer.stop(); if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) { @@ -252,10 +147,10 @@ int main(const int argc, const char** argv) { storm::utility::cleanUp(); return 0; } catch (storm::exceptions::BaseException const& exception) { - STORM_LOG_ERROR("An exception caused Storm-DyFTeE to terminate. The message of the exception is: " << exception.what()); + STORM_LOG_ERROR("An exception caused Storm-DFT to terminate. The message of the exception is: " << exception.what()); return 1; } catch (std::exception const& exception) { - STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DyFTeE to terminate. The message of this exception is: " << exception.what()); + STORM_LOG_ERROR("An unexpected exception occurred and caused Storm-DFT to terminate. The message of this exception is: " << exception.what()); return 2; } } diff --git a/src/storm-dft/CMakeLists.txt b/src/storm-dft/CMakeLists.txt index 9ec70aed2..f191e537f 100644 --- a/src/storm-dft/CMakeLists.txt +++ b/src/storm-dft/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_dft_headers DEPENDS ${STORM_DFT_OUTPUT_HEADERS} ${S add_dependencies(storm-dft copy_storm_dft_headers) # installation -install(TARGETS storm-dft RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-dft EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-dft/api/storm-dft.cpp b/src/storm-dft/api/storm-dft.cpp new file mode 100644 index 000000000..91632739e --- /dev/null +++ b/src/storm-dft/api/storm-dft.cpp @@ -0,0 +1,67 @@ +#include "storm-dft/api/storm-dft.h" + +namespace storm { + namespace api { + + template<> + void exportDFTToJson(storm::storage::DFT<double> const& dft, std::string const& file) { + storm::storage::DftJsonExporter<double>::toFile(dft, file); + } + + template<> + void exportDFTToJson(storm::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to JSON not supported for this data type."); + } + + template<> + void exportDFTToSMT(storm::storage::DFT<double> const& dft, std::string const& file) { + storm::modelchecker::DFTASFChecker asfChecker(dft); + asfChecker.convert(); + asfChecker.toFile(file); + } + + template<> + void exportDFTToSMT(storm::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type."); + } + + template<> + void transformToGSPN(storm::storage::DFT<double> const& dft) { + // Transform to GSPN + storm::transformations::dft::DftToGspnTransformator<double> gspnTransformator(dft); + bool smart = true; + gspnTransformator.transform(smart); + storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); + uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); + + storm::api::handleGSPNExportSettings(*gspn); + + std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn->getExpressionManager(); + storm::builder::JaniGSPNBuilder builder(*gspn); + storm::jani::Model* model = builder.build(); + storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); + + storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); + auto evtlFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression); + auto tbFormula = std::make_shared<storm::logic::BoundedUntilFormula>(std::make_shared<storm::logic::BooleanLiteralFormula>(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundReference(storm::logic::TimeBoundType::Time)); + auto tbUntil = std::make_shared<storm::logic::ProbabilityOperatorFormula>(tbFormula); + + auto evFormula = std::make_shared<storm::logic::EventuallyFormula>(evtlFormula, storm::logic::FormulaContext::Time); + auto rewFormula = std::make_shared<storm::logic::TimeOperatorFormula>(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); + + storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); + if (janiSettings.isJaniFileSet()) { + storm::api::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); + } + + delete model; + delete gspn; + } + + template<> + void transformToGSPN(storm::storage::DFT<storm::RationalFunction> const& dft) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type."); + } + + } +} diff --git a/src/storm-dft/api/storm-dft.h b/src/storm-dft/api/storm-dft.h new file mode 100644 index 000000000..db6d7b3e4 --- /dev/null +++ b/src/storm-dft/api/storm-dft.h @@ -0,0 +1,117 @@ +#pragma once + +#include <type_traits> + +#include "storm-dft/parser/DFTGalileoParser.h" +#include "storm-dft/parser/DFTJsonParser.h" +#include "storm-dft/storage/dft/DftJsonExporter.h" + +#include "storm-dft/modelchecker/dft/DFTModelChecker.h" +#include "storm-dft/modelchecker/dft/DFTASFChecker.h" + +#include "storm-dft/transformations/DftToGspnTransformator.h" +#include "storm-gspn/api/storm-gspn.h" + +namespace storm { + namespace api { + + /*! + * Load DFT from Galileo file. + * + * @param file File containing DFT description in Galileo format. + * + * @return DFT. + */ + template<typename ValueType> + std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTGalileo(std::string const& file) { + return std::make_shared<storm::storage::DFT<ValueType>>(storm::parser::DFTGalileoParser<ValueType>::parseDFT(file)); + } + + /*! + * Load DFT from JSON file. + * + * @param file File containing DFT description in JSON format. + * + * @return DFT. + */ + template<typename ValueType> + std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTJson(std::string const& file) { + storm::parser::DFTJsonParser<ValueType> parser; + return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJson(file)); + } + + /*! + * Analyse the given DFT according to the given properties. + * First the Markov model is built from the DFT and then this model is checked against the given properties. + * + * @param dft DFT. + * @param properties PCTL formulas capturing the properties to check. + * @param symred Flag whether symmetry reduction should be used. + * @param allowModularisation Flag whether modularisation should be applied if possible. + * @param enableDC Flag whether Don't Care propagation should be used. + * + * @return Result. + */ + template <typename ValueType> + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, bool printOutput) { + storm::modelchecker::DFTModelChecker<ValueType> modelChecker; + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, 0.0); + if (printOutput) { + modelChecker.printTimings(); + modelChecker.printResults(); + } + return results; + } + + /*! + * Approximate the analysis result of the given DFT according to the given properties. + * First the Markov model is built from the DFT and then this model is checked against the given properties. + * + * @param dft DFT. + * @param properties PCTL formulas capturing the properties to check. + * @param symred Flag whether symmetry reduction should be used. + * @param allowModularisation Flag whether modularisation should be applied if possible. + * @param enableDC Flag whether Don't Care propagation should be used. + * @param approximationError Allowed approximation error. + * + * @return Result. + */ + template <typename ValueType> + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFTApprox(storm::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError, bool printOutput) { + storm::modelchecker::DFTModelChecker<ValueType> modelChecker; + typename storm::modelchecker::DFTModelChecker<ValueType>::dft_results results = modelChecker.check(dft, properties, symred, allowModularisation, enableDC, approximationError); + if (printOutput) { + modelChecker.printTimings(); + modelChecker.printResults(); + } + return results; + } + + /*! + * Export DFT to JSON file. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + void exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file); + + /*! + * Export DFT to SMT encoding. + * + * @param dft DFT. + * @param file File. + */ + template<typename ValueType> + void exportDFTToSMT(storm::storage::DFT<ValueType> const& dft, std::string const& file); + + /*! + * Transform DFT to GSPN. + * + * @param dft DFT. + */ + template<typename ValueType> + void transformToGSPN(storm::storage::DFT<ValueType> const& dft); + + } +} diff --git a/src/storm-dft/storage/dft/DFTBuilder.cpp b/src/storm-dft/builder/DFTBuilder.cpp similarity index 73% rename from src/storm-dft/storage/dft/DFTBuilder.cpp rename to src/storm-dft/builder/DFTBuilder.cpp index 88abc9665..a333c3cd6 100644 --- a/src/storm-dft/storage/dft/DFTBuilder.cpp +++ b/src/storm-dft/builder/DFTBuilder.cpp @@ -11,15 +11,15 @@ namespace storm { - namespace storage { + namespace builder { template<typename ValueType> std::size_t DFTBuilder<ValueType>::mUniqueOffset = 0; template<typename ValueType> - DFT<ValueType> DFTBuilder<ValueType>::build() { + storm::storage::DFT<ValueType> DFTBuilder<ValueType>::build() { for(auto& elem : mChildNames) { - DFTGatePointer gate = std::static_pointer_cast<DFTGate<ValueType>>(elem.first); + DFTGatePointer gate = std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(elem.first); for(auto const& child : elem.second) { auto itFind = mElements.find(child); if (itFind != mElements.end()) { @@ -54,16 +54,16 @@ namespace storm { for(auto& elem : mDependencyChildNames) { bool first = true; - std::vector<std::shared_ptr<DFTBE<ValueType>>> dependencies; + std::vector<std::shared_ptr<storm::storage::DFTBE<ValueType>>> dependencies; for(auto const& childName : elem.second) { auto itFind = mElements.find(childName); STORM_LOG_ASSERT(itFind != mElements.end(), "Child '" << childName << "' not found"); DFTElementPointer childElement = itFind->second; if (!first) { STORM_LOG_ASSERT(childElement->isBasicElement(), "Child '" << childName << "' of dependency '" << elem.first->name() << "' must be BE."); - dependencies.push_back(std::static_pointer_cast<DFTBE<ValueType>>(childElement)); + dependencies.push_back(std::static_pointer_cast<storm::storage::DFTBE<ValueType>>(childElement)); } else { - elem.first->setTriggerElement(std::static_pointer_cast<DFTGate<ValueType>>(childElement)); + elem.first->setTriggerElement(std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(childElement)); childElement->addOutgoingDependency(elem.first); } first = false; @@ -92,7 +92,7 @@ namespace storm { } STORM_LOG_ASSERT(!mTopLevelIdentifier.empty(), "No top level element."); - DFT<ValueType> dft(elems, mElements[mTopLevelIdentifier]); + storm::storage::DFT<ValueType> dft(elems, mElements[mTopLevelIdentifier]); // Set layout info for (auto& elem : mElements) { @@ -113,7 +113,7 @@ namespace storm { if(elem->nrChildren() == 0 || elem->isDependency()) { elem->setRank(0); } else { - DFTGatePointer gate = std::static_pointer_cast<DFTGate<ValueType>>(elem); + DFTGatePointer gate = std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(elem); unsigned maxrnk = 0; unsigned newrnk = 0; @@ -131,7 +131,7 @@ namespace storm { } template<typename ValueType> - bool DFTBuilder<ValueType>::addRestriction(std::string const& name, std::vector<std::string> const& children, DFTElementType tp) { + bool DFTBuilder<ValueType>::addRestriction(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp) { if (children.size() <= 1) { STORM_LOG_ERROR("Sequence enforcers require at least two children"); } @@ -140,10 +140,10 @@ namespace storm { } DFTRestrictionPointer restr; switch (tp) { - case DFTElementType::SEQ: - restr = std::make_shared<DFTSeq<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::SEQ: + restr = std::make_shared<storm::storage::DFTSeq<ValueType>>(mNextId++, name); break; - case DFTElementType::MUTEX: + case storm::storage::DFTElementType::MUTEX: // TODO notice that mutex state generation support is lacking anyway, as DONT CARE propagation would be broken for this. STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not supported."); break; @@ -159,7 +159,7 @@ namespace storm { } template<typename ValueType> - bool DFTBuilder<ValueType>::addStandardGate(std::string const& name, std::vector<std::string> const& children, DFTElementType tp) { + bool DFTBuilder<ValueType>::addStandardGate(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp) { STORM_LOG_ASSERT(children.size() > 0, "No child for " << name); if(mElements.count(name) != 0) { // Element with that name already exists. @@ -167,28 +167,28 @@ namespace storm { } DFTElementPointer element; switch(tp) { - case DFTElementType::AND: - element = std::make_shared<DFTAnd<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::AND: + element = std::make_shared<storm::storage::DFTAnd<ValueType>>(mNextId++, name); break; - case DFTElementType::OR: - element = std::make_shared<DFTOr<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::OR: + element = std::make_shared<storm::storage::DFTOr<ValueType>>(mNextId++, name); break; - case DFTElementType::PAND: - element = std::make_shared<DFTPand<ValueType>>(mNextId++, name, pandDefaultInclusive); + case storm::storage::DFTElementType::PAND: + element = std::make_shared<storm::storage::DFTPand<ValueType>>(mNextId++, name, pandDefaultInclusive); break; - case DFTElementType::POR: - element = std::make_shared<DFTPor<ValueType>>(mNextId++, name, porDefaultInclusive); + case storm::storage::DFTElementType::POR: + element = std::make_shared<storm::storage::DFTPor<ValueType>>(mNextId++, name, porDefaultInclusive); break; - case DFTElementType::SPARE: - element = std::make_shared<DFTSpare<ValueType>>(mNextId++, name); + case storm::storage::DFTElementType::SPARE: + element = std::make_shared<storm::storage::DFTSpare<ValueType>>(mNextId++, name); break; - case DFTElementType::BE: - case DFTElementType::VOT: - case DFTElementType::PDEP: + case storm::storage::DFTElementType::BE: + case storm::storage::DFTElementType::VOT: + case storm::storage::DFTElementType::PDEP: // Handled separately STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type handled separately."); - case DFTElementType::CONSTF: - case DFTElementType::CONSTS: + case storm::storage::DFTElementType::CONSTF: + case storm::storage::DFTElementType::CONSTS: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not supported."); default: STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Gate type not known."); @@ -199,29 +199,29 @@ namespace storm { } template<typename ValueType> - void DFTBuilder<ValueType>::topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>>& visited, DFTElementVector& L) { + void DFTBuilder<ValueType>::topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>>& visited, DFTElementVector& L) { if(visited[n] == topoSortColour::GREY) { throw storm::exceptions::WrongFormatException("DFT is cyclic"); } else if(visited[n] == topoSortColour::WHITE) { if(n->isGate()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTGate<ValueType>>(n)->children()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(n)->children()) { topoVisit(c, visited, L); } } // TODO restrictions and dependencies have no parents, so this can be done more efficiently. if(n->isRestriction()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTRestriction<ValueType>>(n)->children()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTRestriction<ValueType>>(n)->children()) { topoVisit(c, visited, L); } } if(n->isDependency()) { visited[n] = topoSortColour::GREY; - for (DFTElementPointer const& c : std::static_pointer_cast<DFTDependency<ValueType>>(n)->dependentEvents()) { + for (DFTElementPointer const& c : std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(n)->dependentEvents()) { topoVisit(c, visited, L); } - topoVisit(std::static_pointer_cast<DFTDependency<ValueType>>(n)->triggerEvent(), visited, L); + topoVisit(std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(n)->triggerEvent(), visited, L); } visited[n] = topoSortColour::BLACK; L.push_back(n); @@ -229,8 +229,8 @@ namespace storm { } template<typename ValueType> - std::vector<std::shared_ptr<DFTElement<ValueType>>> DFTBuilder<ValueType>::topoSort() { - std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>> visited; + std::vector<std::shared_ptr<storm::storage::DFTElement<ValueType>>> DFTBuilder<ValueType>::topoSort() { + std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>> visited; for(auto const& e : mElements) { visited.insert(std::make_pair(e.second, topoSortColour::WHITE)); } @@ -252,22 +252,22 @@ namespace storm { void DFTBuilder<ValueType>::copyElement(DFTElementPointer element) { std::vector<std::string> children; switch (element->type()) { - case DFTElementType::AND: - case DFTElementType::OR: - case DFTElementType::PAND: - case DFTElementType::POR: - case DFTElementType::SPARE: - case DFTElementType::VOT: + case storm::storage::DFTElementType::AND: + case storm::storage::DFTElementType::OR: + case storm::storage::DFTElementType::PAND: + case storm::storage::DFTElementType::POR: + case storm::storage::DFTElementType::SPARE: + case storm::storage::DFTElementType::VOT: { - for (DFTElementPointer const& elem : std::static_pointer_cast<DFTGate<ValueType>>(element)->children()) { + for (DFTElementPointer const& elem : std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(element)->children()) { children.push_back(elem->name()); } - copyGate(std::static_pointer_cast<DFTGate<ValueType>>(element), children); + copyGate(std::static_pointer_cast<storm::storage::DFTGate<ValueType>>(element), children); break; } - case DFTElementType::BE: + case storm::storage::DFTElementType::BE: { - std::shared_ptr<DFTBE<ValueType>> be = std::static_pointer_cast<DFTBE<ValueType>>(element); + std::shared_ptr<storm::storage::DFTBE<ValueType>> be = std::static_pointer_cast<storm::storage::DFTBE<ValueType>>(element); ValueType dormancyFactor = storm::utility::zero<ValueType>(); if (be->canFail()) { dormancyFactor = be->passiveFailureRate() / be->activeFailureRate(); @@ -275,14 +275,14 @@ namespace storm { addBasicElement(be->name(), be->activeFailureRate(), dormancyFactor, be->isTransient()); break; } - case DFTElementType::CONSTF: - case DFTElementType::CONSTS: + case storm::storage::DFTElementType::CONSTF: + case storm::storage::DFTElementType::CONSTS: // TODO STORM_LOG_ASSERT(false, "Const elements not supported."); break; - case DFTElementType::PDEP: + case storm::storage::DFTElementType::PDEP: { - DFTDependencyPointer dependency = std::static_pointer_cast<DFTDependency<ValueType>>(element); + DFTDependencyPointer dependency = std::static_pointer_cast<storm::storage::DFTDependency<ValueType>>(element); children.push_back(dependency->triggerEvent()->name()); for(auto const& depEv : dependency->dependentEvents()) { children.push_back(depEv->name()); @@ -290,10 +290,10 @@ namespace storm { addDepElement(element->name(), children, dependency->probability()); break; } - case DFTElementType::SEQ: - case DFTElementType::MUTEX: + case storm::storage::DFTElementType::SEQ: + case storm::storage::DFTElementType::MUTEX: { - for (DFTElementPointer const& elem : std::static_pointer_cast<DFTRestriction<ValueType>>(element)->children()) { + for (DFTElementPointer const& elem : std::static_pointer_cast<storm::storage::DFTRestriction<ValueType>>(element)->children()) { children.push_back(elem->name()); } addRestriction(element->name(), children, element->type()); @@ -308,15 +308,15 @@ namespace storm { template<typename ValueType> void DFTBuilder<ValueType>::copyGate(DFTGatePointer gate, std::vector<std::string> const& children) { switch (gate->type()) { - case DFTElementType::AND: - case DFTElementType::OR: - case DFTElementType::PAND: - case DFTElementType::POR: - case DFTElementType::SPARE: + case storm::storage::DFTElementType::AND: + case storm::storage::DFTElementType::OR: + case storm::storage::DFTElementType::PAND: + case storm::storage::DFTElementType::POR: + case storm::storage::DFTElementType::SPARE: addStandardGate(gate->name(), children, gate->type()); break; - case DFTElementType::VOT: - addVotElement(gate->name(), std::static_pointer_cast<DFTVot<ValueType>>(gate)->threshold(), children); + case storm::storage::DFTElementType::VOT: + addVotElement(gate->name(), std::static_pointer_cast<storm::storage::DFTVot<ValueType>>(gate)->threshold(), children); break; default: STORM_LOG_ASSERT(false, "Dft type not known."); diff --git a/src/storm-dft/storage/dft/DFTBuilder.h b/src/storm-dft/builder/DFTBuilder.h similarity index 81% rename from src/storm-dft/storage/dft/DFTBuilder.h rename to src/storm-dft/builder/DFTBuilder.h index 42713e601..625355371 100644 --- a/src/storm-dft/storage/dft/DFTBuilder.h +++ b/src/storm-dft/builder/DFTBuilder.h @@ -11,18 +11,22 @@ namespace storm { namespace storage { + // Forward declaration template<typename ValueType> class DFT; + } + + namespace builder { template<typename ValueType> class DFTBuilder { - using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>; + using DFTElementPointer = std::shared_ptr<storm::storage::DFTElement<ValueType>>; using DFTElementVector = std::vector<DFTElementPointer>; - using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>; + using DFTGatePointer = std::shared_ptr<storm::storage::DFTGate<ValueType>>; using DFTGateVector = std::vector<DFTGatePointer>; - using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>; - using DFTRestrictionPointer = std::shared_ptr<DFTRestriction<ValueType>>; + using DFTDependencyPointer = std::shared_ptr<storm::storage::DFTDependency<ValueType>>; + using DFTRestrictionPointer = std::shared_ptr<storm::storage::DFTRestriction<ValueType>>; private: std::size_t mNextId = 0; @@ -34,7 +38,7 @@ namespace storm { std::unordered_map<DFTDependencyPointer, std::vector<std::string>> mDependencyChildNames; std::vector<DFTDependencyPointer> mDependencies; std::vector<DFTRestrictionPointer> mRestrictions; - std::unordered_map<std::string, DFTLayoutInfo> mLayoutInfo; + std::unordered_map<std::string, storm::storage::DFTLayoutInfo> mLayoutInfo; public: DFTBuilder(bool defaultInclusive = true, bool binaryDependencies = true) : pandDefaultInclusive(defaultInclusive), porDefaultInclusive(defaultInclusive), binaryDependencies(binaryDependencies) { @@ -42,47 +46,47 @@ namespace storm { } bool addAndElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::AND); + return addStandardGate(name, children, storm::storage::DFTElementType::AND); } bool addOrElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::OR); + return addStandardGate(name, children, storm::storage::DFTElementType::OR); } bool addPandElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::PAND); + return addStandardGate(name, children, storm::storage::DFTElementType::PAND); } bool addPandElement(std::string const& name, std::vector<std::string> const& children, bool inclusive) { bool tmpDefault = pandDefaultInclusive; pandDefaultInclusive = inclusive; - bool result = addStandardGate(name, children, DFTElementType::PAND); + bool result = addStandardGate(name, children, storm::storage::DFTElementType::PAND); pandDefaultInclusive = tmpDefault; return result; } bool addPorElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::POR); + return addStandardGate(name, children, storm::storage::DFTElementType::POR); } bool addPorElement(std::string const& name, std::vector<std::string> const& children, bool inclusive) { bool tmpDefault = porDefaultInclusive; porDefaultInclusive = inclusive; - bool result = addStandardGate(name, children, DFTElementType::POR); + bool result = addStandardGate(name, children, storm::storage::DFTElementType::POR); pandDefaultInclusive = tmpDefault; return result; } bool addSpareElement(std::string const& name, std::vector<std::string> const& children) { - return addStandardGate(name, children, DFTElementType::SPARE); + return addStandardGate(name, children, storm::storage::DFTElementType::SPARE); } bool addSequenceEnforcer(std::string const& name, std::vector<std::string> const& children) { - return addRestriction(name, children, DFTElementType::SEQ); + return addRestriction(name, children, storm::storage::DFTElementType::SEQ); } bool addMutex(std::string const& name, std::vector<std::string> const& children) { - return addRestriction(name, children, DFTElementType::MUTEX); + return addRestriction(name, children, storm::storage::DFTElementType::MUTEX); } bool addDepElement(std::string const& name, std::vector<std::string> const& children, ValueType probability) { @@ -125,15 +129,13 @@ namespace storm { } STORM_LOG_ASSERT(storm::utility::isOne(probability) || children.size() == 2, "PDep with multiple children supported."); - DFTDependencyPointer element = std::make_shared<DFTDependency<ValueType>>(mNextId++, - nameDep, - probability); + DFTDependencyPointer element = std::make_shared<storm::storage::DFTDependency<ValueType>>(mNextId++, nameDep, probability); mElements[element->name()] = element; mDependencyChildNames[element] = {trigger, children[i]}; mDependencies.push_back(element); } } else { - DFTDependencyPointer element = std::make_shared<DFTDependency<ValueType>>(mNextId++, name, probability); + DFTDependencyPointer element = std::make_shared<storm::storage::DFTDependency<ValueType>>(mNextId++, name, probability); mElements[element->name()] = element; mDependencyChildNames[element] = children; mDependencies.push_back(element); @@ -161,7 +163,7 @@ namespace storm { STORM_LOG_ERROR("Voting gates with threshold higher than the number of children is not supported."); return false; } - DFTElementPointer element = std::make_shared<DFTVot<ValueType>>(mNextId++, name, threshold); + DFTElementPointer element = std::make_shared<storm::storage::DFTVot<ValueType>>(mNextId++, name, threshold); mElements[name] = element; mChildNames[element] = children; @@ -173,7 +175,7 @@ namespace storm { //failureRate > 0 //0 <= dormancyFactor <= 1 - mElements[name] = std::make_shared<DFTBE<ValueType>>(mNextId++, name, failureRate, dormancyFactor, transient); + mElements[name] = std::make_shared<storm::storage::DFTBE<ValueType>>(mNextId++, name, failureRate, dormancyFactor, transient); return true; } @@ -189,7 +191,7 @@ namespace storm { std::string getUniqueName(std::string name); - DFT<ValueType> build(); + storm::storage::DFT<ValueType> build(); /** * Copy element and insert it again in the builder. @@ -211,13 +213,13 @@ namespace storm { unsigned computeRank(DFTElementPointer const& elem); - bool addStandardGate(std::string const& name, std::vector<std::string> const& children, DFTElementType tp); + bool addStandardGate(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp); - bool addRestriction(std::string const& name, std::vector<std::string> const& children, DFTElementType tp); + bool addRestriction(std::string const& name, std::vector<std::string> const& children, storm::storage::DFTElementType tp); enum class topoSortColour {WHITE, BLACK, GREY}; - void topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, OrderElementsById<ValueType>>& visited, DFTElementVector& L); + void topoVisit(DFTElementPointer const& n, std::map<DFTElementPointer, topoSortColour, storm::storage::OrderElementsById<ValueType>>& visited, DFTElementVector& L); DFTElementVector topoSort(); diff --git a/src/storm-dft/modelchecker/dft/DFTASFChecker.h b/src/storm-dft/modelchecker/dft/DFTASFChecker.h index c4a47116d..a4337bb58 100644 --- a/src/storm-dft/modelchecker/dft/DFTASFChecker.h +++ b/src/storm-dft/modelchecker/dft/DFTASFChecker.h @@ -33,13 +33,15 @@ namespace storm { } + friend bool operator<(SpareAndChildPair const& p1, SpareAndChildPair const& p2) { + return p1.spareIndex < p2.spareIndex || (p1.spareIndex == p2.spareIndex && p1.childIndex < p2.childIndex); + } + + private: uint64_t spareIndex; uint64_t childIndex; }; - bool operator<(SpareAndChildPair const& p1, SpareAndChildPair const& p2) { - return p1.spareIndex < p2.spareIndex || (p1.spareIndex == p2.spareIndex && p1.childIndex < p2.childIndex); - } class DFTASFChecker { using ValueType = double; diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp index d2b435c1c..8d277d60d 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.cpp @@ -14,7 +14,7 @@ namespace storm { namespace modelchecker { template<typename ValueType> - void DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::vector<std::shared_ptr<const storm::logic::Formula>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { + typename DFTModelChecker<ValueType>::dft_results DFTModelChecker<ValueType>::check(storm::storage::DFT<ValueType> const& origDft, std::vector<std::shared_ptr<const storm::logic::Formula>> const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { // Initialize this->approximationError = approximationError; totalTimer.start(); @@ -33,11 +33,11 @@ namespace storm { for (ValueType result : resultsValue) { checkResults.push_back(result); } - } else { checkResults = checkHelper(dft, properties, symred, allowModularisation, enableDC, approximationError); } totalTimer.stop(); + return checkResults; } template<typename ValueType> @@ -54,14 +54,14 @@ namespace storm { case storm::storage::DFTElementType::AND: STORM_LOG_TRACE("top modularisation called AND"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = dfts.size(); nrM = dfts.size(); break; case storm::storage::DFTElementType::OR: STORM_LOG_TRACE("top modularisation called OR"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = 0; nrM = dfts.size(); invResults = true; @@ -69,7 +69,7 @@ namespace storm { case storm::storage::DFTElementType::VOT: STORM_LOG_TRACE("top modularisation called VOT"); dfts = dft.topModularisation(); - STORM_LOG_TRACE("Modularsation into " << dfts.size() << " submodules."); + STORM_LOG_TRACE("Modularisation into " << dfts.size() << " submodules."); nrK = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dft.getTopLevelGate())->threshold(); nrM = dfts.size(); if(nrK <= nrM/2) { @@ -176,7 +176,7 @@ namespace storm { bool firstTime = true; std::shared_ptr<storm::models::sparse::Ctmc<ValueType>> composedModel; for (auto const ft : dfts) { - STORM_LOG_INFO("Building Model via parallel composition..."); + STORM_LOG_DEBUG("Building Model via parallel composition..."); explorationTimer.start(); // Find symmetries @@ -185,12 +185,12 @@ namespace storm { if(symred) { auto colouring = ft.colourDFT(); symmetries = ft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } // Build a single CTMC - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(ft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties); builder.buildModel(labeloptions, 0, 0.0); @@ -226,7 +226,7 @@ namespace storm { } } - composedModel->printModelInformationToStream(std::cout); + //composedModel->printModelInformationToStream(std::cout); return composedModel; } else { // No composition was possible @@ -237,17 +237,17 @@ namespace storm { if(symred) { auto colouring = dft.colourDFT(); symmetries = dft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } // Build a single CTMC - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties); builder.buildModel(labeloptions, 0, 0.0); std::shared_ptr<storm::models::sparse::Model<ValueType>> model = builder.getModel(); - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); explorationTimer.stop(); STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Ctmc), storm::exceptions::NotSupportedException, "Parallel composition only applicable for CTMCs"); return model->template as<storm::models::sparse::Ctmc<ValueType>>(); @@ -264,7 +264,7 @@ namespace storm { if(symred) { auto colouring = dft.colourDFT(); symmetries = dft.findSymmetries(colouring); - STORM_LOG_INFO("Found " << symmetries.groups.size() << " symmetries."); + STORM_LOG_DEBUG("Found " << symmetries.groups.size() << " symmetries."); STORM_LOG_TRACE("Symmetries: " << std::endl << symmetries); } @@ -292,7 +292,7 @@ namespace storm { if (iteration > 0) { explorationTimer.start(); } - STORM_LOG_INFO("Building model..."); + STORM_LOG_DEBUG("Building model..."); // TODO Matthias refine model using existing model and MC results builder.buildModel(labeloptions, iteration, approximationError); explorationTimer.stop(); @@ -301,10 +301,10 @@ namespace storm { // TODO Matthias: possible to do bisimulation on approximated model and not on concrete one? // Build model for lower bound - STORM_LOG_INFO("Getting model for lower bound..."); + STORM_LOG_DEBUG("Getting model for lower bound..."); model = builder.getModelApproximation(true, !probabilityFormula); // We only output the info from the lower bound as the info for the upper bound is the same - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); buildingTimer.stop(); // Check lower bounds @@ -314,7 +314,7 @@ namespace storm { approxResult.first = newResult[0]; // Build model for upper bound - STORM_LOG_INFO("Getting model for upper bound..."); + STORM_LOG_DEBUG("Getting model for upper bound..."); buildingTimer.start(); model = builder.getModelApproximation(false, !probabilityFormula); buildingTimer.stop(); @@ -326,25 +326,25 @@ namespace storm { ++iteration; STORM_LOG_ASSERT(comparator.isLess(approxResult.first, approxResult.second) || comparator.isEqual(approxResult.first, approxResult.second), "Under-approximation " << approxResult.first << " is greater than over-approximation " << approxResult.second); - STORM_LOG_INFO("Result after iteration " << iteration << ": (" << std::setprecision(10) << approxResult.first << ", " << approxResult.second << ")"); + //STORM_LOG_INFO("Result after iteration " << iteration << ": (" << std::setprecision(10) << approxResult.first << ", " << approxResult.second << ")"); totalTimer.stop(); printTimings(); totalTimer.start(); STORM_LOG_THROW(!storm::utility::isInfinity<ValueType>(approxResult.first) && !storm::utility::isInfinity<ValueType>(approxResult.second), storm::exceptions::NotSupportedException, "Approximation does not work if result might be infinity."); } while (!isApproximationSufficient(approxResult.first, approxResult.second, approximationError, probabilityFormula)); - STORM_LOG_INFO("Finished approximation after " << iteration << " iteration" << (iteration > 1 ? "s." : ".")); + //STORM_LOG_INFO("Finished approximation after " << iteration << " iteration" << (iteration > 1 ? "s." : ".")); dft_results results; results.push_back(approxResult); return results; } else { // Build a single Markov Automaton - STORM_LOG_INFO("Building Model..."); + STORM_LOG_DEBUG("Building Model..."); storm::builder::ExplicitDFTModelBuilder<ValueType> builder(dft, symmetries, enableDC); typename storm::builder::ExplicitDFTModelBuilder<ValueType>::LabelOptions labeloptions(properties, storm::settings::getModule<storm::settings::modules::IOSettings>().isExportExplicitSet()); builder.buildModel(labeloptions, 0, 0.0); std::shared_ptr<storm::models::sparse::Model<ValueType>> model = builder.getModel(); - model->printModelInformationToStream(std::cout); + //model->printModelInformationToStream(std::cout); explorationTimer.stop(); // Export the model if required @@ -373,15 +373,15 @@ namespace storm { // Bisimulation if (model->isOfType(storm::models::ModelType::Ctmc) && storm::settings::getModule<storm::settings::modules::GeneralSettings>().isBisimulationSet()) { bisimulationTimer.start(); - STORM_LOG_INFO("Bisimulation..."); + STORM_LOG_DEBUG("Bisimulation..."); model = storm::api::performDeterministicSparseBisimulationMinimization<storm::models::sparse::Ctmc<ValueType>>(model->template as<storm::models::sparse::Ctmc<ValueType>>(), properties, storm::storage::BisimulationType::Weak)->template as<storm::models::sparse::Ctmc<ValueType>>(); - STORM_LOG_INFO("No. states (Bisimulation): " << model->getNumberOfStates()); - STORM_LOG_INFO("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); + STORM_LOG_DEBUG("No. states (Bisimulation): " << model->getNumberOfStates()); + STORM_LOG_DEBUG("No. transitions (Bisimulation): " << model->getNumberOfTransitions()); bisimulationTimer.stop(); } // Check the model - STORM_LOG_INFO("Model checking..."); + STORM_LOG_DEBUG("Model checking..."); modelCheckingTimer.start(); std::vector<ValueType> results; @@ -390,18 +390,18 @@ namespace storm { for (auto property : properties) { singleModelCheckingTimer.reset(); singleModelCheckingTimer.start(); - STORM_PRINT_AND_LOG("Model checking property " << *property << " ..." << std::endl); + //STORM_PRINT_AND_LOG("Model checking property " << *property << " ..." << std::endl); std::unique_ptr<storm::modelchecker::CheckResult> result(storm::api::verifyWithSparseEngine<ValueType>(model, storm::api::createTask<ValueType>(property, true))); STORM_LOG_ASSERT(result, "Result does not exist."); result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates())); ValueType resultValue = result->asExplicitQuantitativeCheckResult<ValueType>().getValueMap().begin()->second; - STORM_PRINT_AND_LOG("Result (initial states): " << resultValue << std::endl); + //STORM_PRINT_AND_LOG("Result (initial states): " << resultValue << std::endl); results.push_back(resultValue); singleModelCheckingTimer.stop(); - STORM_PRINT_AND_LOG("Time for model checking: " << singleModelCheckingTimer << "." << std::endl); + //STORM_PRINT_AND_LOG("Time for model checking: " << singleModelCheckingTimer << "." << std::endl); } modelCheckingTimer.stop(); - STORM_LOG_INFO("Model checking done."); + STORM_LOG_DEBUG("Model checking done."); return results; } diff --git a/src/storm-dft/modelchecker/dft/DFTModelChecker.h b/src/storm-dft/modelchecker/dft/DFTModelChecker.h index 597feb3cb..6da5d5aaa 100644 --- a/src/storm-dft/modelchecker/dft/DFTModelChecker.h +++ b/src/storm-dft/modelchecker/dft/DFTModelChecker.h @@ -17,12 +17,11 @@ namespace storm { template<typename ValueType> class DFTModelChecker { + public: typedef std::pair<ValueType, ValueType> approximation_result; typedef std::vector<boost::variant<ValueType, approximation_result>> dft_results; typedef std::vector<std::shared_ptr<storm::logic::Formula const>> property_vector; - public: - /*! * Constructor. */ @@ -38,8 +37,10 @@ namespace storm { * @param allowModularisation Flag indication if modularisation is allowed * @param enableDC Flag indicating if dont care propagation should be used * @param approximationError Error allowed for approximation. Value 0 indicates no approximation + * + * @return Model checking results for the given properties. */ - void check(storm::storage::DFT<ValueType> const& origDft, property_vector const& properties, bool symred = true, bool allowModularisation = true, bool enableDC = true, double approximationError = 0.0); + dft_results check(storm::storage::DFT<ValueType> const& origDft, property_vector const& properties, bool symred = true, bool allowModularisation = true, bool enableDC = true, double approximationError = 0.0); /*! * Print timings of all operations to stream. diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index c81c2767a..94ef80c67 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -2,12 +2,14 @@ #include <iostream> #include <fstream> +#include <regex> + #include <boost/algorithm/string.hpp> -#include <boost/lexical_cast.hpp> #include <boost/algorithm/string/replace.hpp> #include "storm/exceptions/NotImplementedException.h" #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/WrongFormatException.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" @@ -15,156 +17,229 @@ namespace storm { namespace parser { template<typename ValueType> - storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename) { - readFile(filename); - storm::storage::DFT<ValueType> dft = builder.build(); - STORM_LOG_DEBUG("Elements:" << std::endl << dft.getElementsString()); - STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString()); - return dft; - } - - template<typename ValueType> - std::string DFTGalileoParser<ValueType>::stripQuotsFromName(std::string const& name) { + std::string DFTGalileoParser<ValueType>::parseName(std::string const& name) { size_t firstQuots = name.find("\""); size_t secondQuots = name.find("\"", firstQuots+1); + std::string parsedName; - if(firstQuots == std::string::npos) { - return name; + if (firstQuots == std::string::npos) { + parsedName = name; } else { - STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::FileIoException, "No ending quotation mark found in " << name); - return name.substr(firstQuots+1,secondQuots-1); + STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::WrongFormatException, "No ending quotation mark found in " << name); + parsedName = name.substr(firstQuots+1,secondQuots-1); } - } - - template<typename ValueType> - std::string DFTGalileoParser<ValueType>::parseNodeIdentifier(std::string const& name) { - return boost::replace_all_copy(name, "'", "__prime__"); + return boost::replace_all_copy(parsedName, "'", "__prime__"); } template<typename ValueType> - void DFTGalileoParser<ValueType>::readFile(const std::string& filename) { - // constants - std::string toplevelToken = "toplevel"; - std::string toplevelId; - std::string parametricToken = "param"; + storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename, bool defaultInclusive, bool binaryDependencies) { + storm::builder::DFTBuilder<ValueType> builder(defaultInclusive, binaryDependencies); + ValueParser<ValueType> valueParser; + // Regular expression to detect comments + // taken from: https://stackoverflow.com/questions/9449887/removing-c-c-style-comments-using-boostregex + const std::regex commentRegex("(/\\*([^*]|(\\*+[^*/]))*\\*+/)|(//.*)"); std::ifstream file; storm::utility::openFile(filename, file); + std::string line; + size_t lineNo = 0; + std::string toplevelId = ""; + bool comment = false; // Indicates whether the current line is part of a multiline comment while (std::getline(file, line)) { - bool success = true; - STORM_LOG_TRACE("Parsing: " << line); - size_t commentstarts = line.find("//"); - line = line.substr(0, commentstarts); - size_t firstsemicolon = line.find(";"); - line = line.substr(0, firstsemicolon); - if (line.find_first_not_of(' ') == std::string::npos) { - // Only whitespace - continue; + ++lineNo; + // First consider comments + if (comment) { + // Line is part of multiline comment -> search for end of this comment + size_t commentEnd = line.find("*/"); + if (commentEnd == std::string::npos) { + continue; + } else { + // Remove comment + line = line.substr(commentEnd + 2); + comment = false; + } + } + // Remove comments + line = std::regex_replace(line, commentRegex, ""); + // Check if multiline comment starts + size_t commentStart = line.find("/*"); + if (commentStart != std::string::npos) { + // Remove comment + line = line.substr(0, commentStart); + comment = true; } - // Top level indicator. - if(boost::starts_with(line, toplevelToken)) { - toplevelId = stripQuotsFromName(line.substr(toplevelToken.size() + 1)); + boost::trim(line); + if (line.empty()) { + // Empty line + continue; } - else if (boost::starts_with(line, parametricToken)) { -#ifdef STORM_HAVE_CARL + + // Remove semicolon + STORM_LOG_THROW(line.back() == ';', storm::exceptions::WrongFormatException, "Semicolon expected at the end of line " << lineNo << "."); + line.pop_back(); + + // Split line into tokens + boost::trim(line); + std::vector<std::string> tokens; + boost::split(tokens, line, boost::is_any_of(" \t"), boost::token_compress_on); + + if (tokens[0] == "toplevel") { + // Top level indicator + STORM_LOG_THROW(toplevelId == "", storm::exceptions::WrongFormatException, "Toplevel element already defined."); + STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected element id after 'toplevel' in line " << lineNo << "."); + toplevelId = parseName(tokens[1]); + } else if (tokens[0] == "param") { + // Parameters + STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, "Expected parameter name after 'param' in line " << lineNo << "."); STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); - std::string parameter = stripQuotsFromName(line.substr(parametricToken.size() + 1)); - storm::expressions::Variable var = manager->declareRationalVariable(parameter); - identifierMapping.emplace(var.getName(), var); - parser.setIdentifierMapping(identifierMapping); - STORM_LOG_TRACE("Added parameter: " << var.getName()); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); -#endif + valueParser.addParameter(parseName(tokens[1])); } else { - std::vector<std::string> tokens; - boost::split(tokens, line, boost::is_any_of(" ")); - std::string name(parseNodeIdentifier(stripQuotsFromName(tokens[0]))); + // DFT element + std::string name = parseName(tokens[0]); std::vector<std::string> childNames; for(unsigned i = 2; i < tokens.size(); ++i) { - childNames.push_back(parseNodeIdentifier(stripQuotsFromName(tokens[i]))); + childNames.push_back(parseName(tokens[i])); } - if(tokens[1] == "and") { + bool success = true; + + // Add element according to type + std::string type = tokens[1]; + if (type == "and") { success = builder.addAndElement(name, childNames); - } else if (tokens[1] == "or") { + } else if (type == "or") { success = builder.addOrElement(name, childNames); - } else if (boost::starts_with(tokens[1], "vot")) { - success = builder.addVotElement(name, boost::lexical_cast<unsigned>(tokens[1].substr(3)), childNames); - } else if (tokens[1].find("of") != std::string::npos) { - size_t pos = tokens[1].find("of"); - unsigned threshold = boost::lexical_cast<unsigned>(tokens[1].substr(0, pos)); - unsigned count = boost::lexical_cast<unsigned>(tokens[1].substr(pos + 2)); - STORM_LOG_THROW(count == childNames.size(), storm::exceptions::FileIoException, "Voting gate does not correspond to number of children."); + } else if (boost::starts_with(type, "vot")) { + unsigned threshold = NumberParser<unsigned>::parse(type.substr(3)); + success = builder.addVotElement(name, threshold, childNames); + } else if (type.find("of") != std::string::npos) { + size_t pos = type.find("of"); + unsigned threshold = NumberParser<unsigned>::parse(type.substr(0, pos)); + unsigned count = NumberParser<unsigned>::parse(type.substr(pos + 2)); + STORM_LOG_THROW(count == childNames.size(), storm::exceptions::WrongFormatException, "Voting gate number " << count << " does not correspond to number of children " << childNames.size() << "in line " << lineNo << "."); success = builder.addVotElement(name, threshold, childNames); - } else if (tokens[1] == "pand") { - success = builder.addPandElement(name, childNames); - } else if (tokens[1] == "pand-inc") { + } else if (type == "pand") { + success = builder.addPandElement(name, childNames, defaultInclusive); + } else if (type == "pand-inc") { success = builder.addPandElement(name, childNames, true); - } else if (tokens[1] == "pand-ex") { + } else if (type == "pand-ex") { success = builder.addPandElement(name, childNames, false); - } else if (tokens[1] == "por") { - success = builder.addPorElement(name, childNames); - } else if (tokens[1] == "por-ex") { + } else if (type == "por") { + success = builder.addPorElement(name, childNames, defaultInclusive); + } else if (type == "por-ex") { success = builder.addPorElement(name, childNames, false); - } else if (tokens[1] == "por-inc") { + } else if (type == "por-inc") { success = builder.addPorElement(name, childNames, true); - } else if (tokens[1] == "wsp" || tokens[1] == "csp") { + } else if (type == "wsp" || type == "csp" || type == "hsp") { success = builder.addSpareElement(name, childNames); - } else if (tokens[1] == "seq") { + } else if (type == "seq") { success = builder.addSequenceEnforcer(name, childNames); - } else if (tokens[1] == "fdep") { + } else if (type == "fdep") { + STORM_LOG_THROW(childNames.size() >= 2, storm::exceptions::WrongFormatException, "FDEP gate needs at least two children in line " << lineNo << "."); success = builder.addDepElement(name, childNames, storm::utility::one<ValueType>()); - } else if (boost::starts_with(tokens[1], "pdep=")) { - ValueType probability = parseRationalExpression(tokens[1].substr(5)); + } else if (boost::starts_with(type, "pdep=")) { + ValueType probability = valueParser.parseValue(type.substr(5)); success = builder.addDepElement(name, childNames, probability); - } else if (boost::starts_with(tokens[1], "lambda=")) { - ValueType failureRate = parseRationalExpression(tokens[1].substr(7)); - ValueType dormancyFactor = parseRationalExpression(tokens[2].substr(5)); - success = builder.addBasicElement(name, failureRate, dormancyFactor, false); // TODO set transient BEs + } else if (type.find("=") != std::string::npos) { + success = parseBasicElement(tokens, builder, valueParser); } else { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << tokens[1] << " not recognized."); + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " << type << " in line " << lineNo << " not recognized."); success = false; } - STORM_LOG_THROW(success, storm::exceptions::FileIoException, "Error while adding element '" << name << "' of line '" << line << "'."); + STORM_LOG_THROW(success, storm::exceptions::FileIoException, "Error while adding element '" << name << "' in line " << lineNo << "."); } } - if(!builder.setTopLevel(toplevelId)) { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown."); + + if (!builder.setTopLevel(toplevelId)) { + STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id '" << toplevelId << "' unknown."); } storm::utility::closeFile(file); + + // Build DFT + storm::storage::DFT<ValueType> dft = builder.build(); + STORM_LOG_DEBUG("DFT Elements:" << std::endl << dft.getElementsString()); + STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString()); + return dft; } template<typename ValueType> - ValueType DFTGalileoParser<ValueType>::parseRationalExpression(std::string const& expr) { - STORM_LOG_ASSERT(false, "Specialized method should be called."); - return 0; - } + bool DFTGalileoParser<ValueType>::parseBasicElement(std::vector<std::string> const& tokens, storm::builder::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser) { + // Default values + Distribution distribution = Distribution::None; + ValueType firstValDistribution = storm::utility::zero<ValueType>(); + ValueType secondValDistribution = storm::utility::zero<ValueType>(); + ValueType dormancyFactor = storm::utility::one<ValueType>(); + size_t replication = 1; - template<> - double DFTGalileoParser<double>::parseRationalExpression(std::string const& expr) { - return boost::lexical_cast<double>(expr); - } + // Parse properties and determine distribution + for (size_t i = 1; i < tokens.size(); ++i) { + std::string token = tokens[i]; + if (boost::starts_with(token, "prob=")) { + STORM_LOG_THROW(distribution == Distribution::None, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::Constant; + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Constant distribution is not supported."); + } else if (boost::starts_with(token, "lambda=")) { + STORM_LOG_THROW(distribution == Distribution::None, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(7)); + distribution = Distribution::Exponential; + } else if (boost::starts_with(token, "rate=")) { + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::Weibull, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::Weibull; + } else if (boost::starts_with(token, "shape=")) { + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::Weibull, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + secondValDistribution = valueParser.parseValue(token.substr(6)); + distribution = Distribution::Weibull; + } else if (boost::starts_with(token, "mean=")) { + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::LogNormal, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + firstValDistribution = valueParser.parseValue(token.substr(5)); + distribution = Distribution::LogNormal; + } else if (boost::starts_with(token, "stddev=")) { + STORM_LOG_THROW(distribution == Distribution::None || distribution == Distribution::LogNormal, storm::exceptions::WrongFormatException, "A different distribution was already defined for this basic element."); + secondValDistribution = valueParser.parseValue(token.substr(7)); + distribution = Distribution::LogNormal; + } else if (boost::starts_with(token, "cov=")) { + STORM_LOG_WARN("Coverage is not supported and will be ignored."); + } else if (boost::starts_with(token, "res=")) { + STORM_LOG_WARN("Restoration is not supported and will be ignored."); + } else if (boost::starts_with(token, "repl=")) { + replication = NumberParser<unsigned>::parse(token.substr(5)); + STORM_LOG_THROW(replication == 1, storm::exceptions::NotSupportedException, "Replication > 1 is not supported."); + } else if (boost::starts_with(token, "dorm=")) { + dormancyFactor = valueParser.parseValue(token.substr(5)); + } + } - // Explicitly instantiate the class. - template class DFTGalileoParser<double>; + switch (distribution) { + case Constant: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Constant distribution is not supported."); + break; + case Exponential: + return builder.addBasicElement(parseName(tokens[0]), firstValDistribution, dormancyFactor, false); // TODO set transient BEs + break; + case Weibull: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Weibull distribution is not supported."); + break; + case LogNormal: + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "LogNormal distribution is not supported."); + break; + case None: + // go-through + default: + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "No distribution for basic element defined."); + break; + } + return false; -#ifdef STORM_HAVE_CARL - template<> - storm::RationalFunction DFTGalileoParser<storm::RationalFunction>::parseRationalExpression(std::string const& expr) { - STORM_LOG_TRACE("Translating expression: " << expr); - storm::expressions::Expression expression = parser.parseFromString(expr); - STORM_LOG_TRACE("Expression: " << expression); - storm::RationalFunction rationalFunction = evaluator.asRational(expression); - STORM_LOG_TRACE("Parsed expression: " << rationalFunction); - return rationalFunction; } + // Explicitly instantiate the class. + template class DFTGalileoParser<double>; template class DFTGalileoParser<RationalFunction>; -#endif - + } } diff --git a/src/storm-dft/parser/DFTGalileoParser.h b/src/storm-dft/parser/DFTGalileoParser.h index c2a35bc50..c56540edd 100644 --- a/src/storm-dft/parser/DFTGalileoParser.h +++ b/src/storm-dft/parser/DFTGalileoParser.h @@ -7,39 +7,53 @@ #include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm-dft/storage/dft/DFT.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" +#include "storm/parser/ValueParser.h" namespace storm { namespace parser { + /*! + * Parser for DFT in the Galileo format. + */ template<typename ValueType> class DFTGalileoParser { - storm::storage::DFTBuilder<ValueType> builder; - - std::shared_ptr<storm::expressions::ExpressionManager> manager; - - storm::parser::ExpressionParser parser; - - storm::expressions::ExpressionEvaluator<ValueType> evaluator; - - std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; - public: - DFTGalileoParser(bool defaultInclusive = true, bool binaryDependencies = true) : builder(defaultInclusive, binaryDependencies), manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { - } - storm::storage::DFT<ValueType> parseDFT(std::string const& filename); + /*! + * Parse DFT in Galileo format and build DFT. + * + * @param filename File. + * @param defaultInclusive Flag indicating if priority gates are inclusive by default. + * @param binaryDependencies Flag indicating if dependencies should be converted to binary dependencies. + * + * @return DFT. + */ + static storm::storage::DFT<ValueType> parseDFT(std::string const& filename, bool defaultInclusive = true, bool binaryDependencies = true); private: - void readFile(std::string const& filename); - - std::string stripQuotsFromName(std::string const& name); - std::string parseNodeIdentifier(std::string const& name); - - ValueType parseRationalExpression(std::string const& expr); - - bool defaultInclusive; + /*! + * Parse element name (strip quotation marks, etc.). + * + * @param name Element name. + * + * @return Name. + */ + static std::string parseName(std::string const& name); + + /*! + * Parse basic element and add it to builder. + * + * @param tokens Tokens defining the basic element. + * @param builder DFTBuilder. + * @param valueParser ValueParser. + * + * @return True iff the parsing and creation was successful. + */ + static bool parseBasicElement(std::vector<std::string> const& tokens, storm::builder::DFTBuilder<ValueType>& builder, ValueParser<ValueType>& valueParser); + + enum Distribution { None, Constant, Exponential, Weibull, LogNormal }; }; } } diff --git a/src/storm-dft/parser/DFTJsonParser.h b/src/storm-dft/parser/DFTJsonParser.h index d23baf58e..5517d85e1 100644 --- a/src/storm-dft/parser/DFTJsonParser.h +++ b/src/storm-dft/parser/DFTJsonParser.h @@ -7,7 +7,7 @@ #include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm-dft/storage/dft/DFT.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" // JSON parser #include "json.hpp" @@ -19,7 +19,7 @@ namespace storm { template<typename ValueType> class DFTJsonParser { - storm::storage::DFTBuilder<ValueType> builder; + storm::builder::DFTBuilder<ValueType> builder; std::shared_ptr<storm::expressions::ExpressionManager> manager; diff --git a/src/storm-dft/settings/DftSettings.cpp b/src/storm-dft/settings/DftSettings.cpp index b80afa2ce..361ccdc8f 100644 --- a/src/storm-dft/settings/DftSettings.cpp +++ b/src/storm-dft/settings/DftSettings.cpp @@ -9,10 +9,14 @@ #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/EigenEquationSolverSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" +#include "storm/settings/modules/GameSolverSettings.h" #include "storm/settings/modules/BisimulationSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" @@ -33,11 +37,15 @@ namespace storm { storm::settings::addModule<storm::settings::modules::CoreSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); - storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EliminationSettings>(); storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); + storm::settings::addModule<storm::settings::modules::GameSolverSettings>(false); // storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); diff --git a/src/storm-dft/settings/modules/DftIOSettings.cpp b/src/storm-dft/settings/modules/DftIOSettings.cpp index cf656333d..8704cd036 100644 --- a/src/storm-dft/settings/modules/DftIOSettings.cpp +++ b/src/storm-dft/settings/modules/DftIOSettings.cpp @@ -26,6 +26,8 @@ namespace storm { const std::string DftIOSettings::maxValueOptionName = "max"; const std::string DftIOSettings::transformToGspnOptionName = "gspn"; const std::string DftIOSettings::exportToJsonOptionName = "export-json"; + const std::string DftIOSettings::displayStatsOptionName = "show-dft-stats"; + DftIOSettings::DftIOSettings() : ModuleSettings(moduleName) { this->addOption(storm::settings::OptionBuilder(moduleName, dftFileOptionName, false, "Parses the model given in the Galileo format.").setShortName(dftFileOptionShortName) @@ -40,6 +42,8 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, maxValueOptionName, false, "Compute maximal value in case of non-determinism.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, transformToGspnOptionName, false, "Transform DFT to GSPN.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, exportToJsonOptionName, false, "Export the model to the Cytoscape JSON format.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the JSON file to export to.").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, displayStatsOptionName, false, "Print stats to stdout").build()); + } bool DftIOSettings::isDftFileSet() const { @@ -109,6 +113,10 @@ namespace storm { return this->getOption(exportToJsonOptionName).getArgumentByName("filename").getValueAsString(); } + bool DftIOSettings::isDisplayStatsSet() const { + return this->getOption(displayStatsOptionName).getHasOptionBeenSet(); + } + void DftIOSettings::finalize() { } @@ -121,3 +129,4 @@ namespace storm { } // namespace modules } // namespace settings } // namespace storm + diff --git a/src/storm-dft/settings/modules/DftIOSettings.h b/src/storm-dft/settings/modules/DftIOSettings.h index 8a8fbcdd1..f57f9ed44 100644 --- a/src/storm-dft/settings/modules/DftIOSettings.h +++ b/src/storm-dft/settings/modules/DftIOSettings.h @@ -121,6 +121,13 @@ namespace storm { * @return The name of the json file to export to. */ std::string getExportJsonFilename() const; + + /*! + * Retrieves whether statistics for the DFT should be displayed. + * + * @return True if the statistics option was set. + */ + bool isDisplayStatsSet() const; bool check() const override; void finalize() override; @@ -143,7 +150,8 @@ namespace storm { static const std::string maxValueOptionName; static const std::string transformToGspnOptionName; static const std::string exportToJsonOptionName; - + static const std::string displayStatsOptionName; + }; } // namespace modules diff --git a/src/storm-dft/storage/BucketPriorityQueue.cpp b/src/storm-dft/storage/BucketPriorityQueue.cpp index 3fccf05f9..c9b2adf24 100644 --- a/src/storm-dft/storage/BucketPriorityQueue.cpp +++ b/src/storm-dft/storage/BucketPriorityQueue.cpp @@ -9,7 +9,7 @@ namespace storm { template<typename ValueType> BucketPriorityQueue<ValueType>::BucketPriorityQueue(size_t nrBuckets, double lowerValue, double ratio) : lowerValue(lowerValue), logBase(std::log(ratio)), nrBuckets(nrBuckets), nrUnsortedItems(0), buckets(nrBuckets), currentBucket(nrBuckets) { - compare = ([this](HeuristicPointer a, HeuristicPointer b) { + compare = ([](HeuristicPointer a, HeuristicPointer b) { return *a < *b; }); } diff --git a/src/storm-dft/storage/dft/DFT.cpp b/src/storm-dft/storage/dft/DFT.cpp index b21338c74..ad89354f3 100644 --- a/src/storm-dft/storage/dft/DFT.cpp +++ b/src/storm-dft/storage/dft/DFT.cpp @@ -7,7 +7,7 @@ #include "storm/utility/iota_n.h" #include "storm/utility/vector.h" -#include "storm-dft/storage/dft/DFTBuilder.h" +#include "storm-dft/builder/DFTBuilder.h" #include "storm-dft/storage/dft/DFTIsomorphism.h" @@ -271,7 +271,7 @@ namespace storm { std::vector<DFT<ValueType>> res; for(auto const& subdft : subdfts) { - DFTBuilder<ValueType> builder; + storm::builder::DFTBuilder<ValueType> builder; for(size_t id : subdft.second) { builder.copyElement(mElements[id]); @@ -293,22 +293,22 @@ namespace storm { } return max; } - + template<typename ValueType> DFT<ValueType> DFT<ValueType>::optimize() const { std::vector<size_t> modIdea = findModularisationRewrite(); STORM_LOG_DEBUG("Modularisation idea: " << storm::utility::vector::toString(modIdea)); - + if (modIdea.empty()) { // No rewrite needed return *this; } - + std::vector<std::vector<size_t>> rewriteIds; rewriteIds.push_back(modIdea); - - DFTBuilder<ValueType> builder; - + + storm::builder::DFTBuilder<ValueType> builder; + // Accumulate elements which must be rewritten std::set<size_t> rewriteSet; for (std::vector<size_t> rewrites : rewriteIds) { @@ -320,7 +320,7 @@ namespace storm { builder.copyElement(elem); } } - + // Add rewritten elements for (std::vector<size_t> rewrites : rewriteIds) { STORM_LOG_ASSERT(rewrites.size() > 1, "No rewritten elements."); @@ -359,7 +359,7 @@ namespace storm { STORM_LOG_ASSERT(false, "Dft type can not be rewritten."); break; } - + // Add parent with the new child newParent and all its remaining children childrenNames.clear(); childrenNames.push_back(newParentName); @@ -371,14 +371,42 @@ namespace storm { } builder.copyGate(originalParent, childrenNames); } - + builder.setTopLevel(mElements[mTopLevelIndex]->name()); // TODO use reference? DFT<ValueType> newDft = builder.build(); STORM_LOG_TRACE(newDft.getElementsString()); return newDft.optimize(); } - + + template<typename ValueType> + size_t DFT<ValueType>::nrDynamicElements() const { + size_t noDyn = 0; + for (auto const& elem : mElements) { + switch (elem->type()) { + case DFTElementType::AND: + case DFTElementType::OR: + case DFTElementType::VOT: + case DFTElementType::BE: + case DFTElementType::CONSTF: + case DFTElementType::CONSTS: + break; + case DFTElementType::PAND: + case DFTElementType::SPARE: + case DFTElementType::POR: + case DFTElementType::SEQ: + case DFTElementType::MUTEX: + case DFTElementType::PDEP: + noDyn += 1; + break; + default: + STORM_LOG_ASSERT(false, "DFT element type " << elem->type() << " not known."); + break; + } + } + return noDyn; + } + template<typename ValueType> std::string DFT<ValueType>::getElementsString() const { std::stringstream stream; @@ -722,11 +750,10 @@ namespace storm { // suitable parent gate! - Lets check the independent submodules of the children auto const& children = std::static_pointer_cast<DFTGate<ValueType>>(e)->children(); for(auto const& child : children) { - - + auto ISD = std::static_pointer_cast<DFTGate<ValueType>>(child)->independentSubDft(true); // In the ISD, check for other children: - + std::vector<size_t> rewrite = {e->id(), child->id()}; for(size_t isdElemId : ISD) { if(isdElemId == child->id()) continue; @@ -737,13 +764,13 @@ namespace storm { if(rewrite.size() > 2 && rewrite.size() < children.size() - 1) { return rewrite; } - - } + + } } - } + } return {}; } - + template<typename ValueType> std::tuple<std::vector<size_t>, std::vector<size_t>, std::vector<size_t>> DFT<ValueType>::getSortedParentAndDependencyIds(size_t index) const { @@ -766,6 +793,13 @@ namespace storm { std::sort(outgoingDeps.begin(), outgoingDeps.end()); return std::make_tuple(parents, ingoingDeps, outgoingDeps); } + + template<typename ValueType> + void DFT<ValueType>::writeStatsToStream(std::ostream& stream) const { + stream << "Number of BEs: " << nrBasicElements() << std::endl; + stream << "Number of dynamic elements: " << nrDynamicElements() << std::endl; + stream << "Number of elements: " << nrElements() << std::endl; + } // Explicitly instantiate the class. template class DFT<double>; diff --git a/src/storm-dft/storage/dft/DFT.h b/src/storm-dft/storage/dft/DFT.h index 304018d97..c373c8199 100644 --- a/src/storm-dft/storage/dft/DFT.h +++ b/src/storm-dft/storage/dft/DFT.h @@ -18,6 +18,11 @@ #include "storm-dft/storage/dft/DFTLayoutInfo.h" namespace storm { + namespace builder { + // Forward declaration + template<typename T> class DFTBuilder; + } + namespace storage { template<typename ValueType> @@ -32,11 +37,8 @@ namespace storm { }; - // Forward declarations + // Forward declaration template<typename T> class DFTColouring; - - template<typename T> class DFTBuilder; - /** * Represents a Dynamic Fault Tree @@ -76,7 +78,7 @@ namespace storm { DFT<ValueType> optimize() const; - void copyElements(std::vector<size_t> elements, DFTBuilder<ValueType> builder) const; + void copyElements(std::vector<size_t> elements, storm::builder::DFTBuilder<ValueType> builder) const; size_t stateVectorSize() const { return mStateVectorSize; @@ -89,6 +91,8 @@ namespace storm { size_t nrBasicElements() const { return mNrOfBEs; } + + size_t nrDynamicElements() const; size_t getTopLevelIndex() const { return mTopLevelIndex; @@ -275,6 +279,8 @@ namespace storm { return mLayoutInfo.at(id); } + void writeStatsToStream(std::ostream& stream) const; + private: std::tuple<std::vector<size_t>, std::vector<size_t>, std::vector<size_t>> getSortedParentAndDependencyIds(size_t index) const; diff --git a/src/storm-dft/transformations/DftToGspnTransformator.cpp b/src/storm-dft/transformations/DftToGspnTransformator.cpp index 975d01f4a..7a2b0f360 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.cpp +++ b/src/storm-dft/transformations/DftToGspnTransformator.cpp @@ -16,72 +16,71 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::transform() { - + void DftToGspnTransformator<ValueType>::transform(bool smart) { + this->smart = smart; builder.setGspnName("DftToGspnTransformation"); - // Loop through every DFT element and draw them as a GSPN. - drawGSPNElements(); + // Translate all GSPN elements + translateGSPNElements(); - // Draw restrictions into the GSPN (i.e. SEQ or MUTEX). - //drawGSPNRestrictions(); + // Create initial template + // TODO } template<typename ValueType> uint64_t DftToGspnTransformator<ValueType>::toplevelFailedPlaceId() { - assert(failedNodes.size() > mDft.getTopLevelIndex()); - return failedNodes[mDft.getTopLevelIndex()]; + STORM_LOG_ASSERT(failedPlaces.size() > mDft.getTopLevelIndex(), "Failed place for top level element does not exist."); + return failedPlaces.at(mDft.getTopLevelIndex()); + } + + template <typename ValueType> + gspn::GSPN* DftToGspnTransformator<ValueType>::obtainGSPN() { + return builder.buildGspn(); } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawGSPNElements() { - - - // Loop through every DFT element and draw them as a GSPN. - for (std::size_t i = 0; i < mDft.nrElements(); i++) { + void DftToGspnTransformator<ValueType>::translateGSPNElements() { + // Loop through every DFT element and create its corresponding GSPN template. + for (std::size_t i = 0; i < mDft.nrElements(); i++) { auto dftElement = mDft.getElement(i); - bool isRepresentative = mDft.isRepresentative(i); - - // Check which type the element is and call the corresponding drawing-function. + + // Check which type the element is and call the corresponding translate-function. switch (dftElement->type()) { - case storm::storage::DFTElementType::AND: - drawAND(std::static_pointer_cast<storm::storage::DFTAnd<ValueType> const>(dftElement), isRepresentative); + case storm::storage::DFTElementType::BE: + translateBE(std::static_pointer_cast<storm::storage::DFTBE<ValueType> const>(dftElement)); + break; + case storm::storage::DFTElementType::CONSTF: + translateCONSTF(dftElement); + break; + case storm::storage::DFTElementType::CONSTS: + translateCONSTS(dftElement); + break; + case storm::storage::DFTElementType::AND: + translateAND(std::static_pointer_cast<storm::storage::DFTAnd<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::OR: - drawOR(std::static_pointer_cast<storm::storage::DFTOr<ValueType> const>(dftElement), isRepresentative); + translateOR(std::static_pointer_cast<storm::storage::DFTOr<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::VOT: - drawVOT(std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dftElement), isRepresentative); + translateVOT(std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(dftElement)); break; case storm::storage::DFTElementType::PAND: - drawPAND(std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement), isRepresentative); + translatePAND(std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement), std::static_pointer_cast<storm::storage::DFTPand<ValueType> const>(dftElement)->isInclusive()); break; + case storm::storage::DFTElementType::POR: + translatePOR(std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement), std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement)->isInclusive()); + break; case storm::storage::DFTElementType::SPARE: - drawSPARE(std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(dftElement), isRepresentative); - break; - case storm::storage::DFTElementType::POR: - drawPOR(std::static_pointer_cast<storm::storage::DFTPor<ValueType> const>(dftElement), isRepresentative); + translateSPARE(std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(dftElement)); break; + case storm::storage::DFTElementType::PDEP: + translatePDEP(std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(dftElement)); + break; case storm::storage::DFTElementType::SEQ: - drawSeq(std::static_pointer_cast<storm::storage::DFTSeq<ValueType> const>(dftElement)); + translateSeq(std::static_pointer_cast<storm::storage::DFTSeq<ValueType> const>(dftElement)); break; - case storm::storage::DFTElementType::MUTEX: - // No method call needed here. MUTEX only consists of restrictions, which are handled later. - break; - case storm::storage::DFTElementType::BE: - drawBE(std::static_pointer_cast<storm::storage::DFTBE<ValueType> const>(dftElement), isRepresentative); - break; - case storm::storage::DFTElementType::CONSTF: - drawCONSTF(dftElement, isRepresentative); - break; - case storm::storage::DFTElementType::CONSTS: - drawCONSTS(dftElement, isRepresentative); - break; - case storm::storage::DFTElementType::PDEP: - drawPDEP(std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(dftElement)); - break; default: - STORM_LOG_ASSERT(false, "DFT type unknown."); + STORM_LOG_ASSERT(false, "DFT type " << dftElement->type() << " unknown."); break; } } @@ -89,281 +88,282 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE, bool isRepresentative) { - uint64_t beActive = builder.addPlace(defaultCapacity, isBEActive(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); - activeNodes.emplace(dftBE->id(), beActive); - uint64_t beFailed = builder.addPlace(defaultCapacity, 0, dftBE->name() + STR_FAILED); - + void DftToGspnTransformator<ValueType>::translateBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE) { double xcenter = mDft.getElementLayoutInfo(dftBE->id()).x; double ycenter = mDft.getElementLayoutInfo(dftBE->id()).y; - builder.setPlaceLayoutInfo(beActive, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); - builder.setPlaceLayoutInfo(beFailed, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); - - uint64_t disabledNode = 0; - if (!smart || dftBE->nrRestrictions() > 0) { - disabledNode = addDisabledPlace(dftBE); - } - - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftBE, storm::gspn::LayoutInfo(xcenter+9.0, ycenter)); - } - - assert(failedNodes.size() == dftBE->id()); - failedNodes.push_back(beFailed); + uint64_t failedPlace = addFailedPlace(dftBE, storm::gspn::LayoutInfo(xcenter + 3.0, ycenter)); + + uint64_t activePlace = builder.addPlace(defaultCapacity, isActiveInitially(dftBE) ? 1 : 0, dftBE->name() + STR_ACTIVATED); + activePlaces.emplace(dftBE->id(), activePlace); + builder.setPlaceLayoutInfo(activePlace, storm::gspn::LayoutInfo(xcenter - 3.0, ycenter)); + uint64_t tActive = builder.addTimedTransition(defaultPriority, dftBE->activeFailureRate(), dftBE->name() + "_activeFailing"); builder.setTransitionLayoutInfo(tActive, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0)); - builder.addInputArc(beActive, tActive); - builder.addInhibitionArc(beFailed, tActive); - builder.addOutputArc(tActive, beActive); - builder.addOutputArc(tActive, beFailed); + builder.addInputArc(activePlace, tActive); + builder.addInhibitionArc(failedPlace, tActive); + builder.addOutputArc(tActive, activePlace); + builder.addOutputArc(tActive, failedPlace); + uint64_t tPassive = builder.addTimedTransition(defaultPriority, dftBE->passiveFailureRate(), dftBE->name() + "_passiveFailing"); builder.setTransitionLayoutInfo(tPassive, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0)); - builder.addInhibitionArc(beActive, tPassive); - builder.addInhibitionArc(beFailed, tPassive); - builder.addOutputArc(tPassive, beFailed); + builder.addInhibitionArc(activePlace, tPassive); + builder.addInhibitionArc(failedPlace, tPassive); + builder.addOutputArc(tPassive, failedPlace); if (!smart || dftBE->nrRestrictions() > 0) { - builder.addInhibitionArc(disabledNode, tActive); - builder.addInhibitionArc(disabledNode, tPassive); + uint64_t disabledPlace = addDisabledPlace(dftBE, storm::gspn::LayoutInfo(xcenter-9.0, ycenter)); + builder.addInhibitionArc(disabledPlace, tActive); + builder.addInhibitionArc(disabledPlace, tPassive); } - if (!smart || isRepresentative) { - builder.addOutputArc(tActive, unavailableNode); - builder.addOutputArc(tPassive, unavailableNode); + if (!smart || mDft.isRepresentative(dftBE->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftBE, storm::gspn::LayoutInfo(xcenter+9.0, ycenter)); + builder.addOutputArc(tActive, unavailablePlace); + builder.addOutputArc(tPassive, unavailablePlace); } } - - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftAnd->name() + STR_FAILED); - assert(failedNodes.size() == dftAnd->id()); - failedNodes.push_back(nodeFailed); + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF) { + double xcenter = mDft.getElementLayoutInfo(dftConstF->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftConstF->id()).y; + + addFailedPlace(dftConstF, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0), true); + + if (!smart || mDft.isRepresentative(dftConstF->id())) { + addUnavailablePlace(dftConstF, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0), false); + } + } + + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS) { + double xcenter = mDft.getElementLayoutInfo(dftConstS->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftConstS->id()).y; + + size_t capacity = 0; // It cannot contain a token, because it cannot fail. + + uint64_t failedPlace = builder.addPlace(capacity, 0, dftConstS->name() + STR_FAILED); + assert(failedPlaces.size() == dftConstS->id()); + failedPlaces.push_back(failedPlace); + builder.setPlaceLayoutInfo(failedPlace, storm::gspn::LayoutInfo(xcenter, ycenter - 3.0)); + + if (!smart || mDft.isRepresentative(dftConstS->id())) { + uint64_t unavailablePlace = builder.addPlace(capacity, 0, dftConstS->name() + "_unavail"); + unavailablePlaces.emplace(dftConstS->id(), unavailablePlace); + builder.setPlaceLayoutInfo(unavailablePlace, storm::gspn::LayoutInfo(xcenter, ycenter + 3.0)); + } + } + + template <typename ValueType> + void DftToGspnTransformator<ValueType>::translateAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd) { double xcenter = mDft.getElementLayoutInfo(dftAnd->id()).x; double ycenter = mDft.getElementLayoutInfo(dftAnd->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - unavailableNode = addUnavailableNode(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); - } + uint64_t failedPlace = addFailedPlace(dftAnd, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - - uint64_t tAndFailed = builder.addImmediateTransition( getFailPriority(dftAnd) , 0.0, dftAnd->name() + STR_FAILING ); - builder.setTransitionLayoutInfo(tAndFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tAndFailed); - builder.addOutputArc(tAndFailed, nodeFailed); - if (isRepresentative) { - builder.addOutputArc(tAndFailed, unavailableNode); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftAnd), 0.0, dftAnd->name() + STR_FAILING ); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); + + if (!smart || mDft.isRepresentative(dftAnd->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftAnd, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - for(auto const& child : dftAnd->children()) { - assert(failedNodes.size() > child->id()); - builder.addInputArc(failedNodes[child->id()], tAndFailed); - builder.addOutputArc(tAndFailed, failedNodes[child->id()]); + + for (auto const& child : dftAnd->children()) { + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftOr->name() + STR_FAILED); - assert(failedNodes.size() == dftOr->id()); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translateOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr) { double xcenter = mDft.getElementLayoutInfo(dftOr->id()).x; double ycenter = mDft.getElementLayoutInfo(dftOr->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - unavailableNode = addUnavailableNode(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + uint64_t failedPlace = addFailedPlace(dftOr, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); + + bool isRepresentative = mDft.isRepresentative(dftOr->id()); + uint64_t unavailablePlace = 0; + if (!smart || isRepresentative) { + unavailablePlace = addUnavailablePlace(dftOr, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); } - uint64_t i = 0; - for (auto const& child : dftOr->children()) { - uint64_t tNodeFailed = builder.addImmediateTransition( getFailPriority(dftOr), 0.0, dftOr->name() + STR_FAILING + std::to_string(i) ); - builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addOutputArc(tNodeFailed, nodeFailed); - if (isRepresentative) { - builder.addOutputArc(tNodeFailed, unavailableNode); + for (size_t i = 0; i < dftOr->nrChildren(); ++i) { + auto const& child = dftOr->children().at(i); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftOr), 0.0, dftOr->name() + STR_FAILING + std::to_string(i) ); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); + if (!smart || isRepresentative) { + builder.addOutputArc(tFailed, unavailablePlace); } - assert(failedNodes.size() > child->id()); - builder.addInputArc(failedNodes[child->id()], tNodeFailed); - builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); - ++i; + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot, bool isRepresentative) { + void DftToGspnTransformator<ValueType>::translateVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot) { // TODO: finish layouting - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftVot->name() + STR_FAILED); - assert(failedNodes.size() == dftVot->id()); - failedNodes.push_back(nodeFailed); double xcenter = mDft.getElementLayoutInfo(dftVot->id()).x; double ycenter = mDft.getElementLayoutInfo(dftVot->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - unavailableNode = addUnavailableNode(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); - } - - uint64_t nodeCollector = builder.addPlace(dftVot->nrChildren(), 0, dftVot->name() + "_collector"); - builder.setPlaceLayoutInfo(nodeCollector, storm::gspn::LayoutInfo(xcenter, ycenter)); + uint64_t failedPlace = addFailedPlace(dftVot, storm::gspn::LayoutInfo(xcenter, ycenter-3.0)); + + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); + builder.addOutputArc(tFailed, failedPlace); + builder.addInhibitionArc(failedPlace, tFailed); - uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + STR_FAILING); - builder.addOutputArc(tNodeFailed, nodeFailed); - if (isRepresentative) { - builder.addOutputArc(tNodeFailed, unavailableNode); + if (!smart || mDft.isRepresentative(dftVot->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftVot, storm::gspn::LayoutInfo(xcenter+6.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addInputArc(nodeCollector, tNodeFailed, dftVot->threshold()); - builder.addOutputArc(tNodeFailed, nodeCollector, dftVot->threshold()); - uint64_t i = 0; - for (auto const& child : dftVot->children()) { - uint64_t childInhibPlace = builder.addPlace(1, 0, dftVot->name() + "_child_fail_inhib" + std::to_string(i)); + + uint64_t collectorPlace = builder.addPlace(dftVot->nrChildren(), 0, dftVot->name() + "_collector"); + builder.setPlaceLayoutInfo(collectorPlace, storm::gspn::LayoutInfo(xcenter, ycenter)); + builder.addInputArc(collectorPlace, tFailed, dftVot->threshold()); + + for (size_t i = 0; i < dftVot->nrChildren(); ++i) { + auto const& child = dftVot->children().at(i); + uint64_t childNextPlace = builder.addPlace(defaultCapacity, 1, dftVot->name() + "_child_next" + std::to_string(i)); + uint64_t tCollect = builder.addImmediateTransition(getFailPriority(dftVot), 0.0, dftVot->name() + "_child_collect" + std::to_string(i)); - builder.addOutputArc(tCollect, nodeCollector); - builder.addOutputArc(tCollect, childInhibPlace); - builder.addInhibitionArc(childInhibPlace, tCollect); - builder.addInputArc(failedNodes[child->id()], tCollect); - builder.addOutputArc(tCollect, failedNodes[child->id()]); - ++i; + builder.addOutputArc(tCollect, collectorPlace); + builder.addInputArc(childNextPlace, tCollect); + builder.addInputArc(getFailedPlace(child), tCollect); + builder.addOutputArc(tCollect, getFailedPlace(child)); } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILED); - assert(failedNodes.size() == dftPand->id()); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translatePAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool inclusive) { double xcenter = mDft.getElementLayoutInfo(dftPand->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPand->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftPand, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); - } - - uint64_t tNodeFailed = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING); - builder.setTransitionLayoutInfo(tNodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); - builder.addInhibitionArc(nodeFailed, tNodeFailed); - builder.addOutputArc(tNodeFailed, nodeFailed); - if (!smart || isRepresentative) { - builder.addOutputArc(tNodeFailed, nodeFailed); + uint64_t failedPlace = addFailedPlace(dftPand, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); + + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); + builder.addInhibitionArc(failedPlace, tFailed); + builder.addOutputArc(tFailed, failedPlace); + + if (!smart || mDft.isRepresentative(dftPand->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftPand, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - if(dftPand->isInclusive()) { + if (inclusive) { // Inclusive PAND - uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILSAVE); - builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); + uint64_t failSafePlace = builder.addPlace(defaultCapacity, 0, dftPand->name() + STR_FAILSAVE); + builder.setPlaceLayoutInfo(failSafePlace, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); - builder.addInhibitionArc(nodeFS, tNodeFailed); - for(auto const& child : dftPand->children()) { - builder.addInputArc(failedNodes[child->id()], tNodeFailed); - builder.addOutputArc(tNodeFailed, failedNodes[child->id()]); + builder.addInhibitionArc(failSafePlace, tFailed); + + // Transitions for failed place + for (auto const& child : dftPand->children()) { + builder.addInputArc(getFailedPlace(child), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(child)); } - for (uint64_t j = 1; j < dftPand->nrChildren(); ++j) { - uint64_t tfs = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(j)); - builder.setTransitionLayoutInfo(tfs, storm::gspn::LayoutInfo(xcenter-6.0+j*3.0, ycenter+3.0)); - - builder.addInputArc(failedNodes[dftPand->children().at(j)->id()], tfs); - builder.addOutputArc(tfs, failedNodes[dftPand->children().at(j)->id()]); - builder.addInhibitionArc(failedNodes[dftPand->children().at(j-1)->id()], tfs); - builder.addOutputArc(tfs, nodeFS); - builder.addInhibitionArc(nodeFS, tfs); - + // Transitions for fail-safe place + for (uint64_t i = 1; i < dftPand->nrChildren(); ++i) { + auto const& child = dftPand->children().at(i); + uint64_t tFailSafe = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILSAVING + std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafe, storm::gspn::LayoutInfo(xcenter-6.0+i*3.0, ycenter+3.0)); + + builder.addInputArc(getFailedPlace(child), tFailSafe); + builder.addOutputArc(tFailSafe, getFailedPlace(child)); + builder.addInhibitionArc(getFailedPlace(dftPand->children().at(i-1)), tFailSafe); + builder.addOutputArc(tFailSafe, failSafePlace); + builder.addInhibitionArc(failSafePlace, tFailSafe); } } else { // Exclusive PAND - uint64_t fi = 0; - uint64_t tn = 0; - for(uint64_t j = 0; j < dftPand->nrChildren(); ++j) { - auto const& child = dftPand->children()[j]; - if (j > 0) { - builder.addInhibitionArc(failedNodes.at(child->id()), tn); + uint64_t failSafeXPlace = 0; + uint64_t tFailSafeX = 0; + for (size_t i = 0; i < dftPand->nrChildren(); ++i) { + auto const& child = dftPand->children().at(i); + + if (i > 0) { + // Set inhibition arc to previous transition + builder.addInhibitionArc(getFailedPlace(child), tFailSafeX); } - if (j != dftPand->nrChildren() - 1) { - tn = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(j)); - builder.setTransitionLayoutInfo(tn, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); + + if (i < dftPand->nrChildren() - 1) { + // Not last child + tFailSafeX = builder.addImmediateTransition(getFailPriority(dftPand), 0.0, dftPand->name() + STR_FAILING + "_" +std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafeX, storm::gspn::LayoutInfo(xcenter-3.0, ycenter+3.0)); } else { - tn = tNodeFailed; + // Last child + tFailSafeX = tFailed; } - builder.addInputArc(failedNodes.at(child->id()), tn); - builder.addOutputArc(tn, failedNodes.at(child->id())); - if (j > 0) { - builder.addInputArc(fi, tn); + builder.addInputArc(getFailedPlace(child), tFailSafeX); + builder.addOutputArc(tFailSafeX, getFailedPlace(child)); + + if (i > 0) { + builder.addInputArc(failSafeXPlace, tFailSafeX); } - if (j != dftPand->nrChildren() - 1) { - fi = builder.addPlace(defaultCapacity, 0, dftPand->name() + "_F_" + std::to_string(j)); - builder.setPlaceLayoutInfo(fi, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter)); - builder.addOutputArc(tn, fi); + + if (i < dftPand->nrChildren() - 1) { + // Add fail-safe X place + failSafeXPlace = builder.addPlace(defaultCapacity, 0, dftPand->name() + "_F_" + std::to_string(i)); + builder.setPlaceLayoutInfo(failSafeXPlace, storm::gspn::LayoutInfo(xcenter-3.0+i*3.0, ycenter)); + builder.addOutputArc(tFailSafeX, failSafeXPlace); + builder.addInhibitionArc(failSafeXPlace, tFailSafeX); } - } } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool isRepresentative) { - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translatePOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool inclusive) { double xcenter = mDft.getElementLayoutInfo(dftPor->id()).x; double ycenter = mDft.getElementLayoutInfo(dftPor->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t unavailableNode = 0; - if (!smart || isRepresentative) { - unavailableNode = addUnavailableNode(dftPor, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); - } + uint64_t failedPlace = addFailedPlace(dftPor, storm::gspn::LayoutInfo(xcenter+3.0, ycenter-3.0)); - uint64_t tfail = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILING); - builder.setTransitionLayoutInfo(tfail, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); - builder.addOutputArc(tfail, nodeFailed); - builder.addInhibitionArc(nodeFailed, tfail); + uint64_t tFailed = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILING); + builder.setTransitionLayoutInfo(tFailed, storm::gspn::LayoutInfo(xcenter+3.0, ycenter+3.0)); + builder.addOutputArc(tFailed, failedPlace); + builder.addInhibitionArc(failedPlace, tFailed); - builder.addInputArc(failedNodes.at(dftPor->children().front()->id()), tfail); - builder.addOutputArc(tfail, failedNodes.at(dftPor->children().front()->id())); + // Arcs from first child + builder.addInputArc(getFailedPlace(dftPor->children().front()), tFailed); + builder.addOutputArc(tFailed, getFailedPlace(dftPor->children().front())); - if(!smart || isRepresentative) { - builder.addOutputArc(tfail, unavailableNode); + if (!smart || mDft.isRepresentative(dftPor->id())) { + uint64_t unavailablePlace = addUnavailablePlace(dftPor, storm::gspn::LayoutInfo(xcenter+9.0, ycenter-3.0)); + builder.addOutputArc(tFailed, unavailablePlace); } - if(dftPor->isInclusive()) { + if (inclusive) { // Inclusive POR - uint64_t nodeFS = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILSAVE); - builder.setPlaceLayoutInfo(nodeFS, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); - - builder.addInhibitionArc(nodeFS, tfail); - uint64_t j = 0; - for (auto const& child : dftPor->children()) { - if(j > 0) { - uint64_t tfailsf = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILSAVING + std::to_string(j)); - builder.setTransitionLayoutInfo(tfailsf, storm::gspn::LayoutInfo(xcenter-3.0+j*3.0, ycenter+3.0)); - builder.addInputArc(failedNodes.at(child->id()), tfailsf); - builder.addOutputArc(tfailsf, failedNodes.at(child->id())); - builder.addOutputArc(tfailsf, nodeFS); - builder.addInhibitionArc(nodeFS, tfailsf); - builder.addInhibitionArc(failedNodes.at(dftPor->children().front()->id()), tfailsf); - } - - ++j; + uint64_t failSafePlace = builder.addPlace(defaultCapacity, 0, dftPor->name() + STR_FAILSAVE); + builder.setPlaceLayoutInfo(failSafePlace, storm::gspn::LayoutInfo(xcenter-3.0, ycenter-3.0)); + + builder.addInhibitionArc(failSafePlace, tFailed); + + // For all children except the first one + for (size_t i = 1; i < dftPor->nrChildren(); ++i) { + auto const& child = dftPor->children().at(i); + uint64_t tFailSafe = builder.addImmediateTransition(getFailPriority(dftPor), 0.0, dftPor->name() + STR_FAILSAVING + std::to_string(i)); + builder.setTransitionLayoutInfo(tFailSafe, storm::gspn::LayoutInfo(xcenter-3.0+i*3.0, ycenter+3.0)); + + builder.addInputArc(getFailedPlace(child), tFailSafe); + builder.addOutputArc(tFailSafe, getFailedPlace(child)); + builder.addOutputArc(tFailSafe, failSafePlace); + builder.addInhibitionArc(failSafePlace, tFailSafe); + builder.addInhibitionArc(getFailedPlace(dftPor->children().front()), tFailSafe); } } else { // Exclusive POR - uint64_t j = 0; + + // For all children except the first one for (auto const& child : dftPor->children()) { - if(j > 0) { - builder.addInhibitionArc(failedNodes.at(child->id()), tfail); - } - ++j; + builder.addInhibitionArc(getFailedPlace(child), tFailed); } } @@ -371,252 +371,218 @@ namespace storm { } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare, bool isRepresentative) { - - uint64_t nodeFailed = builder.addPlace(defaultCapacity, 0, dftSpare->name() + STR_FAILED); - failedNodes.push_back(nodeFailed); - + void DftToGspnTransformator<ValueType>::translateSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare) { double xcenter = mDft.getElementLayoutInfo(dftSpare->id()).x; double ycenter = mDft.getElementLayoutInfo(dftSpare->id()).y; - builder.setPlaceLayoutInfo(nodeFailed, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - unavailableNode = addUnavailableNode(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + uint64_t failedPlace = addFailedPlace(dftSpare, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + + bool isRepresentative = mDft.isRepresentative(dftSpare->id()); + uint64_t unavailablePlace = 0; + if (!smart || isRepresentative) { + unavailablePlace = addUnavailablePlace(dftSpare, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - uint64_t spareActive = builder.addPlace(defaultCapacity, isBEActive(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); - builder.setPlaceLayoutInfo(spareActive, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-8.0)); - activeNodes.emplace(dftSpare->id(), spareActive); + uint64_t activePlace = builder.addPlace(defaultCapacity, isActiveInitially(dftSpare) ? 1 : 0, dftSpare->name() + STR_ACTIVATED); + builder.setPlaceLayoutInfo(activePlace, storm::gspn::LayoutInfo(xcenter-20.0, ycenter-12.0)); + activePlaces.emplace(dftSpare->id(), activePlace); - std::vector<uint64_t> cucNodes; - std::vector<uint64_t> considerNodes; - std::vector<uint64_t> nextclTransitions; - std::vector<uint64_t> nextconsiderTransitions; - uint64_t j = 0; - for(auto const& child : dftSpare->children()) { - if (j > 0) { - size_t nodeConsider = builder.addPlace(defaultCapacity, 0, dftSpare->name()+ "_consider_" + child->name()); - considerNodes.push_back(nodeConsider); - builder.setPlaceLayoutInfo(nodeConsider, storm::gspn::LayoutInfo(xcenter-15.0+j*14.0, ycenter-8.0)); - - builder.addOutputArc(nextclTransitions.back(), considerNodes.back(), 1); - if (j > 1) { - builder.addOutputArc(nextconsiderTransitions.back(), considerNodes.back()); - } - - uint64_t tnextconsider = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); - builder.setTransitionLayoutInfo(tnextconsider, storm::gspn::LayoutInfo(xcenter-7.0+j*14.0, ycenter-8.0)); - builder.addInputArc(considerNodes.back(), tnextconsider); - builder.addInputArc(unavailableNodes.at(child->id()), tnextconsider); - nextconsiderTransitions.push_back(tnextconsider); - + std::vector<uint64_t> tNextClaims; + std::vector<uint64_t> tNextConsiders; + for (size_t i = 0; i < dftSpare->nrChildren(); ++i) { + auto const& child = dftSpare->children().at(i); + // Consider next child + size_t considerPlace = builder.addPlace(defaultCapacity, i == 0 ? 1 : 0, dftSpare->name()+ "_consider_" + child->name()); + builder.setPlaceLayoutInfo(considerPlace, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter-8.0)); + + if (i > 0) { + // Set output transition from previous next_claim + builder.addOutputArc(tNextClaims.back(), considerPlace); + // Set output transition from previous cannot_claim + builder.addOutputArc(tNextConsiders.back(), considerPlace); } - size_t nodeCUC = builder.addPlace(defaultCapacity, j == 0 ? 1 : 0, dftSpare->name() + "_claimed_" + child->name()); - cucNodes.push_back(nodeCUC); - builder.setPlaceLayoutInfo(nodeCUC, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter+5.0)); - if (j > 0) { - uint64_t tclaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); - builder.setTransitionLayoutInfo(tclaim, storm::gspn::LayoutInfo(xcenter-9.0+j*14.0, ycenter)); - builder.addInhibitionArc(unavailableNodes.at(child->id()), tclaim); - builder.addInputArc(considerNodes.back(), tclaim); - builder.addOutputArc(tclaim, cucNodes.back()); - } - uint64_t tnextcl = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(j)); - builder.setTransitionLayoutInfo(tnextcl, storm::gspn::LayoutInfo(xcenter-3.0+j*14.0, ycenter+5.0)); - builder.addInputArc(cucNodes.back(), tnextcl); - builder.addInputArc(failedNodes.at(child->id()), tnextcl); - builder.addOutputArc(tnextcl, failedNodes.at(child->id())); - nextclTransitions.push_back(tnextcl); - ++j; + + // Cannot claim child + uint64_t tConsiderNext = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_cannot_claim_" + child->name()); + builder.setTransitionLayoutInfo(tConsiderNext, storm::gspn::LayoutInfo(xcenter-7.0+i*14.0, ycenter-8.0)); + builder.addInputArc(considerPlace, tConsiderNext); + builder.addInputArc(unavailablePlaces.at(child->id()), tConsiderNext); + builder.addOutputArc(tConsiderNext, unavailablePlaces.at(child->id())); + tNextConsiders.push_back(tConsiderNext); + + // Claimed child + size_t claimedPlace = builder.addPlace(defaultCapacity, 0, dftSpare->name() + "_claimed_" + child->name()); + builder.setPlaceLayoutInfo(claimedPlace, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter+5.0)); + uint64_t tClaim = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_claim_" + child->name()); + builder.setTransitionLayoutInfo(tClaim, storm::gspn::LayoutInfo(xcenter-15.0+i*14.0, ycenter)); + builder.addInhibitionArc(unavailablePlaces.at(child->id()), tClaim); + builder.addInputArc(considerPlace, tClaim); + builder.addOutputArc(tClaim, claimedPlace); + builder.addOutputArc(tClaim, unavailablePlaces.at(child->id())); + + // Claim next + uint64_t tClaimNext = builder.addImmediateTransition(getFailPriority(dftSpare), 0.0, dftSpare->name() + "_next_claim_" + std::to_string(i)); + builder.setTransitionLayoutInfo(tClaimNext, storm::gspn::LayoutInfo(xcenter-7.0+i*14.0, ycenter+5.0)); + builder.addInputArc(claimedPlace, tClaimNext); + builder.addInputArc(getFailedPlace(child), tClaimNext); + builder.addOutputArc(tClaimNext, getFailedPlace(child)); + tNextClaims.push_back(tClaimNext); + + // Activate all elements in spare module + uint64_t l = 0; for (uint64_t k : mDft.module(child->id())) { - - uint64_t tactive = builder.addImmediateTransition(defaultPriority+1, 0.0, dftSpare->name() + "_activate_" + std::to_string(j) + "_" + std::to_string(k)); - builder.addInputArc(cucNodes.back(), tactive); - builder.addOutputArc(tactive, cucNodes.back()); - builder.addInputArc(spareActive, tactive); - builder.addOutputArc(tactive, activeNodes.at(k)); - builder.addInhibitionArc(activeNodes.at(k), tactive); + uint64_t tActivate = builder.addImmediateTransition(defaultPriority, 0.0, dftSpare->name() + "_activate_" + std::to_string(i) + "_" + std::to_string(k)); + builder.setTransitionLayoutInfo(tActivate, storm::gspn::LayoutInfo(xcenter-18.0+(i+l)*3, ycenter-12.0)); + builder.addInhibitionArc(activePlaces.at(k), tActivate); + builder.addInputArc(claimedPlace, tActivate); + builder.addInputArc(activePlace, tActivate); + builder.addOutputArc(tActivate, claimedPlace); + builder.addOutputArc(tActivate, activePlace); + builder.addOutputArc(tActivate, activePlaces.at(k)); + ++l; } - - } - builder.addOutputArc(nextconsiderTransitions.back(), nodeFailed); - builder.addOutputArc(nextclTransitions.back(), nodeFailed); - if (isRepresentative) { - builder.addOutputArc(nextconsiderTransitions.back(), unavailableNode); - builder.addOutputArc(nextclTransitions.back(), unavailableNode); - } - - + // Set arcs to failed + builder.addOutputArc(tNextConsiders.back(), failedPlace); + builder.addOutputArc(tNextClaims.back(), failedPlace); + if (!smart || isRepresentative) { + builder.addOutputArc(tNextConsiders.back(), unavailablePlace); + builder.addOutputArc(tNextClaims.back(), unavailablePlace); + } } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF, bool isRepresentative) { - failedNodes.push_back(builder.addPlace(defaultCapacity, 1, dftConstF->name() + STR_FAILED)); - uint64_t unavailableNode = 0; - if (isRepresentative) { - // TODO set position - unavailableNode = addUnavailableNode(dftConstF, storm::gspn::LayoutInfo(0, 0), false); + void DftToGspnTransformator<ValueType>::translatePDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency) { + double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y; + + if (!smart) { + addFailedPlace(dftDependency, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailablePlace(dftDependency, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); } - } -// - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS, bool isRepresentative) { -// storm::gspn::Place placeCONSTSFailed; -// placeCONSTSFailed.setName(dftConstS->name() + STR_FAILED); -// placeCONSTSFailed.setNumberOfInitialTokens(0); -// placeCONSTSFailed.setCapacity(0); // It cannot contain a token, because it cannot fail. -// mGspn.addPlace(placeCONSTSFailed); - } -// - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawPDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency) { - double xcenter = mDft.getElementLayoutInfo(dftDependency->id()).x;; - double ycenter = mDft.getElementLayoutInfo(dftDependency->id()).y;; - - uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); - builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); - uint64_t t1 = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); - - builder.addInputArc(coinPlace, t1); - builder.addInputArc(failedNodes.at(dftDependency->triggerEvent()->id()), t1); - builder.addOutputArc(t1, failedNodes.at(dftDependency->triggerEvent()->id())); - uint64_t forwardPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_forward"); - builder.setPlaceLayoutInfo(forwardPlace, storm::gspn::LayoutInfo(xcenter+1.0, ycenter+2.0)); - - if (!smart || dftDependency->probability() < 1.0) { + uint64_t forwardPlace = 0; + if (dftDependency->probability() < 1.0) { + // PDEP + forwardPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_forward"); + builder.setPlaceLayoutInfo(forwardPlace, storm::gspn::LayoutInfo(xcenter+1.0, ycenter+2.0)); + + uint64_t coinPlace = builder.addPlace(defaultCapacity, 1, dftDependency->name() + "_coin"); + builder.setPlaceLayoutInfo(coinPlace, storm::gspn::LayoutInfo(xcenter-5.0, ycenter+2.0)); + + uint64_t tStartFlip = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_start_flip"); + builder.addInputArc(coinPlace, tStartFlip); + builder.addInputArc(getFailedPlace(dftDependency->triggerEvent()), tStartFlip); + builder.addOutputArc(tStartFlip, getFailedPlace(dftDependency->triggerEvent())); + uint64_t flipPlace = builder.addPlace(defaultCapacity, 0, dftDependency->name() + "_flip"); - builder.addOutputArc(t1, flipPlace); - builder.setPlaceLayoutInfo(flipPlace, storm::gspn::LayoutInfo(xcenter-2.0, ycenter+2.0)); - uint64_t t2 = builder.addImmediateTransition(defaultPriority + 1, dftDependency->probability(), "_win_flip"); - builder.addInputArc(flipPlace, t2); - builder.addOutputArc(t2, forwardPlace); - if (dftDependency->probability() < 1.0) { - uint64_t t3 = builder.addImmediateTransition(defaultPriority + 1, 1 - dftDependency->probability(), "_loose_flip"); - builder.addInputArc(flipPlace, t3); - } + builder.addOutputArc(tStartFlip, flipPlace); + + uint64_t tWinFlip = builder.addImmediateTransition(defaultPriority, dftDependency->probability(), "_win_flip"); + builder.addInputArc(flipPlace, tWinFlip); + builder.addOutputArc(tWinFlip, forwardPlace); + + uint64_t tLooseFlip = builder.addImmediateTransition(defaultPriority, storm::utility::one<ValueType>() - dftDependency->probability(), "_loose_flip"); + builder.addInputArc(flipPlace, tLooseFlip); } else { - builder.addOutputArc(t1, forwardPlace); + // FDEP + forwardPlace = getFailedPlace(dftDependency->triggerEvent()); } - for(auto const& depEv : dftDependency->dependentEvents()) { - uint64_t tx = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_propagate_" + depEv->name()); - builder.addInputArc(forwardPlace, tx); - builder.addOutputArc(tx, forwardPlace); - builder.addOutputArc(tx, failedNodes.at(depEv->id())); - builder.addInhibitionArc(failedNodes.at(depEv->id()), tx); - if (!smart || depEv->nrRestrictions() > 0) { - builder.addInhibitionArc(disabledNodes.at(depEv->id()), tx); + + for (auto const& child : dftDependency->dependentEvents()) { + uint64_t tForwardFailure = builder.addImmediateTransition(defaultPriority, 0.0, dftDependency->name() + "_propagate_" + child->name()); + builder.addInputArc(forwardPlace, tForwardFailure); + builder.addOutputArc(tForwardFailure, forwardPlace); + builder.addOutputArc(tForwardFailure, getFailedPlace(child)); + builder.addInhibitionArc(getFailedPlace(child), tForwardFailure); + if (!smart || child->nrRestrictions() > 0) { + builder.addInhibitionArc(disabledPlaces.at(child->id()), tForwardFailure); } - if (!smart || mDft.isRepresentative(depEv->id())) { - builder.addOutputArc(tx, unavailableNodes.at(depEv->id())); + if (!smart || mDft.isRepresentative(child->id())) { + builder.addOutputArc(tForwardFailure, unavailablePlaces.at(child->id())); } - } - - - - - } template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq) { + void DftToGspnTransformator<ValueType>::translateSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq) { STORM_LOG_THROW(dftSeq->allChildrenBEs(), storm::exceptions::NotImplementedException, "Sequence enforcers with gates as children are currently not supported"); - uint64_t j = 0; + double xcenter = mDft.getElementLayoutInfo(dftSeq->id()).x; + double ycenter = mDft.getElementLayoutInfo(dftSeq->id()).y; + + if (!smart) { + addFailedPlace(dftSeq, storm::gspn::LayoutInfo(xcenter+10.0, ycenter-8.0)); + addUnavailablePlace(dftSeq, storm::gspn::LayoutInfo(xcenter+16.0, ycenter-8.0)); + } + uint64_t tEnable = 0; uint64_t nextPlace = 0; - for(auto const& child : dftSeq->children()) { - nextPlace = builder.addPlace(defaultCapacity, j==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); - if (j>0) { + for (size_t i = 0; i < dftSeq->nrChildren(); ++i) { + auto const& child = dftSeq->children().at(i); + + nextPlace = builder.addPlace(defaultCapacity, i==0 ? 1 : 0, dftSeq->name() + "_next_" + child->name()); + builder.setPlaceLayoutInfo(nextPlace, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter-3.0)); + + if (i>0) { builder.addOutputArc(tEnable, nextPlace); } - tEnable = builder.addImmediateTransition(defaultPriority + 1, 0.0, dftSeq->name() + "_unblock_" +child->name() ); + tEnable = builder.addImmediateTransition(defaultPriority, 0.0, dftSeq->name() + "_unblock_" +child->name()); + builder.setTransitionLayoutInfo(tEnable, storm::gspn::LayoutInfo(xcenter-5.0+i*3.0, ycenter+3.0)); builder.addInputArc(nextPlace, tEnable); - builder.addInputArc(disabledNodes.at(child->id()), tEnable); - if (j>0) { - builder.addInputArc(failedNodes.at(dftSeq->children().at(j-1)->id()), tEnable); + builder.addInputArc(disabledPlaces.at(child->id()), tEnable); + if (i>0) { + builder.addInputArc(getFailedPlace(dftSeq->children().at(i-1)), tEnable); } - ++j; } } - + + template<typename ValueType> + uint64_t DftToGspnTransformator<ValueType>::addFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialFailed) { + uint64_t failedPlace = builder.addPlace(defaultCapacity, initialFailed ? 1 : 0, dftElement->name() + STR_FAILED); + assert(failedPlaces.size() == dftElement->id()); + failedPlaces.push_back(failedPlace); + builder.setPlaceLayoutInfo(failedPlace, layoutInfo); + return failedPlace; + } + + template<typename ValueType> - uint64_t DftToGspnTransformator<ValueType>::addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { - uint64_t unavailableNode = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavailable"); - assert(unavailableNode != 0); - unavailableNodes.emplace(dftElement->id(), unavailableNode); - builder.setPlaceLayoutInfo(unavailableNode, layoutInfo); - return unavailableNode; + uint64_t DftToGspnTransformator<ValueType>::addUnavailablePlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable) { + uint64_t unavailablePlace = builder.addPlace(defaultCapacity, initialAvailable ? 0 : 1, dftElement->name() + "_unavail"); + unavailablePlaces.emplace(dftElement->id(), unavailablePlace); + builder.setPlaceLayoutInfo(unavailablePlace, layoutInfo); + return unavailablePlace; } template<typename ValueType> - uint64_t DftToGspnTransformator<ValueType>::addDisabledPlace(std::shared_ptr<const storm::storage::DFTBE<ValueType> > dftBe) { - uint64_t disabledNode = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); - disabledNodes.emplace(dftBe->id(), disabledNode); - return disabledNode; + uint64_t DftToGspnTransformator<ValueType>::addDisabledPlace(std::shared_ptr<const storm::storage::DFTBE<ValueType> > dftBe, storm::gspn::LayoutInfo const& layoutInfo) { + uint64_t disabledPlace = builder.addPlace(dftBe->nrRestrictions(), dftBe->nrRestrictions(), dftBe->name() + "_dabled"); + disabledPlaces.emplace(dftBe->id(), disabledPlace); + builder.setPlaceLayoutInfo(disabledPlace, layoutInfo); + return disabledPlace; } -// template <typename ValueType> - bool DftToGspnTransformator<ValueType>::isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) - { - // If element is the top element, return true. - if (dftElement->id() == mDft.getTopLevelIndex()) { - return true; - } - else { // Else look at all parents. - auto parents = dftElement->parents(); - std::vector<bool> pathValidities; - - for (std::size_t i = 0; i < parents.size(); i++) { - // Add all parents to the vector, except if the parent is a SPARE and the current element is an inactive child of the SPARE. - if (parents[i]->type() == storm::storage::DFTElementType::SPARE) { - auto children = std::static_pointer_cast<storm::storage::DFTSpare<ValueType> const>(parents[i])->children(); - if (children[0]->id() != dftElement->id()) { - continue; - } - } - - pathValidities.push_back(isBEActive(parents[i])); - } - - // Check all vector entries. If one is true, a "valid" path has been found. - for (std::size_t i = 0; i < pathValidities.size(); i++) { - if (pathValidities[i]) { - return true; - } - } - } - - // No "valid" path found. BE is inactive. - return false; + bool DftToGspnTransformator<ValueType>::isActiveInitially(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { + // If element is in the top module, return true. + return !mDft.hasRepresentant(dftElement->id()); } template <typename ValueType> uint64_t DftToGspnTransformator<ValueType>::getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { - return mDft.maxRank() - dftElement->rank() + 2; + // Temporariliy use one priority for all + return defaultPriority; + //return mDft.maxRank() - dftElement->rank() + 2; } - - template <typename ValueType> - void DftToGspnTransformator<ValueType>::drawGSPNRestrictions() { - } - template <typename ValueType> - gspn::GSPN* DftToGspnTransformator<ValueType>::obtainGSPN() { - return builder.buildGspn(); - } - // Explicitly instantiate the class. template class DftToGspnTransformator<double>; - #ifdef STORM_HAVE_CARL // template class DftToGspnTransformator<storm::RationalFunction>; diff --git a/src/storm-dft/transformations/DftToGspnTransformator.h b/src/storm-dft/transformations/DftToGspnTransformator.h index 4ec911b23..3d49505c9 100644 --- a/src/storm-dft/transformations/DftToGspnTransformator.h +++ b/src/storm-dft/transformations/DftToGspnTransformator.h @@ -25,7 +25,7 @@ namespace storm { /*! * Transform the DFT to a GSPN. */ - void transform(); + void transform(bool smart = true); /*! * Extract Gspn by building @@ -33,129 +33,174 @@ namespace storm { */ gspn::GSPN* obtainGSPN(); - + /*! + * Get failed place id of top level element. + */ uint64_t toplevelFailedPlaceId(); private: - /* - * Draw all elements of the GSPN. - */ - void drawGSPNElements(); - /* - * Draw restrictions between the elements of the GSPN (i.e. SEQ or MUTEX). + /*! + * Translate all elements of the GSPN. */ - void drawGSPNRestrictions(); - - /* - * Draw a Petri net Basic Event. + void translateGSPNElements(); + + /*! + * Translate a GSPN Basic Event. * * @param dftBE The Basic Event. */ - void drawBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE, bool isRepresentative); - - /* - * Draw a Petri net AND. + void translateBE(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBE); + + /*! + * Translate a GSPN CONSTF (Constant Failure, a Basic Event that has already failed). + * + * @param dftPor The CONSTF Basic Event. + */ + void translateCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF); + + /*! + * Translate a GSPN CONSTS (Constant Save, a Basic Event that cannot fail). + * + * @param dftPor The CONSTS Basic Event. + */ + void translateCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS); + + /*! + * Translate a GSPN AND. * * @param dftAnd The AND gate. */ - void drawAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd, bool isRepresentative); + void translateAND(std::shared_ptr<storm::storage::DFTAnd<ValueType> const> dftAnd); - /* - * Draw a Petri net OR. + /*! + * Translate a GSPN OR. * * @param dftOr The OR gate. */ - void drawOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr, bool isRepresentative); + void translateOR(std::shared_ptr<storm::storage::DFTOr<ValueType> const> dftOr); - /* - * Draw a Petri net VOT. + /*! + * Translate a GSPN VOT. * * @param dftVot The VOT gate. */ - void drawVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot, bool isRepresentative); + void translateVOT(std::shared_ptr<storm::storage::DFTVot<ValueType> const> dftVot); - /* - * Draw a Petri net PAND. - * This PAND is inklusive (children are allowed to fail simultaneously and the PAND will fail nevertheless). - * + /*! + * Translate a GSPN PAND. + * * @param dftPand The PAND gate. + * @param inclusive Flag wether the PAND is inclusive (children are allowed to fail simultaneously and the PAND will fail nevertheless) */ - void drawPAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool isRepresentative); - - /* - * Draw a Petri net SPARE. + void translatePAND(std::shared_ptr<storm::storage::DFTPand<ValueType> const> dftPand, bool inclusive = true); + + /*! + * Translate a GSPN POR. + * + * @param dftPor The POR gate. + * @param inclusive Flag wether the POR is inclusive (children are allowed to fail simultaneously and the POR will fail nevertheless) + */ + void translatePOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool inclusive = true); + + /*! + * Translate a GSPN SPARE. * * @param dftSpare The SPARE gate. */ - void drawSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare, bool isRepresentative); - - /* - * Draw a Petri net POR. - * This POR is inklusive (children are allowed to fail simultaneously and the POR will fail nevertheless). - * - * @param dftPor The POR gate. - */ - void drawPOR(std::shared_ptr<storm::storage::DFTPor<ValueType> const> dftPor, bool isRepresentative); - - /* - * Draw a Petri net CONSTF (Constant Failure, a Basic Event that has already failed). - * - * @param dftPor The CONSTF Basic Event. - */ - void drawCONSTF(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstF, bool isRepresentative); - - /* - * Draw a Petri net CONSTS (Constant Save, a Basic Event that cannot fail). - * - * @param dftPor The CONSTS Basic Event. - */ - void drawCONSTS(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftConstS, bool isRepresentative); + void translateSPARE(std::shared_ptr<storm::storage::DFTSpare<ValueType> const> dftSpare); + + /*! + * Translate a GSPN PDEP (FDEP is included with a probability of 1). + * + * @param dftDependency The PDEP gate. + */ + void translatePDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency); - /* - * Draw a Petri net PDEP (FDEP is included with a firerate of 1). + /*! + * Translate a GSPN SEQ. + * + * @param dftSeq The SEQ gate. + */ + void translateSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq); + + /*! + * Check if the element is active intially. + * + * @param dFTElement DFT element. + * + * @return True iff element is active initially. */ - void drawPDEP(std::shared_ptr<storm::storage::DFTDependency<ValueType> const> dftDependency); - - - void drawSeq(std::shared_ptr<storm::storage::DFTSeq<ValueType> const> dftSeq); - /* - * Return true if BE is active (corresponding place contains one initial token) or false if BE is inactive (corresponding place contains no initial token). - * - * @param dFTElement DFT element. - */ - bool isBEActive(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); + bool isActiveInitially(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - /* - * Get the priority of the element. - * The priority is two times the length of the shortest path to the top event. - * - * @param priority The priority of the gate. Top Event has priority 0, its children 2, its grandchildren 4, ... - * - * @param dftElement The element whose priority shall be determined. - */ - uint64_t getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); + /*! + * Get the priority of the element. + * The priority is two times the length of the shortest path to the top event. + * + * @param priority The priority of the gate. Top Event has priority 0, its children 2, its grandchildren 4, ... + * + * @param dftElement The element whose priority shall be determined. + */ + uint64_t getFailPriority(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dFTElement); - - uint64_t addUnavailableNode(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); - - uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe); + /*! + * Add failed place for an element. + * + * @param dftElement Element. + * @param layoutInfo Information about layout. + * @param initialFailed Flag indicating whether the element is initially failed. + * + * @return Id of added failed place. + */ + uint64_t addFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialFailed = false); + + /*! + * Add unavailable place for element. + * + * @param dftElement Element. + * @param layoutInfo Information about layout. + * @param initialAvailable Flag indicating whether the element is available initially. + * + * @return Id of added unavailable place. + */ + uint64_t addUnavailablePlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement, storm::gspn::LayoutInfo const& layoutInfo, bool initialAvailable = true); + + /*! + * Add disabled place for element. + * + * @param dftBe Basic Element. + * @param layoutInfo Information about layout. + * + * @return Id of added disabled place. + */ + uint64_t addDisabledPlace(std::shared_ptr<storm::storage::DFTBE<ValueType> const> dftBe, storm::gspn::LayoutInfo const& layoutInfo); + + /*! + * Get failed place for element. + * + * @param dftElement Element. + * + * @return Id of failed place corresponding to the given element. + */ + uint64_t getFailedPlace(std::shared_ptr<storm::storage::DFTElement<ValueType> const> dftElement) { + return failedPlaces.at(dftElement->id()); + } storm::storage::DFT<ValueType> const& mDft; storm::gspn::GspnBuilder builder; - std::vector<uint64_t> failedNodes; - std::map<uint64_t, uint64_t> unavailableNodes; - std::map<uint64_t, uint64_t> activeNodes; - std::map<uint64_t, uint64_t> disabledNodes; - bool smart = true; + + // Interface places for DFT elements + std::vector<uint64_t> failedPlaces; + std::map<uint64_t, uint64_t> unavailablePlaces; + std::map<uint64_t, uint64_t> activePlaces; + std::map<uint64_t, uint64_t> disabledPlaces; + bool smart; static constexpr const char* STR_FAILING = "_failing"; // Name standard for transitions that point towards a place, which in turn indicates the failure of a gate. static constexpr const char* STR_FAILED = "_failed"; // Name standard for place which indicates the failure of a gate. static constexpr const char* STR_FAILSAVING = "_failsaving"; // Name standard for transition that point towards a place, which in turn indicates the failsave state of a gate. static constexpr const char* STR_FAILSAVE = "_failsave"; // Name standard for place which indicates the failsave state of a gate. - static constexpr const char* STR_ACTIVATED = "_activated"; // Name standard for place which indicates the activity. static constexpr const char* STR_ACTIVATING = "_activating"; // Name standard for transition that point towards a place, which in turn indicates its activity. - - + static constexpr const char* STR_ACTIVATED = "_active"; // Name standard for place which indicates the activity. }; } } diff --git a/src/storm-gspn-cli/CMakeLists.txt b/src/storm-gspn-cli/CMakeLists.txt index 39d656a4c..f06ff4a53 100644 --- a/src/storm-gspn-cli/CMakeLists.txt +++ b/src/storm-gspn-cli/CMakeLists.txt @@ -5,4 +5,4 @@ set_target_properties(storm-gspn-cli PROPERTIES OUTPUT_NAME "storm-gspn") add_dependencies(binaries storm-gspn-cli) # installation -install(TARGETS storm-gspn-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-gspn-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-gspn-cli/storm-gspn.cpp b/src/storm-gspn-cli/storm-gspn.cpp index d6a493981..602b353a0 100644 --- a/src/storm-gspn-cli/storm-gspn.cpp +++ b/src/storm-gspn-cli/storm-gspn.cpp @@ -3,7 +3,7 @@ #include "storm-gspn/storage/gspn/GSPN.h" #include "storm-gspn/storage/gspn/GspnBuilder.h" #include "storm-gspn/builder/JaniGSPNBuilder.h" -#include "storm-gspn/storm-gspn.h" +#include "storm-gspn/api/storm-gspn.h" #include "storm/exceptions/BaseException.h" #include "storm/exceptions/WrongFormatException.h" @@ -44,6 +44,7 @@ void initializeSettings() { // Register all known settings modules. storm::settings::addModule<storm::settings::modules::GeneralSettings>(); + storm::settings::addModule<storm::settings::modules::IOSettings>(); storm::settings::addModule<storm::settings::modules::GSPNSettings>(); storm::settings::addModule<storm::settings::modules::GSPNExportSettings>(); storm::settings::addModule<storm::settings::modules::CoreSettings>(); @@ -92,7 +93,7 @@ int main(const int argc, const char **argv) { auto gspn = parser.parse(storm::settings::getModule<storm::settings::modules::GSPNSettings>().getGspnFilename()); std::string formulaString = ""; - if (!storm::settings::getModule<storm::settings::modules::IOSettings>().isPropertySet()) { + if (storm::settings::getModule<storm::settings::modules::IOSettings>().isPropertySet()) { formulaString = storm::settings::getModule<storm::settings::modules::IOSettings>().getProperty(); } boost::optional<std::set<std::string>> propertyFilter; @@ -108,10 +109,10 @@ int main(const int argc, const char **argv) { gspn->setCapacities(capacities); } - storm::handleGSPNExportSettings(*gspn); + storm::api::handleGSPNExportSettings(*gspn); if(storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) { - storm::jani::Model* model = storm::buildJani(*gspn); + storm::jani::Model* model = storm::api::buildJani(*gspn); storm::api::exportJaniModel(*model, properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename()); delete model; } @@ -124,25 +125,6 @@ int main(const int argc, const char **argv) { // auto builder = storm::builder::ExplicitGspnModelBuilder<>(); // auto ma = builder.translateGspn(gspn, formula); // -// // write gspn into output file -// if (!outputFile.empty()) { -// std::ofstream file; -// file.open(outputFile); -// if (outputType == "pnml") { -// gspn.toPnml(file); -// } -// if (outputType == "pnpro") { -// gspn.toPnpro(file); -// } -// if (outputType == "dot") { -// gspn.writeDotToStream(file); -// } -// if (outputType == "ma") { -// ma.writeDotToStream(file); -// } -// file.close(); -// } - // All operations have now been performed, so we clean up everything and terminate. storm::utility::cleanUp(); return 0; diff --git a/src/storm-gspn/CMakeLists.txt b/src/storm-gspn/CMakeLists.txt index cf80ff6aa..9312af543 100644 --- a/src/storm-gspn/CMakeLists.txt +++ b/src/storm-gspn/CMakeLists.txt @@ -15,4 +15,4 @@ set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) target_link_libraries(storm-gspn storm ${STORM_GSPN_LINK_LIBRARIES}) # installation -install(TARGETS storm-gspn RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-gspn EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-gspn/api/storm-gspn.cpp b/src/storm-gspn/api/storm-gspn.cpp new file mode 100644 index 000000000..08796386b --- /dev/null +++ b/src/storm-gspn/api/storm-gspn.cpp @@ -0,0 +1,61 @@ +#include "storm-gspn/api/storm-gspn.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/utility/file.h" +#include "storm-gspn/settings/modules/GSPNExportSettings.h" + + +namespace storm { + namespace api { + + storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn) { + storm::builder::JaniGSPNBuilder builder(gspn); + return builder.build(); + } + + void handleGSPNExportSettings(storm::gspn::GSPN const& gspn) { + storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>(); + if (exportSettings.isWriteToDotSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs); + gspn.writeDotToStream(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToPnproSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs); + gspn.toPnpro(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToPnmlSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs); + gspn.toPnml(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isWriteToJsonSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteToJsonFilename(), fs); + gspn.toJson(fs); + storm::utility::closeFile(fs); + } + + if (exportSettings.isDisplayStatsSet()) { + std::cout << "============GSPN Statistics==============" << std::endl; + gspn.writeStatsToStream(std::cout); + std::cout << "=========================================" << std::endl; + } + + if (exportSettings.isWriteStatsToFileSet()) { + std::ofstream fs; + storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs); + gspn.writeStatsToStream(fs); + storm::utility::closeFile(fs); + } + } + + } +} diff --git a/src/storm-gspn/api/storm-gspn.h b/src/storm-gspn/api/storm-gspn.h new file mode 100644 index 000000000..7687c35e4 --- /dev/null +++ b/src/storm-gspn/api/storm-gspn.h @@ -0,0 +1,17 @@ +#pragma once + +#include "storm/storage/jani/Model.h" +#include "storm-gspn/storage/gspn/GSPN.h" +#include "storm-gspn/builder/JaniGSPNBuilder.h" + +namespace storm { + namespace api { + + /** + * Builds JANI model from GSPN. + */ + storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn); + + void handleGSPNExportSettings(storm::gspn::GSPN const& gspn); + } +} diff --git a/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp b/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp index 2ab73ac91..ae17ca59b 100644 --- a/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp +++ b/src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp @@ -212,7 +212,7 @@ namespace storm { STORM_PRINT_AND_LOG("unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) + "): " + name + "\n"); } } - builder.addPlace(-1, initialTokens, placeName); + builder.addPlace(boost::none, initialTokens, placeName); } bool ignoreTransitionAttribute(std::string const& name) { diff --git a/src/storm-gspn/parser/PnmlParser.cpp b/src/storm-gspn/parser/PnmlParser.cpp index 71757defc..189e34266 100644 --- a/src/storm-gspn/parser/PnmlParser.cpp +++ b/src/storm-gspn/parser/PnmlParser.cpp @@ -104,7 +104,7 @@ namespace storm { std::string placeName; // the first entry is false if the corresponding information was not found in the pnml file std::pair<bool, uint_fast64_t> numberOfInitialTokens(false, defaultNumberOfInitialTokens); - std::pair<bool, int_fast64_t> capacity(false, defaultCapacity); + std::pair<bool, boost::optional<uint64_t>> capacity(false, boost::none); // traverse attributes for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) { @@ -150,10 +150,9 @@ namespace storm { } if (!capacity.first) { // no information about the capacity is found - // use default capacity STORM_PRINT_AND_LOG("unknown capacity (place=" + placeName + ")\n"); } - builder.addPlace(capacity.first ? capacity.second : -1, numberOfInitialTokens.first ? numberOfInitialTokens.second : 0, placeName); + builder.addPlace(capacity.second, numberOfInitialTokens.first ? numberOfInitialTokens.second : 0, placeName); } void PnmlParser::traverseTransition(xercesc::DOMNode const* const node) { diff --git a/src/storm-gspn/settings/modules/GSPNExportSettings.cpp b/src/storm-gspn/settings/modules/GSPNExportSettings.cpp index a3c46f250..5b7653eef 100644 --- a/src/storm-gspn/settings/modules/GSPNExportSettings.cpp +++ b/src/storm-gspn/settings/modules/GSPNExportSettings.cpp @@ -19,6 +19,7 @@ namespace storm { const std::string GSPNExportSettings::writeToPnmlOptionName = "to-pnml"; const std::string GSPNExportSettings::writeToPnproOptionName = "to-pnpro"; + const std::string GSPNExportSettings::writeToJsonOptionName = "to-json"; const std::string GSPNExportSettings::writeStatsOptionName = "to-stats"; const std::string GSPNExportSettings::displayStatsOptionName = "show-stats"; @@ -29,6 +30,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, writeToDotOptionName, false, "Destination for the dot output.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeToPnmlOptionName, false, "Destination for the pnml output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeToPnproOptionName, false, "Destination for the pnpro output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, writeToJsonOptionName, false, "Destination for the json output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, writeStatsOptionName, false, "Destination for the stats file").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, displayStatsOptionName, false, "Print stats to stdout").build()); } @@ -56,7 +58,14 @@ namespace storm { std::string GSPNExportSettings::getWriteToPnproFilename() const { return this->getOption(writeToPnproOptionName).getArgumentByName("filename").getValueAsString(); } - + + bool GSPNExportSettings::isWriteToJsonSet() const { + return this->getOption(writeToJsonOptionName).getHasOptionBeenSet(); + } + + std::string GSPNExportSettings::getWriteToJsonFilename() const { + return this->getOption(writeToJsonOptionName).getArgumentByName("filename").getValueAsString(); + } bool GSPNExportSettings::isDisplayStatsSet() const { return this->getOption(displayStatsOptionName).getHasOptionBeenSet(); diff --git a/src/storm-gspn/settings/modules/GSPNExportSettings.h b/src/storm-gspn/settings/modules/GSPNExportSettings.h index 554cce223..ce203a841 100644 --- a/src/storm-gspn/settings/modules/GSPNExportSettings.h +++ b/src/storm-gspn/settings/modules/GSPNExportSettings.h @@ -37,6 +37,13 @@ namespace storm { * */ std::string getWriteToPnproFilename() const; + + bool isWriteToJsonSet() const; + + /** + * + */ + std::string getWriteToJsonFilename() const; bool isDisplayStatsSet() const; @@ -54,6 +61,7 @@ namespace storm { static const std::string writeToDotOptionName; static const std::string writeToPnmlOptionName; static const std::string writeToPnproOptionName; + static const std::string writeToJsonOptionName; static const std::string displayStatsOptionName; static const std::string writeStatsOptionName; diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index 4a093b30e..c622cc4fe 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -6,8 +6,7 @@ #include "storm/utility/macros.h" #include "storm/exceptions/InvalidArgumentException.h" - - +#include "storm-gspn/storage/gspn/GspnJsonExporter.h" namespace storm { namespace gspn { @@ -396,6 +395,15 @@ namespace storm { this->transitionLayout = transitionLayout; } + std::map<uint64_t, LayoutInfo> const& GSPN::getPlaceLayoutInfos() const { + return this->placeLayout; + } + + std::map<uint64_t, LayoutInfo> const& GSPN::getTransitionLayoutInfos() const { + return this->transitionLayout; + } + + void GSPN::toPnpro(std::ostream &stream) const { auto space = " "; auto space2 = " "; @@ -525,6 +533,11 @@ namespace storm { stream << space3 << "<initialMarking>" << std::endl; stream << space4 << "<value>Default," << place.getNumberOfInitialTokens() << "</value>" << std::endl; stream << space3 << "</initialMarking>" << std::endl; + if(place.hasRestrictedCapacity()) { + stream << space3 << "<capacity>" << std::endl; + stream << space4 << "<value>Default," << place.getCapacity() << "</value>" << std::endl; + stream << space3 << "</capacity>" << std::endl; + } stream << space2 << "</place>" << std::endl; } @@ -607,9 +620,68 @@ namespace storm { } } + // add arcs for immediate transitions + for (const auto &trans : timedTransitions) { + // add input arcs + for (auto const& inEntry : trans.getInputPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << places.at(inEntry.first).getName() << "\" "; + stream << "target=\"" << trans.getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << inEntry.second << "</value>" << std::endl; + stream << space3 << "</inscription>" << std::endl; + + stream << space3 << "<type value=\"normal\" />" << std::endl; + + stream << space2 << "</arc>" << std::endl; + } + + // add inhibition arcs + for (auto const& inhEntry : trans.getInhibitionPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << places.at(inhEntry.first).getName() << "\" "; + stream << "target=\"" << trans.getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << inhEntry.second << "</value>" << std::endl; + stream << space3 << "</inscription>" << std::endl; + + stream << space3 << "<type value=\"inhibition\" />" << std::endl; + + stream << space2 << "</arc>" << std::endl; + } + + // add output arcs + for (auto const& outEntry : trans.getOutputPlaces()) { + stream << space2 << "<arc "; + stream << "id=\"arc" << i++ << "\" "; + stream << "source=\"" << trans.getName() << "\" "; + stream << "target=\"" << places.at(outEntry.first).getName() << "\" "; + stream << ">" << std::endl; + + stream << space3 << "<inscription>" << std::endl; + stream << space4 << "<value>Default," << outEntry.second << "</value>" << std::endl; + stream << space3 << "</inscription>" << std::endl; + + stream << space3 << "<type value=\"normal\" />" << std::endl; + + stream << space2 << "</arc>" << std::endl; + } + } + stream << space << "</net>" << std::endl; stream << "</pnml>" << std::endl; } + + void GSPN::toJson(std::ostream &stream) const { + return storm::gspn::GspnJsonExporter::toStream(*this, stream); + } + void GSPN::writeStatsToStream(std::ostream& stream) const { stream << "Number of places: " << getNumberOfPlaces() << std::endl; diff --git a/src/storm-gspn/storage/gspn/GSPN.h b/src/storm-gspn/storage/gspn/GSPN.h index 19101ffe4..7b37ed5cb 100644 --- a/src/storm-gspn/storage/gspn/GSPN.h +++ b/src/storm-gspn/storage/gspn/GSPN.h @@ -154,7 +154,10 @@ namespace storm { void setTransitionLayoutInfo(uint64_t transitionId, LayoutInfo const& layout) const; void setPlaceLayoutInfo(std::map<uint64_t, LayoutInfo> const& placeLayout) const; void setTransitionLayoutInfo(std::map<uint64_t, LayoutInfo> const& transitionLayout) const; - + + std::map<uint64_t, LayoutInfo> const& getPlaceLayoutInfos() const; + + std::map<uint64_t, LayoutInfo> const& getTransitionLayoutInfos() const; /*! * Performe some checks @@ -168,7 +171,14 @@ namespace storm { void toPnpro(std::ostream& stream) const; // TODO doc void toPnml(std::ostream& stream) const; - + + /*! + * Export GSPN in Json format. + * + * @param stream Outputstream. + */ + void toJson(std::ostream& stream) const; + void writeStatsToStream(std::ostream& stream) const; private: storm::gspn::Place* getPlace(uint64_t id); diff --git a/src/storm-gspn/storage/gspn/GspnBuilder.cpp b/src/storm-gspn/storage/gspn/GspnBuilder.cpp index 5303a89c6..e273768ea 100644 --- a/src/storm-gspn/storage/gspn/GspnBuilder.cpp +++ b/src/storm-gspn/storage/gspn/GspnBuilder.cpp @@ -13,7 +13,7 @@ namespace storm { gspnName = name; } - uint_fast64_t GspnBuilder::addPlace(int_fast64_t const& capacity, uint_fast64_t const& initialTokens, std::string const& name) { + uint_fast64_t GspnBuilder::addPlace(boost::optional<uint64_t> capacity, uint_fast64_t const& initialTokens, std::string const& name) { auto newId = places.size(); auto place = storm::gspn::Place(newId); place.setCapacity(capacity); diff --git a/src/storm-gspn/storage/gspn/GspnBuilder.h b/src/storm-gspn/storage/gspn/GspnBuilder.h index 79fb2e712..a9a99699f 100644 --- a/src/storm-gspn/storage/gspn/GspnBuilder.h +++ b/src/storm-gspn/storage/gspn/GspnBuilder.h @@ -25,7 +25,7 @@ namespace storm { * A capacity of -1 indicates an unbounded place. * @param initialTokens The number of inital tokens in the place. */ - uint_fast64_t addPlace(int_fast64_t const& capacity = 1, uint_fast64_t const& initialTokens = 0, std::string const& name = ""); + uint_fast64_t addPlace(boost::optional<uint64_t> capacity = 1, uint_fast64_t const& initialTokens = 0, std::string const& name = ""); void setPlaceLayoutInfo(uint64_t placeId, LayoutInfo const& layoutInfo); diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp new file mode 100644 index 000000000..4e451d094 --- /dev/null +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.cpp @@ -0,0 +1,203 @@ +#include "GspnJsonExporter.h" + +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/FileIoException.h" + +#include <algorithm> +#include <string> + +namespace storm { + namespace gspn { + + // Prevent some magic constants + static constexpr const uint64_t scaleFactor = 50; + + + void GspnJsonExporter::toStream(storm::gspn::GSPN const& gspn, std::ostream& os) { + os << translate(gspn).dump(4) << std::endl; + } + + modernjson::json GspnJsonExporter::translate(storm::gspn::GSPN const& gspn) { + modernjson::json jsonGspn; + + // Layouts + std::map<uint64_t, LayoutInfo> placeLayout = gspn.getPlaceLayoutInfos(); + std::map<uint64_t, LayoutInfo> transitionLayout = gspn.getTransitionLayoutInfos(); + double tmpX = 0; + double tmpY = 10; + + // Export places + for (const auto &place : gspn.getPlaces()) { + double x = tmpX; + double y = tmpY; + if (placeLayout.count(place.getID()) > 0) { + x = placeLayout.at(place.getID()).x; + y = placeLayout.at(place.getID()).y; + } + tmpX += 3; + modernjson::json jsonPlace = translatePlace(place, x, y); + jsonGspn.push_back(jsonPlace); + } + + // Export immediate transitions + for (const auto &transition : gspn.getImmediateTransitions()) { + double x = tmpX; + double y = tmpY; + if (transitionLayout.count(transition.getID()) > 0) { + x = transitionLayout.at(transition.getID()).x; + y = transitionLayout.at(transition.getID()).y; + } + tmpX += 3; + modernjson::json jsonImmediateTransition = translateImmediateTransition(transition, x, y); + jsonGspn.push_back(jsonImmediateTransition); + } + + // Export timed transitions + for (const auto &transition : gspn.getTimedTransitions()) { + double x = tmpX; + double y = tmpY; + if (transitionLayout.count(transition.getID()) > 0) { + x = transitionLayout.at(transition.getID()).x; + y = transitionLayout.at(transition.getID()).y; + } + tmpX += 3; + modernjson::json jsonTimedTransition = translateTimedTransition(transition, x, y); + jsonGspn.push_back(jsonTimedTransition); + } + + // Export arcs + std::vector<storm::gspn::Place> places = gspn.getPlaces(); + // Export arcs for immediate transitions + for (const auto &transition : gspn.getImmediateTransitions()) { + // Export input arcs + for (auto const& entry : transition.getInputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::INPUT); + jsonGspn.push_back(jsonInputArc); + } + + // Export inhibitor arcs + for (auto const& entry : transition.getInhibitionPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::INHIBITOR); + jsonGspn.push_back(jsonInputArc); + } + + // Export output arcs + for (auto const& entry : transition.getOutputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, true, ArcType::OUTPUT); + jsonGspn.push_back(jsonInputArc); + } + } + // Export arcs for timed transitions + for (const auto &transition : gspn.getTimedTransitions()) { + // Export input arcs + for (auto const& entry : transition.getInputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::INPUT); + jsonGspn.push_back(jsonInputArc); + } + + // Export inhibitor arcs + for (auto const& entry : transition.getInhibitionPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::INHIBITOR); + jsonGspn.push_back(jsonInputArc); + } + + // Export output arcs + for (auto const& entry : transition.getOutputPlaces()) { + storm::gspn::Place place = places.at(entry.first); + modernjson::json jsonInputArc = translateArc(transition, place, entry.second, false, ArcType::OUTPUT); + jsonGspn.push_back(jsonInputArc); + } + } + return jsonGspn; + } + + + modernjson::json GspnJsonExporter::translatePlace(storm::gspn::Place const& place, double x, double y) { + modernjson::json data; + data["id"] = toJsonString(place); + data["name"] = place.getName(); + data["marking"] = place.getNumberOfInitialTokens(); + + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + + modernjson::json jsonPlace; + jsonPlace["data"] = data; + jsonPlace["position"] = position; + jsonPlace["group"] = "nodes"; + jsonPlace["classes"] = "place"; + return jsonPlace; + } + + modernjson::json GspnJsonExporter::translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition, double x, double y) { + modernjson::json data; + data["id"] = toJsonString(transition, true); + data["name"] = transition.getName(); + data["priority"] = transition.getPriority(); + data["weight"] = transition.getWeight(); + + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + + modernjson::json jsonTrans; + jsonTrans["data"] = data; + jsonTrans["position"] = position; + jsonTrans["group"] = "nodes"; + jsonTrans["classes"] = "trans_im"; + return jsonTrans; + } + + modernjson::json GspnJsonExporter::translateTimedTransition(storm::gspn::TimedTransition<double> const& transition, double x, double y) { + modernjson::json data; + data["id"] = toJsonString(transition, false); + data["name"] = transition.getName(); + data["rate"] = transition.getRate(); + data["priority"] = transition.getPriority(); + + modernjson::json position; + position["x"] = x * scaleFactor; + position["y"] = y * scaleFactor; + + modernjson::json jsonTrans; + jsonTrans["data"] = data; + jsonTrans["position"] = position; + jsonTrans["group"] = "nodes"; + jsonTrans["classes"] = "trans_time"; + return jsonTrans; + } + + modernjson::json GspnJsonExporter::translateArc(storm::gspn::Transition const& transition, storm::gspn::Place const& place, uint64_t multiplicity, bool immediate, ArcType arctype) { + modernjson::json data; + data["id"] = toJsonString(transition, place, arctype); + data["source"] = toJsonString(place); + data["target"] = toJsonString(transition, immediate); + data["mult"] = multiplicity; + + modernjson::json jsonArc; + jsonArc["data"] = data; + //jsonTrans["group"] = "nodes"; + switch (arctype) { + case INPUT: + jsonArc["classes"] = "input"; + break; + case OUTPUT: + jsonArc["classes"] = "output"; + break; + case INHIBITOR: + jsonArc["classes"] = "inhibit"; + break; + default: + STORM_LOG_ASSERT(false, "Unknown type " << arctype << " used."); + } + return jsonArc; + } + + } +} diff --git a/src/storm-gspn/storage/gspn/GspnJsonExporter.h b/src/storm-gspn/storage/gspn/GspnJsonExporter.h new file mode 100644 index 000000000..9c225434d --- /dev/null +++ b/src/storm-gspn/storage/gspn/GspnJsonExporter.h @@ -0,0 +1,71 @@ +#pragma once + +#include "storm/utility/macros.h" + +#include "storm-gspn/storage/gspn/GSPN.h" + +// JSON parser +#include "json.hpp" +namespace modernjson { + using json = nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double, std::allocator>; +} + +namespace storm { + namespace gspn { + + /** + * Exports a GSPN into the JSON format for visualizing it. + */ + class GspnJsonExporter { + + public: + static void toStream(storm::gspn::GSPN const& gspn, std::ostream& os); + + static modernjson::json translate(storm::gspn::GSPN const& gspn); + + private: + enum ArcType { INPUT, OUTPUT, INHIBITOR }; + + static modernjson::json translatePlace(storm::gspn::Place const& place, double x, double y); + + static modernjson::json translateImmediateTransition(storm::gspn::ImmediateTransition<double> const& transition, double x, double y); + + static modernjson::json translateTimedTransition(storm::gspn::TimedTransition<double> const& transition, double x, double y); + + static modernjson::json translateArc(storm::gspn::Transition const& transition, storm::gspn::Place const& place, uint64_t multiplicity, bool immediate, ArcType arctype); + + std::string static inline toJsonString(storm::gspn::Place const& place) { + std::stringstream stream; + stream << "p" << place.getID(); + return stream.str(); + } + + std::string static inline toJsonString(storm::gspn::Transition const& transition, bool immediate) { + std::stringstream stream; + stream << (immediate ? "i" : "t") << transition.getID(); + return stream.str(); + } + + std::string static inline toJsonString(storm::gspn::Transition const& transition, storm::gspn::Place const& place, ArcType arctype) { + std::stringstream stream; + stream << place.getID(); + switch (arctype) { + case INPUT: + stream << "i"; + break; + case OUTPUT: + stream << "o"; + break; + case INHIBITOR: + stream << "h"; + break; + default: + STORM_LOG_ASSERT(false, "Unknown type " << arctype << " used."); + } + stream << transition.getID(); + return stream.str(); + } + }; + + } +} diff --git a/src/storm-gspn/storage/gspn/Place.cpp b/src/storm-gspn/storage/gspn/Place.cpp index a78b7c585..ca9a4a9e1 100644 --- a/src/storm-gspn/storage/gspn/Place.cpp +++ b/src/storm-gspn/storage/gspn/Place.cpp @@ -29,11 +29,12 @@ namespace storm { return this->numberOfInitialTokens; } - void Place::setCapacity(uint64_t cap) { + void Place::setCapacity(boost::optional<uint64_t> cap) { this->capacity = cap; } uint64_t Place::getCapacity() const { + assert(hasRestrictedCapacity()); return capacity.get(); } diff --git a/src/storm-gspn/storage/gspn/Place.h b/src/storm-gspn/storage/gspn/Place.h index e995f6a93..55c9da6fb 100644 --- a/src/storm-gspn/storage/gspn/Place.h +++ b/src/storm-gspn/storage/gspn/Place.h @@ -54,9 +54,9 @@ namespace storm { * Sets the capacity of tokens of this place. * * @param capacity The capacity of this place. A non-negative number represents the capacity. - * The value -1 indicates that the capacity is not set. + * boost::none indicates that the flag is not set. */ - void setCapacity(uint64_t capacity); + void setCapacity(boost::optional<uint64_t> capacity); /*! * Returns the capacity of tokens of this place. diff --git a/src/storm-gspn/storm-gspn.h b/src/storm-gspn/storm-gspn.h deleted file mode 100644 index e0d6dd3a6..000000000 --- a/src/storm-gspn/storm-gspn.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "storm/storage/jani/Model.h" - -#include "storm-gspn/builder/JaniGSPNBuilder.h" -#include "storm-gspn/storage/gspn/GSPN.h" - -#include "storm/settings/SettingsManager.h" -#include "storm-gspn/settings/modules/GSPNExportSettings.h" - -#include "storm/utility/file.h" - -namespace storm { - /** - * Builds JANI model from GSPN. - */ - storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn) { - storm::builder::JaniGSPNBuilder builder(gspn); - return builder.build(); - } - - void handleGSPNExportSettings(storm::gspn::GSPN const& gspn) { - storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>(); - if (exportSettings.isWriteToDotSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs); - gspn.writeDotToStream(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isWriteToPnproSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs); - gspn.toPnpro(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isWriteToPnmlSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs); - gspn.toPnml(fs); - storm::utility::closeFile(fs); - } - - if (exportSettings.isDisplayStatsSet()) { - std::cout << "============GSPN Statistics==============" << std::endl; - gspn.writeStatsToStream(std::cout); - std::cout << "=========================================" << std::endl; - } - - if (exportSettings.isWriteStatsToFileSet()) { - std::ofstream fs; - storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs); - gspn.writeStatsToStream(fs); - storm::utility::closeFile(fs); - } - - - - } - -} diff --git a/src/storm-pars-cli/CMakeLists.txt b/src/storm-pars-cli/CMakeLists.txt index 9e2f6f315..955ee93c8 100644 --- a/src/storm-pars-cli/CMakeLists.txt +++ b/src/storm-pars-cli/CMakeLists.txt @@ -6,4 +6,4 @@ set_target_properties(storm-pars-cli PROPERTIES OUTPUT_NAME "storm-pars") add_dependencies(binaries storm-pars-cli) # installation -install(TARGETS storm-pars-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-pars-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pars/CMakeLists.txt b/src/storm-pars/CMakeLists.txt index 4e2ec1e0f..b91292be4 100644 --- a/src/storm-pars/CMakeLists.txt +++ b/src/storm-pars/CMakeLists.txt @@ -36,5 +36,5 @@ add_custom_target(copy_storm_pars_headers DEPENDS ${STORM_PARS_OUTPUT_HEADERS} $ add_dependencies(storm-pars copy_storm_pars_headers) # installation -install(TARGETS storm-pars RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm-pars EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp index b5c2ab11e..a199b3781 100644 --- a/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp +++ b/src/storm-pars/modelchecker/region/SparseDtmcParameterLiftingModelChecker.cpp @@ -10,7 +10,8 @@ #include "storm/modelchecker/prctl/helper/BaierUpperRewardBoundsComputer.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/solver/StandardMinMaxLinearEquationSolver.h" +#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/utility/vector.h" #include "storm/utility/graph.h" #include "storm/utility/NumberTraits.h" @@ -149,9 +150,9 @@ namespace storm { upperResultBound = storm::utility::one<ConstantType>(); // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). - auto req = solverFactory->getRequirements(env, true); + auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearBounds(); - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "Unchecked solver requirement."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solverFactory->setRequirementsChecked(true); } @@ -188,13 +189,13 @@ namespace storm { lowerResultBound = storm::utility::zero<ConstantType>(); // The solution of the min-max equation system will always be unique (assuming graph-preserving instantiations). - auto req = solverFactory->getRequirements(env, true); + auto req = solverFactory->getRequirements(env, true, boost::none, true); req.clearLowerBounds(); - if (req.requiresUpperBounds()) { + if (req.upperBounds()) { solvingRequiresUpperRewardBounds = true; req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "Unchecked solver requirement."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solverFactory->setRequirementsChecked(true); @@ -249,49 +250,50 @@ namespace storm { parameterLifter->specifyRegion(region, dirForParameters); - auto solver = solverFactory->create(env, parameterLifter->getMatrix()); - solver->setHasUniqueSolution(); - if (lowerResultBound) solver->setLowerBound(lowerResultBound.get()); - if (upperResultBound) { - solver->setUpperBound(upperResultBound.get()); - } else if (solvingRequiresUpperRewardBounds) { - // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17). - std::vector<ConstantType> oneStepProbs; - oneStepProbs.reserve(parameterLifter->getMatrix().getRowCount()); - for (uint64_t row = 0; row < parameterLifter->getMatrix().getRowCount(); ++row) { - oneStepProbs.push_back(storm::utility::one<ConstantType>() - parameterLifter->getMatrix().getRowSum(row)); - } - if (dirForParameters == storm::OptimizationDirection::Minimize) { - storm::modelchecker::helper::DsMpiMdpUpperRewardBoundsComputer<ConstantType> dsmpi(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); - solver->setUpperBounds(dsmpi.computeUpperBounds()); - } else { - storm::modelchecker::helper::BaierUpperRewardBoundsComputer<ConstantType> baier(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); - solver->setUpperBound(baier.computeUpperBound()); - } - } - if (!stepBound) solver->setTrackScheduler(true); - if (storm::solver::minimize(dirForParameters) && minSchedChoices && !stepBound) solver->setInitialScheduler(std::move(minSchedChoices.get())); - if (storm::solver::maximize(dirForParameters) && maxSchedChoices && !stepBound) solver->setInitialScheduler(std::move(maxSchedChoices.get())); - if (this->currentCheckTask->isBoundSet() && solver->hasInitialScheduler()) { - // If we reach this point, we know that after applying the hint, the x-values can only become larger (if we maximize) or smaller (if we minimize). - std::unique_ptr<storm::solver::TerminationCondition<ConstantType>> termCond; - storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel->getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); - if (storm::solver::minimize(dirForParameters)) { - // Terminate if the value for ALL relevant states is already below the threshold - termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumBelowThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), false); - } else { - // Terminate if the value for ALL relevant states is already above the threshold - termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumExceedsThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), true); - } - solver->setTerminationCondition(std::move(termCond)); - } - - // Invoke the solver if (stepBound) { assert(*stepBound > 0); x = std::vector<ConstantType>(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>()); - solver->repeatedMultiply(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); + auto multiplier = storm::solver::MultiplierFactory<ConstantType>().create(env, parameterLifter->getMatrix()); + multiplier->repeatedMultiplyAndReduce(env, dirForParameters, x, ¶meterLifter->getVector(), *stepBound); } else { + auto solver = solverFactory->create(env, parameterLifter->getMatrix()); + solver->setHasUniqueSolution(); + if (lowerResultBound) solver->setLowerBound(lowerResultBound.get()); + if (upperResultBound) { + solver->setUpperBound(upperResultBound.get()); + } else if (solvingRequiresUpperRewardBounds) { + // For the min-case, we use DS-MPI, for the max-case variant 2 of the Baier et al. paper (CAV'17). + std::vector<ConstantType> oneStepProbs; + oneStepProbs.reserve(parameterLifter->getMatrix().getRowCount()); + for (uint64_t row = 0; row < parameterLifter->getMatrix().getRowCount(); ++row) { + oneStepProbs.push_back(storm::utility::one<ConstantType>() - parameterLifter->getMatrix().getRowSum(row)); + } + if (dirForParameters == storm::OptimizationDirection::Minimize) { + storm::modelchecker::helper::DsMpiMdpUpperRewardBoundsComputer<ConstantType> dsmpi(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); + solver->setUpperBounds(dsmpi.computeUpperBounds()); + } else { + storm::modelchecker::helper::BaierUpperRewardBoundsComputer<ConstantType> baier(parameterLifter->getMatrix(), parameterLifter->getVector(), oneStepProbs); + solver->setUpperBound(baier.computeUpperBound()); + } + } + solver->setTrackScheduler(true); + if (storm::solver::minimize(dirForParameters) && minSchedChoices) solver->setInitialScheduler(std::move(minSchedChoices.get())); + if (storm::solver::maximize(dirForParameters) && maxSchedChoices) solver->setInitialScheduler(std::move(maxSchedChoices.get())); + if (this->currentCheckTask->isBoundSet() && solver->hasInitialScheduler()) { + // If we reach this point, we know that after applying the hint, the x-values can only become larger (if we maximize) or smaller (if we minimize). + std::unique_ptr<storm::solver::TerminationCondition<ConstantType>> termCond; + storm::storage::BitVector relevantStatesInSubsystem = this->currentCheckTask->isOnlyInitialStatesRelevantSet() ? this->parametricModel->getInitialStates() % maybeStates : storm::storage::BitVector(maybeStates.getNumberOfSetBits(), true); + if (storm::solver::minimize(dirForParameters)) { + // Terminate if the value for ALL relevant states is already below the threshold + termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumBelowThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), false); + } else { + // Terminate if the value for ALL relevant states is already above the threshold + termCond = std::make_unique<storm::solver::TerminateIfFilteredExtremumExceedsThreshold<ConstantType>> (relevantStatesInSubsystem, true, this->currentCheckTask->getBoundThreshold(), true); + } + solver->setTerminationCondition(std::move(termCond)); + } + + // Invoke the solver x.resize(maybeStates.getNumberOfSetBits(), storm::utility::zero<ConstantType>()); solver->solveEquations(env, dirForParameters, x, parameterLifter->getVector()); if(storm::solver::minimize(dirForParameters)) { diff --git a/src/storm-pars/settings/ParsSettings.cpp b/src/storm-pars/settings/ParsSettings.cpp index e36793b04..a0e9d8073 100644 --- a/src/storm-pars/settings/ParsSettings.cpp +++ b/src/storm-pars/settings/ParsSettings.cpp @@ -9,19 +9,21 @@ #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" #include "storm/settings/modules/BuildSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/SylvanSettings.h" #include "storm/settings/modules/EigenEquationSolverSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GameSolverSettings.h" #include "storm/settings/modules/BisimulationSettings.h" -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" namespace storm { @@ -37,22 +39,22 @@ namespace storm { storm::settings::addModule<storm::settings::modules::RegionSettings>(); storm::settings::addModule<storm::settings::modules::BuildSettings>(); storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>(); - - + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); storm::settings::addModule<storm::settings::modules::SylvanSettings>(); storm::settings::addModule<storm::settings::modules::GmmxxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EigenEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::NativeEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::EliminationSettings>(); storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::GameSolverSettings>(); storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); - storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); } } -} \ No newline at end of file +} diff --git a/src/storm-pgcl-cli/CMakeLists.txt b/src/storm-pgcl-cli/CMakeLists.txt index 4f2799d4d..506772fd9 100644 --- a/src/storm-pgcl-cli/CMakeLists.txt +++ b/src/storm-pgcl-cli/CMakeLists.txt @@ -5,4 +5,4 @@ set_target_properties(storm-pgcl-cli PROPERTIES OUTPUT_NAME "storm-pgcl") add_dependencies(binaries storm-pgcl-cli) # installation -install(TARGETS storm-pgcl-cli RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-pgcl-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pgcl/CMakeLists.txt b/src/storm-pgcl/CMakeLists.txt index e20a99483..059bff395 100644 --- a/src/storm-pgcl/CMakeLists.txt +++ b/src/storm-pgcl/CMakeLists.txt @@ -13,4 +13,4 @@ add_library(storm-pgcl SHARED ${STORM_PGCL_SOURCES} ${STORM_PGCL_HEADERS}) target_link_libraries(storm-pgcl storm) # installation -install(TARGETS storm-pgcl RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) \ No newline at end of file +install(TARGETS storm-pgcl EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm-pgcl/parser/PgclParser.cpp b/src/storm-pgcl/parser/PgclParser.cpp index 6ecde3054..2afe737be 100755 --- a/src/storm-pgcl/parser/PgclParser.cpp +++ b/src/storm-pgcl/parser/PgclParser.cpp @@ -40,7 +40,7 @@ namespace storm { storm::parser::PgclParser grammar(filename, first); try { // Start the parsing run. - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing of PGCL program failed."); STORM_LOG_DEBUG("Parse of PGCL program finished."); } catch(qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/CMakeLists.txt b/src/storm/CMakeLists.txt index 0cf8d3183..6a8cda64e 100644 --- a/src/storm/CMakeLists.txt +++ b/src/storm/CMakeLists.txt @@ -72,7 +72,7 @@ add_dependencies(storm copy_resources_headers) add_dependencies(binaries storm-main) # installation -install(TARGETS storm RUNTIME DESTINATION bin LIBRARY DESTINATION lib) -install(TARGETS storm-main RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) +install(TARGETS storm EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib) +install(TARGETS storm-main EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION include/storm FILES_MATCHING PATTERN "*.h") diff --git a/src/storm/abstraction/ExpressionTranslator.cpp b/src/storm/abstraction/ExpressionTranslator.cpp index fe2d28f97..76dd8a2a3 100644 --- a/src/storm/abstraction/ExpressionTranslator.cpp +++ b/src/storm/abstraction/ExpressionTranslator.cpp @@ -17,7 +17,8 @@ namespace storm { template <storm::dd::DdType DdType> ExpressionTranslator<DdType>::ExpressionTranslator(AbstractionInformation<DdType>& abstractionInformation, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractionInformation(abstractionInformation), equivalenceChecker(std::move(smtSolver)), locationVariables(abstractionInformation.getLocationExpressionVariables()), abstractedVariables(abstractionInformation.getAbstractedVariables()) { - // Intentionally left empty. + + equivalenceChecker.addConstraints(abstractionInformation.getConstraints()); } template <storm::dd::DdType DdType> @@ -51,6 +52,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -108,6 +111,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -124,6 +129,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } @@ -154,6 +161,8 @@ namespace storm { for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { return abstractionInformation.get().encodePredicateAsSource(predicateIndex); + } else if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), !expression.toExpression())) { + return !abstractionInformation.get().encodePredicateAsSource(predicateIndex); } } diff --git a/src/storm/abstraction/MenuGameAbstractor.cpp b/src/storm/abstraction/MenuGameAbstractor.cpp index 7ce40950b..f68694c30 100644 --- a/src/storm/abstraction/MenuGameAbstractor.cpp +++ b/src/storm/abstraction/MenuGameAbstractor.cpp @@ -4,6 +4,9 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/AbstractionSettings.h" + #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/utility/dd.h" @@ -15,6 +18,11 @@ namespace storm { namespace abstraction { + template <storm::dd::DdType DdType, typename ValueType> + MenuGameAbstractor<DdType, ValueType>::MenuGameAbstractor() : restrictToRelevantStates(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isRestrictToRelevantStatesSet()) { + // Intentionally left empty. + } + template <typename ValueType> std::string getStateName(std::pair<storm::expressions::SimpleValuation, ValueType> const& stateValue, std::set<storm::expressions::Variable> const& locationVariables, std::set<storm::expressions::Variable> const& predicateVariables, storm::expressions::Variable const& bottomVariable) { std::stringstream stateName; @@ -45,6 +53,11 @@ namespace storm { return stateName.str(); } + template <storm::dd::DdType DdType, typename ValueType> + bool MenuGameAbstractor<DdType, ValueType>::isRestrictToRelevantStatesSet() const { + return restrictToRelevantStates; + } + template <storm::dd::DdType DdType, typename ValueType> void MenuGameAbstractor<DdType, ValueType>::exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const { @@ -135,6 +148,21 @@ namespace storm { storm::utility::closeFile(out); } + template <storm::dd::DdType DdType, typename ValueType> + void MenuGameAbstractor<DdType, ValueType>::setTargetStates(storm::expressions::Expression const& targetStateExpression) { + this->targetStateExpression = targetStateExpression; + } + + template <storm::dd::DdType DdType, typename ValueType> + storm::expressions::Expression const& MenuGameAbstractor<DdType, ValueType>::getTargetStateExpression() const { + return this->targetStateExpression; + } + + template <storm::dd::DdType DdType, typename ValueType> + bool MenuGameAbstractor<DdType, ValueType>::hasTargetStateExpression() const { + return this->targetStateExpression.isInitialized(); + } + template class MenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class MenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/MenuGameAbstractor.h b/src/storm/abstraction/MenuGameAbstractor.h index 946fb0a97..35fc75c42 100644 --- a/src/storm/abstraction/MenuGameAbstractor.h +++ b/src/storm/abstraction/MenuGameAbstractor.h @@ -24,6 +24,7 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> class MenuGameAbstractor { public: + MenuGameAbstractor(); virtual ~MenuGameAbstractor() = default; /// Retrieves the abstraction. @@ -48,8 +49,35 @@ namespace storm { /// Exports a representation of the current abstraction state in the dot format. virtual void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const = 0; + /// Retrieves the number of predicates currently in use. + virtual uint64_t getNumberOfPredicates() const = 0; + + /*! + * Adds the expression to the ones characterizing terminal states, i.e. states whose transitions are not + * explored. For this to work, appropriate predicates must have been used to refine the abstraction, + * otherwise this will fail. + */ + virtual void addTerminalStates(storm::expressions::Expression const& expression) = 0; + + /*! + * Sets the expression characterizing the target states. For this to work, appropriate predicates must have + * been used to refine the abstraction, otherwise this will fail. + */ + void setTargetStates(storm::expressions::Expression const& targetStateExpression); + + storm::expressions::Expression const& getTargetStateExpression() const; + bool hasTargetStateExpression() const; + protected: + bool isRestrictToRelevantStatesSet() const; + void exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const; + + private: + bool restrictToRelevantStates; + + // An expression characterizing the target states. + storm::expressions::Expression targetStateExpression; }; } diff --git a/src/storm/abstraction/MenuGameRefiner.cpp b/src/storm/abstraction/MenuGameRefiner.cpp index 642cb83fb..cd3522ac0 100644 --- a/src/storm/abstraction/MenuGameRefiner.cpp +++ b/src/storm/abstraction/MenuGameRefiner.cpp @@ -59,6 +59,8 @@ namespace storm { template<storm::dd::DdType Type, typename ValueType> MenuGameRefiner<Type, ValueType>::MenuGameRefiner(MenuGameAbstractor<Type, ValueType>& abstractor, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractor(abstractor), useInterpolation(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isUseInterpolationSet()), splitAll(false), splitPredicates(false), addedAllGuardsFlag(false), pivotSelectionHeuristic(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().getPivotSelectionHeuristic()), splitter(), equivalenceChecker(std::move(smtSolver)) { + equivalenceChecker.addConstraints(abstractor.getAbstractionInformation().getConstraints()); + AbstractionSettings::SplitMode splitMode = storm::settings::getModule<storm::settings::modules::AbstractionSettings>().getSplitMode(); splitAll = splitMode == AbstractionSettings::SplitMode::All; splitPredicates = splitMode == AbstractionSettings::SplitMode::NonGuard; @@ -325,7 +327,7 @@ namespace storm { } for (auto const& otherPredicate : otherRefinementPredicates) { for (uint64_t index = 0; index < possibleRefinementPredicates.size(); ++index) { - if (equivalenceChecker.areEquivalent(otherPredicate, possibleRefinementPredicates[index])) { + if (equivalenceChecker.areEquivalentModuloNegation(otherPredicate, possibleRefinementPredicates[index])) { ++refinementPredicateIndexToCount[index]; } } @@ -390,7 +392,7 @@ namespace storm { storm::dd::Bdd<Type> lowerChoice1 = (lowerChoice && minPlayer2Strategy).existsAbstract(variablesToAbstract); storm::dd::Bdd<Type> lowerChoice2 = (lowerChoice && maxPlayer2Strategy).existsAbstract(variablesToAbstract); - bool lowerChoicesDifferent = !lowerChoice1.exclusiveOr(lowerChoice2).isZero(); + bool lowerChoicesDifferent = !lowerChoice1.exclusiveOr(lowerChoice2).isZero() && !lowerChoice1.isZero() && !lowerChoice2.isZero(); if (lowerChoicesDifferent) { STORM_LOG_TRACE("Deriving predicate based on lower choice."); predicates = derivePredicatesFromDifferingChoices((pivotState && minPlayer1Strategy).existsAbstract(game.getRowVariables()), lowerChoice1, lowerChoice2); @@ -405,7 +407,7 @@ namespace storm { storm::dd::Bdd<Type> upperChoice1 = (upperChoice && minPlayer2Strategy).existsAbstract(variablesToAbstract); storm::dd::Bdd<Type> upperChoice2 = (upperChoice && maxPlayer2Strategy).existsAbstract(variablesToAbstract); - bool upperChoicesDifferent = !upperChoice1.exclusiveOr(upperChoice2).isZero(); + bool upperChoicesDifferent = !upperChoice1.exclusiveOr(upperChoice2).isZero() && !upperChoice1.isZero() && !upperChoice2.isZero(); if (upperChoicesDifferent) { STORM_LOG_TRACE("Deriving predicate based on upper choice."); additionalPredicates = derivePredicatesFromDifferingChoices((pivotState && maxPlayer1Strategy).existsAbstract(game.getRowVariables()), upperChoice1, upperChoice2); @@ -476,12 +478,26 @@ namespace storm { // Retrieve the variable updates that the predecessor needs to perform to get to the current state. auto variableUpdates = abstractor.get().getVariableUpdates(std::get<1>(decodedPredecessor), std::get<2>(decodedPredecessor)); - for (auto const& update : variableUpdates) { - storm::expressions::Variable newVariable = oldToNewVariables.at(update.first); - if (update.second.hasBooleanType()) { - predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(oldToNewVariables.at(update.first)), update.second.changeManager(expressionManager).substitute(substitution))); + for (auto const& oldNewVariablePair : oldToNewVariables) { + storm::expressions::Variable const& newVariable = oldNewVariablePair.second; + + // If the variable was set, use its update expression. + auto updateIt = variableUpdates.find(oldNewVariablePair.first); + if (updateIt != variableUpdates.end()) { + auto const& update = *updateIt; + + if (update.second.hasBooleanType()) { + predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(newVariable), update.second.changeManager(expressionManager).substitute(substitution))); + } else { + predicates.back().push_back(lastSubstitution.at(newVariable) == update.second.changeManager(expressionManager).substitute(substitution)); + } } else { - predicates.back().push_back(lastSubstitution.at(oldToNewVariables.at(update.first)) == update.second.changeManager(expressionManager).substitute(substitution)); + // Otherwise, make sure that the new variable maintains the old value. + if (newVariable.hasBooleanType()) { + predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(newVariable), substitution.at(newVariable))); + } else { + predicates.back().push_back(lastSubstitution.at(newVariable) == substitution.at(newVariable)); + } } } @@ -581,6 +597,7 @@ namespace storm { // Redirect all player 1 choices of the min strategy to that of the max strategy if this leads to a player 2 // state that is also a prob 0 state. + auto oldMinPlayer1Strategy = minPlayer1Strategy; minPlayer1Strategy = (maxPlayer1Strategy && qualitativeResult.prob0Min.getPlayer2States()).existsAbstract(game.getPlayer1Variables()).ite(maxPlayer1Strategy, minPlayer1Strategy); // Compute all reached pivot states. @@ -597,7 +614,49 @@ namespace storm { // Now that we have the pivot state candidates, we need to pick one. PivotStateResult<Type, ValueType> pivotStateResult = pickPivotState<Type, ValueType>(pivotSelectionHeuristic, game, pivotStateCandidatesResult, qualitativeResult, boost::none); - + +// // SANITY CHECK TO MAKE SURE OUR STRATEGIES ARE NOT BROKEN. +// // FIXME. +// auto min1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && minPlayer1Strategy; +// STORM_LOG_ASSERT(!min1ChoiceInPivot.isZero(), "wth?"); +// bool min1ChoiceInPivotIsProb0Min = !(min1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb0Max = !(min1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb1Min = !(min1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero(); +// bool min1ChoiceInPivotIsProb1Max = !(min1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero(); +// std::cout << "after redirection (min)" << std::endl; +// std::cout << "min choice is prob0 in min? " << min1ChoiceInPivotIsProb0Min << ", max? " << min1ChoiceInPivotIsProb0Max << std::endl; +// std::cout << "min choice is prob1 in min? " << min1ChoiceInPivotIsProb1Min << ", max? " << min1ChoiceInPivotIsProb1Max << std::endl; +// std::cout << "min" << std::endl; +// for (auto const& e : (min1ChoiceInPivot && minPlayer2Strategy).template toAdd<ValueType>()) { +// std::cout << e.first << " -> " << e.second << std::endl; +// } +// std::cout << "max" << std::endl; +// for (auto const& e : (min1ChoiceInPivot && maxPlayer2Strategy).template toAdd<ValueType>()) { +// std::cout << e.first << " -> " << e.second << std::endl; +// } +// bool different = (min1ChoiceInPivot && minPlayer2Strategy) != (min1ChoiceInPivot && maxPlayer2Strategy); +// std::cout << "min/max choice of player 2 is different? " << different << std::endl; +// bool min1MinPlayer2Choice = !(min1ChoiceInPivot && minPlayer2Strategy).isZero(); +// bool min1MaxPlayer2Choice = !(min1ChoiceInPivot && maxPlayer2Strategy).isZero(); +// std::cout << "max/min choice there? " << min1MinPlayer2Choice << std::endl; +// std::cout << "max/max choice there? " << min1MaxPlayer2Choice << std::endl; +// +// auto max1ChoiceInPivot = pivotStateResult.pivotState && game.getExtendedTransitionMatrix().toBdd() && maxPlayer1Strategy; +// STORM_LOG_ASSERT(!max1ChoiceInPivot.isZero(), "wth?"); +// bool max1ChoiceInPivotIsProb0Min = !(max1ChoiceInPivot && qualitativeResult.prob0Min.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb0Max = !(max1ChoiceInPivot && qualitativeResult.prob0Max.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb1Min = !(max1ChoiceInPivot && qualitativeResult.prob1Min.getPlayer2States()).isZero(); +// bool max1ChoiceInPivotIsProb1Max = !(max1ChoiceInPivot && qualitativeResult.prob1Max.getPlayer2States()).isZero(); +// std::cout << "after redirection (max)" << std::endl; +// std::cout << "max choice is prob0 in min? " << max1ChoiceInPivotIsProb0Min << ", max? " << max1ChoiceInPivotIsProb0Max << std::endl; +// std::cout << "max choice is prob1 in min? " << max1ChoiceInPivotIsProb1Min << ", max? " << max1ChoiceInPivotIsProb1Max << std::endl; +// different = (max1ChoiceInPivot && minPlayer2Strategy) != (max1ChoiceInPivot && maxPlayer2Strategy); +// std::cout << "min/max choice of player 2 is different? " << different << std::endl; +// bool max1MinPlayer2Choice = !(max1ChoiceInPivot && minPlayer2Strategy).isZero(); +// bool max1MaxPlayer2Choice = !(max1ChoiceInPivot && maxPlayer2Strategy).isZero(); +// std::cout << "max/min choice there? " << max1MinPlayer2Choice << std::endl; +// std::cout << "max/max choice there? " << max1MaxPlayer2Choice << std::endl; + boost::optional<RefinementPredicates> predicates; if (useInterpolation) { predicates = derivePredicatesFromInterpolation(game, pivotStateResult, minPlayer1Strategy, minPlayer2Strategy, maxPlayer1Strategy, maxPlayer2Strategy); @@ -669,13 +728,13 @@ namespace storm { // set or in the set that is to be added. bool addAtom = true; for (auto const& oldPredicate : abstractionInformation.getPredicates()) { - if (equivalenceChecker.areEquivalent(atom, oldPredicate)) { + if (equivalenceChecker.areEquivalent(atom, oldPredicate) || equivalenceChecker.areEquivalent(atom, !oldPredicate)) { addAtom = false; break; } } for (auto const& addedAtom : cleanedAtoms) { - if (equivalenceChecker.areEquivalent(addedAtom, atom)) { + if (equivalenceChecker.areEquivalent(addedAtom, atom) || equivalenceChecker.areEquivalent(addedAtom, !atom)) { addAtom = false; break; } diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp index b3c7a755a..09782e9fd 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp @@ -17,6 +17,7 @@ #include "storm/settings/SettingsManager.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/dd.h" #include "storm/utility/macros.h" #include "storm/utility/solver.h" @@ -154,12 +155,48 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); + storm::utility::Stopwatch relevantStatesWatch(true); + storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); + if (this->isRestrictToRelevantStatesSet()) { + // Compute which states are non-terminal. + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + if (this->hasTargetStateExpression()) { + nonTerminalStates &= !this->getStates(this->getTargetStateExpression()); + } + } + relevantStatesWatch.stop(); + // Do a reachability analysis on the raw transition relation. - storm::dd::Bdd<DdType> transitionRelation = game.bdd.existsAbstract(variablesToAbstract); + storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); storm::dd::Bdd<DdType> initialStates = initialLocationsBdd && initialStateAbstractor.getAbstractStates(); initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.start(); + if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) { + // Cut transition relation to the reachable states for backward search. + transitionRelation &= reachableStates; + + // Get the target state BDD. + storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression()); + + // In the presence of target states, we keep only states that can reach the target states. + reachableStates = storm::utility::dd::computeBackwardsReachableStates(targetStates, reachableStates && !initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()) || initialStates; + + // Cut the transition relation to the 'extended backward reachable states', so we have the appropriate self- + // loops of (now) deadlock states. + transitionRelation &= reachableStates; + + // Include all successors of reachable states, because the backward search otherwise potentially + // cuts probability 0 choices of these states. + reachableStates |= reachableStates.relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.stop(); + + STORM_LOG_TRACE("Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() << "ms."); + } + // Find the deadlock states in the model. Note that this does not find the 'deadlocks' in bottom states, // as the bottom states are not contained in the reachable states. storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(abstractionInformation.getSuccessorVariables()); @@ -208,6 +245,16 @@ namespace storm { this->exportToDot(*currentGame, filename, highlightStates, filter); } + template <storm::dd::DdType DdType, typename ValueType> + uint64_t JaniMenuGameAbstractor<DdType, ValueType>::getNumberOfPredicates() const { + return abstractionInformation.getNumberOfPredicates(); + } + + template <storm::dd::DdType DdType, typename ValueType> + void JaniMenuGameAbstractor<DdType, ValueType>::addTerminalStates(storm::expressions::Expression const& expression) { + terminalStateExpressions.emplace_back(expression); + } + // Explicitly instantiate the class. template class JaniMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class JaniMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h index 3a478fcb0..0ef49f908 100644 --- a/src/storm/abstraction/jani/JaniMenuGameAbstractor.h +++ b/src/storm/abstraction/jani/JaniMenuGameAbstractor.h @@ -109,6 +109,10 @@ namespace storm { */ void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const override; + virtual uint64_t getNumberOfPredicates() const override; + + virtual void addTerminalStates(storm::expressions::Expression const& expression) override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; @@ -157,6 +161,9 @@ namespace storm { // A flag storing whether a refinement was performed. bool refinementPerformed; + + // A list of terminal state expressions. + std::vector<storm::expressions::Expression> terminalStateExpressions; }; } } diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp index 4cb3d46eb..9da47fee3 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp @@ -15,6 +15,7 @@ #include "storm/settings/SettingsManager.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/dd.h" #include "storm/utility/macros.h" #include "storm/utility/solver.h" @@ -99,7 +100,7 @@ namespace storm { MenuGame<DdType, ValueType> PrismMenuGameAbstractor<DdType, ValueType>::abstract() { if (refinementPerformed) { currentGame = buildGame(); - refinementPerformed = true; + refinementPerformed = false; } return *currentGame; } @@ -147,12 +148,48 @@ namespace storm { auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount()); variablesToAbstract.insert(auxVariables.begin(), auxVariables.end()); + storm::utility::Stopwatch relevantStatesWatch(true); + storm::dd::Bdd<DdType> nonTerminalStates = this->abstractionInformation.getDdManager().getBddOne(); + if (this->isRestrictToRelevantStatesSet()) { + // Compute which states are non-terminal. + for (auto const& expression : this->terminalStateExpressions) { + nonTerminalStates &= !this->getStates(expression); + } + if (this->hasTargetStateExpression()) { + nonTerminalStates &= !this->getStates(this->getTargetStateExpression()); + } + } + relevantStatesWatch.stop(); + // Do a reachability analysis on the raw transition relation. - storm::dd::Bdd<DdType> transitionRelation = game.bdd.existsAbstract(variablesToAbstract); + storm::dd::Bdd<DdType> transitionRelation = nonTerminalStates && game.bdd.existsAbstract(variablesToAbstract); storm::dd::Bdd<DdType> initialStates = initialStateAbstractor.getAbstractStates(); initialStates.addMetaVariables(abstractionInformation.getSourcePredicateVariables()); storm::dd::Bdd<DdType> reachableStates = storm::utility::dd::computeReachableStates(initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.start(); + if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) { + // Cut transition relation to the reachable states for backward search. + transitionRelation &= reachableStates; + + // Get the target state BDD. + storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression()); + + // In the presence of target states, we keep only states that can reach the target states. + reachableStates = storm::utility::dd::computeBackwardsReachableStates(targetStates, reachableStates && !initialStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()) || initialStates; + + // Cut the transition relation to the 'extended backward reachable states', so we have the appropriate self- + // loops of (now) deadlock states. + transitionRelation &= reachableStates; + + // Include all successors of reachable states, because the backward search otherwise potentially + // cuts probability 0 choices of these states. + reachableStates |= reachableStates.relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables()); + relevantStatesWatch.stop(); + + STORM_LOG_TRACE("Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() << "ms."); + } + // Find the deadlock states in the model. Note that this does not find the 'deadlocks' in bottom states, // as the bottom states are not contained in the reachable states. storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(abstractionInformation.getSuccessorVariables()); @@ -203,6 +240,16 @@ namespace storm { this->exportToDot(*currentGame, filename, highlightStates, filter); } + template <storm::dd::DdType DdType, typename ValueType> + uint64_t PrismMenuGameAbstractor<DdType, ValueType>::getNumberOfPredicates() const { + return abstractionInformation.getNumberOfPredicates(); + } + + template <storm::dd::DdType DdType, typename ValueType> + void PrismMenuGameAbstractor<DdType, ValueType>::addTerminalStates(storm::expressions::Expression const& expression) { + terminalStateExpressions.emplace_back(expression); + } + // Explicitly instantiate the class. template class PrismMenuGameAbstractor<storm::dd::DdType::CUDD, double>; template class PrismMenuGameAbstractor<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h index 49dc8e9dc..55845f134 100644 --- a/src/storm/abstraction/prism/PrismMenuGameAbstractor.h +++ b/src/storm/abstraction/prism/PrismMenuGameAbstractor.h @@ -109,6 +109,10 @@ namespace storm { */ virtual void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const override; + virtual uint64_t getNumberOfPredicates() const override; + + virtual void addTerminalStates(storm::expressions::Expression const& expression) override; + protected: using MenuGameAbstractor<DdType, ValueType>::exportToDot; @@ -154,6 +158,9 @@ namespace storm { // A flag storing whether a refinement was performed. bool refinementPerformed; + + // A list of terminal state expressions. + std::vector<storm::expressions::Expression> terminalStateExpressions; }; } } diff --git a/src/storm/adapters/AddExpressionAdapter.cpp b/src/storm/adapters/AddExpressionAdapter.cpp index f792584a8..c713cae38 100644 --- a/src/storm/adapters/AddExpressionAdapter.cpp +++ b/src/storm/adapters/AddExpressionAdapter.cpp @@ -111,6 +111,9 @@ namespace storm { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Power: result = leftResult.pow(rightResult); break; + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Modulo: + result = leftResult.mod(rightResult); + break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate expression containing power operator."); } diff --git a/src/storm/adapters/MathsatExpressionAdapter.h b/src/storm/adapters/MathsatExpressionAdapter.h index 357c482b3..4b4d7cb57 100644 --- a/src/storm/adapters/MathsatExpressionAdapter.h +++ b/src/storm/adapters/MathsatExpressionAdapter.h @@ -116,6 +116,8 @@ namespace storm { msat_term leftResult = boost::any_cast<msat_term>(expression.getFirstOperand()->accept(*this, data)); msat_term rightResult = boost::any_cast<msat_term>(expression.getSecondOperand()->accept(*this, data)); + msat_term result = leftResult; + int_fast64_t exponent; switch (expression.getOperatorType()) { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus: return msat_make_plus(env, leftResult, rightResult); @@ -124,11 +126,21 @@ namespace storm { case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times: return msat_make_times(env, leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide: - STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unsupported numerical binary operator: '/' (division) in expression."); + return msat_make_divide(env, leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min: return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), leftResult, rightResult); case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max: return msat_make_term_ite(env, msat_make_leq(env, leftResult, rightResult), rightResult, leftResult); + case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Power: + exponent = expression.getSecondOperand()->evaluateAsInt(); + STORM_LOG_THROW(exponent >= 0, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression with negative exponent."); + --exponent; + if (exponent > 0) { + for (; exponent > 0; --exponent) { + result = msat_make_times(env, result, leftResult); + } + } + return result; default: STORM_LOG_THROW(false, storm::exceptions::ExpressionEvaluationException, "Cannot evaluate expression: unknown numerical binary operator '" << static_cast<uint_fast64_t>(expression.getOperatorType()) << "' in expression " << expression << "."); } diff --git a/src/storm/api/bisimulation.h b/src/storm/api/bisimulation.h index aaaa67618..dc7181e87 100644 --- a/src/storm/api/bisimulation.h +++ b/src/storm/api/bisimulation.h @@ -55,22 +55,22 @@ namespace storm { } } - template <storm::dd::DdType DdType, typename ValueType> - typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + typename std::enable_if<DdType == storm::dd::DdType::Sylvan || std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ExportValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { - STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs and CTMCs."); + STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc) || model->isOfType(storm::models::ModelType::Ctmc) || model->isOfType(storm::models::ModelType::Mdp) || model->isOfType(storm::models::ModelType::MarkovAutomaton), storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is currently only available for DTMCs, CTMCs, MDPs and MAs."); STORM_LOG_THROW(bisimulationType == storm::storage::BisimulationType::Strong, storm::exceptions::NotSupportedException, "Currently only strong bisimulation is supported."); // Try to get rid of non state-rewards to easy bisimulation computation. model->reduceToStateBasedRewards(); - storm::dd::BisimulationDecomposition<DdType, ValueType> decomposition(*model, formulas, bisimulationType); + storm::dd::BisimulationDecomposition<DdType, ValueType, ExportValueType> decomposition(*model, formulas, bisimulationType); decomposition.compute(mode); return decomposition.getQuotient(); } - template <storm::dd::DdType DdType, typename ValueType> - typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> + typename std::enable_if<DdType != storm::dd::DdType::Sylvan && !std::is_same<ValueType, double>::value, std::shared_ptr<storm::models::Model<ExportValueType>>>::type performBisimulationMinimization(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType = storm::storage::BisimulationType::Strong, storm::dd::bisimulation::SignatureMode const& mode = storm::dd::bisimulation::SignatureMode::Eager) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Symbolic bisimulation minimization is not supported for this combination of DD library and value type."); return nullptr; } diff --git a/src/storm/api/counterexamples.cpp b/src/storm/api/counterexamples.cpp index 483dc57d4..c57724ad5 100644 --- a/src/storm/api/counterexamples.cpp +++ b/src/storm/api/counterexamples.cpp @@ -5,14 +5,14 @@ namespace storm { namespace api { - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMilp(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { Environment env; - return storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(env, program, *mdp, formula); + return storm::counterexamples::MILPMinimalLabelSetGenerator<double>::computeCounterexample(env, symbolicModel, *mdp, formula); } - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula) { Environment env; - return storm::counterexamples::SMTMinimalLabelSetGenerator<double>::computeCounterexample(env, program, *model, formula); + return storm::counterexamples::SMTMinimalLabelSetGenerator<double>::computeCounterexample(env, symbolicModel, *model, formula); } } diff --git a/src/storm/api/counterexamples.h b/src/storm/api/counterexamples.h index 6481c4efd..672ddc4df 100644 --- a/src/storm/api/counterexamples.h +++ b/src/storm/api/counterexamples.h @@ -6,9 +6,9 @@ namespace storm { namespace api { - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMilp(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula); + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMilp(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Mdp<double>> mdp, std::shared_ptr<storm::logic::Formula const> const& formula); - std::shared_ptr<storm::counterexamples::Counterexample> computePrismHighLevelCounterexampleMaxSmt(storm::prism::Program const& program, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); + std::shared_ptr<storm::counterexamples::Counterexample> computeHighLevelCounterexampleMaxSmt(storm::storage::SymbolicModelDescription const& symbolicModel, std::shared_ptr<storm::models::sparse::Model<double>> model, std::shared_ptr<storm::logic::Formula const> const& formula); } } diff --git a/src/storm/api/properties.cpp b/src/storm/api/properties.cpp index f6a2d00e3..163679013 100644 --- a/src/storm/api/properties.cpp +++ b/src/storm/api/properties.cpp @@ -24,10 +24,10 @@ namespace storm { } std::vector<storm::jani::Property> parseProperties(storm::parser::FormulaParser& formulaParser, std::string const& inputString, boost::optional<std::set<std::string>> const& propertyFilter) { - // If the given property looks like a file (containing a dot and there exists a file with that name), - // we try to parse it as a file, otherwise we assume it's a property. + // If the given property is a file, we parse it as a file, otherwise we assume it's a property. std::vector<storm::jani::Property> properties; - if (inputString.find(".") != std::string::npos && std::ifstream(inputString).good()) { + if (std::ifstream(inputString).good()) { + STORM_LOG_INFO("Loading properties from file: " << inputString << std::endl); properties = formulaParser.parseFromFile(inputString); } else { properties = formulaParser.parseFromString(inputString); @@ -78,6 +78,11 @@ namespace storm { std::set<std::string> const& propertyNameSet = propertyFilter.get(); std::vector<storm::jani::Property> result; std::set<std::string> reducedPropertyNames; + + if (propertyNameSet.empty()) { + STORM_LOG_WARN("Filtering all properties."); + } + for (auto const& property : properties) { if (propertyNameSet.find(property.getName()) != propertyNameSet.end()) { result.push_back(property); diff --git a/src/storm/builder/BuilderOptions.cpp b/src/storm/builder/BuilderOptions.cpp index 00718e3f1..d4d729d21 100644 --- a/src/storm/builder/BuilderOptions.cpp +++ b/src/storm/builder/BuilderOptions.cpp @@ -36,7 +36,7 @@ namespace storm { return boost::get<storm::expressions::Expression>(labelOrExpression); } - BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), showProgress(false), showProgressDelay(0) { + BuilderOptions::BuilderOptions(bool buildAllRewardModels, bool buildAllLabels) : buildAllRewardModels(buildAllRewardModels), buildAllLabels(buildAllLabels), buildChoiceLabels(false), buildStateValuations(false), buildChoiceOrigins(false), explorationChecks(false), addOverlappingGuardsLabel(false), addOutOfBoundsState(false), showProgress(false), showProgressDelay(0) { // Intentionally left empty. } @@ -159,7 +159,15 @@ namespace storm { bool BuilderOptions::isBuildAllLabelsSet() const { return buildAllLabels; } - + + bool BuilderOptions::isAddOutOfBoundsStateSet() const { + return addOutOfBoundsState; + } + + bool BuilderOptions::isAddOverlappingGuardLabelSet() const { + return addOverlappingGuardsLabel; + } + BuilderOptions& BuilderOptions::setBuildAllRewardModels(bool newValue) { buildAllRewardModels = newValue; return *this; @@ -229,5 +237,15 @@ namespace storm { return *this; } + BuilderOptions& BuilderOptions::setAddOutOfBoundsState(bool newValue) { + addOutOfBoundsState = newValue; + return *this; + } + + BuilderOptions& BuilderOptions::setAddOverlappingGuardsLabel(bool newValue) { + addOverlappingGuardsLabel = newValue; + return *this; + } + } } diff --git a/src/storm/builder/BuilderOptions.h b/src/storm/builder/BuilderOptions.h index fe56994c7..904d45de6 100644 --- a/src/storm/builder/BuilderOptions.h +++ b/src/storm/builder/BuilderOptions.h @@ -107,6 +107,8 @@ namespace storm { bool isBuildAllLabelsSet() const; bool isExplorationChecksSet() const; bool isShowProgressSet() const; + bool isAddOutOfBoundsStateSet() const; + bool isAddOverlappingGuardLabelSet() const; uint64_t getShowProgressDelay() const; /** @@ -155,7 +157,21 @@ namespace storm { * @return this */ BuilderOptions& setExplorationChecks(bool newValue = true); - + + /** + * Should a state for out of bounds be constructed + * @param newValue The new value (default true) + * @return this + */ + BuilderOptions& setAddOutOfBoundsState(bool newValue = true); + + /** + * Should a state be labelled for overlapping guards + * @param newValue the new value (default true) + */ + BuilderOptions& setAddOverlappingGuardsLabel(bool newValue = true); + + private: /// A flag that indicates whether all reward models are to be built. In this case, the reward model names are /// to be ignored. @@ -185,13 +201,19 @@ namespace storm { // A flag that indicates whether or not to generate the information from which parts of the model specification // each choice originates. bool buildChoiceOrigins; - + /// A flag that stores whether exploration checks are to be performed. bool explorationChecks; - + + /// A flag for states with overlapping guards + bool addOverlappingGuardsLabel; + + /// A flag indicating that the an additional state for out of bounds should be created. + bool addOutOfBoundsState; + /// A flag that stores whether the progress of exploration is to be printed. bool showProgress; - + /// The delay for printing progress information. uint64_t showProgressDelay; }; diff --git a/src/storm/builder/ChoiceInformationBuilder.cpp b/src/storm/builder/ChoiceInformationBuilder.cpp index 53d61c2f9..6578fe590 100644 --- a/src/storm/builder/ChoiceInformationBuilder.cpp +++ b/src/storm/builder/ChoiceInformationBuilder.cpp @@ -10,7 +10,7 @@ namespace storm { } void ChoiceInformationBuilder::addOriginData(boost::any const& originData, uint_fast64_t choiceIndex) { - if(dataOfOrigins.size() != choiceIndex) { + if (dataOfOrigins.size() != choiceIndex) { dataOfOrigins.resize(choiceIndex); } dataOfOrigins.push_back(originData); @@ -35,4 +35,4 @@ namespace storm { } } -} \ No newline at end of file +} diff --git a/src/storm/builder/ChoiceInformationBuilder.h b/src/storm/builder/ChoiceInformationBuilder.h index 1f9445330..8dbe8721a 100644 --- a/src/storm/builder/ChoiceInformationBuilder.h +++ b/src/storm/builder/ChoiceInformationBuilder.h @@ -31,11 +31,10 @@ namespace storm { std::vector<boost::any> buildDataOfChoiceOrigins(uint_fast64_t totalNumberOfChoices); - private: std::unordered_map<std::string, storm::storage::BitVector> labels; std::vector<boost::any> dataOfOrigins; }; } } - \ No newline at end of file + diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp index 48496b352..091c3fe6d 100644 --- a/src/storm/builder/DdJaniModelBuilder.cpp +++ b/src/storm/builder/DdJaniModelBuilder.cpp @@ -6,7 +6,6 @@ #include "storm/logic/Formulas.h" - #include "storm/storage/jani/Edge.h" #include "storm/storage/jani/EdgeDestination.h" #include "storm/storage/jani/Model.h" @@ -25,6 +24,7 @@ #include "storm/models/symbolic/Dtmc.h" #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/models/symbolic/StandardRewardModel.h" #include "storm/settings/SettingsManager.h" @@ -229,8 +229,8 @@ namespace storm { std::vector<storm::expressions::Variable> localNondeterminismVariables; // The meta variable used to distinguish Markovian from probabilistic choices in Markov automata. - storm::expressions::Variable markovNondeterminismVariable; - storm::dd::Bdd<Type> markovMarker; + storm::expressions::Variable probabilisticNondeterminismVariable; + storm::dd::Bdd<Type> probabilisticMarker; // The meta variables used to encode the actions and nondeterminism. std::set<storm::expressions::Variable> allNondeterminismVariables; @@ -322,9 +322,9 @@ namespace storm { } if (this->model.getModelType() == storm::jani::ModelType::MA) { - result.markovNondeterminismVariable = result.manager->addMetaVariable("markov").first; - result.markovMarker = result.manager->getEncoding(result.markovNondeterminismVariable, 1); - result.allNondeterminismVariables.insert(result.markovNondeterminismVariable); + result.probabilisticNondeterminismVariable = result.manager->addMetaVariable("prob").first; + result.probabilisticMarker = result.manager->getEncoding(result.probabilisticNondeterminismVariable, 1); + result.allNondeterminismVariables.insert(result.probabilisticNondeterminismVariable); } for (auto const& automatonName : this->automata) { @@ -560,7 +560,7 @@ namespace storm { } template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> encodeAction(boost::optional<uint64_t> const& actionIndex, CompositionVariables<Type, ValueType> const& variables) { + storm::dd::Add<Type, ValueType> encodeAction(boost::optional<uint64_t> const& actionIndex, boost::optional<bool> const& markovian, CompositionVariables<Type, ValueType> const& variables) { storm::dd::Add<Type, ValueType> encoding = variables.manager->template getAddOne<ValueType>(); for (auto it = variables.actionVariablesMap.rbegin(), ite = variables.actionVariablesMap.rend(); it != ite; ++it) { @@ -571,6 +571,14 @@ namespace storm { } } + if (markovian) { + if (markovian.get()) { + encoding *= (!variables.probabilisticMarker).template toAdd<ValueType>(); + } else { + encoding *= variables.probabilisticMarker.template toAdd<ValueType>(); + } + } + return encoding; } @@ -679,20 +687,28 @@ namespace storm { }; struct ActionIdentification { - ActionIdentification(uint64_t actionIndex) : actionIndex(actionIndex), synchronizationVectorIndex(boost::none) { + ActionIdentification(uint64_t actionIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(boost::none), markovian(markovian) { // Intentionally left empty. } - ActionIdentification(uint64_t actionIndex, uint64_t synchronizationVectorIndex) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex) { + ActionIdentification(uint64_t actionIndex, uint64_t synchronizationVectorIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), markovian(markovian) { // Intentionally left empty. } - ActionIdentification(uint64_t actionIndex, boost::optional<uint64_t> synchronizationVectorIndex) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex) { + ActionIdentification(uint64_t actionIndex, boost::optional<uint64_t> synchronizationVectorIndex, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), markovian(markovian) { // Intentionally left empty. } + bool setMarkovian(bool markovian) { + this->markovian = markovian; + } + + bool isMarkovian() const { + return this->markovian; + } + bool operator==(ActionIdentification const& other) const { - bool result = actionIndex == other.actionIndex; + bool result = actionIndex == other.actionIndex && markovian == other.markovian; if (synchronizationVectorIndex) { if (other.synchronizationVectorIndex) { result &= synchronizationVectorIndex.get() == other.synchronizationVectorIndex.get(); @@ -709,6 +725,7 @@ namespace storm { uint64_t actionIndex; boost::optional<uint64_t> synchronizationVectorIndex; + bool markovian; }; struct ActionIdentificationHash { @@ -718,7 +735,7 @@ namespace storm { if (identification.synchronizationVectorIndex) { boost::hash_combine(seed, identification.synchronizationVectorIndex.get()); } - return seed; + return identification.markovian ? ~seed : seed; } }; @@ -775,16 +792,24 @@ namespace storm { } struct ActionInstantiation { - ActionInstantiation(uint64_t actionIndex, uint64_t synchronizationVectorIndex, uint64_t localNondeterminismVariableOffset) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset) { + ActionInstantiation(uint64_t actionIndex, uint64_t synchronizationVectorIndex, uint64_t localNondeterminismVariableOffset, bool markovian = false) : actionIndex(actionIndex), synchronizationVectorIndex(synchronizationVectorIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset), markovian(markovian) { // Intentionally left empty. } - ActionInstantiation(uint64_t actionIndex, uint64_t localNondeterminismVariableOffset) : actionIndex(actionIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset) { + ActionInstantiation(uint64_t actionIndex, uint64_t localNondeterminismVariableOffset, bool markovian = false) : actionIndex(actionIndex), localNondeterminismVariableOffset(localNondeterminismVariableOffset), markovian(markovian) { // Intentionally left empty. } + void setMarkovian(bool markovian) { + this->markovian = markovian; + } + + bool isMarkovian() const { + return this->markovian; + } + bool operator==(ActionInstantiation const& other) const { - bool result = actionIndex == other.actionIndex; + bool result = actionIndex == other.actionIndex && markovian == other.markovian; result &= localNondeterminismVariableOffset == other.localNondeterminismVariableOffset; if (synchronizationVectorIndex) { if (!other.synchronizationVectorIndex) { @@ -803,6 +828,7 @@ namespace storm { uint64_t actionIndex; boost::optional<uint64_t> synchronizationVectorIndex; uint64_t localNondeterminismVariableOffset; + bool markovian; }; struct ActionInstantiationHash { @@ -813,7 +839,7 @@ namespace storm { if (instantiation.synchronizationVectorIndex) { boost::hash_combine(seed, instantiation.synchronizationVectorIndex.get()); } - return seed; + return instantiation.isMarkovian() ? ~seed : seed; } }; @@ -823,10 +849,15 @@ namespace storm { ActionInstantiations actionInstantiations; if (data.empty()) { // If no data was provided, this is the top level element in which case we build the full automaton. + bool isCtmc = this->model.getModelType() == storm::jani::ModelType::CTMC; + for (auto const& actionIndex : actionInformation.getNonSilentActionIndices()) { - actionInstantiations[actionIndex].emplace_back(actionIndex, 0); + actionInstantiations[actionIndex].emplace_back(actionIndex, 0, isCtmc); + } + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0, isCtmc); + if (this->model.getModelType() == storm::jani::ModelType::MA) { + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0, true); } - actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(storm::jani::Model::SILENT_ACTION_INDEX, 0); } std::set<uint64_t> inputEnabledActionIndices; @@ -840,6 +871,8 @@ namespace storm { boost::any visit(storm::jani::ParallelComposition const& composition, boost::any const& data) override { STORM_LOG_ASSERT(data.empty(), "Expected parallel composition to be on topmost level to be JANI compliant."); + bool isCtmc = this->model.getModelType() == storm::jani::ModelType::CTMC; + // Prepare storage for the subautomata of the composition. std::vector<AutomatonDd> subautomata; @@ -849,8 +882,11 @@ namespace storm { for (uint64_t subcompositionIndex = 0; subcompositionIndex < composition.getNumberOfSubcompositions(); ++subcompositionIndex) { // Now build a new set of action instantiations for the current subcomposition index. ActionInstantiations actionInstantiations; - actionInstantiations[silentActionIndex].emplace_back(silentActionIndex, 0); - + actionInstantiations[silentActionIndex].emplace_back(silentActionIndex, 0, isCtmc); + if (this->model.getModelType() == storm::jani::ModelType::MA) { + actionInstantiations[storm::jani::Model::SILENT_ACTION_INDEX].emplace_back(silentActionIndex, 0, true); + } + for (uint64_t synchronizationVectorIndex = 0; synchronizationVectorIndex < composition.getNumberOfSynchronizationVectors(); ++synchronizationVectorIndex) { auto const& synchVector = composition.getSynchronizationVector(synchronizationVectorIndex); @@ -859,7 +895,7 @@ namespace storm { // is required to have. if (subcompositionIndex == synchVector.getPositionOfFirstParticipatingAction()) { uint64_t actionIndex = actionInformation.getActionIndex(synchVector.getInput(subcompositionIndex)); - actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, 0); + actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, 0, isCtmc); } else if (synchVector.getInput(subcompositionIndex) != storm::jani::SynchronizationVector::NO_ACTION_INPUT) { uint64_t actionIndex = actionInformation.getActionIndex(synchVector.getInput(subcompositionIndex)); @@ -869,9 +905,9 @@ namespace storm { boost::optional<uint64_t> previousActionPosition = synchVector.getPositionOfPrecedingParticipatingAction(subcompositionIndex); STORM_LOG_ASSERT(previousActionPosition, "Inconsistent information about synchronization vector."); AutomatonDd const& previousAutomatonDd = subautomata[previousActionPosition.get()]; - auto precedingActionIt = previousAutomatonDd.actions.find(ActionIdentification(actionInformation.getActionIndex(synchVector.getInput(previousActionPosition.get())), synchronizationVectorIndex)); + auto precedingActionIt = previousAutomatonDd.actions.find(ActionIdentification(actionInformation.getActionIndex(synchVector.getInput(previousActionPosition.get())), synchronizationVectorIndex, isCtmc)); STORM_LOG_THROW(precedingActionIt != previousAutomatonDd.actions.end(), storm::exceptions::WrongFormatException, "Subcomposition does not have action that is mentioned in parallel composition."); - actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, precedingActionIt->second.getHighestLocalNondeterminismVariable()); + actionInstantiations[actionIndex].emplace_back(actionIndex, synchronizationVectorIndex, precedingActionIt->second.getHighestLocalNondeterminismVariable(), isCtmc); } } @@ -886,43 +922,61 @@ namespace storm { AutomatonDd result(this->variables.manager->template getAddOne<ValueType>()); // Build the results of the synchronization vectors. - std::map<uint64_t, std::vector<ActionDd>> actions; + std::unordered_map<ActionIdentification, std::vector<ActionDd>, ActionIdentificationHash> actions; for (uint64_t synchronizationVectorIndex = 0; synchronizationVectorIndex < synchronizationVectors.size(); ++synchronizationVectorIndex) { auto const& synchVector = synchronizationVectors[synchronizationVectorIndex]; boost::optional<ActionDd> synchronizingAction = combineSynchronizingActions(subautomata, synchVector, synchronizationVectorIndex); if (synchronizingAction) { - actions[actionInformation.getActionIndex(synchVector.getOutput())].emplace_back(synchronizingAction.get()); + actions[ActionIdentification(actionInformation.getActionIndex(synchVector.getOutput()), this->model.getModelType() == storm::jani::ModelType::CTMC)].emplace_back(synchronizingAction.get()); } } + // Construct the two silent action identifications. + ActionIdentification silentActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX); + ActionIdentification silentMarkovianActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX, true); + // Construct the silent action DDs. std::vector<ActionDd> silentActionDds; + std::vector<ActionDd> silentMarkovianActionDds; for (auto const& automaton : subautomata) { for (auto& actionDd : silentActionDds) { - STORM_LOG_TRACE("Extending previous silent action by identity of current automaton."); + STORM_LOG_TRACE("Extending previous (non-Markovian) silent action by identity of current automaton."); + actionDd = actionDd.multiplyTransitions(automaton.identity); + } + for (auto& actionDd : silentMarkovianActionDds) { + STORM_LOG_TRACE("Extending previous (Markovian) silent action by identity of current automaton."); actionDd = actionDd.multiplyTransitions(automaton.identity); } - ActionIdentification silentActionIdentification(storm::jani::Model::SILENT_ACTION_INDEX); auto silentActionIt = automaton.actions.find(silentActionIdentification); if (silentActionIt != automaton.actions.end()) { - STORM_LOG_TRACE("Extending silent action by running identity."); + STORM_LOG_TRACE("Extending (non-Markovian) silent action by running identity."); silentActionDds.emplace_back(silentActionIt->second.multiplyTransitions(result.identity)); } + silentActionIt = automaton.actions.find(silentMarkovianActionIdentification); + if (silentActionIt != automaton.actions.end()) { + STORM_LOG_TRACE("Extending (Markovian) silent action by running identity."); + silentMarkovianActionDds.emplace_back(silentActionIt->second.multiplyTransitions(result.identity)); + } + result.identity *= automaton.identity; } if (!silentActionDds.empty()) { - auto& allSilentActionDds = actions[storm::jani::Model::SILENT_ACTION_INDEX]; - allSilentActionDds.insert(actions[storm::jani::Model::SILENT_ACTION_INDEX].end(), silentActionDds.begin(), silentActionDds.end()); + auto& allSilentActionDds = actions[silentActionIdentification]; + allSilentActionDds.insert(allSilentActionDds.end(), silentActionDds.begin(), silentActionDds.end()); } - - // Finally, combine (potential) multiple action DDs. + if (!silentMarkovianActionDds.empty()) { + auto& allMarkovianSilentActionDds = actions[silentMarkovianActionIdentification]; + allMarkovianSilentActionDds.insert(allMarkovianSilentActionDds.end(), silentMarkovianActionDds.begin(), silentMarkovianActionDds.end()); + } + + // Finally, combine (potentially) multiple action DDs. for (auto const& actionDds : actions) { ActionDd combinedAction = actionDds.second.size() > 1 ? combineUnsynchronizedActions(actionDds.second) : actionDds.second.front(); - result.actions[ActionIdentification(actionDds.first)] = combinedAction; + result.actions[actionDds.first] = combinedAction; result.extendLocalNondeterminismVariables(combinedAction.getLocalNondeterminismVariables()); } @@ -940,7 +994,7 @@ namespace storm { for (uint64_t subautomatonIndex = 0; subautomatonIndex < subautomata.size(); ++subautomatonIndex) { auto const& subautomaton = subautomata[subautomatonIndex]; if (synchronizationVector.getInput(subautomatonIndex) != storm::jani::SynchronizationVector::NO_ACTION_INPUT) { - auto it = subautomaton.actions.find(ActionIdentification(actionInformation.getActionIndex(synchronizationVector.getInput(subautomatonIndex)), synchronizationVectorIndex)); + auto it = subautomaton.actions.find(ActionIdentification(actionInformation.getActionIndex(synchronizationVector.getInput(subautomatonIndex)), synchronizationVectorIndex, this->model.getModelType() == storm::jani::ModelType::CTMC)); if (it != subautomaton.actions.end()) { actions.emplace_back(subautomatonIndex, it->second); } else { @@ -1075,7 +1129,7 @@ namespace storm { result = ActionDd(result.guard || actionIt->guard, result.transitions + actionIt->transitions, joinTransientAssignmentMaps(result.transientEdgeAssignments, actionIt->transientEdgeAssignments), std::make_pair<uint64_t, uint64_t>(0, 0), joinVariableWritingFragmentMaps(result.variableToWritingFragment, actionIt->variableToWritingFragment), result.illegalFragment || actionIt->illegalFragment); } return result; - } else if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS ) { + } else if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS || this->model.getModelType() == storm::jani::ModelType::MA) { // Ensure that all actions start at the same local nondeterminism variable. uint_fast64_t lowestLocalNondeterminismVariable = actions.front().getLowestLocalNondeterminismVariable(); uint_fast64_t highestLocalNondeterminismVariable = actions.front().getHighestLocalNondeterminismVariable(); @@ -1214,14 +1268,14 @@ namespace storm { // If the edge has a rate, we multiply it to the DD. bool isMarkovian = false; if (edge.hasRate()) { - transitions *= this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); + transitions *= this->variables.rowExpressionAdapter->translateExpression(edge.getRate()); isMarkovian = true; } // Finally treat the transient assignments. std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; if (!this->transientVariables.empty()) { - performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &guard, &sourceLocationAndGuard] (storm::jani::Assignment const& assignment) { + performTransientAssignments(edge.getAssignments().getTransientAssignments(), [this, &transientEdgeAssignments, &sourceLocationAndGuard] (storm::jani::Assignment const& assignment) { transientEdgeAssignments[assignment.getExpressionVariable()] = sourceLocationAndGuard * this->variables.rowExpressionAdapter->translateExpression(assignment.getAssignedExpression()); } ); } @@ -1258,43 +1312,32 @@ namespace storm { return EdgeDd(true, guard, transitions, transientEdgeAssignments, variableToWritingFragment); } - ActionDd buildActionDdForActionIndex(storm::jani::Automaton const& automaton, uint64_t actionIndex, uint64_t localNondeterminismVariableOffset) { + ActionDd buildActionDdForActionInstantiation(storm::jani::Automaton const& automaton, ActionInstantiation const& instantiation) { // Translate the individual edges. - std::vector<EdgeDd> markovianEdges; - std::vector<EdgeDd> nonMarkovianEdges; - uint64_t numberOfEdges = 0; + std::vector<EdgeDd> edgeDds; for (auto const& edge : automaton.getEdges()) { - ++numberOfEdges; - if (edge.getActionIndex() == actionIndex) { + if (edge.getActionIndex() == instantiation.actionIndex && edge.hasRate() == instantiation.isMarkovian()) { EdgeDd result = buildEdgeDd(automaton, edge); - if (result.isMarkovian) { - markovianEdges.push_back(result); - } else { - nonMarkovianEdges.push_back(result); - } + edgeDds.emplace_back(result); } } // Now combine the edges to a single action. - if (numberOfEdges > 0) { + uint64_t localNondeterminismVariableOffset = instantiation.localNondeterminismVariableOffset; + if (!edgeDds.empty()) { storm::jani::ModelType modelType = this->model.getModelType(); if (modelType == storm::jani::ModelType::DTMC) { - STORM_LOG_THROW(markovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal Markovian edges in DTMC."); - return combineEdgesToActionDeterministic(nonMarkovianEdges); + return combineEdgesToActionDeterministic(edgeDds); } else if (modelType == storm::jani::ModelType::CTMC) { - STORM_LOG_THROW(nonMarkovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal non-Markovian edges in CTMC."); - return combineEdgesToActionDeterministic(markovianEdges); + return combineEdgesToActionDeterministic(edgeDds); } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) { - STORM_LOG_THROW(markovianEdges.empty(), storm::exceptions::WrongFormatException, "Illegal Markovian edges in MDP."); - return combineEdgesToActionNondeterministic(nonMarkovianEdges, boost::none, localNondeterminismVariableOffset); + return combineEdgesToActionNondeterministic(edgeDds, localNondeterminismVariableOffset); } else if (modelType == storm::jani::ModelType::MA) { - boost::optional<EdgeDd> markovianEdge = boost::none; - if (markovianEdges.size() > 1) { - markovianEdge = combineMarkovianEdgesToSingleEdge(markovianEdges); - } else if (markovianEdges.size() == 1) { - markovianEdge = markovianEdges.front(); + if (instantiation.isMarkovian()){ + return combineEdgesToActionDeterministic(edgeDds); + } else { + return combineEdgesToActionNondeterministic(edgeDds, localNondeterminismVariableOffset); } - return combineEdgesToActionNondeterministic(nonMarkovianEdges, markovianEdge, localNondeterminismVariableOffset); } else { STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Cannot translate model of type " << modelType << "."); } @@ -1347,13 +1390,13 @@ namespace storm { std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; bool overlappingGuards = false; for (auto const& edgeDd : edgeDds) { - STORM_LOG_THROW((this->model.getModelType() == storm::jani::ModelType::CTMC) == edgeDd.isMarkovian, storm::exceptions::WrongFormatException, "Unexpected non-Markovian edge in CTMC."); + STORM_LOG_THROW((this->model.getModelType() == storm::jani::ModelType::CTMC || this->model.getModelType() == storm::jani::ModelType::MA) == edgeDd.isMarkovian, storm::exceptions::WrongFormatException, "Unexpected edge type."); // Check for overlapping guards. overlappingGuards = !(edgeDd.guard && allGuards).isZero(); // Issue a warning if there are overlapping guards in a DTMC. - STORM_LOG_WARN_COND(!overlappingGuards || this->model.getModelType() == storm::jani::ModelType::CTMC, "Guard of an edge in a DTMC overlaps with previous guards."); + STORM_LOG_WARN_COND(!overlappingGuards || this->model.getModelType() == storm::jani::ModelType::CTMC || this->model.getModelType() == storm::jani::ModelType::MA, "Guard of an edge in a DTMC overlaps with previous guards."); // Add the elements of the current edge to the global ones. allGuards |= edgeDd.guard; @@ -1403,49 +1446,29 @@ namespace storm { return result; } - ActionDd combineEdgesBySummation(storm::dd::Bdd<Type> const& guard, std::vector<EdgeDd> const& edges, boost::optional<EdgeDd> const& markovianEdge) { - bool addMarkovianFlag = this->model.getModelType() == storm::jani::ModelType::MA; - STORM_LOG_ASSERT(addMarkovianFlag || !markovianEdge, "Illegally adding Markovian edge without marker."); - + ActionDd combineEdgesBySummation(storm::dd::Bdd<Type> const& guard, std::vector<EdgeDd> const& edges) { storm::dd::Add<Type, ValueType> transitions = this->variables.manager->template getAddZero<ValueType>(); std::map<storm::expressions::Variable, storm::dd::Bdd<Type>> globalVariableToWritingFragment; std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; - storm::dd::Bdd<Type> flagBdd = addMarkovianFlag ? !this->variables.markovMarker : this->variables.manager->getBddOne(); - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); for (auto const& edge : edges) { - transitions += addMarkovianFlag ? flag * edge.transitions : edge.transitions; - for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, addMarkovianFlag ? flag * assignment.second : assignment.second); - } - for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, addMarkovianFlag ? flagBdd && variableFragment.second : variableFragment.second); - } - } - - // Add the Markovian edge (if any). - if (markovianEdge) { - flagBdd = addMarkovianFlag ? !this->variables.markovMarker : this->variables.manager->getBddOne(); - flag = flagBdd.template toAdd<ValueType>(); - EdgeDd const& edge = markovianEdge.get(); - - transitions += flag * edge.transitions; + transitions += edge.transitions; for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, addMarkovianFlag ? flag * assignment.second : assignment.second); + addToTransientAssignmentMap(transientEdgeAssignments, assignment.first, assignment.second); } for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, addMarkovianFlag ? flagBdd && variableFragment.second : variableFragment.second); + addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, variableFragment.second); } } return ActionDd(guard, transitions, transientEdgeAssignments, std::make_pair<uint64_t, uint64_t>(0, 0), globalVariableToWritingFragment, this->variables.manager->getBddZero()); } - ActionDd combineEdgesToActionNondeterministic(std::vector<EdgeDd> const& nonMarkovianEdges, boost::optional<EdgeDd> const& markovianEdge, uint64_t localNondeterminismVariableOffset) { + ActionDd combineEdgesToActionNondeterministic(std::vector<EdgeDd> const& edges, uint64_t localNondeterminismVariableOffset) { // Sum all guards, so we can read off the maximal number of nondeterministic choices in any given state. storm::dd::Bdd<Type> allGuards = this->variables.manager->getBddZero(); storm::dd::Add<Type, uint_fast64_t> sumOfGuards = this->variables.manager->template getAddZero<uint_fast64_t>(); - for (auto const& edge : nonMarkovianEdges) { + for (auto const& edge : edges) { STORM_LOG_ASSERT(!edge.isMarkovian, "Unexpected Markovian edge."); sumOfGuards += edge.guard.template toAdd<uint_fast64_t>(); allGuards |= edge.guard; @@ -1455,7 +1478,7 @@ namespace storm { // Depending on the maximal number of nondeterminstic choices, we need to use some variables to encode the nondeterminism. if (maxChoices <= 1) { - return combineEdgesBySummation(allGuards, nonMarkovianEdges, markovianEdge); + return combineEdgesBySummation(allGuards, edges); } else { // Calculate number of required variables to encode the nondeterminism. uint_fast64_t numberOfBinaryVariables = static_cast<uint_fast64_t>(std::ceil(storm::utility::math::log2(maxChoices))); @@ -1488,8 +1511,8 @@ namespace storm { remainingDds[j] = equalsNumberOfChoicesDd; } - for (std::size_t j = 0; j < nonMarkovianEdges.size(); ++j) { - EdgeDd const& currentEdge = nonMarkovianEdges[j]; + for (std::size_t j = 0; j < edges.size(); ++j) { + EdgeDd const& currentEdge = edges[j]; // Check if edge guard overlaps with equalsNumberOfChoicesDd. That is, there are states with exactly currentChoices // choices such that one outgoing choice is given by the j-th edge. @@ -1543,36 +1566,6 @@ namespace storm { sumOfGuards = sumOfGuards * (!equalsNumberOfChoicesDd).template toAdd<uint_fast64_t>(); } - // Extend the transitions with the appropriate flag if needed. - bool addMarkovianFlag = this->model.getModelType() == storm::jani::ModelType::MA; - STORM_LOG_ASSERT(addMarkovianFlag || !markovianEdge, "Illegally adding Markovian edge without marker."); - if (addMarkovianFlag) { - storm::dd::Bdd<Type> flagBdd = !this->variables.markovMarker; - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); - allEdges *= flag; - for (auto& assignment : transientAssignments) { - assignment.second *= flag; - } - for (auto& writingFragment : globalVariableToWritingFragment) { - writingFragment.second &= flagBdd; - } - } - - // Add Markovian edge (if there is any). - if (markovianEdge) { - storm::dd::Bdd<Type> flagBdd = this->variables.markovMarker; - storm::dd::Add<Type, ValueType> flag = flagBdd.template toAdd<ValueType>(); - EdgeDd const& edge = markovianEdge.get(); - - allEdges += flag * edge.transitions; - for (auto const& assignment : edge.transientEdgeAssignments) { - addToTransientAssignmentMap(transientAssignments, assignment.first, flag * assignment.second); - } - for (auto const& variableFragment : edge.variableToWritingFragment) { - addToVariableWritingFragmentMap(globalVariableToWritingFragment, variableFragment.first, flagBdd && variableFragment.second); - } - } - return ActionDd(allGuards, allEdges, transientAssignments, std::make_pair(localNondeterminismVariableOffset, localNondeterminismVariableOffset + numberOfBinaryVariables), globalVariableToWritingFragment, this->variables.manager->getBddZero()); } } @@ -1591,14 +1584,14 @@ namespace storm { if (inputEnabledActionIndices.find(actionIndex) != inputEnabledActionIndices.end()) { inputEnabled = true; } - for (auto const& instantiationOffset : actionInstantiation.second) { - STORM_LOG_TRACE("Building " << (actionInformation.getActionName(actionIndex).empty() ? "silent " : "") << "action " << (actionInformation.getActionName(actionIndex).empty() ? "" : actionInformation.getActionName(actionIndex) + " ") << "from offset " << instantiationOffset.localNondeterminismVariableOffset << "."); - ActionDd actionDd = buildActionDdForActionIndex(automaton, actionIndex, instantiationOffset.localNondeterminismVariableOffset); + for (auto const& instantiation : actionInstantiation.second) { + STORM_LOG_TRACE("Building " << (instantiation.isMarkovian() ? "(Markovian) " : "") << (actionInformation.getActionName(actionIndex).empty() ? "silent " : "") << "action " << (actionInformation.getActionName(actionIndex).empty() ? "" : actionInformation.getActionName(actionIndex) + " ") << "from offset " << instantiation.localNondeterminismVariableOffset << "."); + ActionDd actionDd = buildActionDdForActionInstantiation(automaton, instantiation); if (inputEnabled) { actionDd.setIsInputEnabled(); } STORM_LOG_TRACE("Used local nondeterminism variables are " << actionDd.getLowestLocalNondeterminismVariable() << " to " << actionDd.getHighestLocalNondeterminismVariable() << "."); - result.actions[ActionIdentification(actionIndex, instantiationOffset.synchronizationVectorIndex)] = actionDd; + result.actions[ActionIdentification(actionIndex, instantiation.synchronizationVectorIndex, instantiation.isMarkovian())] = actionDd; result.extendLocalNondeterminismVariables(actionDd.getLocalNondeterminismVariables()); } } @@ -1636,8 +1629,12 @@ namespace storm { } ComposerResult<Type, ValueType> buildSystemFromAutomaton(AutomatonDd& automaton) { + STORM_LOG_TRACE("Building system from final automaton."); + + auto modelType = this->model.getModelType(); + // If the model is an MDP, we need to encode the nondeterminism using additional variables. - if (this->model.getModelType() == storm::jani::ModelType::MDP || this->model.getModelType() == storm::jani::ModelType::LTS) { + if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::MA || modelType == storm::jani::ModelType::LTS) { storm::dd::Add<Type, ValueType> result = this->variables.manager->template getAddZero<ValueType>(); storm::dd::Bdd<Type> illegalFragment = this->variables.manager->getBddZero(); @@ -1648,14 +1645,20 @@ namespace storm { // Add missing global variable identities, action and nondeterminism encodings. std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> transientEdgeAssignments; - std::unordered_set<uint64_t> actionIndices; + std::unordered_set<ActionIdentification, ActionIdentificationHash> containedActions; for (auto& action : automaton.actions) { + STORM_LOG_TRACE("Treating action with index " << action.first.actionIndex << (action.first.isMarkovian() ? " (Markovian)" : "") << "."); + uint64_t actionIndex = action.first.actionIndex; - STORM_LOG_THROW(actionIndices.find(actionIndex) == actionIndices.end(), storm::exceptions::WrongFormatException, "Duplication action " << actionInformation.getActionName(actionIndex)); - actionIndices.insert(action.first.actionIndex); + bool markovian = action.first.isMarkovian(); + ActionIdentification identificationWithoutSynchVector(actionIndex, markovian); + + STORM_LOG_THROW(containedActions.find(identificationWithoutSynchVector) == containedActions.end(), storm::exceptions::WrongFormatException, "Duplicate action " << actionInformation.getActionName(actionIndex)); + containedActions.insert(identificationWithoutSynchVector); illegalFragment |= action.second.illegalFragment; addMissingGlobalVariableIdentities(action.second); - storm::dd::Add<Type, ValueType> actionEncoding = encodeAction(actionIndex != storm::jani::Model::SILENT_ACTION_INDEX ? boost::optional<uint64_t>(actionIndex) : boost::none, this->variables); + storm::dd::Add<Type, ValueType> actionEncoding = encodeAction(actionIndex != storm::jani::Model::SILENT_ACTION_INDEX ? boost::make_optional(actionIndex) : boost::none, this->model.getModelType() == storm::jani::ModelType::MA ? boost::make_optional(markovian) : boost::none, this->variables); + storm::dd::Add<Type, ValueType> missingNondeterminismEncoding = encodeIndex(0, action.second.getHighestLocalNondeterminismVariable(), numberOfUsedNondeterminismVariables - action.second.getHighestLocalNondeterminismVariable(), this->variables); storm::dd::Add<Type, ValueType> extendedTransitions = actionEncoding * missingNondeterminismEncoding * action.second.transitions; for (auto const& transientAssignment : action.second.transientEdgeAssignments) { @@ -1666,7 +1669,7 @@ namespace storm { } return ComposerResult<Type, ValueType>(result, automaton.transientLocationAssignments, transientEdgeAssignments, illegalFragment, numberOfUsedNondeterminismVariables); - } else if (this->model.getModelType() == storm::jani::ModelType::DTMC || this->model.getModelType() == storm::jani::ModelType::CTMC) { + } else if (modelType == storm::jani::ModelType::DTMC || modelType == storm::jani::ModelType::CTMC) { // Simply add all actions, but make sure to include the missing global variable identities. storm::dd::Add<Type, ValueType> result = this->variables.manager->template getAddZero<ValueType>(); @@ -1708,6 +1711,8 @@ namespace storm { result = std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS) { result = std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(variables.manager, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); + } else if (modelType == storm::jani::ModelType::MA) { + result = std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(variables.manager, !variables.probabilisticMarker, modelComponents.reachableStates, modelComponents.initialStates, modelComponents.deadlockStates, modelComponents.transitionMatrix, variables.rowMetaVariables, variables.rowExpressionAdapter, variables.columnMetaVariables, variables.rowColumnMetaVariablePairs, variables.allNondeterminismVariables, modelComponents.labelToExpressionMap, modelComponents.rewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Model type '" << modelType << "' not supported."); } @@ -1824,16 +1829,15 @@ namespace storm { if (modelType == storm::jani::ModelType::DTMC || modelType == storm::jani::ModelType::CTMC) { // For DTMCs, we can simply add the identity of the global module for all deadlock states. transitionMatrix += deadlockStatesAdd * globalIdentity; - } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS ) { - // For MDPs, however, we need to select an action associated with the self-loop, if we do not + } else if (modelType == storm::jani::ModelType::MDP || modelType == storm::jani::ModelType::LTS || modelType == storm::jani::ModelType::MA) { + // For nondeterministic models, however, we need to select an action associated with the self-loop, if we do not // want to attach a lot of self-loops to the deadlock states. - storm::dd::Add<Type, ValueType> action = variables.manager->template getAddOne<ValueType>(); - for (auto const& variable : variables.actionVariablesMap) { - action *= variables.manager->template getIdentity<ValueType>(variable.second); - } + storm::dd::Add<Type, ValueType> action = encodeAction(boost::none, modelType == storm::jani::ModelType::MA ? boost::make_optional(true) : boost::none, variables); + for (auto const& variable : variables.localNondeterminismVariables) { - action *= variables.manager->template getIdentity<ValueType>(variable); + action *= variables.manager->getEncoding(variable, 0).template toAdd<ValueType>(); } + transitionMatrix += deadlockStatesAdd * globalIdentity * action; } } else { @@ -1963,10 +1967,10 @@ namespace storm { // Create a builder to compose and build the model. CombinedEdgesSystemComposer<Type, ValueType> composer(preparedModel, actionInformation, variables, rewardVariables); ComposerResult<Type, ValueType> system = composer.compose(); - + // Postprocess the variables in place. postprocessVariables(preparedModel.getModelType(), system, variables); - + // Postprocess the system in place and get the states that were terminal (i.e. whose transitions were cut off). storm::dd::Bdd<Type> terminalStates = postprocessSystem(preparedModel, system, variables, options); @@ -1978,7 +1982,7 @@ namespace storm { // Perform reachability analysis to obtain reachable states. storm::dd::Bdd<Type> transitionMatrixBdd = system.transitions.notZero(); - if (preparedModel.getModelType() == storm::jani::ModelType::MDP || preparedModel.getModelType() == storm::jani::ModelType::LTS) { + if (preparedModel.getModelType() == storm::jani::ModelType::MDP || preparedModel.getModelType() == storm::jani::ModelType::LTS || preparedModel.getModelType() == storm::jani::ModelType::MA) { transitionMatrixBdd = transitionMatrixBdd.existsAbstract(variables.allNondeterminismVariables); } modelComponents.reachableStates = storm::utility::dd::computeReachableStates(modelComponents.initialStates, transitionMatrixBdd, variables.rowMetaVariables, variables.columnMetaVariables); diff --git a/src/storm/builder/DdPrismModelBuilder.cp b/src/storm/builder/DdPrismModelBuilder.cp deleted file mode 100644 index 26308f45b..000000000 --- a/src/storm/builder/DdPrismModelBuilder.cp +++ /dev/null @@ -1,1429 +0,0 @@ -#include "storm/builder/DdPrismModelBuilder.h" - -#include <boost/algorithm/string/join.hpp> - -#include "storm/models/symbolic/Dtmc.h" -#include "storm/models/symbolic/Ctmc.h" -#include "storm/models/symbolic/Mdp.h" -#include "storm/models/symbolic/StandardRewardModel.h" - -#include "storm/settings/SettingsManager.h" - -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/InvalidArgumentException.h" - -#include "storm/utility/prism.h" -#include "storm/utility/math.h" -#include "storm/utility/dd.h" - -#include "storm/storage/dd/DdManager.h" -#include "storm/storage/prism/Program.h" -#include "storm/storage/prism/Compositions.h" -#include "storm/storage/dd/Add.h" -#include "storm/storage/dd/cudd/CuddAddIterator.h" -#include "storm/storage/dd/Bdd.h" - -#include "storm/settings/modules/CoreSettings.h" - -namespace storm { - namespace builder { - - template <storm::dd::DdType Type, typename ValueType> - class DdPrismModelBuilder<Type, ValueType>::GenerationInformation { - public: - GenerationInformation(storm::prism::Program const& program) : program(program), manager(std::make_shared<storm::dd::DdManager<Type>>()), rowMetaVariables(), variableToRowMetaVariableMap(std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>()), rowExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToRowMetaVariableMap)), columnMetaVariables(), variableToColumnMetaVariableMap((std::make_shared<std::map<storm::expressions::Variable, storm::expressions::Variable>>())), columnExpressionAdapter(std::make_shared<storm::adapters::AddExpressionAdapter<Type, ValueType>>(manager, variableToColumnMetaVariableMap)), rowColumnMetaVariablePairs(), nondeterminismMetaVariables(), variableToIdentityMap(), allGlobalVariables(), moduleToIdentityMap() { - // Initializes variables and identity DDs. - createMetaVariablesAndIdentities(); - } - - // The program that is currently translated. - storm::prism::Program const& program; - - // The manager used to build the decision diagrams. - std::shared_ptr<storm::dd::DdManager<Type>> manager; - - // The meta variables for the row encoding. - std::set<storm::expressions::Variable> rowMetaVariables; - std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToRowMetaVariableMap; - std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter; - - // The meta variables for the column encoding. - std::set<storm::expressions::Variable> columnMetaVariables; - std::shared_ptr<std::map<storm::expressions::Variable, storm::expressions::Variable>> variableToColumnMetaVariableMap; - std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> columnExpressionAdapter; - - // All pairs of row/column meta variables. - std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> rowColumnMetaVariablePairs; - - // The meta variables used to encode the nondeterminism. - std::vector<storm::expressions::Variable> nondeterminismMetaVariables; - - // The meta variables used to encode the synchronization. - std::vector<storm::expressions::Variable> synchronizationMetaVariables; - - // A set of all variables used for encoding the nondeterminism (i.e. nondetermism + synchronization - // variables). This is handy to abstract from this variable set. - std::set<storm::expressions::Variable> allNondeterminismVariables; - - // As set of all variables used for encoding the synchronization. - std::set<storm::expressions::Variable> allSynchronizationMetaVariables; - - // DDs representing the identity for each variable. - std::map<storm::expressions::Variable, storm::dd::Add<Type, ValueType>> variableToIdentityMap; - - // A set of all meta variables that correspond to global variables. - std::set<storm::expressions::Variable> allGlobalVariables; - - // DDs representing the identity for each module. - std::map<std::string, storm::dd::Add<Type, ValueType>> moduleToIdentityMap; - - // DDs representing the valid ranges of the variables of each module. - std::map<std::string, storm::dd::Add<Type, ValueType>> moduleToRangeMap; - - private: - /*! - * Creates the required meta variables and variable/module identities. - */ - void createMetaVariablesAndIdentities() { - // Add synchronization variables. - for (auto const& actionIndex : program.getSynchronizingActionIndices()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(program.getActionName(actionIndex)); - synchronizationMetaVariables.push_back(variablePair.first); - allSynchronizationMetaVariables.insert(variablePair.first); - allNondeterminismVariables.insert(variablePair.first); - } - - // Add nondeterminism variables (number of modules + number of commands). - uint_fast64_t numberOfNondeterminismVariables = program.getModules().size(); - for (auto const& module : program.getModules()) { - numberOfNondeterminismVariables += module.getNumberOfCommands(); - } - for (uint_fast64_t i = 0; i < numberOfNondeterminismVariables; ++i) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable("nondet" + std::to_string(i)); - nondeterminismMetaVariables.push_back(variablePair.first); - allNondeterminismVariables.insert(variablePair.first); - } - - // Create meta variables for global program variables. - for (storm::prism::IntegerVariable const& integerVariable : program.getGlobalIntegerVariables()) { - int_fast64_t low = integerVariable.getLowerBoundExpression().evaluateAsInt(); - int_fast64_t high = integerVariable.getUpperBoundExpression().evaluateAsInt(); - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(integerVariable.getName(), low, high); - - STORM_LOG_TRACE("Created meta variables for global integer variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>() * manager->getRange(variablePair.first).template toAdd<ValueType>() * manager->getRange(variablePair.second).template toAdd<ValueType>(); - variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity); - rowColumnMetaVariablePairs.push_back(variablePair); - - allGlobalVariables.insert(integerVariable.getExpressionVariable()); - } - for (storm::prism::BooleanVariable const& booleanVariable : program.getGlobalBooleanVariables()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(booleanVariable.getName()); - - STORM_LOG_TRACE("Created meta variables for global boolean variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>(); - variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity); - - rowColumnMetaVariablePairs.push_back(variablePair); - allGlobalVariables.insert(booleanVariable.getExpressionVariable()); - } - - // Create meta variables for each of the modules' variables. - for (storm::prism::Module const& module : program.getModules()) { - storm::dd::Bdd<Type> moduleIdentity = manager->getBddOne(); - storm::dd::Bdd<Type> moduleRange = manager->getBddOne(); - - for (storm::prism::IntegerVariable const& integerVariable : module.getIntegerVariables()) { - int_fast64_t low = integerVariable.getLowerBoundExpression().evaluateAsInt(); - int_fast64_t high = integerVariable.getUpperBoundExpression().evaluateAsInt(); - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(integerVariable.getName(), low, high); - STORM_LOG_TRACE("Created meta variables for integer variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second); - variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>()); - moduleIdentity &= variableIdentity; - moduleRange &= manager->getRange(variablePair.first); - - rowColumnMetaVariablePairs.push_back(variablePair); - } - for (storm::prism::BooleanVariable const& booleanVariable : module.getBooleanVariables()) { - std::pair<storm::expressions::Variable, storm::expressions::Variable> variablePair = manager->addMetaVariable(booleanVariable.getName()); - STORM_LOG_TRACE("Created meta variables for boolean variable: " << variablePair.first.getName() << "[" << variablePair.first.getIndex() << "] and " << variablePair.second.getName() << "[" << variablePair.second.getIndex() << "]"); - - rowMetaVariables.insert(variablePair.first); - variableToRowMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.first); - - columnMetaVariables.insert(variablePair.second); - variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second); - - storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second); - variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>()); - moduleIdentity &= variableIdentity; - moduleRange &= manager->getRange(variablePair.first); - - rowColumnMetaVariablePairs.push_back(variablePair); - } - moduleToIdentityMap[module.getName()] = moduleIdentity.template toAdd<ValueType>(); - moduleToRangeMap[module.getName()] = moduleRange.template toAdd<ValueType>(); - } - } - }; - - template <storm::dd::DdType Type, typename ValueType> - class ModuleComposer : public storm::prism::CompositionVisitor { - public: - ModuleComposer(typename DdPrismModelBuilder<Type, ValueType>::GenerationInformation& generationInfo) : generationInfo(generationInfo) { - // Intentionally left empty. - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram compose(storm::prism::Composition const& composition) { - return boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.accept(*this, newSynchronizingActionToOffsetMap())); - } - - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap() const { - std::map<uint_fast64_t, uint_fast64_t> result; - for (auto const& actionIndex : generationInfo.program.getSynchronizingActionIndices()) { - result[actionIndex] = 0; - } - return result; - } - - std::map<uint_fast64_t, uint_fast64_t> updateSynchronizingActionToOffsetMap(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram const& sub, std::map<uint_fast64_t, uint_fast64_t> const& oldMapping) const { - std::map<uint_fast64_t, uint_fast64_t> result = oldMapping; - for (auto const& action : sub.synchronizingActionToDecisionDiagramMap) { - result[action.first] = action.second.numberOfUsedNondeterminismVariables; - } - return result; - } - - virtual boost::any visit(storm::prism::ModuleComposition const& composition, boost::any const& data) override { - STORM_LOG_TRACE("Translating module '" << composition.getModuleName() << "'."); - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram result = DdPrismModelBuilder<Type, ValueType>::createModuleDecisionDiagram(generationInfo, generationInfo.program.getModule(composition.getModuleName()), synchronizingActionToOffsetMap); - - return result; - } - - virtual boost::any visit(storm::prism::RenamingComposition const& composition, boost::any const& data) override { - // Create the mapping from action indices to action indices. - std::map<uint_fast64_t, uint_fast64_t> renaming; - for (auto const& namePair : composition.getActionRenaming()) { - STORM_LOG_THROW(generationInfo.program.hasAction(namePair.first), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << namePair.first << "'."); - STORM_LOG_THROW(generationInfo.program.hasAction(namePair.second), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << namePair.second << "'."); - renaming.emplace(generationInfo.program.getActionIndex(namePair.first), generationInfo.program.getActionIndex(namePair.second)); - } - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& indexPair : renaming) { - auto it = synchronizingActionToOffsetMap.find(indexPair.second); - STORM_LOG_THROW(it != synchronizingActionToOffsetMap.end(), storm::exceptions::InvalidArgumentException, "Invalid action index " << indexPair.second << "."); - newSynchronizingActionToOffsetMap[indexPair.first] = it->second; - } - - // Then, we translate the subcomposition. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram sub = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Perform the renaming and return result. - return rename(sub, renaming); - } - - virtual boost::any visit(storm::prism::HidingComposition const& composition, boost::any const& data) override { - // Create the mapping from action indices to action indices. - std::set<uint_fast64_t> actionIndicesToHide; - for (auto const& action : composition.getActionsToHide()) { - STORM_LOG_THROW(generationInfo.program.hasAction(action), storm::exceptions::InvalidArgumentException, "Composition refers to unknown action '" << action << "'."); - actionIndicesToHide.insert(generationInfo.program.getActionIndex(action)); - } - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& index : actionIndicesToHide) { - newSynchronizingActionToOffsetMap[index] = 0; - } - - // Then, we translate the subcomposition. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram sub = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Perform the hiding and return result. - hide(sub, actionIndicesToHide); - return sub; - } - - virtual boost::any visit(storm::prism::SynchronizingParallelComposition const& composition, boost::any const& data) override { - // First, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& action : left.synchronizingActionToDecisionDiagramMap) { - newSynchronizingActionToOffsetMap[action.first] = action.second.numberOfUsedNondeterminismVariables; - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - // Then, determine the action indices on which we need to synchronize. - std::set<uint_fast64_t> leftSynchronizationActionIndices = left.getSynchronizingActionIndices(); - std::set<uint_fast64_t> rightSynchronizationActionIndices = right.getSynchronizingActionIndices(); - std::set<uint_fast64_t> synchronizationActionIndices; - std::set_intersection(leftSynchronizationActionIndices.begin(), leftSynchronizationActionIndices.end(), rightSynchronizationActionIndices.begin(), rightSynchronizationActionIndices.end(), std::inserter(synchronizationActionIndices, synchronizationActionIndices.begin())); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, synchronizationActionIndices); - return left; - } - - virtual boost::any visit(storm::prism::InterleavingParallelComposition const& composition, boost::any const& data) override { - // First, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, data)); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, std::set<uint_fast64_t>()); - return left; - } - - virtual boost::any visit(storm::prism::RestrictedParallelComposition const& composition, boost::any const& data) override { - // Construct the synchronizing action indices from the synchronizing action names. - std::set<uint_fast64_t> synchronizingActionIndices; - for (auto const& action : composition.getSynchronizingActions()) { - synchronizingActionIndices.insert(generationInfo.program.getActionIndex(action)); - } - - // Then, we translate the subcompositions. - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram left = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getLeftSubcomposition().accept(*this, data)); - - // Prepare the new offset mapping. - std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap = boost::any_cast<std::map<uint_fast64_t, uint_fast64_t> const&>(data); - std::map<uint_fast64_t, uint_fast64_t> newSynchronizingActionToOffsetMap = synchronizingActionToOffsetMap; - for (auto const& actionIndex : synchronizingActionIndices) { - auto it = left.synchronizingActionToDecisionDiagramMap.find(actionIndex); - if (it != left.synchronizingActionToDecisionDiagramMap.end()) { - newSynchronizingActionToOffsetMap[actionIndex] = it->second.numberOfUsedNondeterminismVariables; - } - } - - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram right = boost::any_cast<typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram>(composition.getRightSubcomposition().accept(*this, newSynchronizingActionToOffsetMap)); - - std::set<uint_fast64_t> leftSynchronizationActionIndices = left.getSynchronizingActionIndices(); - bool isContainedInLeft = std::includes(leftSynchronizationActionIndices.begin(), leftSynchronizationActionIndices.end(), synchronizingActionIndices.begin(), synchronizingActionIndices.end()); - STORM_LOG_WARN_COND(isContainedInLeft, "Left subcomposition of composition '" << composition << "' does not include all actions over which to synchronize."); - - std::set<uint_fast64_t> rightSynchronizationActionIndices = right.getSynchronizingActionIndices(); - bool isContainedInRight = std::includes(rightSynchronizationActionIndices.begin(), rightSynchronizationActionIndices.end(), synchronizingActionIndices.begin(), synchronizingActionIndices.end()); - STORM_LOG_WARN_COND(isContainedInRight, "Right subcomposition of composition '" << composition << "' does not include all actions over which to synchronize."); - - // Finally, we compose the subcompositions to create the result. - composeInParallel(left, right, synchronizingActionIndices); - return left; - } - - private: - /*! - * Hides the actions of the given module according to the given set. As a result, the module is modified in - * place. - */ - void hide(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& sub, std::set<uint_fast64_t> const& actionIndicesToHide) const { - STORM_LOG_TRACE("Hiding actions."); - - for (auto const& actionIndex : actionIndicesToHide) { - auto it = sub.synchronizingActionToDecisionDiagramMap.find(actionIndex); - if (it != sub.synchronizingActionToDecisionDiagramMap.end()) { - sub.independentAction = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, sub.independentAction, it->second); - sub.numberOfUsedNondeterminismVariables = std::max(sub.numberOfUsedNondeterminismVariables, sub.independentAction.numberOfUsedNondeterminismVariables); - sub.synchronizingActionToDecisionDiagramMap.erase(it); - } - } - } - - /*! - * Renames the actions of the given module according to the given renaming. - */ - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram rename(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& sub, std::map<uint_fast64_t, uint_fast64_t> const& renaming) const { - STORM_LOG_TRACE("Renaming actions."); - std::map<uint_fast64_t, typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram> actionIndexToDdMap; - - // Go through all action DDs with a synchronizing label and rename them if they appear in the renaming. - for (auto& action : sub.synchronizingActionToDecisionDiagramMap) { - auto renamingIt = renaming.find(action.first); - if (renamingIt != renaming.end()) { - // If the action is to be renamed and an action with the target index already exists, we need - // to combine the action DDs. - auto itNewActions = actionIndexToDdMap.find(renamingIt->second); - if (itNewActions != actionIndexToDdMap.end()) { - actionIndexToDdMap[renamingIt->second] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, itNewActions->second); - - } else { - // In this case, we can simply copy the action over. - actionIndexToDdMap[renamingIt->second] = action.second; - } - } else { - // If the action is not to be renamed, we need to copy it over. However, if some other action - // was renamed to the very same action name before, we need to combine the transitions. - auto itNewActions = actionIndexToDdMap.find(action.first); - if (itNewActions != actionIndexToDdMap.end()) { - actionIndexToDdMap[action.first] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, itNewActions->second); - } else { - // In this case, we can simply copy the action over. - actionIndexToDdMap[action.first] = action.second; - } - } - } - - return typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram(sub.independentAction, actionIndexToDdMap, sub.identity, sub.numberOfUsedNondeterminismVariables); - } - - /*! - * Composes the given modules while synchronizing over the provided action indices. As a result, the first - * module is modified in place and will contain the composition after a call to this method. - */ - void composeInParallel(typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& left, typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram& right, std::set<uint_fast64_t> const& synchronizationActionIndices) const { - STORM_LOG_TRACE("Composing two modules."); - - // Combine the tau action. - uint_fast64_t numberOfUsedNondeterminismVariables = right.independentAction.numberOfUsedNondeterminismVariables; - left.independentAction = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, left.independentAction, right.independentAction, left.identity, right.identity); - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, left.independentAction.numberOfUsedNondeterminismVariables); - - // Create an empty action for the case where one of the modules does not have a certain action. - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram emptyAction(*generationInfo.manager); - - // Treat all non-tau actions of the left module. - for (auto& action : left.synchronizingActionToDecisionDiagramMap) { - // If we need to synchronize over this action index, we try to do so now. - if (synchronizationActionIndices.find(action.first) != synchronizationActionIndices.end()) { - // If we are to synchronize over an action that does not exist in the second module, the result - // is that the synchronization is the empty action. - if (!right.hasSynchronizingAction(action.first)) { - action.second = emptyAction; - } else { - // Otherwise, the actions of the modules are synchronized. - action.second = DdPrismModelBuilder<Type, ValueType>::combineSynchronizingActions(action.second, right.synchronizingActionToDecisionDiagramMap[action.first]); - } - } else { - // If we don't synchronize over this action, we need to construct the interleaving. - - // If both modules contain the action, we need to mutually multiply the other identity. - if (right.hasSynchronizingAction(action.first)) { - action.second = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, right.synchronizingActionToDecisionDiagramMap[action.first], left.identity, right.identity); - } else { - // If only the first module has this action, we need to use a dummy action decision diagram - // for the second module. - action.second = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, action.second, emptyAction, left.identity, right.identity); - } - } - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, action.second.numberOfUsedNondeterminismVariables); - } - - // Treat all non-tau actions of the right module. - for (auto const& actionIndex : right.getSynchronizingActionIndices()) { - // Here, we only need to treat actions that the first module does not have, because we have handled - // this case earlier. - if (!left.hasSynchronizingAction(actionIndex)) { - if (synchronizationActionIndices.find(actionIndex) != synchronizationActionIndices.end()) { - // If we are to synchronize over this action that does not exist in the first module, the - // result is that the synchronization is the empty action. - left.synchronizingActionToDecisionDiagramMap[actionIndex] = emptyAction; - } else { - // If only the second module has this action, we need to use a dummy action decision diagram - // for the first module. - left.synchronizingActionToDecisionDiagramMap[actionIndex] = DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(generationInfo, emptyAction, right.synchronizingActionToDecisionDiagramMap[actionIndex], left.identity, right.identity); - } - } - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, left.synchronizingActionToDecisionDiagramMap[actionIndex].numberOfUsedNondeterminismVariables); - } - - // Combine identity matrices. - left.identity = left.identity * right.identity; - - // Keep track of the number of nondeterminism variables used. - left.numberOfUsedNondeterminismVariables = std::max(left.numberOfUsedNondeterminismVariables, numberOfUsedNondeterminismVariables); - } - - typename DdPrismModelBuilder<Type, ValueType>::GenerationInformation& generationInfo; - }; - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options() : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(), terminalStates(), negatedTerminalStates() { - // Intentionally left empty. - } - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options(storm::logic::Formula const& formula) : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), terminalStates(), negatedTerminalStates() { - this->preserveFormula(formula); - this->setTerminalStatesFromFormula(formula); - } - - template <storm::dd::DdType Type, typename ValueType> - DdPrismModelBuilder<Type, ValueType>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) : buildAllRewardModels(false), rewardModelsToBuild(), buildAllLabels(false), labelsToBuild(), terminalStates(), negatedTerminalStates() { - if (formulas.empty()) { - this->buildAllRewardModels = true; - this->buildAllLabels = true; - } else { - for (auto const& formula : formulas) { - this->preserveFormula(*formula); - } - if (formulas.size() == 1) { - this->setTerminalStatesFromFormula(*formulas.front()); - } - } - } - - template <storm::dd::DdType Type, typename ValueType> - void DdPrismModelBuilder<Type, ValueType>::Options::preserveFormula(storm::logic::Formula const& formula) { - // If we already had terminal states, we need to erase them. - if (terminalStates) { - terminalStates.reset(); - } - if (negatedTerminalStates) { - negatedTerminalStates.reset(); - } - - // If we are not required to build all reward models, we determine the reward models we need to build. - if (!buildAllRewardModels) { - std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); - rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end()); - } - - // Extract all the labels used in the formula. - std::vector<std::shared_ptr<storm::logic::AtomicLabelFormula const>> atomicLabelFormulas = formula.getAtomicLabelFormulas(); - for (auto const& formula : atomicLabelFormulas) { - if (!labelsToBuild) { - labelsToBuild = std::set<std::string>(); - } - labelsToBuild.get().insert(formula.get()->getLabel()); - } - } - - template <storm::dd::DdType Type, typename ValueType> - void DdPrismModelBuilder<Type, ValueType>::Options::setTerminalStatesFromFormula(storm::logic::Formula const& formula) { - if (formula.isAtomicExpressionFormula()) { - terminalStates = formula.asAtomicExpressionFormula().getExpression(); - } else if (formula.isAtomicLabelFormula()) { - terminalStates = formula.asAtomicLabelFormula().getLabel(); - } else if (formula.isEventuallyFormula()) { - storm::logic::Formula const& sub = formula.asEventuallyFormula().getSubformula(); - if (sub.isAtomicExpressionFormula() || sub.isAtomicLabelFormula()) { - this->setTerminalStatesFromFormula(sub); - } - } else if (formula.isUntilFormula()) { - storm::logic::Formula const& right = formula.asUntilFormula().getRightSubformula(); - if (right.isAtomicExpressionFormula() || right.isAtomicLabelFormula()) { - this->setTerminalStatesFromFormula(right); - } - storm::logic::Formula const& left = formula.asUntilFormula().getLeftSubformula(); - if (left.isAtomicExpressionFormula()) { - negatedTerminalStates = left.asAtomicExpressionFormula().getExpression(); - } else if (left.isAtomicLabelFormula()) { - negatedTerminalStates = left.asAtomicLabelFormula().getLabel(); - } - } else if (formula.isProbabilityOperatorFormula()) { - storm::logic::Formula const& sub = formula.asProbabilityOperatorFormula().getSubformula(); - if (sub.isEventuallyFormula() || sub.isUntilFormula()) { - this->setTerminalStatesFromFormula(sub); - } - } - } - - template <storm::dd::DdType Type, typename ValueType> - struct DdPrismModelBuilder<Type, ValueType>::SystemResult { - SystemResult(storm::dd::Add<Type, ValueType> const& allTransitionsDd, DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type, ValueType> const& stateActionDd) : allTransitionsDd(allTransitionsDd), globalModule(globalModule), stateActionDd(stateActionDd) { - // Intentionally left empty. - } - - storm::dd::Add<Type, ValueType> allTransitionsDd; - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram globalModule; - storm::dd::Add<Type, ValueType> stateActionDd; - }; - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::UpdateDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createUpdateDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::dd::Add<Type, ValueType> const& guard, storm::prism::Update const& update) { - storm::dd::Add<Type, ValueType> updateDd = generationInfo.manager->template getAddOne<ValueType>(); - - STORM_LOG_TRACE("Translating update " << update); - - // Iterate over all assignments (boolean and integer) and build the DD for it. - std::vector<storm::prism::Assignment> assignments = update.getAssignments(); - std::set<storm::expressions::Variable> assignedVariables; - for (auto const& assignment : assignments) { - // Record the variable as being written. - STORM_LOG_TRACE("Assigning to variable " << generationInfo.variableToRowMetaVariableMap->at(assignment.getVariable()).getName()); - assignedVariables.insert(assignment.getVariable()); - - // Translate the written variable. - auto const& primedMetaVariable = generationInfo.variableToColumnMetaVariableMap->at(assignment.getVariable()); - storm::dd::Add<Type, ValueType> writtenVariable = generationInfo.manager->template getIdentity<ValueType>(primedMetaVariable); - - // Translate the expression that is being assigned. - storm::dd::Add<Type, ValueType> updateExpression = generationInfo.rowExpressionAdapter->translateExpression(assignment.getExpression()); - - // Combine the update expression with the guard. - storm::dd::Add<Type, ValueType> result = updateExpression * guard; - - // Combine the variable and the assigned expression. - storm::dd::Add<Type, ValueType> tmp = result; - result = result.equals(writtenVariable).template toAdd<ValueType>(); - result *= guard; - - // Restrict the transitions to the range of the written variable. - result = result * generationInfo.manager->getRange(primedMetaVariable).template toAdd<ValueType>(); - - updateDd *= result; - } - - // Compute the set of assigned global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables; - std::set_intersection(assignedVariables.begin(), assignedVariables.end(), generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), std::inserter(assignedGlobalVariables, assignedGlobalVariables.begin())); - - // All unassigned boolean variables need to keep their value. - for (storm::prism::BooleanVariable const& booleanVariable : module.getBooleanVariables()) { - if (assignedVariables.find(booleanVariable.getExpressionVariable()) == assignedVariables.end()) { - STORM_LOG_TRACE("Multiplying identity of variable " << booleanVariable.getName()); - updateDd *= generationInfo.variableToIdentityMap.at(booleanVariable.getExpressionVariable()); - } - } - - // All unassigned integer variables need to keep their value. - for (storm::prism::IntegerVariable const& integerVariable : module.getIntegerVariables()) { - if (assignedVariables.find(integerVariable.getExpressionVariable()) == assignedVariables.end()) { - STORM_LOG_TRACE("Multiplying identity of variable " << integerVariable.getName()); - updateDd *= generationInfo.variableToIdentityMap.at(integerVariable.getExpressionVariable()); - } - } - - return UpdateDecisionDiagram(updateDd, assignedGlobalVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createCommandDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, storm::prism::Command const& command) { - STORM_LOG_TRACE("Translating guard " << command.getGuardExpression()); - storm::dd::Add<Type, ValueType> guard = generationInfo.rowExpressionAdapter->translateExpression(command.getGuardExpression()) * generationInfo.moduleToRangeMap[module.getName()]; - STORM_LOG_WARN_COND(!guard.isZero(), "The guard '" << command.getGuardExpression() << "' is unsatisfiable."); - - if (!guard.isZero()) { - // Create the DDs representing the individual updates. - std::vector<UpdateDecisionDiagram> updateResults; - for (storm::prism::Update const& update : command.getUpdates()) { - updateResults.push_back(createUpdateDecisionDiagram(generationInfo, module, guard, update)); - - STORM_LOG_WARN_COND(!updateResults.back().updateDd.isZero(), "Update '" << update << "' does not have any effect."); - } - - // Start by gathering all variables that were written in at least one update. - std::set<storm::expressions::Variable> globalVariablesInSomeUpdate; - - // If the command is labeled, we have to analyze which portion of the global variables was written by - // any of the updates and make all update results equal w.r.t. this set. If the command is not labeled, - // we can already multiply the identities of all global variables. - if (command.isLabeled()) { - std::for_each(updateResults.begin(), updateResults.end(), [&globalVariablesInSomeUpdate] (UpdateDecisionDiagram const& update) { globalVariablesInSomeUpdate.insert(update.assignedGlobalVariables.begin(), update.assignedGlobalVariables.end()); } ); - } else { - globalVariablesInSomeUpdate = generationInfo.allGlobalVariables; - } - - // Then, multiply the missing identities. - for (auto& updateResult : updateResults) { - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(globalVariablesInSomeUpdate.begin(), globalVariablesInSomeUpdate.end(), updateResult.assignedGlobalVariables.begin(), updateResult.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity for variable " << variable.getName() << "[" << variable.getIndex() << "] to update."); - updateResult.updateDd *= generationInfo.variableToIdentityMap.at(variable); - } - } - - // Now combine the update DDs to the command DD. - storm::dd::Add<Type, ValueType> commandDd = generationInfo.manager->template getAddZero<ValueType>(); - auto updateResultsIt = updateResults.begin(); - for (auto updateIt = command.getUpdates().begin(), updateIte = command.getUpdates().end(); updateIt != updateIte; ++updateIt, ++updateResultsIt) { - storm::dd::Add<Type, ValueType> probabilityDd = generationInfo.rowExpressionAdapter->translateExpression(updateIt->getLikelihoodExpression()); - commandDd += updateResultsIt->updateDd * probabilityDd; - } - - return ActionDecisionDiagram(guard, guard * commandDd, globalVariablesInSomeUpdate); - } else { - return ActionDecisionDiagram(*generationInfo.manager); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createActionDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, uint_fast64_t synchronizationActionIndex, uint_fast64_t nondeterminismVariableOffset) { - std::vector<ActionDecisionDiagram> commandDds; - for (storm::prism::Command const& command : module.getCommands()) { - - // Determine whether the command is relevant for the selected action. - bool relevant = (synchronizationActionIndex == 0 && !command.isLabeled()) || (synchronizationActionIndex && command.isLabeled() && command.getActionIndex() == synchronizationActionIndex); - - if (!relevant) { - continue; - } - - STORM_LOG_TRACE("Translating command " << command); - - // At this point, the command is known to be relevant for the action. - commandDds.push_back(createCommandDecisionDiagram(generationInfo, module, command)); - } - - ActionDecisionDiagram result(*generationInfo.manager); - if (!commandDds.empty()) { - switch (generationInfo.program.getModelType()){ - case storm::prism::Program::ModelType::DTMC: - case storm::prism::Program::ModelType::CTMC: - result = combineCommandsToActionMarkovChain(generationInfo, commandDds); - break; - case storm::prism::Program::ModelType::MDP: - result = combineCommandsToActionMDP(generationInfo, commandDds, nondeterminismVariableOffset); - break; - default: - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate model of this type."); - } - } - - return result; - } - - template <storm::dd::DdType Type, typename ValueType> - std::set<storm::expressions::Variable> DdPrismModelBuilder<Type, ValueType>::equalizeAssignedGlobalVariables(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2) { - // Start by gathering all variables that were written in at least one action DD. - std::set<storm::expressions::Variable> globalVariablesInActionDd; - std::set_union(action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), action2.assignedGlobalVariables.begin(), action2.assignedGlobalVariables.end(), std::inserter(globalVariablesInActionDd, globalVariablesInActionDd.begin())); - - std::set<storm::expressions::Variable> missingIdentitiesInAction1; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), std::inserter(missingIdentitiesInAction1, missingIdentitiesInAction1.begin())); - for (auto const& variable : missingIdentitiesInAction1) { - action1.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - - std::set<storm::expressions::Variable> missingIdentitiesInAction2; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), std::inserter(missingIdentitiesInAction2, missingIdentitiesInAction2.begin())); - for (auto const& variable : missingIdentitiesInAction2) { - action2.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - - return globalVariablesInActionDd; - } - - template <storm::dd::DdType Type, typename ValueType> - std::set<storm::expressions::Variable> DdPrismModelBuilder<Type, ValueType>::equalizeAssignedGlobalVariables(GenerationInformation const& generationInfo, std::vector<ActionDecisionDiagram>& actionDds) { - // Start by gathering all variables that were written in at least one action DD. - std::set<storm::expressions::Variable> globalVariablesInActionDd; - for (auto const& commandDd : actionDds) { - globalVariablesInActionDd.insert(commandDd.assignedGlobalVariables.begin(), commandDd.assignedGlobalVariables.end()); - } - - STORM_LOG_TRACE("Equalizing assigned global variables."); - - // Then multiply the transitions of each action with the missing identities. - for (auto& actionDd : actionDds) { - STORM_LOG_TRACE("Equalizing next action."); - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(globalVariablesInActionDd.begin(), globalVariablesInActionDd.end(), actionDd.assignedGlobalVariables.begin(), actionDd.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of variable " << variable.getName() << "."); - actionDd.transitionsDd *= generationInfo.variableToIdentityMap.at(variable); - } - } - return globalVariablesInActionDd; - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineCommandsToActionMarkovChain(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram>& commandDds) { - storm::dd::Add<Type, ValueType> allGuards = generationInfo.manager->template getAddZero<ValueType>(); - storm::dd::Add<Type, ValueType> allCommands = generationInfo.manager->template getAddZero<ValueType>(); - storm::dd::Add<Type, ValueType> temporary; - - // Make all command DDs assign to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, commandDds); - - // Then combine the commands to the full action DD and multiply missing identities along the way. - for (auto& commandDd : commandDds) { - // Check for overlapping guards. - temporary = commandDd.guardDd * allGuards; - - // Issue a warning if there are overlapping guards in a non-CTMC model. - STORM_LOG_WARN_COND(temporary.isZero() || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC, "Guard of a command overlaps with previous guards."); - - allGuards += commandDd.guardDd; - allCommands += commandDd.transitionsDd; - } - - return ActionDecisionDiagram(allGuards, allCommands, assignedGlobalVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::encodeChoice(GenerationInformation& generationInfo, uint_fast64_t nondeterminismVariableOffset, uint_fast64_t numberOfBinaryVariables, int_fast64_t value) { - storm::dd::Add<Type, ValueType> result = generationInfo.manager->template getAddZero<ValueType>(); - - STORM_LOG_TRACE("Encoding " << value << " with " << numberOfBinaryVariables << " binary variable(s) starting from offset " << nondeterminismVariableOffset << "."); - - std::map<storm::expressions::Variable, int_fast64_t> metaVariableNameToValueMap; - for (uint_fast64_t i = nondeterminismVariableOffset; i < nondeterminismVariableOffset + numberOfBinaryVariables; ++i) { - if (value & (1ull << (numberOfBinaryVariables - i - 1))) { - metaVariableNameToValueMap.emplace(generationInfo.nondeterminismMetaVariables[i], 1); - } else { - metaVariableNameToValueMap.emplace(generationInfo.nondeterminismMetaVariables[i], 0); - } - } - - result.setValue(metaVariableNameToValueMap, ValueType(1)); - return result; - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineCommandsToActionMDP(GenerationInformation& generationInfo, std::vector<ActionDecisionDiagram>& commandDds, uint_fast64_t nondeterminismVariableOffset) { - storm::dd::Bdd<Type> allGuards = generationInfo.manager->getBddZero(); - storm::dd::Add<Type, ValueType> allCommands = generationInfo.manager->template getAddZero<ValueType>(); - - // Make all command DDs assign to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, commandDds); - - // Sum all guards, so we can read off the maximal number of nondeterministic choices in any given state. - storm::dd::Add<Type, ValueType> sumOfGuards = generationInfo.manager->template getAddZero<ValueType>(); - for (auto const& commandDd : commandDds) { - sumOfGuards += commandDd.guardDd; - allGuards |= commandDd.guardDd.toBdd(); - } - uint_fast64_t maxChoices = static_cast<uint_fast64_t>(sumOfGuards.getMax()); - - STORM_LOG_TRACE("Found " << maxChoices << " local choices."); - - // Depending on the maximal number of nondeterminstic choices, we need to use some variables to encode the nondeterminism. - if (maxChoices == 0) { - return ActionDecisionDiagram(*generationInfo.manager); - } else if (maxChoices == 1) { - // Sum up all commands. - for (auto const& commandDd : commandDds) { - allCommands += commandDd.transitionsDd; - } - return ActionDecisionDiagram(sumOfGuards, allCommands, assignedGlobalVariables); - } else { - // Calculate number of required variables to encode the nondeterminism. - uint_fast64_t numberOfBinaryVariables = static_cast<uint_fast64_t>(std::ceil(storm::utility::math::log2(maxChoices))); - - storm::dd::Bdd<Type> equalsNumberOfChoicesDd; - std::vector<storm::dd::Add<Type, ValueType>> choiceDds(maxChoices, generationInfo.manager->template getAddZero<ValueType>()); - std::vector<storm::dd::Bdd<Type>> remainingDds(maxChoices, generationInfo.manager->getBddZero()); - - for (uint_fast64_t currentChoices = 1; currentChoices <= maxChoices; ++currentChoices) { - // Determine the set of states with exactly currentChoices choices. - equalsNumberOfChoicesDd = sumOfGuards.equals(generationInfo.manager->getConstant(ValueType(currentChoices))); - - // If there is no such state, continue with the next possible number of choices. - if (equalsNumberOfChoicesDd.isZero()) { - continue; - } - - // Reset the previously used intermediate storage. - for (uint_fast64_t j = 0; j < currentChoices; ++j) { - choiceDds[j] = generationInfo.manager->template getAddZero<ValueType>(); - remainingDds[j] = equalsNumberOfChoicesDd; - } - - for (std::size_t j = 0; j < commandDds.size(); ++j) { - // Check if command guard overlaps with equalsNumberOfChoicesDd. That is, there are states with exactly currentChoices - // choices such that one outgoing choice is given by the j-th command. - storm::dd::Bdd<Type> guardChoicesIntersection = commandDds[j].guardDd.toBdd() && equalsNumberOfChoicesDd; - - // If there is no such state, continue with the next command. - if (guardChoicesIntersection.isZero()) { - continue; - } - - // Split the nondeterministic choices. - for (uint_fast64_t k = 0; k < currentChoices; ++k) { - // Calculate the overlapping part of command guard and the remaining DD. - storm::dd::Bdd<Type> remainingGuardChoicesIntersection = guardChoicesIntersection && remainingDds[k]; - - // Check if we can add some overlapping parts to the current index. - if (!remainingGuardChoicesIntersection.isZero()) { - // Remove overlapping parts from the remaining DD. - remainingDds[k] = remainingDds[k] && !remainingGuardChoicesIntersection; - - // Combine the overlapping part of the guard with command updates and add it to the resulting DD. - choiceDds[k] += remainingGuardChoicesIntersection.template toAdd<ValueType>() * commandDds[j].transitionsDd; - } - - // Remove overlapping parts from the command guard DD - guardChoicesIntersection = guardChoicesIntersection && !remainingGuardChoicesIntersection; - - // If the guard DD has become equivalent to false, we can stop here. - if (guardChoicesIntersection.isZero()) { - break; - } - } - } - - // Add the meta variables that encode the nondeterminisim to the different choices. - for (uint_fast64_t j = 0; j < currentChoices; ++j) { - allCommands += encodeChoice(generationInfo, nondeterminismVariableOffset, numberOfBinaryVariables, j) * choiceDds[j]; - } - - // Delete currentChoices out of overlapping DD - sumOfGuards = sumOfGuards * (!equalsNumberOfChoicesDd).template toAdd<ValueType>(); - } - - return ActionDecisionDiagram(allGuards.template toAdd<ValueType>(), allCommands, assignedGlobalVariables, nondeterminismVariableOffset + numberOfBinaryVariables); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineSynchronizingActions(ActionDecisionDiagram const& action1, ActionDecisionDiagram const& action2) { - std::set<storm::expressions::Variable> assignedGlobalVariables; - std::set_union(action1.assignedGlobalVariables.begin(), action1.assignedGlobalVariables.end(), action2.assignedGlobalVariables.begin(), action2.assignedGlobalVariables.end(), std::inserter(assignedGlobalVariables, assignedGlobalVariables.begin())); - return ActionDecisionDiagram(action1.guardDd * action2.guardDd, action1.transitionsDd * action2.transitionsDd, assignedGlobalVariables, std::max(action1.numberOfUsedNondeterminismVariables, action2.numberOfUsedNondeterminismVariables)); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2, storm::dd::Add<Type, ValueType> const& identityDd1, storm::dd::Add<Type, ValueType> const& identityDd2) { - - // First extend the action DDs by the other identities. - STORM_LOG_TRACE("Multiplying identities to combine unsynchronized actions."); - action1.transitionsDd = action1.transitionsDd * identityDd2; - action2.transitionsDd = action2.transitionsDd * identityDd1; - - // Then combine the extended action DDs. - return combineUnsynchronizedActions(generationInfo, action1, action2); - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ActionDecisionDiagram DdPrismModelBuilder<Type, ValueType>::combineUnsynchronizedActions(GenerationInformation const& generationInfo, ActionDecisionDiagram& action1, ActionDecisionDiagram& action2) { - STORM_LOG_TRACE("Combining unsynchronized actions."); - - // Make both action DDs write to the same global variables. - std::set<storm::expressions::Variable> assignedGlobalVariables = equalizeAssignedGlobalVariables(generationInfo, action1, action2); - - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - return ActionDecisionDiagram(action1.guardDd + action2.guardDd, action1.transitionsDd + action2.transitionsDd, assignedGlobalVariables, 0); - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - if (action1.transitionsDd.isZero()) { - return ActionDecisionDiagram(action2.guardDd, action2.transitionsDd, assignedGlobalVariables, action2.numberOfUsedNondeterminismVariables); - } else if (action2.transitionsDd.isZero()) { - return ActionDecisionDiagram(action1.guardDd, action1.transitionsDd, assignedGlobalVariables, action1.numberOfUsedNondeterminismVariables); - } - - // Bring both choices to the same number of variables that encode the nondeterminism. - uint_fast64_t numberOfUsedNondeterminismVariables = std::max(action1.numberOfUsedNondeterminismVariables, action2.numberOfUsedNondeterminismVariables); - if (action1.numberOfUsedNondeterminismVariables > action2.numberOfUsedNondeterminismVariables) { - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - - for (uint_fast64_t i = action2.numberOfUsedNondeterminismVariables; i < action1.numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - action2.transitionsDd *= nondeterminismEncoding; - } else if (action2.numberOfUsedNondeterminismVariables > action1.numberOfUsedNondeterminismVariables) { - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - - for (uint_fast64_t i = action1.numberOfUsedNondeterminismVariables; i < action2.numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - action1.transitionsDd *= nondeterminismEncoding; - } - - // Add a new variable that resolves the nondeterminism between the two choices. - storm::dd::Add<Type, ValueType> combinedTransitions = generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[numberOfUsedNondeterminismVariables], 1).ite(action2.transitionsDd, action1.transitionsDd); - - return ActionDecisionDiagram((action1.guardDd.toBdd() || action2.guardDd.toBdd()).template toAdd<ValueType>(), combinedTransitions, assignedGlobalVariables, numberOfUsedNondeterminismVariables + 1); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Illegal model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::ModuleDecisionDiagram DdPrismModelBuilder<Type, ValueType>::createModuleDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap) { - // Start by creating the action DD for the independent action. - ActionDecisionDiagram independentActionDd = createActionDecisionDiagram(generationInfo, module, 0, 0); - uint_fast64_t numberOfUsedNondeterminismVariables = independentActionDd.numberOfUsedNondeterminismVariables; - - // Create module DD for all synchronizing actions of the module. - std::map<uint_fast64_t, ActionDecisionDiagram> actionIndexToDdMap; - for (auto const& actionIndex : module.getSynchronizingActionIndices()) { - STORM_LOG_TRACE("Creating DD for action '" << actionIndex << "'."); - ActionDecisionDiagram tmp = createActionDecisionDiagram(generationInfo, module, actionIndex, synchronizingActionToOffsetMap.at(actionIndex)); - numberOfUsedNondeterminismVariables = std::max(numberOfUsedNondeterminismVariables, tmp.numberOfUsedNondeterminismVariables); - actionIndexToDdMap.emplace(actionIndex, tmp); - } - - return ModuleDecisionDiagram(independentActionDd, actionIndexToDdMap, generationInfo.moduleToIdentityMap.at(module.getName()), numberOfUsedNondeterminismVariables); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, uint_fast64_t actionIndex) { - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - if (actionIndex != 0) { - for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) { - if ((actionIndex - 1) == i) { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1).template toAdd<ValueType>(); - } else { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0).template toAdd<ValueType>(); - } - } - } else { - for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) { - synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0).template toAdd<ValueType>(); - } - } - return synchronization; - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Add<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module) { - // If the model is an MDP, we need to encode the nondeterminism using additional variables. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - storm::dd::Add<Type, ValueType> result = generationInfo.manager->template getAddZero<ValueType>(); - - // First, determine the highest number of nondeterminism variables that is used in any action and make - // all actions use the same amout of nondeterminism variables. - uint_fast64_t numberOfUsedNondeterminismVariables = module.numberOfUsedNondeterminismVariables; - - // Compute missing global variable identities in independent action. - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), module.independentAction.assignedGlobalVariables.begin(), module.independentAction.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - storm::dd::Add<Type, ValueType> identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to independent action."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - // Add variables to independent action DD. - storm::dd::Add<Type, ValueType> nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (uint_fast64_t i = module.independentAction.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - result = identityEncoding * module.independentAction.transitionsDd * nondeterminismEncoding; - - // Add variables to synchronized action DDs. - std::map<uint_fast64_t, storm::dd::Add<Type, ValueType>> synchronizingActionToDdMap; - for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) { - // Compute missing global variable identities in synchronizing actions. - missingIdentities = std::set<storm::expressions::Variable>(); - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), synchronizingAction.second.assignedGlobalVariables.begin(), synchronizingAction.second.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to synchronizing action '" << synchronizingAction.first << "'."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - nondeterminismEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (uint_fast64_t i = synchronizingAction.second.numberOfUsedNondeterminismVariables; i < numberOfUsedNondeterminismVariables; ++i) { - nondeterminismEncoding *= generationInfo.manager->getEncoding(generationInfo.nondeterminismMetaVariables[i], 0).template toAdd<ValueType>(); - } - synchronizingActionToDdMap.emplace(synchronizingAction.first, identityEncoding * synchronizingAction.second.transitionsDd * nondeterminismEncoding); - } - - // Add variables for synchronization. - result *= getSynchronizationDecisionDiagram(generationInfo); - - for (auto& synchronizingAction : synchronizingActionToDdMap) { - synchronizingAction.second *= getSynchronizationDecisionDiagram(generationInfo, synchronizingAction.first); - } - - // Now, we can simply add all synchronizing actions to the result. - for (auto const& synchronizingAction : synchronizingActionToDdMap) { - result += synchronizingAction.second; - } - - return result; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - // Simply add all actions, but make sure to include the missing global variable identities. - - // Compute missing global variable identities in independent action. - std::set<storm::expressions::Variable> missingIdentities; - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), module.independentAction.assignedGlobalVariables.begin(), module.independentAction.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - storm::dd::Add<Type, ValueType> identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to independent action."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - storm::dd::Add<Type, ValueType> result = identityEncoding * module.independentAction.transitionsDd; - - for (auto const& synchronizingAction : module.synchronizingActionToDecisionDiagramMap) { - // Compute missing global variable identities in synchronizing actions. - missingIdentities = std::set<storm::expressions::Variable>(); - std::set_difference(generationInfo.allGlobalVariables.begin(), generationInfo.allGlobalVariables.end(), synchronizingAction.second.assignedGlobalVariables.begin(), synchronizingAction.second.assignedGlobalVariables.end(), std::inserter(missingIdentities, missingIdentities.begin())); - identityEncoding = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& variable : missingIdentities) { - STORM_LOG_TRACE("Multiplying identity of global variable " << variable.getName() << " to synchronizing action '" << synchronizingAction.first << "'."); - identityEncoding *= generationInfo.variableToIdentityMap.at(variable); - } - - result += identityEncoding * synchronizingAction.second.transitionsDd; - } - return result; - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Illegal model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - typename DdPrismModelBuilder<Type, ValueType>::SystemResult DdPrismModelBuilder<Type, ValueType>::createSystemDecisionDiagram(GenerationInformation& generationInfo) { - ModuleComposer<Type, ValueType> composer(generationInfo); - ModuleDecisionDiagram system = composer.compose(generationInfo.program.specifiesSystemComposition() ? generationInfo.program.getSystemCompositionConstruct().getSystemComposition() : *generationInfo.program.getDefaultSystemComposition()); - - storm::dd::Add<Type, ValueType> result = createSystemFromModule(generationInfo, system); - - // Create an auxiliary DD that is used later during the construction of reward models. - STORM_LOG_TRACE("Counting: " << result.getNonZeroCount() << " // " << result.getNodeCount()); - storm::dd::Add<Type, ValueType> stateActionDd = result.sumAbstract(generationInfo.columnMetaVariables); - - // For DTMCs, we normalize each row to 1 (to account for non-determinism). - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - result = result / stateActionDd; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - // For MDPs, we need to throw away the nondeterminism variables from the generation information that - // were never used. - for (uint_fast64_t index = system.numberOfUsedNondeterminismVariables; index < generationInfo.nondeterminismMetaVariables.size(); ++index) { - generationInfo.allNondeterminismVariables.erase(generationInfo.nondeterminismMetaVariables[index]); - } - generationInfo.nondeterminismMetaVariables.resize(system.numberOfUsedNondeterminismVariables); - } - - return SystemResult(result, system, stateActionDd); - } - - template <storm::dd::DdType Type, typename ValueType> - storm::models::symbolic::StandardRewardModel<Type, ValueType> DdPrismModelBuilder<Type, ValueType>::createRewardModelDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, ModuleDecisionDiagram const& globalModule, storm::dd::Add<Type, ValueType> const& reachableStatesAdd, storm::dd::Add<Type, ValueType> const& stateActionDd) { - - // Start by creating the state reward vector. - boost::optional<storm::dd::Add<Type, ValueType>> stateRewards; - if (rewardModel.hasStateRewards()) { - stateRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& stateReward : rewardModel.getStateRewards()) { - storm::dd::Add<Type, ValueType> states = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getRewardValueExpression()); - - // Restrict the rewards to those states that satisfy the condition. - rewards = reachableStatesAdd * states * rewards; - - // Perform some sanity checks. - STORM_LOG_WARN_COND(rewards.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!rewards.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global state reward vector. - stateRewards.get() += rewards; - } - } - - // Next, build the state-action reward vector. - boost::optional<storm::dd::Add<Type, ValueType>> stateActionRewards; - if (rewardModel.hasStateActionRewards()) { - stateActionRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& stateActionReward : rewardModel.getStateActionRewards()) { - storm::dd::Add<Type, ValueType> states = generationInfo.rowExpressionAdapter->translateExpression(stateActionReward.getStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateActionReward.getRewardValueExpression()); - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo, stateActionReward.getActionIndex()); - } - ActionDecisionDiagram const& actionDd = stateActionReward.isLabeled() ? globalModule.synchronizingActionToDecisionDiagramMap.at(stateActionReward.getActionIndex()) : globalModule.independentAction; - states *= actionDd.guardDd * reachableStatesAdd; - storm::dd::Add<Type, ValueType> stateActionRewardDd = synchronization * states * rewards; - - // If we are building the state-action rewards for an MDP, we need to make sure that the encoding - // of the nondeterminism is present in the reward vector, so we ne need to multiply it with the - // legal state-actions. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - stateActionRewardDd *= stateActionDd; - } else if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - // For CTMCs, we need to multiply the entries with the exit rate of the corresponding action. - stateActionRewardDd *= actionDd.transitionsDd.sumAbstract(generationInfo.columnMetaVariables); - } - - // Perform some sanity checks. - STORM_LOG_WARN_COND(stateActionRewardDd.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!stateActionRewardDd.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global transition reward matrix. - stateActionRewards.get() += stateActionRewardDd; - } - - // Scale state-action rewards for DTMCs and CTMCs. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC || generationInfo.program.getModelType() == storm::prism::Program::ModelType::CTMC) { - stateActionRewards.get() /= stateActionDd; - } - } - - // Then build the transition reward matrix. - boost::optional<storm::dd::Add<Type, ValueType>> transitionRewards; - if (rewardModel.hasTransitionRewards()) { - transitionRewards = generationInfo.manager->template getAddZero<ValueType>(); - - for (auto const& transitionReward : rewardModel.getTransitionRewards()) { - storm::dd::Add<Type, ValueType> sourceStates = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getSourceStatePredicateExpression()); - storm::dd::Add<Type, ValueType> targetStates = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getTargetStatePredicateExpression()); - storm::dd::Add<Type, ValueType> rewards = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getRewardValueExpression()); - - storm::dd::Add<Type, ValueType> synchronization = generationInfo.manager->template getAddOne<ValueType>(); - - storm::dd::Add<Type, ValueType> transitions; - if (transitionReward.isLabeled()) { - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo, transitionReward.getActionIndex()); - } - transitions = globalModule.synchronizingActionToDecisionDiagramMap.at(transitionReward.getActionIndex()).transitionsDd; - } else { - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) { - synchronization = getSynchronizationDecisionDiagram(generationInfo); - } - transitions = globalModule.independentAction.transitionsDd; - } - - storm::dd::Add<Type, ValueType> transitionRewardDd = synchronization * sourceStates * targetStates * rewards; - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - // For DTMCs we need to keep the weighting for the scaling that follows. - transitionRewardDd = transitions * transitionRewardDd; - } else { - // For all other model types, we do not scale the rewards. - transitionRewardDd = transitions.notZero().template toAdd<ValueType>() * transitionRewardDd; - } - - // Perform some sanity checks. - STORM_LOG_WARN_COND(transitionRewardDd.getMin() >= 0, "The reward model assigns negative rewards to some states."); - STORM_LOG_WARN_COND(!transitionRewardDd.isZero(), "The reward model does not assign any non-zero rewards."); - - // Add the rewards to the global transition reward matrix. - transitionRewards.get() += transitionRewardDd; - } - - // Scale transition rewards for DTMCs. - if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) { - transitionRewards.get() /= stateActionDd; - } - } - - return storm::models::symbolic::StandardRewardModel<Type, ValueType>(stateRewards, stateActionRewards, transitionRewards); - } - - template <storm::dd::DdType Type, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>> DdPrismModelBuilder<Type, ValueType>::build(storm::prism::Program const& program, Options const& options) { - if (program.hasUndefinedConstants()) { - std::vector<std::reference_wrapper<storm::prism::Constant const>> undefinedConstants = program.getUndefinedConstants(); - std::stringstream stream; - bool printComma = false; - for (auto const& constant : undefinedConstants) { - if (printComma) { - stream << ", "; - } else { - printComma = true; - } - stream << constant.get().getName() << " (" << constant.get().getType() << ")"; - } - stream << "."; - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Program still contains these undefined constants: " + stream.str()); - } - - STORM_LOG_TRACE("Building representation of program:" << std::endl << program << std::endl); - - // Start by initializing the structure used for storing all information needed during the model generation. - // In particular, this creates the meta variables used to encode the model. - GenerationInformation generationInfo(program); - - SystemResult system = createSystemDecisionDiagram(generationInfo); - storm::dd::Add<Type, ValueType> transitionMatrix = system.allTransitionsDd; - - ModuleDecisionDiagram const& globalModule = system.globalModule; - storm::dd::Add<Type, ValueType> stateActionDd = system.stateActionDd; - - // If we were asked to treat some states as terminal states, we cut away their transitions now. - storm::dd::Bdd<Type> terminalStatesBdd = generationInfo.manager->getBddZero(); - if (options.terminalStates || options.negatedTerminalStates) { - std::map<storm::expressions::Variable, storm::expressions::Expression> constantsSubstitution = program.getConstantsSubstitution(); - - if (options.terminalStates) { - storm::expressions::Expression terminalExpression; - if (options.terminalStates.get().type() == typeid(storm::expressions::Expression)) { - terminalExpression = boost::get<storm::expressions::Expression>(options.terminalStates.get()); - } else { - std::string const& labelName = boost::get<std::string>(options.terminalStates.get()); - if (program.hasLabel(labelName)) { - terminalExpression = program.getLabelExpression(labelName); - } else { - STORM_LOG_THROW(labelName == "init" || labelName == "deadlock", storm::exceptions::InvalidArgumentException, "Terminal states refer to illegal label '" << labelName << "'."); - } - } - - if (terminalExpression.isInitialized()) { - // If the expression refers to constants of the model, we need to substitute them. - terminalExpression = terminalExpression.substitute(constantsSubstitution); - - STORM_LOG_TRACE("Making the states satisfying " << terminalExpression << " terminal."); - terminalStatesBdd = generationInfo.rowExpressionAdapter->translateExpression(terminalExpression).toBdd(); - } - } - if (options.negatedTerminalStates) { - storm::expressions::Expression negatedTerminalExpression; - if (options.negatedTerminalStates.get().type() == typeid(storm::expressions::Expression)) { - negatedTerminalExpression = boost::get<storm::expressions::Expression>(options.negatedTerminalStates.get()); - } else { - std::string const& labelName = boost::get<std::string>(options.negatedTerminalStates.get()); - if (program.hasLabel(labelName)) { - negatedTerminalExpression = program.getLabelExpression(labelName); - } else { - STORM_LOG_THROW(labelName == "init" || labelName == "deadlock", storm::exceptions::InvalidArgumentException, "Terminal states refer to illegal label '" << labelName << "'."); - } - } - - if (negatedTerminalExpression.isInitialized()) { - // If the expression refers to constants of the model, we need to substitute them. - negatedTerminalExpression = negatedTerminalExpression.substitute(constantsSubstitution); - - STORM_LOG_TRACE("Making the states *not* satisfying " << negatedTerminalExpression << " terminal."); - terminalStatesBdd |= !generationInfo.rowExpressionAdapter->translateExpression(negatedTerminalExpression).toBdd(); - } - } - - transitionMatrix *= (!terminalStatesBdd).template toAdd<ValueType>(); - } - - std::cout << "trans matrix has size " << transitionMatrix.getNodeCount() << std::endl; - - // Cut the transitions and rewards to the reachable fragment of the state space. - storm::dd::Bdd<Type> initialStates = createInitialStatesDecisionDiagram(generationInfo); - - storm::dd::Bdd<Type> transitionMatrixBdd = transitionMatrix.notZero(); - if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - transitionMatrixBdd = transitionMatrixBdd.existsAbstract(generationInfo.allNondeterminismVariables); - } - - storm::dd::Bdd<Type> reachableStates = storm::utility::dd::computeReachableStates<Type>(initialStates, transitionMatrixBdd, generationInfo.rowMetaVariables, generationInfo.columnMetaVariables); - storm::dd::Add<Type, ValueType> reachableStatesAdd = reachableStates.template toAdd<ValueType>(); - transitionMatrix *= reachableStatesAdd; - stateActionDd *= reachableStatesAdd; - - // Detect deadlocks and 1) fix them if requested 2) throw an error otherwise. - storm::dd::Bdd<Type> statesWithTransition = transitionMatrixBdd.existsAbstract(generationInfo.columnMetaVariables); - storm::dd::Bdd<Type> deadlockStates = reachableStates && !statesWithTransition; - - // If there are deadlocks, either fix them or raise an error. - if (!deadlockStates.isZero()) { - // If we need to fix deadlocks, we do so now. - if (!storm::settings::getModule<storm::settings::modules::CoreSettings>().isDontFixDeadlocksSet()) { - STORM_LOG_INFO("Fixing deadlocks in " << deadlockStates.getNonZeroCount() << " states. The first three of these states are: "); - - storm::dd::Add<Type, ValueType> deadlockStatesAdd = deadlockStates.template toAdd<ValueType>(); - uint_fast64_t count = 0; - for (auto it = deadlockStatesAdd.begin(), ite = deadlockStatesAdd.end(); it != ite && count < 3; ++it, ++count) { - STORM_LOG_INFO((*it).first.toPrettyString(generationInfo.rowMetaVariables) << std::endl); - } - - if (program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::CTMC) { - storm::dd::Add<Type, ValueType> identity = globalModule.identity; - - // Make sure that global variables do not change along the introduced self-loops. - for (auto const& var : generationInfo.allGlobalVariables) { - identity *= generationInfo.variableToIdentityMap.at(var); - } - - // For DTMCs, we can simply add the identity of the global module for all deadlock states. - transitionMatrix += deadlockStatesAdd * identity; - } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - // For MDPs, however, we need to select an action associated with the self-loop, if we do not - // want to attach a lot of self-loops to the deadlock states. - storm::dd::Add<Type, ValueType> action = generationInfo.manager->template getAddOne<ValueType>(); - for (auto const& metaVariable : generationInfo.allNondeterminismVariables) { - action *= generationInfo.manager->template getIdentity<ValueType>(metaVariable); - } - // Make sure that global variables do not change along the introduced self-loops. - for (auto const& var : generationInfo.allGlobalVariables) { - action *= generationInfo.variableToIdentityMap.at(var); - } - transitionMatrix += deadlockStatesAdd * globalModule.identity * action; - } - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The model contains " << deadlockStates.getNonZeroCount() << " deadlock states. Please unset the option to not fix deadlocks, if you want to fix them automatically."); - } - } - - // Reduce the deadlock states by the states that we did simply not explore. - deadlockStates = deadlockStates && !terminalStatesBdd; - - // Now build the reward models. - std::vector<std::reference_wrapper<storm::prism::RewardModel const>> selectedRewardModels; - - // First, we make sure that all selected reward models actually exist. - for (auto const& rewardModelName : options.rewardModelsToBuild) { - STORM_LOG_THROW(rewardModelName.empty() || program.hasRewardModel(rewardModelName), storm::exceptions::InvalidArgumentException, "Model does not possess a reward model with the name '" << rewardModelName << "'."); - } - - for (auto const& rewardModel : program.getRewardModels()) { - if (options.buildAllRewardModels || options.rewardModelsToBuild.find(rewardModel.getName()) != options.rewardModelsToBuild.end()) { - std::cout << "build all? " << buildAllRewardModels << std::endl; - selectedRewardModels.push_back(rewardModel); - } - } - // If no reward model was selected until now and a referenced reward model appears to be unique, we build - // the only existing reward model (given that no explicit name was given for the referenced reward model). - if (selectedRewardModels.empty() && program.getNumberOfRewardModels() == 1 && options.rewardModelsToBuild.size() == 1 && *options.rewardModelsToBuild.begin() == "") { - selectedRewardModels.push_back(program.getRewardModel(0)); - } - - std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<Type, ValueType>> rewardModels; - for (auto const& rewardModel : selectedRewardModels) { - rewardModels.emplace(rewardModel.get().getName(), createRewardModelDecisionDiagrams(generationInfo, rewardModel.get(), globalModule, reachableStatesAdd, stateActionDd)); - } - - // Build the labels that can be accessed as a shortcut. - std::map<std::string, storm::expressions::Expression> labelToExpressionMapping; - for (auto const& label : program.getLabels()) { - labelToExpressionMapping.emplace(label.getName(), label.getStatePredicateExpression()); - } - - if (program.getModelType() == storm::prism::Program::ModelType::DTMC) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Dtmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); - } else if (program.getModelType() == storm::prism::Program::ModelType::CTMC) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Ctmc<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, labelToExpressionMapping, rewardModels)); - } else if (program.getModelType() == storm::prism::Program::ModelType::MDP) { - return std::shared_ptr<storm::models::symbolic::Model<Type, ValueType>>(new storm::models::symbolic::Mdp<Type, ValueType>(generationInfo.manager, reachableStates, initialStates, deadlockStates, transitionMatrix, generationInfo.rowMetaVariables, generationInfo.rowExpressionAdapter, generationInfo.columnMetaVariables, generationInfo.columnExpressionAdapter, generationInfo.rowColumnMetaVariablePairs, generationInfo.allNondeterminismVariables, labelToExpressionMapping, rewardModels)); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Invalid model type."); - } - } - - template <storm::dd::DdType Type, typename ValueType> - storm::dd::Bdd<Type> DdPrismModelBuilder<Type, ValueType>::createInitialStatesDecisionDiagram(GenerationInformation& generationInfo) { - storm::dd::Bdd<Type> initialStates = generationInfo.rowExpressionAdapter->translateExpression(generationInfo.program.getInitialStatesExpression()).toBdd(); - - for (auto const& metaVariable : generationInfo.rowMetaVariables) { - initialStates &= generationInfo.manager->getRange(metaVariable); - } - - return initialStates; - } - - // Explicitly instantiate the symbolic model builder. - template class DdPrismModelBuilder<storm::dd::DdType::CUDD>; - template class DdPrismModelBuilder<storm::dd::DdType::Sylvan>; - - } // namespace adapters -} // namespace storm - - diff --git a/src/storm/builder/ExplicitModelBuilder.cpp b/src/storm/builder/ExplicitModelBuilder.cpp index 986e04ae7..70e548ae4 100644 --- a/src/storm/builder/ExplicitModelBuilder.cpp +++ b/src/storm/builder/ExplicitModelBuilder.cpp @@ -275,6 +275,7 @@ namespace storm { // (a) the transition matrix // (b) the initial states // (c) the hash map storing the mapping states -> ids + // (d) fix remapping for state-generation labels // Fix (a). transitionMatrixBuilder.replaceColumns(remapping, 0); @@ -287,6 +288,8 @@ namespace storm { // Fix (c). this->stateStorage.stateToId.remap([&remapping] (StateType const& state) { return remapping[state]; } ); + + this->generator->remapStateIds([&remapping] (StateType const& state) { return remapping[state]; }); } } diff --git a/src/storm/counterexamples/HighLevelCounterexample.cpp b/src/storm/counterexamples/HighLevelCounterexample.cpp new file mode 100644 index 000000000..707ed6d39 --- /dev/null +++ b/src/storm/counterexamples/HighLevelCounterexample.cpp @@ -0,0 +1,28 @@ +#include "storm/counterexamples/HighLevelCounterexample.h" + +namespace storm { + namespace counterexamples { + + HighLevelCounterexample::HighLevelCounterexample(storm::storage::SymbolicModelDescription const& model) : model(model) { + // Intentionally left empty. + } + + bool HighLevelCounterexample::isPrismHighLevelCounterexample() const { + return model.isPrismProgram(); + } + + bool HighLevelCounterexample::isJaniHighLevelCounterexample() const { + return model.isJaniModel(); + } + + storm::storage::SymbolicModelDescription const& HighLevelCounterexample::getModelDescription() const { + return model; + } + + void HighLevelCounterexample::writeToStream(std::ostream& out) const { + out << "High-level counterexample: " << std::endl; + out << model; + } + + } +} diff --git a/src/storm/counterexamples/HighLevelCounterexample.h b/src/storm/counterexamples/HighLevelCounterexample.h new file mode 100644 index 000000000..92310a5ba --- /dev/null +++ b/src/storm/counterexamples/HighLevelCounterexample.h @@ -0,0 +1,26 @@ +#pragma once + +#include "storm/counterexamples/Counterexample.h" + +#include "storm/storage/SymbolicModelDescription.h" + +namespace storm { + namespace counterexamples { + + class HighLevelCounterexample : public Counterexample { + public: + HighLevelCounterexample(storm::storage::SymbolicModelDescription const& model); + + void writeToStream(std::ostream& out) const override; + + bool isPrismHighLevelCounterexample() const; + bool isJaniHighLevelCounterexample() const; + + storm::storage::SymbolicModelDescription const& getModelDescription() const; + + private: + storm::storage::SymbolicModelDescription model; + }; + + } +} diff --git a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h index 7843bb4b0..861f86f83 100644 --- a/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1,5 +1,4 @@ -#ifndef STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ -#define STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ +#pragma once #include <chrono> #include <boost/container/flat_set.hpp> @@ -18,7 +17,7 @@ #include "storm/solver/MinMaxLinearEquationSolver.h" -#include "storm/counterexamples/PrismHighLevelCounterexample.h" +#include "storm/counterexamples/HighLevelCounterexample.h" #include "storm/utility/graph.h" #include "storm/utility/counterexamples.h" @@ -26,6 +25,7 @@ #include "storm/solver/LpSolver.h" #include "storm/storage/sparse/PrismChoiceOrigins.h" +#include "storm/storage/sparse/JaniChoiceOrigins.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -341,7 +341,7 @@ namespace storm { std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state); for (uint_fast64_t row : relevantChoicesForState) { for (auto const& successorEntry : mdp.getTransitionMatrix().getRow(row)) { - if (stateInformation.relevantStates.get(successorEntry.getColumn())) { + if (stateInformation.relevantStates.get(successorEntry.getColumn()) && resultingMap.find(std::make_pair(state, successorEntry.getColumn())) == resultingMap.end()) { variableNameBuffer.str(""); variableNameBuffer.clear(); variableNameBuffer << "t" << state << "to" << successorEntry.getColumn(); @@ -935,7 +935,7 @@ namespace storm { double maximalReachabilityProbability = 0; if (checkThresholdFeasible) { storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelcheckerHelper; - std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(env, false, mdp.getTransitionMatrix(), mdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values); + std::vector<T> result = std::move(modelcheckerHelper.computeUntilProbabilities(env, false, mdp.getTransitionMatrix(), mdp.getBackwardTransitions(), phiStates, psiStates, false, false).values); for (auto state : mdp.getInitialStates()) { maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]); } @@ -976,12 +976,12 @@ namespace storm { * @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested * formula can be either an unbounded until formula or an eventually formula. */ - static std::shared_ptr<PrismHighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program const& program, storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { + static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Mdp<T> const& mdp, std::shared_ptr<storm::logic::Formula const> const& formula) { std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; // Check whether there are choice origins available STORM_LOG_THROW(mdp.hasChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to minimal command set is impossible for model without choice origns."); - STORM_LOG_THROW(mdp.getChoiceOrigins()->isPrismChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without prism choice origins."); + STORM_LOG_THROW(mdp.getChoiceOrigins()->isPrismChoiceOrigins() || mdp.getChoiceOrigins()->isJaniChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without PRISM or JANI choice origins."); STORM_LOG_THROW(formula->isProbabilityOperatorFormula(), storm::exceptions::InvalidPropertyException, "Counterexample generation does not support this kind of formula. Expecting a probability operator as the outermost formula element."); storm::logic::ProbabilityOperatorFormula const& probabilityOperator = formula->asProbabilityOperatorFormula(); @@ -1020,21 +1020,34 @@ namespace storm { } // Obtain the label sets for each choice. - // The label set of a choice corresponds to the set of prism commands that induce the choice. - storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asPrismChoiceOrigins(); - std::vector<boost::container::flat_set<uint_fast64_t>> labelSets; - labelSets.reserve(mdp.getNumberOfChoices()); - for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { - labelSets.push_back(choiceOrigins.getCommandSet(choice)); + std::vector<boost::container::flat_set<uint_fast64_t>> labelSets(mdp.getNumberOfChoices()); + if (mdp.getChoiceOrigins()->isPrismChoiceOrigins()) { + storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asPrismChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getCommandSet(choice); + } + } else { + storm::storage::sparse::JaniChoiceOrigins const& choiceOrigins = mdp.getChoiceOrigins()->asJaniChoiceOrigins(); + + // The choice origins are known to be JANI ones at this point. + for (uint_fast64_t choice = 0; choice < mdp.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getEdgeIndexSet(choice); + } } // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - boost::container::flat_set<uint_fast64_t> usedCommandSet = getMinimalLabelSet(env, mdp, labelSets, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet()); + boost::container::flat_set<uint_fast64_t> usedLabelSet = getMinimalLabelSet(env, mdp, labelSets, phiStates, psiStates, threshold, strictBound, true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isUseSchedulerCutsSet()); auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Computed minimal command set of size " << usedCommandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + std::cout << std::endl << "Computed minimal command set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; - return std::make_shared<PrismHighLevelCounterexample>(program.restrictCommands(usedCommandSet)); + + if (symbolicModel.isPrismProgram()) { + return std::make_shared<HighLevelCounterexample>(symbolicModel.asPrismProgram().restrictCommands(usedLabelSet)); + } else { + STORM_LOG_ASSERT(symbolicModel.isJaniModel(), "Unknown symbolic model description type."); + return std::make_shared<HighLevelCounterexample>(symbolicModel.asJaniModel().restrictEdges(usedLabelSet)); + } } }; @@ -1042,4 +1055,3 @@ namespace storm { } // namespace counterexamples } // namespace storm -#endif /* STORM_COUNTEREXAMPLES_MILPMINIMALLABELSETGENERATOR_MDP_H_ */ diff --git a/src/storm/counterexamples/PrismHighLevelCounterexample.cpp b/src/storm/counterexamples/PrismHighLevelCounterexample.cpp deleted file mode 100644 index ae0e7fb06..000000000 --- a/src/storm/counterexamples/PrismHighLevelCounterexample.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "storm/counterexamples/PrismHighLevelCounterexample.h" - -namespace storm { - namespace counterexamples { - - PrismHighLevelCounterexample::PrismHighLevelCounterexample(storm::prism::Program const& program) : program(program) { - // Intentionally left empty. - } - - void PrismHighLevelCounterexample::writeToStream(std::ostream& out) const { - out << "High-level counterexample (PRISM program): " << std::endl; - out << program; - } - - } -} diff --git a/src/storm/counterexamples/PrismHighLevelCounterexample.h b/src/storm/counterexamples/PrismHighLevelCounterexample.h deleted file mode 100644 index 3e3de71c2..000000000 --- a/src/storm/counterexamples/PrismHighLevelCounterexample.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "storm/counterexamples/Counterexample.h" - -#include "storm/storage/prism/Program.h" - -namespace storm { - namespace counterexamples { - - class PrismHighLevelCounterexample : public Counterexample { - public: - PrismHighLevelCounterexample(storm::prism::Program const& program); - - void writeToStream(std::ostream& out) const override; - - private: - storm::prism::Program program; - }; - - } -} diff --git a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h index 7210d6e1b..6b4c440c1 100644 --- a/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h +++ b/src/storm/counterexamples/SMTMinimalLabelSetGenerator.h @@ -5,7 +5,7 @@ #include "storm/solver/Z3SmtSolver.h" -#include "storm/counterexamples/PrismHighLevelCounterexample.h" +#include "storm/counterexamples/HighLevelCounterexample.h" #include "storm/storage/prism/Program.h" #include "storm/storage/expressions/Expression.h" @@ -40,7 +40,7 @@ namespace storm { struct RelevancyInformation { // The set of relevant states in the model. storm::storage::BitVector relevantStates; - + // The set of relevant labels. boost::container::flat_set<uint_fast64_t> relevantLabels; @@ -319,11 +319,12 @@ namespace storm { * Asserts cuts that are derived from the explicit representation of the model and rule out a lot of * suboptimal solutions. * + * @param symbolicModel The symbolic model description used to build the model. * @param model The labeled model for which to compute the cuts. * @param context The Z3 context in which to build the expressions. * @param solver The solver to use for the satisfiability evaluation. */ - static void assertCuts(storm::prism::Program& program, storm::models::sparse::Model<T> const& model, std::vector<boost::container::flat_set<uint_fast64_t>> const& labelSets, storm::storage::BitVector const& psiStates, VariableInformation const& variableInformation, RelevancyInformation const& relevancyInformation, storm::solver::SmtSolver& solver) { + static void assertCuts(storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::vector<boost::container::flat_set<uint_fast64_t>> const& labelSets, storm::storage::BitVector const& psiStates, VariableInformation const& variableInformation, RelevancyInformation const& relevancyInformation, storm::solver::SmtSolver& solver) { // Walk through the model and // * identify labels enabled in initial states // * identify labels that can directly precede a given action @@ -400,189 +401,265 @@ namespace storm { } } - // Create a new solver over the same variables as the given program to use it for determining the symbolic - // cuts. - std::unique_ptr<storm::solver::SmtSolver> localSolver(new storm::solver::Z3SmtSolver(program.getManager())); - storm::expressions::ExpressionManager const& localManager = program.getManager(); - - // Then add the constraints for bounds of the integer variables.. - for (auto const& integerVariable : program.getGlobalIntegerVariables()) { - localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); - localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); - } - for (auto const& module : program.getModules()) { - for (auto const& integerVariable : module.getIntegerVariables()) { - localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); - localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); - } - } - - // Construct an expression that exactly characterizes the initial state. - storm::expressions::Expression initialStateExpression = program.getInitialStatesExpression(); - // Store the found implications in a container similar to the preceding label sets. std::map<boost::container::flat_set<uint_fast64_t>, std::set<boost::container::flat_set<uint_fast64_t>>> backwardImplications; - - // Now check for possible backward cuts. - for (auto const& labelSetAndPrecedingLabelSetsPair : precedingLabels) { - // Find out the commands for the currently considered label set. - std::vector<std::reference_wrapper<storm::prism::Command const>> currentCommandVector; - for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { - storm::prism::Module const& module = program.getModule(moduleIndex); + + if (!symbolicModel.isJaniModel() || !symbolicModel.asJaniModel().usesAssignmentLevels()) { + // Create a new solver over the same variables as the given symbolic model description to use it for + // determining the symbolic cuts. + std::unique_ptr<storm::solver::SmtSolver> localSolver; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); + localSolver = std::make_unique<storm::solver::Z3SmtSolver>(program.getManager()); + + // Then add the constraints for bounds of the integer variables. + for (auto const& integerVariable : program.getGlobalIntegerVariables()) { + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); + } + for (auto const& module : program.getModules()) { + for (auto const& integerVariable : module.getIntegerVariables()) { + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBoundExpression()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBoundExpression()); + } + } + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + localSolver = std::make_unique<storm::solver::Z3SmtSolver>(janiModel.getManager()); - for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { - storm::prism::Command const& command = module.getCommand(commandIndex); + for (auto const& integerVariable : janiModel.getGlobalVariables().getBoundedIntegerVariables()) { + if (integerVariable.isTransient()) { + continue; + } - // If the current command is one of the commands we need to consider, store a reference to it in the container. - if (labelSetAndPrecedingLabelSetsPair.first.find(command.getGlobalIndex()) != labelSetAndPrecedingLabelSetsPair.first.end()) { - currentCommandVector.push_back(command); + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBound()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBound()); + } + for (auto const& automaton : janiModel.getAutomata()) { + for (auto const& integerVariable : automaton.getVariables().getBoundedIntegerVariables()) { + if (integerVariable.isTransient()) { + continue; + } + + localSolver->add(integerVariable.getExpressionVariable() >= integerVariable.getLowerBound()); + localSolver->add(integerVariable.getExpressionVariable() <= integerVariable.getUpperBound()); } } } - // Save the state of the solver so we can easily backtrack. - localSolver->push(); - // Check if the command set is enabled in the initial state. - for (auto const& command : currentCommandVector) { - localSolver->add(command.get().getGuardExpression()); + // Construct an expression that exactly characterizes the initial state. + storm::expressions::Expression initialStateExpression; + if (symbolicModel.isPrismProgram()) { + initialStateExpression = symbolicModel.asPrismProgram().getInitialStatesExpression(); + } else { + initialStateExpression = symbolicModel.asJaniModel().getInitialStatesExpression(); } - localSolver->add(initialStateExpression); - - storm::solver::SmtSolver::CheckResult checkResult = localSolver->check(); - localSolver->pop(); - localSolver->push(); -// std::cout << "combi" << std::endl; -// for (auto const& e : labelSetAndPrecedingLabelSetsPair.first) { -// std::cout << e << ", "; -// } -// std::cout << std::endl; - - // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. - if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { - STORM_LOG_DEBUG("Selection not enabled in initial state."); + // Now check for possible backward cuts. + for (auto const& labelSetAndPrecedingLabelSetsPair : precedingLabels) { + bool backwardImplicationAdded = false; +// std::cout << "labelSetAndPrecedingLabelSetsPair.first "; +// for (auto const& e : labelSetAndPrecedingLabelSetsPair.first) { +// std::cout << e << ", "; +// } +// std::cout << std::endl; + // Find out the commands for the currently considered label set. storm::expressions::Expression guardConjunction; - if (currentCommandVector.size() == 1) { - guardConjunction = currentCommandVector.begin()->get().getGuardExpression(); - } else if (currentCommandVector.size() > 1) { - std::vector<std::reference_wrapper<storm::prism::Command const>>::const_iterator setIterator = currentCommandVector.begin(); - storm::expressions::Expression first = setIterator->get().getGuardExpression(); - ++setIterator; - storm::expressions::Expression second = setIterator->get().getGuardExpression(); - guardConjunction = first && second; - ++setIterator; - - while (setIterator != currentCommandVector.end()) { - guardConjunction = guardConjunction && setIterator->get().getGuardExpression(); - ++setIterator; - } - } else { - STORM_LOG_ASSERT(false, "Choice label set is empty."); - } - - STORM_LOG_DEBUG("About to assert that combination is not enabled in the current state."); -// std::cout << "negated guard expr " << !guardConjunction << std::endl; - localSolver->add(!guardConjunction); - STORM_LOG_DEBUG("Asserted disjunction of negated guards."); - // Now check the possible preceding label sets for the essential ones. - for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { - if (labelSetAndPrecedingLabelSetsPair.first == precedingLabelSet) continue; - -// std::cout << "new preceeding label set" << std::endl; -// for (auto const& e : precedingLabelSet) { -// std::cout << e << ", "; -// } -// std::cout << std::endl; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); - // Create a restore point so we can easily pop-off all weakest precondition expressions. - localSolver->push(); - - // Find out the commands for the currently considered preceding label set. - std::vector<std::reference_wrapper<storm::prism::Command const>> currentPrecedingCommandVector; for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { storm::prism::Module const& module = program.getModule(moduleIndex); for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { storm::prism::Command const& command = module.getCommand(commandIndex); - // If the current command is one of the commands we need to consider, store a reference to it in the container. - if (precedingLabelSet.find(command.getGlobalIndex()) != precedingLabelSet.end()) { - currentPrecedingCommandVector.push_back(command); + // If the current command is one of the commands we need to consider, add its guard. + if (labelSetAndPrecedingLabelSetsPair.first.find(command.getGlobalIndex()) != labelSetAndPrecedingLabelSetsPair.first.end()) { + guardConjunction = guardConjunction && command.getGuardExpression(); } } } - - // Assert all the guards of the preceding command set. - for (auto const& command : currentPrecedingCommandVector) { -// std::cout << "command guard " << command.get().getGuardExpression() << std::endl; - localSolver->add(command.get().getGuardExpression()); + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + + for (uint_fast64_t automatonIndex = 0; automatonIndex < janiModel.getNumberOfAutomata(); ++automatonIndex) { + storm::jani::Automaton const& automaton = janiModel.getAutomaton(automatonIndex); + + for (uint_fast64_t edgeIndex = 0; edgeIndex < automaton.getNumberOfEdges(); ++edgeIndex) { + // If the current edge is one of the edges we need to consider, add its guard. + if (labelSetAndPrecedingLabelSetsPair.first.find(janiModel.encodeAutomatonAndEdgeIndices(automatonIndex, edgeIndex)) != labelSetAndPrecedingLabelSetsPair.first.end()) { + storm::jani::Edge const& edge = automaton.getEdge(edgeIndex); + + guardConjunction = guardConjunction && edge.getGuard(); + } + } } + } + + // Save the state of the solver so we can easily backtrack. + localSolver->push(); + + // Push initial state expression. + STORM_LOG_DEBUG("About to assert that combination is not enabled in the current state."); + localSolver->add(initialStateExpression); + + // Check if the label set is enabled in the initial state. + localSolver->add(guardConjunction); + + storm::solver::SmtSolver::CheckResult checkResult = localSolver->check(); + localSolver->pop(); + localSolver->push(); + + // If the solver reports unsat, then we know that the current selection is not enabled in the initial state. + if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { + STORM_LOG_DEBUG("Selection not enabled in initial state."); + + //std::cout << "not gc: " << !guardConjunction << std::endl; + localSolver->add(!guardConjunction); + STORM_LOG_DEBUG("Asserted disjunction of negated guards."); - std::vector<std::vector<storm::prism::Update>::const_iterator> iteratorVector; - for (auto const& command : currentPrecedingCommandVector) { - iteratorVector.push_back(command.get().getUpdates().begin()); - } - // Iterate over all possible combinations of updates of the preceding command set. - std::vector<storm::expressions::Expression> formulae; - bool done = false; - while (!done) { - std::map<storm::expressions::Variable, storm::expressions::Expression> currentUpdateCombinationMap; - for (auto const& updateIterator : iteratorVector) { - for (auto const& assignment : updateIterator->getAssignments()) { - currentUpdateCombinationMap.emplace(assignment.getVariable(), assignment.getExpression()); + // Now check the possible preceding label sets for the essential ones. + for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { + + if (labelSetAndPrecedingLabelSetsPair.first == precedingLabelSet) continue; + + //std::cout << "push" << std::endl; + // Create a restore point so we can easily pop-off all weakest precondition expressions. + localSolver->push(); + + // Find out the commands for the currently considered preceding label set. + std::vector<std::vector<boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression>>> currentPreceedingVariableUpdates; + storm::expressions::Expression preceedingGuardConjunction; + if (symbolicModel.isPrismProgram()) { + storm::prism::Program const& program = symbolicModel.asPrismProgram(); + for (uint_fast64_t moduleIndex = 0; moduleIndex < program.getNumberOfModules(); ++moduleIndex) { + storm::prism::Module const& module = program.getModule(moduleIndex); + + for (uint_fast64_t commandIndex = 0; commandIndex < module.getNumberOfCommands(); ++commandIndex) { + storm::prism::Command const& command = module.getCommand(commandIndex); + + // If the current command is one of the commands we need to consider, store a reference to it in the container. + if (precedingLabelSet.find(command.getGlobalIndex()) != precedingLabelSet.end()) { + preceedingGuardConjunction = preceedingGuardConjunction && command.getGuardExpression(); + + currentPreceedingVariableUpdates.emplace_back(); + + for (uint64_t updateIndex = 0; updateIndex < command.getNumberOfUpdates(); ++updateIndex) { + storm::prism::Update const& update = command.getUpdate(updateIndex); + boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression> variableUpdates; + for (auto const& assignment : update.getAssignments()) { + variableUpdates.emplace(assignment.getVariable(), assignment.getExpression()); + } + currentPreceedingVariableUpdates.back().emplace_back(std::move(variableUpdates)); + } + } + } + } + } else { + storm::jani::Model const& janiModel = symbolicModel.asJaniModel(); + for (uint_fast64_t automatonIndex = 0; automatonIndex < janiModel.getNumberOfAutomata(); ++automatonIndex) { + storm::jani::Automaton const& automaton = janiModel.getAutomaton(automatonIndex); + + for (uint_fast64_t edgeIndex = 0; edgeIndex < automaton.getNumberOfEdges(); ++edgeIndex) { + // If the current command is one of the commands we need to consider, store a reference to it in the container. + if (precedingLabelSet.find(janiModel.encodeAutomatonAndEdgeIndices(automatonIndex, edgeIndex)) != precedingLabelSet.end()) { + storm::jani::Edge const& edge = automaton.getEdge(edgeIndex); + + preceedingGuardConjunction = preceedingGuardConjunction && edge.getGuard(); + + currentPreceedingVariableUpdates.emplace_back(); + + for (uint64_t destinationIndex = 0; destinationIndex < edge.getNumberOfDestinations(); ++destinationIndex) { + storm::jani::EdgeDestination const& destination = edge.getDestination(destinationIndex); + boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression> variableUpdates; + for (auto const& assignment : destination.getOrderedAssignments().getNonTransientAssignments()) { + variableUpdates.emplace(assignment.getVariable().getExpressionVariable(), assignment.getAssignedExpression()); + } + currentPreceedingVariableUpdates.back().emplace_back(std::move(variableUpdates)); + } + } + } } } + + //std::cout << "pgc: " << preceedingGuardConjunction << std::endl; + + // Assert all the guards of the preceding command set. + localSolver->add(preceedingGuardConjunction); - STORM_LOG_DEBUG("About to assert a weakest precondition."); - storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap); -// std::cout << "wp: " << wp << std::endl; - formulae.push_back(wp); - STORM_LOG_DEBUG("Asserted weakest precondition."); + std::vector<std::vector<boost::container::flat_map<storm::expressions::Variable, storm::expressions::Expression>>::const_iterator> iteratorVector; + for (auto const& variableUpdates : currentPreceedingVariableUpdates) { + iteratorVector.push_back(variableUpdates.begin()); + } - // Now try to move iterators to the next position if possible. If we could properly move it, we can directly - // move on to the next combination of updates. If we have to reset it to the start, we - uint_fast64_t k = iteratorVector.size(); - for (; k > 0; --k) { - ++iteratorVector[k - 1]; - if (iteratorVector[k - 1] == currentPrecedingCommandVector[k - 1].get().getUpdates().end()) { - iteratorVector[k - 1] = currentPrecedingCommandVector[k - 1].get().getUpdates().begin(); - } else { - break; + // Iterate over all possible combinations of updates of the preceding command set. + std::vector<storm::expressions::Expression> formulae; + bool done = false; + while (!done) { + std::map<storm::expressions::Variable, storm::expressions::Expression> currentVariableUpdateCombinationMap; + for (auto const& updateIterator : iteratorVector) { + for (auto const& variableUpdatePair : *updateIterator) { + currentVariableUpdateCombinationMap.emplace(variableUpdatePair.first, variableUpdatePair.second); + } + } + + STORM_LOG_DEBUG("About to assert a weakest precondition."); + storm::expressions::Expression wp = guardConjunction.substitute(currentVariableUpdateCombinationMap); + formulae.push_back(wp); + STORM_LOG_DEBUG("Asserted weakest precondition."); + + // Now try to move iterators to the next position if possible. If we could properly + // move it, we can directly move on to the next combination of updates. If we have + // to reset it to the start, we do so unless there is no more iterator to reset. + uint_fast64_t k = iteratorVector.size(); + for (; k > 0; --k) { + ++iteratorVector[k - 1]; + if (iteratorVector[k - 1] == currentPreceedingVariableUpdates[k - 1].end()) { + iteratorVector[k - 1] = currentPreceedingVariableUpdates[k - 1].begin(); + } else { + break; + } + } + + // If we had to reset all iterator to the start, we are done. + if (k == 0) { + done = true; } } - // If we had to reset all iterator to the start, we are done. - if (k == 0) { - done = true; + // Now assert the disjunction of all weakest preconditions of all considered update combinations. + assertDisjunction(*localSolver, formulae, symbolicModel.isPrismProgram() ? symbolicModel.asPrismProgram().getManager() : symbolicModel.asJaniModel().getManager()); + + STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); + storm::solver::SmtSolver::CheckResult result = localSolver->check(); + + if (result == storm::solver::SmtSolver::CheckResult::Sat) { + backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); + backwardImplicationAdded = true; + } else if (result == storm::solver::SmtSolver::CheckResult::Unknown) { + STORM_LOG_ERROR("The SMT solver does not come to a conclusive answer. Does your model contain integer division?"); } + + localSolver->pop(); } - // Now assert the disjunction of all weakest preconditions of all considered update combinations. - assertDisjunction(*localSolver, formulae, localManager); - - STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions."); - - if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { -// std::cout << "sat" << std::endl; - backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); - } -// else { -// std::cout << "unsat" << std::endl; -// } - + // Popping the disjunction of negated guards from the solver stack. localSolver->pop(); + } else { + STORM_LOG_DEBUG("Selection is enabled in initial state."); } - - // Popping the disjunction of negated guards from the solver stack. - localSolver->pop(); - } else { - STORM_LOG_DEBUG("Selection is enabled in initial state."); + STORM_LOG_ERROR_COND(backwardImplicationAdded, "Error in adding cuts for counterexample generation (backward implication misses a label set)."); } + } else if (symbolicModel.isJaniModel()) { + STORM_LOG_WARN("Model uses assignment levels, did not assert backward implications."); } + STORM_LOG_DEBUG("Successfully gathered data for cuts."); + // Compute the sets of labels such that the transitions labeled with this set possess at least one known label. boost::container::flat_set<boost::container::flat_set<uint_fast64_t>> hasKnownSuccessor; for (auto const& labelSetFollowingSetsPair : followingLabels) { @@ -604,9 +681,6 @@ namespace storm { } } } - - - STORM_LOG_DEBUG("Successfully gathered data for cuts."); STORM_LOG_DEBUG("Asserting initial combination is taken."); { @@ -1264,6 +1338,24 @@ namespace storm { return getUsedLabelSet(*solver.getModel(), variableInformation); } + static void ruleOutSingleSolution(storm::solver::SmtSolver& solver, boost::container::flat_set<uint_fast64_t> const& labelSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { + std::vector<storm::expressions::Expression> formulae; + + boost::container::flat_set<uint_fast64_t> unknownLabels; + std::set_difference(labelSet.begin(), labelSet.end(), relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end(), std::inserter(unknownLabels, unknownLabels.end())); + for (auto const& label : unknownLabels) { + formulae.emplace_back(!variableInformation.labelVariables.at(variableInformation.labelToIndexMap.at(label))); + } + boost::container::flat_set<uint_fast64_t> remainingLabels; + std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), labelSet.begin(), labelSet.end(), std::inserter(remainingLabels, remainingLabels.end())); + for (auto const& label : remainingLabels) { + formulae.emplace_back(variableInformation.labelVariables.at(variableInformation.labelToIndexMap.at(label))); + } + + STORM_LOG_DEBUG("Ruling out single solution."); + assertDisjunction(solver, formulae, *variableInformation.manager); + } + /*! * Analyzes the given sub-model that has a maximal reachability of zero (i.e. no psi states are reachable) and tries to construct assertions that aim to make at least one psi state reachable. * @@ -1502,7 +1594,7 @@ namespace storm { for(uint_fast64_t state = 0; state < model.getNumberOfStates(); ++state) { bool stateHasValidChoice = false; for (uint_fast64_t choice = model.getTransitionMatrix().getRowGroupIndices()[state]; choice < model.getTransitionMatrix().getRowGroupIndices()[state + 1]; ++choice) { - auto const& choiceLabelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice); + auto const& choiceLabelSet = model.getChoiceOrigins()->isPrismChoiceOrigins() ? model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice) : model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(choice); bool choiceValid = std::includes(filterLabelSet.begin(), filterLabelSet.end(), choiceLabelSet.begin(), choiceLabelSet.end()); // If the choice is valid, copy over all its elements. @@ -1548,10 +1640,10 @@ namespace storm { STORM_LOG_DEBUG("Invoking model checker."); if (model.isOfType(storm::models::ModelType::Dtmc)) { - allStatesResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<T>::computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, storm::solver::GeneralLinearEquationSolverFactory<T>()); + allStatesResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<T>::computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false); } else { storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; - allStatesResult = std::move(modelCheckerHelper.computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, false, storm::solver::GeneralMinMaxLinearEquationSolverFactory<T>()).values); + allStatesResult = std::move(modelCheckerHelper.computeUntilProbabilities(env, false, model.getTransitionMatrix(), model.getBackwardTransitions(), phiStates, psiStates, false, false).values); } for (auto state : model.getInitialStates()) { result = std::max(result, allStatesResult[state]); @@ -1560,23 +1652,36 @@ namespace storm { } public: + struct Options { + Options(bool checkThresholdFeasible = false) : checkThresholdFeasible(checkThresholdFeasible) { + auto const& settings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>(); + + encodeReachability = settings.isEncodeReachabilitySet(); + useDynamicConstraints = settings.isUseDynamicConstraintsSet(); + } + + bool checkThresholdFeasible; + bool encodeReachability; + bool useDynamicConstraints; + bool silent = false; + }; + /*! * Computes the minimal command set that is needed in the given model to exceed the given probability threshold for satisfying phi until psi. * - * @param program The program that was used to build the model. + * @param symbolicModel The symbolic model description that was used to build the model. * @param model The sparse model in which to find the minimal command set. * @param phiStates A bit vector characterizing all phi states in the model. * @param psiStates A bit vector characterizing all psi states in the model. * @param probabilityThreshold The threshold that is to be achieved or exceeded. * @param strictBound Indicates whether the threshold needs to be achieved (true) or exceeded (false). - * @param checkThresholdFeasible If set, it is verified that the model can actually achieve/exceed the given probability value. If this check - * is made and fails, an exception is thrown. + * @param options A set of options for customization. */ - static boost::container::flat_set<uint_fast64_t> getMinimalCommandSet(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), bool checkThresholdFeasible = false, bool includeReachabilityEncoding = false) { + static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), Options const& options = Options()) { #ifdef STORM_HAVE_Z3 // Set up all clocks used for time measurement. auto totalClock = std::chrono::high_resolution_clock::now(); - auto localClock = std::chrono::high_resolution_clock::now(); + auto timeOfLastMessage = std::chrono::high_resolution_clock::now(); decltype(std::chrono::high_resolution_clock::now() - totalClock) totalTime(0); auto setupTimeClock = std::chrono::high_resolution_clock::now(); @@ -1594,17 +1699,25 @@ namespace storm { // (0) Obtain the label sets for each choice. // The label set of a choice corresponds to the set of prism commands that induce the choice. STORM_LOG_THROW(model.hasChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to minimal command set is impossible for model without choice origins."); - STORM_LOG_THROW(model.getChoiceOrigins()->isPrismChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to command set is impossible for model without prism choice origins."); - storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asPrismChoiceOrigins(); - std::vector<boost::container::flat_set<uint_fast64_t>> labelSets; - labelSets.reserve(model.getNumberOfChoices()); - for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { - labelSets.push_back(choiceOrigins.getCommandSet(choice)); + STORM_LOG_THROW(model.getChoiceOrigins()->isPrismChoiceOrigins() || model.getChoiceOrigins()->isJaniChoiceOrigins(), storm::exceptions::InvalidArgumentException, "Restriction to label set is impossible for model without PRISM or JANI choice origins."); + + std::vector<boost::container::flat_set<uint_fast64_t>> labelSets(model.getNumberOfChoices()); + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + storm::storage::sparse::PrismChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asPrismChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getCommandSet(choice); + } + } else { + storm::storage::sparse::JaniChoiceOrigins const& choiceOrigins = model.getChoiceOrigins()->asJaniChoiceOrigins(); + for (uint_fast64_t choice = 0; choice < model.getNumberOfChoices(); ++choice) { + labelSets[choice] = choiceOrigins.getEdgeIndexSet(choice); + } } + assert(labelSets.size() == model.getNumberOfChoices()); // (1) Check whether its possible to exceed the threshold if checkThresholdFeasible is set. double maximalReachabilityProbability = 0; - if (checkThresholdFeasible) { + if (options.checkThresholdFeasible) { maximalReachabilityProbability = computeMaximalReachabilityProbability(env, model, phiStates, psiStates); STORM_LOG_THROW((strictBound && maximalReachabilityProbability >= probabilityThreshold) || (!strictBound && maximalReachabilityProbability > probabilityThreshold), storm::exceptions::InvalidArgumentException, "Given probability threshold " << probabilityThreshold << " can not be " << (strictBound ? "achieved" : "exceeded") << " in model with maximal reachability probability of " << maximalReachabilityProbability << "."); @@ -1619,7 +1732,7 @@ namespace storm { std::unique_ptr<storm::solver::SmtSolver> solver = std::make_unique<storm::solver::Z3SmtSolver>(*manager); // (4) Create the variables for the relevant commands. - VariableInformation variableInformation = createVariables(manager, model, psiStates, relevancyInformation, includeReachabilityEncoding); + VariableInformation variableInformation = createVariables(manager, model, psiStates, relevancyInformation, options.encodeReachability); STORM_LOG_DEBUG("Created variables."); // (5) Now assert an adder whose result variables can later be used to constrain the nummber of label @@ -1630,9 +1743,9 @@ namespace storm { // (6) Add constraints that cut off a lot of suboptimal solutions. STORM_LOG_DEBUG("Asserting cuts."); - assertCuts(program, model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); + assertCuts(symbolicModel, model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); STORM_LOG_DEBUG("Asserted cuts."); - if (includeReachabilityEncoding) { + if (options.encodeReachability) { assertReachabilityCuts(model, labelSets, psiStates, variableInformation, relevancyInformation, *solver); STORM_LOG_DEBUG("Asserted reachability cuts."); } @@ -1657,16 +1770,18 @@ namespace storm { // Set up some variables for the iterations. bool done = false; + uint_fast64_t lastSize = 0; uint_fast64_t iterations = 0; uint_fast64_t currentBound = 0; maximalReachabilityProbability = 0; uint_fast64_t zeroProbabilityCount = 0; + uint64_t progressDelay = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getShowProgressDelay(); do { STORM_LOG_DEBUG("Computing minimal command set."); solverClock = std::chrono::high_resolution_clock::now(); commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound); totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock; - STORM_LOG_DEBUG("Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << "."); + STORM_LOG_DEBUG("Computed minimal command set of size " << commandSet.size() + relevancyInformation.knownLabels.size() << " (" << commandSet.size() << " + " << relevancyInformation.knownLabels.size() << ") "); // Restrict the given model to the current set of labels and compute the reachability probability. modelCheckingClock = std::chrono::high_resolution_clock::now(); @@ -1682,31 +1797,58 @@ namespace storm { // Depending on whether the threshold was successfully achieved or not, we proceed by either analyzing the bad solution or stopping the iteration process. analysisClock = std::chrono::high_resolution_clock::now(); if ((strictBound && maximalReachabilityProbability < probabilityThreshold) || (!strictBound && maximalReachabilityProbability <= probabilityThreshold)) { - if (maximalReachabilityProbability == 0) { + if (maximalReachabilityProbability == storm::utility::zero<T>()) { ++zeroProbabilityCount; + } + + if (options.useDynamicConstraints) { + // Determine which of the two analysis techniques to call by performing a reachability analysis. + storm::storage::BitVector reachableStates = storm::utility::graph::getReachableStates(subModel->getTransitionMatrix(), subModel->getInitialStates(), phiStates, psiStates); - // If there was no target state reachable, analyze the solution and guide the solver into the right direction. - analyzeZeroProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + if (reachableStates.isDisjointFrom(psiStates)) { + // If there was no target state reachable, analyze the solution and guide the solver into the right direction. + analyzeZeroProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + } else { + // If the reachability probability was greater than zero (i.e. there is a reachable target state), but the probability was insufficient to exceed + // the given threshold, we analyze the solution and try to guide the solver into the right direction. + analyzeInsufficientProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + } } else { - // If the reachability probability was greater than zero (i.e. there is a reachable target state), but the probability was insufficient to exceed - // the given threshold, we analyze the solution and try to guide the solver into the right direction. - analyzeInsufficientProbabilitySolution(*solver, *subModel, subLabelSets, model, labelSets, phiStates, psiStates, commandSet, variableInformation, relevancyInformation); + // Do not guide solver, just rule out current solution. + ruleOutSingleSolution(*solver, commandSet, variableInformation, relevancyInformation); } } else { done = true; } totalAnalysisTime += (std::chrono::high_resolution_clock::now() - analysisClock); ++iterations; - - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - localClock).count() >= 5) { - std::cout << "Checked " << iterations << " models in " << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - totalClock).count() << "s (out of which " << zeroProbabilityCount << " could not reach the target states). Current command set size is " << commandSet.size() << "." << std::endl; - localClock = std::chrono::high_resolution_clock::now(); + + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= progressDelay || lastSize < commandSet.size()) { + auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(now - totalClock).count(); + if (lastSize < commandSet.size()) { + std::cout << "Improved lower bound to " << commandSet.size() << " after " << milliseconds << "ms." << std::endl; + lastSize = commandSet.size(); + } else { + std::cout << "Lower bound on label set size is " << commandSet.size() << " after " << milliseconds << "ms (checked " << iterations << " models, " << zeroProbabilityCount << " could not reach the target set)." << std::endl; + timeOfLastMessage = std::chrono::high_resolution_clock::now(); + } } } while (!done); // Compute and emit the time measurements if the corresponding flag was set. totalTime = std::chrono::high_resolution_clock::now() - totalClock; if (storm::settings::getModule<storm::settings::modules::CoreSettings>().isShowStatisticsSet()) { + boost::container::flat_set<uint64_t> allLabels; + for (auto const& e : labelSets) { + allLabels.insert(e.begin(), e.end()); + } + + std::cout << "Metrics:" << std::endl; + std::cout << " * all labels: " << allLabels.size() << std::endl; + std::cout << " * known labels: " << relevancyInformation.knownLabels.size() << std::endl; + std::cout << " * relevant labels: " << (relevancyInformation.knownLabels.size() + relevancyInformation.relevantLabels.size()) << std::endl; std::cout << std::endl; std::cout << "Time breakdown:" << std::endl; std::cout << " * time for setup: " << std::chrono::duration_cast<std::chrono::milliseconds>(totalSetupTime).count() << "ms" << std::endl; @@ -1727,7 +1869,7 @@ namespace storm { #endif } - static void extendCommandSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + static void extendLabelSetLowerBound(storm::models::sparse::Model<T> const& model, boost::container::flat_set<uint_fast64_t>& commandSet, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool silent = false) { auto startTime = std::chrono::high_resolution_clock::now(); // Create sub-model that only contains the choices allowed by the given command set. @@ -1765,11 +1907,17 @@ namespace storm { } if (onlyProb0ESuccessors) { - auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice); - hasLabeledChoice |= !labelSet.empty(); + uint64_t labelSetSize = 0; + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + labelSetSize = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(choice).size(); + } else { + assert(model.getChoiceOrigins()->isJaniChoiceOrigins()); + labelSetSize = model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(choice).size(); + } + hasLabeledChoice |= (labelSetSize != 0); - if (smallestCommandChoice == 0 || labelSet.size() < smallestCommandSetSize) { - smallestCommandSetSize = labelSet.size(); + if (smallestCommandChoice == 0 || labelSetSize < smallestCommandSetSize) { + smallestCommandSetSize = labelSetSize; smallestCommandChoice = choice; } } @@ -1777,9 +1925,15 @@ namespace storm { if (hasLabeledChoice) { // Take all labels of the selected choice. - auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(smallestCommandChoice); - commandSet.insert(labelSet.begin(), labelSet.end()); - + if (model.getChoiceOrigins()->isPrismChoiceOrigins()) { + auto const& labelSet = model.getChoiceOrigins()->asPrismChoiceOrigins().getCommandSet(smallestCommandChoice); + commandSet.insert(labelSet.begin(), labelSet.end()); + } else { + assert(model.getChoiceOrigins()->isJaniChoiceOrigins()); + auto const& labelSet = model.getChoiceOrigins()->asJaniChoiceOrigins().getEdgeIndexSet(smallestCommandChoice); + commandSet.insert(labelSet.begin(), labelSet.end()); + } + // Check for which successor states choices need to be added for (auto const& successorEntry : model.getTransitionMatrix().getRow(smallestCommandChoice)) { if (!storm::utility::isZero(successorEntry.getValue())) { @@ -1793,12 +1947,17 @@ namespace storm { } auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Extended command for lower bounded property to size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + if (!silent) { + std::cout << std::endl << "Extended command for lower bounded property to size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + } + } - static boost::container::flat_set<uint_fast64_t> computeCounterexampleCommandSet(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static boost::container::flat_set<uint_fast64_t> computeCounterexampleLabelSet(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula, boost::container::flat_set<uint_fast64_t> const& dontCareLabels = boost::container::flat_set<uint_fast64_t>(), Options const& options = Options(true)) { STORM_LOG_THROW(model.isOfType(storm::models::ModelType::Dtmc) || model.isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "MaxSAT-based counterexample generation is supported only for discrete-time models."); - std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; + if (!options.silent) { + std::cout << std::endl << "Generating minimal label counterexample for formula " << *formula << std::endl; + } STORM_LOG_THROW(formula->isProbabilityOperatorFormula(), storm::exceptions::InvalidPropertyException, "Counterexample generation does not support this kind of formula. Expecting a probability operator as the outermost formula element."); storm::logic::ProbabilityOperatorFormula const& probabilityOperator = formula->asProbabilityOperatorFormula(); @@ -1846,7 +2005,9 @@ namespace storm { // This means that from all states in prob0E(psi) we need to include labels such that \sigma_0 // is actually included in the resulting model. This prevents us from guaranteeing the minimality of // the returned counterexample, so we warn about that. - STORM_LOG_WARN("Generating counterexample for lower-bounded property. The resulting command set need not be minimal."); + if (!options.silent) { + STORM_LOG_WARN("Generating counterexample for lower-bounded property. The resulting command set need not be minimal."); + } // Modify bound appropriately. comparisonType = storm::logic::invertPreserveStrictness(comparisonType); @@ -1864,23 +2025,29 @@ namespace storm { // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - auto commandSet = getMinimalCommandSet(env, program, model, phiStates, psiStates, threshold, strictBound, boost::container::flat_set<uint_fast64_t>(), true, storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>().isEncodeReachabilitySet()); + auto labelSet = getMinimalLabelSet(env, symbolicModel, model, phiStates, psiStates, threshold, strictBound, dontCareLabels, options); auto endTime = std::chrono::high_resolution_clock::now(); - std::cout << std::endl << "Computed minimal command set of size " << commandSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + if (!options.silent) { + std::cout << std::endl << "Computed minimal label set of size " << labelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; + } // Extend the command set properly. if (lowerBoundedFormula) { - extendCommandSetLowerBound(model, commandSet, phiStates, psiStates); + extendLabelSetLowerBound(model, labelSet, phiStates, psiStates, options.silent); } - return commandSet; + return labelSet; } - static std::shared_ptr<PrismHighLevelCounterexample> computeCounterexample(Environment const& env, storm::prism::Program program, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { + static std::shared_ptr<HighLevelCounterexample> computeCounterexample(Environment const& env, storm::storage::SymbolicModelDescription const& symbolicModel, storm::models::sparse::Model<T> const& model, std::shared_ptr<storm::logic::Formula const> const& formula) { #ifdef STORM_HAVE_Z3 - auto commandSet = computeCounterexampleCommandSet(env, program, model, formula); + auto labelSet = computeCounterexampleLabelSet(env, symbolicModel, model, formula); - return std::make_shared<PrismHighLevelCounterexample>(program.restrictCommands(commandSet)); - + if (symbolicModel.isPrismProgram()) { + return std::make_shared<HighLevelCounterexample>(symbolicModel.asPrismProgram().restrictCommands(labelSet)); + } else { + STORM_LOG_ASSERT(symbolicModel.isJaniModel(), "Unknown symbolic model description type."); + return std::make_shared<HighLevelCounterexample>(symbolicModel.asJaniModel().restrictEdges(labelSet)); + } #else throw storm::exceptions::NotImplementedException() << "This functionality is unavailable since storm has been compiled without support for Z3."; return nullptr; diff --git a/src/storm/environment/Environment.cpp b/src/storm/environment/Environment.cpp index 0836de3f7..6d5d3ca2b 100644 --- a/src/storm/environment/Environment.cpp +++ b/src/storm/environment/Environment.cpp @@ -1,6 +1,8 @@ #include "storm/environment/Environment.h" #include "storm/environment/SubEnvironment.h" #include "storm/environment/solver/SolverEnvironment.h" +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + namespace storm { @@ -12,11 +14,28 @@ namespace storm { // Intentionally left empty. } + Environment::Environment(Environment const& other) : internalEnv(other.internalEnv) { + // Intentionally left empty. + } + + Environment& Environment::operator=(Environment const& other) { + internalEnv = other.internalEnv; + return *this; + } + SolverEnvironment& Environment::solver() { - return solverEnvironment.get(); + return internalEnv.get().solverEnvironment.get(); } SolverEnvironment const& Environment::solver() const { - return solverEnvironment.get(); + return internalEnv.get().solverEnvironment.get(); + } + + ModelCheckerEnvironment& Environment::modelchecker() { + return internalEnv.get().modelcheckerEnvironment.get(); + } + + ModelCheckerEnvironment const& Environment::modelchecker() const { + return internalEnv.get().modelcheckerEnvironment.get(); } } \ No newline at end of file diff --git a/src/storm/environment/Environment.h b/src/storm/environment/Environment.h index 988ca34c6..30ac31803 100644 --- a/src/storm/environment/Environment.h +++ b/src/storm/environment/Environment.h @@ -6,19 +6,30 @@ namespace storm { // Forward declare sub-environments class SolverEnvironment; + class ModelCheckerEnvironment; + + // Avoid implementing ugly copy constructors for environment by using an internal environment. + struct InternalEnvironment { + SubEnvironment<SolverEnvironment> solverEnvironment; + SubEnvironment<ModelCheckerEnvironment> modelcheckerEnvironment; + }; class Environment { public: Environment(); virtual ~Environment(); + Environment(Environment const& other); + Environment& operator=(Environment const& other); SolverEnvironment& solver(); SolverEnvironment const& solver() const; + ModelCheckerEnvironment& modelchecker(); + ModelCheckerEnvironment const& modelchecker() const; private: - SubEnvironment<SolverEnvironment> solverEnvironment; + SubEnvironment<InternalEnvironment> internalEnv; }; } diff --git a/src/storm/environment/SubEnvironment.cpp b/src/storm/environment/SubEnvironment.cpp index 698300f03..5226fdca4 100644 --- a/src/storm/environment/SubEnvironment.cpp +++ b/src/storm/environment/SubEnvironment.cpp @@ -1,45 +1,72 @@ -#include<memory> +#include <memory> + +#include "storm/environment/Environment.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + #include "storm/environment/solver/SolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/MultiplierEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" namespace storm { template<typename EnvironmentType> - SubEnvironment<EnvironmentType>::SubEnvironment() : subEnv(std::make_unique<EnvironmentType>()) { + SubEnvironment<EnvironmentType>::SubEnvironment() : subEnv(nullptr) { // Intentionally left empty } template<typename EnvironmentType> - SubEnvironment<EnvironmentType>::SubEnvironment(SubEnvironment const& other) : subEnv(new EnvironmentType(*other.subEnv)) { + SubEnvironment<EnvironmentType>::SubEnvironment(SubEnvironment const& other) : subEnv(other.subEnv ? new EnvironmentType(*other.subEnv) : nullptr) { // Intentionally left empty } template<typename EnvironmentType> SubEnvironment<EnvironmentType>& SubEnvironment<EnvironmentType>::operator=(SubEnvironment const& other) { - subEnv = std::make_unique<EnvironmentType>(*other.subEnv); + if (other.subEnv) { + subEnv = std::make_unique<EnvironmentType>(*other.subEnv); + } else { + subEnv.reset(); + } return *this; } template<typename EnvironmentType> EnvironmentType const& SubEnvironment<EnvironmentType>::get() const { + assertInitialized(); return *subEnv; } template<typename EnvironmentType> EnvironmentType& SubEnvironment<EnvironmentType>::get() { + assertInitialized(); return *subEnv; } + template<typename EnvironmentType> + void SubEnvironment<EnvironmentType>::assertInitialized() const { + if (!subEnv) { + subEnv = std::make_unique<EnvironmentType>(); + } + } + + template class SubEnvironment<InternalEnvironment>; + + template class SubEnvironment<MultiObjectiveModelCheckerEnvironment>; + template class SubEnvironment<ModelCheckerEnvironment>; + template class SubEnvironment<SolverEnvironment>; template class SubEnvironment<EigenSolverEnvironment>; template class SubEnvironment<GmmxxSolverEnvironment>; template class SubEnvironment<NativeSolverEnvironment>; template class SubEnvironment<MinMaxSolverEnvironment>; + template class SubEnvironment<MultiplierEnvironment>; template class SubEnvironment<GameSolverEnvironment>; + template class SubEnvironment<TopologicalSolverEnvironment>; } diff --git a/src/storm/environment/SubEnvironment.h b/src/storm/environment/SubEnvironment.h index 2b6ecbf87..b1858936d 100644 --- a/src/storm/environment/SubEnvironment.h +++ b/src/storm/environment/SubEnvironment.h @@ -16,8 +16,8 @@ namespace storm { EnvironmentType& get(); private: - std::unique_ptr<EnvironmentType> subEnv; + void assertInitialized() const; + mutable std::unique_ptr<EnvironmentType> subEnv; }; } - diff --git a/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp b/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp new file mode 100644 index 000000000..f0d917a28 --- /dev/null +++ b/src/storm/environment/modelchecker/ModelCheckerEnvironment.cpp @@ -0,0 +1,31 @@ +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" + +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" + + +namespace storm { + + ModelCheckerEnvironment::ModelCheckerEnvironment() { + // Intentionally left empty + } + + ModelCheckerEnvironment::~ModelCheckerEnvironment() { + // Intentionally left empty + } + + MultiObjectiveModelCheckerEnvironment& ModelCheckerEnvironment::multi() { + return multiObjectiveModelCheckerEnvironment.get(); + } + + MultiObjectiveModelCheckerEnvironment const& ModelCheckerEnvironment::multi() const { + return multiObjectiveModelCheckerEnvironment.get(); + } +} + + diff --git a/src/storm/environment/modelchecker/ModelCheckerEnvironment.h b/src/storm/environment/modelchecker/ModelCheckerEnvironment.h new file mode 100644 index 000000000..2ec1eebd8 --- /dev/null +++ b/src/storm/environment/modelchecker/ModelCheckerEnvironment.h @@ -0,0 +1,28 @@ +#pragma once + +#include <memory> +#include <boost/optional.hpp> + +#include "storm/environment/Environment.h" +#include "storm/environment/SubEnvironment.h" + +namespace storm { + + // Forward declare subenvironments + class MultiObjectiveModelCheckerEnvironment; + + class ModelCheckerEnvironment { + public: + + ModelCheckerEnvironment(); + ~ModelCheckerEnvironment(); + + MultiObjectiveModelCheckerEnvironment& multi(); + MultiObjectiveModelCheckerEnvironment const& multi() const; + + + private: + SubEnvironment<MultiObjectiveModelCheckerEnvironment> multiObjectiveModelCheckerEnvironment; + }; +} + diff --git a/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp new file mode 100644 index 000000000..92b51fde8 --- /dev/null +++ b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.cpp @@ -0,0 +1,100 @@ +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/utility/constants.h" +#include "storm/utility/macros.h" + +namespace storm { + + MultiObjectiveModelCheckerEnvironment::MultiObjectiveModelCheckerEnvironment() { + auto const& multiobjectiveSettings = storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>(); + method = multiobjectiveSettings.getMultiObjectiveMethod(); + if (multiobjectiveSettings.isExportPlotSet()) { + plotPathUnderApprox = multiobjectiveSettings.getExportPlotDirectory() + "underapproximation.csv"; + plotPathOverApprox = multiobjectiveSettings.getExportPlotDirectory() + "overapproximation.csv"; + plotPathParetoPoints = multiobjectiveSettings.getExportPlotDirectory() + "paretopoints.csv"; + } + + precision = storm::utility::convertNumber<storm::RationalNumber>(multiobjectiveSettings.getPrecision()); + if (multiobjectiveSettings.isMaxStepsSet()) { + maxSteps = multiobjectiveSettings.getMaxSteps(); + } + } + + MultiObjectiveModelCheckerEnvironment::~MultiObjectiveModelCheckerEnvironment() { + // Intentionally left empty + } + + storm::modelchecker::multiobjective::MultiObjectiveMethod const& MultiObjectiveModelCheckerEnvironment::getMethod() const { + return this->method; + } + + void MultiObjectiveModelCheckerEnvironment::setMethod(storm::modelchecker::multiobjective::MultiObjectiveMethod value) { + this->method = value; + } + + bool MultiObjectiveModelCheckerEnvironment::isExportPlotSet() const { + return this->plotPathUnderApprox.is_initialized() || this->plotPathOverApprox.is_initialized() || this->plotPathParetoPoints.is_initialized(); + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathUnderApproximation() const { + return plotPathUnderApprox; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathUnderApproximation(std::string const& path) { + plotPathUnderApprox = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathUnderApproximation() { + plotPathUnderApprox = boost::none; + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathOverApproximation() const { + return plotPathOverApprox; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathOverApproximation(std::string const& path) { + plotPathOverApprox = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathOverApproximation() { + plotPathOverApprox = boost::none; + } + + boost::optional<std::string> MultiObjectiveModelCheckerEnvironment::getPlotPathParetoPoints() const { + return plotPathParetoPoints; + } + + void MultiObjectiveModelCheckerEnvironment::setPlotPathParetoPoints(std::string const& path) { + plotPathParetoPoints = path; + } + + void MultiObjectiveModelCheckerEnvironment::unsetPlotPathParetoPoints() { + plotPathParetoPoints = boost::none; + } + + storm::RationalNumber const& MultiObjectiveModelCheckerEnvironment::getPrecision() const { + return precision; + } + + void MultiObjectiveModelCheckerEnvironment::setPrecision(storm::RationalNumber const& value) { + precision = value; + } + + bool MultiObjectiveModelCheckerEnvironment::isMaxStepsSet() const { + return maxSteps.is_initialized(); + } + + uint64_t const& MultiObjectiveModelCheckerEnvironment::getMaxSteps() const { + return maxSteps.get(); + } + + void MultiObjectiveModelCheckerEnvironment::setMaxSteps(uint64_t const& value) { + maxSteps = value; + } + + void MultiObjectiveModelCheckerEnvironment::unsetMaxSteps() { + maxSteps = boost::none; + } +} \ No newline at end of file diff --git a/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h new file mode 100644 index 000000000..f1d4f0203 --- /dev/null +++ b/src/storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h @@ -0,0 +1,48 @@ +#pragma once + +#include <string> + +#include "storm/environment/modelchecker/ModelCheckerEnvironment.h" +#include "storm/modelchecker/multiobjective/MultiObjectiveModelCheckingMethod.h" +#include "storm/adapters/RationalNumberAdapter.h" + +namespace storm { + + class MultiObjectiveModelCheckerEnvironment { + public: + + MultiObjectiveModelCheckerEnvironment(); + ~MultiObjectiveModelCheckerEnvironment(); + + storm::modelchecker::multiobjective::MultiObjectiveMethod const& getMethod() const; + void setMethod(storm::modelchecker::multiobjective::MultiObjectiveMethod value); + + bool isExportPlotSet() const; + boost::optional<std::string> getPlotPathUnderApproximation() const; + void setPlotPathUnderApproximation(std::string const& path); + void unsetPlotPathUnderApproximation(); + boost::optional<std::string> getPlotPathOverApproximation() const; + void setPlotPathOverApproximation(std::string const& path); + void unsetPlotPathOverApproximation(); + boost::optional<std::string> getPlotPathParetoPoints() const; + void setPlotPathParetoPoints(std::string const& path); + void unsetPlotPathParetoPoints(); + + storm::RationalNumber const& getPrecision() const; + void setPrecision(storm::RationalNumber const& value); + + uint64_t const& getMaxSteps() const; + bool isMaxStepsSet() const; + void setMaxSteps(uint64_t const& value); + void unsetMaxSteps(); + + + private: + storm::modelchecker::multiobjective::MultiObjectiveMethod method; + boost::optional<std::string> plotPathUnderApprox, plotPathOverApprox, plotPathParetoPoints; + storm::RationalNumber precision; + boost::optional<uint64_t> maxSteps; + + }; +} + diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp index ed4b6145b..536bf5913 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.cpp +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.cpp @@ -17,12 +17,12 @@ namespace storm { considerRelativeTerminationCriterion = minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Relative; STORM_LOG_ASSERT(considerRelativeTerminationCriterion || minMaxSettings.getConvergenceCriterion() == storm::settings::modules::MinMaxEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); multiplicationStyle = minMaxSettings.getValueIterationMultiplicationStyle(); + symmetricUpdates = minMaxSettings.isForceIntervalIterationSymmetricUpdatesSet(); } MinMaxSolverEnvironment::~MinMaxSolverEnvironment() { // Intentionally left empty } - storm::solver::MinMaxMethod const& MinMaxSolverEnvironment::getMethod() const { return minMaxMethod; @@ -32,8 +32,8 @@ namespace storm { return methodSetFromDefault; } - void MinMaxSolverEnvironment::setMethod(storm::solver::MinMaxMethod value) { - methodSetFromDefault = false; + void MinMaxSolverEnvironment::setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault) { + methodSetFromDefault = isSetFromDefault; minMaxMethod = value; } @@ -69,6 +69,12 @@ namespace storm { multiplicationStyle = value; } - - + bool MinMaxSolverEnvironment::isSymmetricUpdatesSet() const { + return symmetricUpdates; + } + + void MinMaxSolverEnvironment::setSymmetricUpdates(bool value) { + symmetricUpdates = value; + } + } diff --git a/src/storm/environment/solver/MinMaxSolverEnvironment.h b/src/storm/environment/solver/MinMaxSolverEnvironment.h index 6cca14221..3f54f0fa9 100644 --- a/src/storm/environment/solver/MinMaxSolverEnvironment.h +++ b/src/storm/environment/solver/MinMaxSolverEnvironment.h @@ -16,7 +16,7 @@ namespace storm { storm::solver::MinMaxMethod const& getMethod() const; bool const& isMethodSetFromDefault() const; - void setMethod(storm::solver::MinMaxMethod value); + void setMethod(storm::solver::MinMaxMethod value, bool isSetFromDefault = false); uint64_t const& getMaximalNumberOfIterations() const; void setMaximalNumberOfIterations(uint64_t value); storm::RationalNumber const& getPrecision() const; @@ -25,6 +25,10 @@ namespace storm { void setRelativeTerminationCriterion(bool value); storm::solver::MultiplicationStyle const& getMultiplicationStyle() const; void setMultiplicationStyle(storm::solver::MultiplicationStyle value); + bool isForceBoundsSet() const; + void setForceBounds(bool value); + bool isSymmetricUpdatesSet() const; + void setSymmetricUpdates(bool value); private: storm::solver::MinMaxMethod minMaxMethod; @@ -33,7 +37,8 @@ namespace storm { storm::RationalNumber precision; bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle multiplicationStyle; - + bool forceBounds; + bool symmetricUpdates; }; } diff --git a/src/storm/environment/solver/MultiplierEnvironment.cpp b/src/storm/environment/solver/MultiplierEnvironment.cpp new file mode 100644 index 000000000..85e3bac77 --- /dev/null +++ b/src/storm/environment/solver/MultiplierEnvironment.cpp @@ -0,0 +1,33 @@ +#include "storm/environment/solver/MultiplierEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/MultiplierSettings.h" +#include "storm/utility/constants.h" +#include "storm/utility/macros.h" + +namespace storm { + + MultiplierEnvironment::MultiplierEnvironment() { + auto const& multiplierSettings = storm::settings::getModule<storm::settings::modules::MultiplierSettings>(); + type = multiplierSettings.getMultiplierType(); + typeSetFromDefault = multiplierSettings.isMultiplierTypeSetFromDefaultValue(); + } + + MultiplierEnvironment::~MultiplierEnvironment() { + // Intentionally left empty + } + + storm::solver::MultiplierType const& MultiplierEnvironment::getType() const { + return type; + } + + bool const& MultiplierEnvironment::isTypeSetFromDefault() const { + return typeSetFromDefault; + } + + void MultiplierEnvironment::setType(storm::solver::MultiplierType value, bool isSetFromDefault) { + type = value; + typeSetFromDefault = isSetFromDefault; + } + +} diff --git a/src/storm/environment/solver/MultiplierEnvironment.h b/src/storm/environment/solver/MultiplierEnvironment.h new file mode 100644 index 000000000..d9e35f5fb --- /dev/null +++ b/src/storm/environment/solver/MultiplierEnvironment.h @@ -0,0 +1,23 @@ +#pragma once + +#include "storm/environment/solver/SolverEnvironment.h" +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + + class MultiplierEnvironment { + public: + + MultiplierEnvironment(); + ~MultiplierEnvironment(); + + storm::solver::MultiplierType const& getType() const; + bool const& isTypeSetFromDefault() const; + void setType(storm::solver::MultiplierType value, bool isSetFromDefault = false); + + private: + storm::solver::MultiplierType type; + bool typeSetFromDefault; + }; +} + diff --git a/src/storm/environment/solver/NativeSolverEnvironment.cpp b/src/storm/environment/solver/NativeSolverEnvironment.cpp index 3a3d0cb08..149a2feb6 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.cpp +++ b/src/storm/environment/solver/NativeSolverEnvironment.cpp @@ -18,6 +18,8 @@ namespace storm { STORM_LOG_ASSERT(considerRelativeTerminationCriterion || nativeSettings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Absolute, "Unknown convergence criterion"); powerMethodMultiplicationStyle = nativeSettings.getPowerMethodMultiplicationStyle(); sorOmega = storm::utility::convertNumber<storm::RationalNumber>(nativeSettings.getOmega()); + symmetricUpdates = nativeSettings.isForceIntervalIterationSymmetricUpdatesSet(); + } NativeSolverEnvironment::~NativeSolverEnvironment() { @@ -77,4 +79,12 @@ namespace storm { sorOmega = value; } + bool NativeSolverEnvironment::isSymmetricUpdatesSet() const { + return symmetricUpdates; + } + + void NativeSolverEnvironment::setSymmetricUpdates(bool value) { + symmetricUpdates = value; + } + } diff --git a/src/storm/environment/solver/NativeSolverEnvironment.h b/src/storm/environment/solver/NativeSolverEnvironment.h index 51b96f613..d0b0e8b9b 100644 --- a/src/storm/environment/solver/NativeSolverEnvironment.h +++ b/src/storm/environment/solver/NativeSolverEnvironment.h @@ -27,6 +27,8 @@ namespace storm { void setPowerMethodMultiplicationStyle(storm::solver::MultiplicationStyle value); storm::RationalNumber const& getSorOmega() const; void setSorOmega(storm::RationalNumber const& value); + bool isSymmetricUpdatesSet() const; + void setSymmetricUpdates(bool value); private: storm::solver::NativeLinearEquationSolverMethod method; @@ -36,6 +38,7 @@ namespace storm { bool considerRelativeTerminationCriterion; storm::solver::MultiplicationStyle powerMethodMultiplicationStyle; storm::RationalNumber sorOmega; + bool symmetricUpdates; }; } diff --git a/src/storm/environment/solver/SolverEnvironment.cpp b/src/storm/environment/solver/SolverEnvironment.cpp index 8371b8158..42600adbb 100644 --- a/src/storm/environment/solver/SolverEnvironment.cpp +++ b/src/storm/environment/solver/SolverEnvironment.cpp @@ -1,10 +1,12 @@ #include "storm/environment/solver/SolverEnvironment.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/MultiplierEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GameSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -12,6 +14,7 @@ #include "storm/utility/macros.h" #include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" namespace storm { @@ -34,6 +37,14 @@ namespace storm { return minMaxSolverEnvironment.get(); } + MultiplierEnvironment& SolverEnvironment::multiplier() { + return multiplierEnvironment.get(); + } + + MultiplierEnvironment const& SolverEnvironment::multiplier() const { + return multiplierEnvironment.get(); + } + EigenSolverEnvironment& SolverEnvironment::eigen() { return eigenSolverEnvironment.get(); } @@ -66,6 +77,14 @@ namespace storm { return gameSolverEnvironment.get(); } + TopologicalSolverEnvironment& SolverEnvironment::topological() { + return topologicalSolverEnvironment.get(); + } + + TopologicalSolverEnvironment const& SolverEnvironment::topological() const { + return topologicalSolverEnvironment.get(); + } + bool SolverEnvironment::isForceSoundness() const { return forceSoundness; } @@ -78,8 +97,8 @@ namespace storm { return linearEquationSolverType; } - void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value) { - linearEquationSolverTypeSetFromDefault = false; + void SolverEnvironment::setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool isSetFromDefault) { + linearEquationSolverTypeSetFromDefault = isSetFromDefault; linearEquationSolverType = value; } @@ -87,44 +106,49 @@ namespace storm { return linearEquationSolverTypeSetFromDefault; } - boost::optional<storm::RationalNumber> SolverEnvironment::getPrecisionOfCurrentLinearEquationSolver() const { - switch (getLinearEquationSolverType()) { + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> SolverEnvironment::getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const& solverType) const { + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> result; + switch (solverType) { case storm::solver::EquationSolverType::Gmmxx: - return gmmxx().getPrecision(); + result.first = gmmxx().getPrecision(); + break; case storm::solver::EquationSolverType::Eigen: - return eigen().getPrecision(); + result.first = eigen().getPrecision(); + break; case storm::solver::EquationSolverType::Native: - return native().getPrecision(); + result.first = native().getPrecision(); + result.second = native().getRelativeTerminationCriterion(); + break; case storm::solver::EquationSolverType::Elimination: - return boost::none; + break; + case storm::solver::EquationSolverType::Topological: + result = getPrecisionOfLinearEquationSolver(topological().getUnderlyingEquationSolverType()); + break; default: - STORM_LOG_ASSERT(false, "The selected solver type is unknown."); + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "The selected solver type is unknown."); } + return result; } - void SolverEnvironment::setLinearEquationSolverPrecision(storm::RationalNumber const& value) { - STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination, - "The current solver type is not respected in this method."); - native().setPrecision(value); - gmmxx().setPrecision(value); - eigen().setPrecision(value); - // Elimination solver does not have a precision - } - - void SolverEnvironment::setLinearEquationSolverRelativeTerminationCriterion(bool value) { + void SolverEnvironment::setLinearEquationSolverPrecision(boost::optional<storm::RationalNumber> const& newPrecision, boost::optional<bool> const& relativePrecision) { + // Assert that each solver type is handled in this method. STORM_LOG_ASSERT(getLinearEquationSolverType() == storm::solver::EquationSolverType::Native || getLinearEquationSolverType() == storm::solver::EquationSolverType::Gmmxx || getLinearEquationSolverType() == storm::solver::EquationSolverType::Eigen || - getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination, + getLinearEquationSolverType() == storm::solver::EquationSolverType::Elimination || + getLinearEquationSolverType() == storm::solver::EquationSolverType::Topological, "The current solver type is not respected in this method."); - native().setRelativeTerminationCriterion(value); - // Elimination, gmm and eigen solver do not have an option for relative termination criterion + if (newPrecision) { + native().setPrecision(newPrecision.get()); + gmmxx().setPrecision(newPrecision.get()); + eigen().setPrecision(newPrecision.get()); + // Elimination and Topological solver do not have a precision + } + if (relativePrecision) { + native().setRelativeTerminationCriterion(relativePrecision.get()); + // gmm, eigen, elimination, and topological solvers do not have a precision + } } - - } diff --git a/src/storm/environment/solver/SolverEnvironment.h b/src/storm/environment/solver/SolverEnvironment.h index ec591beb2..5e24652e1 100644 --- a/src/storm/environment/solver/SolverEnvironment.h +++ b/src/storm/environment/solver/SolverEnvironment.h @@ -15,7 +15,9 @@ namespace storm { class GmmxxSolverEnvironment; class NativeSolverEnvironment; class MinMaxSolverEnvironment; + class MultiplierEnvironment; class GameSolverEnvironment; + class TopologicalSolverEnvironment; class SolverEnvironment { public: @@ -31,26 +33,31 @@ namespace storm { NativeSolverEnvironment const& native() const; MinMaxSolverEnvironment& minMax(); MinMaxSolverEnvironment const& minMax() const; + MultiplierEnvironment& multiplier(); + MultiplierEnvironment const& multiplier() const; GameSolverEnvironment& game(); GameSolverEnvironment const& game() const; + TopologicalSolverEnvironment& topological(); + TopologicalSolverEnvironment const& topological() const; bool isForceSoundness() const; void setForceSoundness(bool value); storm::solver::EquationSolverType const& getLinearEquationSolverType() const; - void setLinearEquationSolverType(storm::solver::EquationSolverType const& value); + void setLinearEquationSolverType(storm::solver::EquationSolverType const& value, bool isSetFromDefault = false); bool isLinearEquationSolverTypeSetFromDefaultValue() const; - - boost::optional<storm::RationalNumber> getPrecisionOfCurrentLinearEquationSolver() const; - void setLinearEquationSolverPrecision(storm::RationalNumber const& value); - void setLinearEquationSolverRelativeTerminationCriterion(bool value); + + std::pair<boost::optional<storm::RationalNumber>, boost::optional<bool>> getPrecisionOfLinearEquationSolver(storm::solver::EquationSolverType const& solverType) const; + void setLinearEquationSolverPrecision(boost::optional<storm::RationalNumber> const& newPrecision, boost::optional<bool> const& relativePrecision = boost::none); private: SubEnvironment<EigenSolverEnvironment> eigenSolverEnvironment; SubEnvironment<GmmxxSolverEnvironment> gmmxxSolverEnvironment; SubEnvironment<NativeSolverEnvironment> nativeSolverEnvironment; SubEnvironment<GameSolverEnvironment> gameSolverEnvironment; + SubEnvironment<TopologicalSolverEnvironment> topologicalSolverEnvironment; SubEnvironment<MinMaxSolverEnvironment> minMaxSolverEnvironment; + SubEnvironment<MultiplierEnvironment> multiplierEnvironment; storm::solver::EquationSolverType linearEquationSolverType; bool linearEquationSolverTypeSetFromDefault; diff --git a/src/storm/environment/solver/TopologicalSolverEnvironment.cpp b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp new file mode 100644 index 000000000..678c6cb6c --- /dev/null +++ b/src/storm/environment/solver/TopologicalSolverEnvironment.cpp @@ -0,0 +1,54 @@ +#include "storm/environment/solver/TopologicalSolverEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/InvalidArgumentException.h" + +namespace storm { + + TopologicalSolverEnvironment::TopologicalSolverEnvironment() { + auto const& topologicalSettings = storm::settings::getModule<storm::settings::modules::TopologicalEquationSolverSettings>(); + underlyingEquationSolverType = topologicalSettings.getUnderlyingEquationSolverType(); + underlyingEquationSolverTypeSetFromDefault = topologicalSettings.isUnderlyingEquationSolverTypeSetFromDefaultValue(); + + underlyingMinMaxMethod = topologicalSettings.getUnderlyingMinMaxMethod(); + underlyingEquationSolverTypeSetFromDefault = topologicalSettings.isUnderlyingMinMaxMethodSetFromDefaultValue(); + } + + TopologicalSolverEnvironment::~TopologicalSolverEnvironment() { + // Intentionally left empty + } + + storm::solver::EquationSolverType const& TopologicalSolverEnvironment::getUnderlyingEquationSolverType() const { + return underlyingEquationSolverType; + } + + bool const& TopologicalSolverEnvironment::isUnderlyingEquationSolverTypeSetFromDefault() const { + return underlyingEquationSolverTypeSetFromDefault; + } + + void TopologicalSolverEnvironment::setUnderlyingEquationSolverType(storm::solver::EquationSolverType value) { + STORM_LOG_THROW(value != storm::solver::EquationSolverType::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); + underlyingEquationSolverTypeSetFromDefault = false; + underlyingEquationSolverType = value; + } + + storm::solver::MinMaxMethod const& TopologicalSolverEnvironment::getUnderlyingMinMaxMethod() const { + return underlyingMinMaxMethod; + } + + bool const& TopologicalSolverEnvironment::isUnderlyingMinMaxMethodSetFromDefault() const { + return underlyingMinMaxMethodSetFromDefault; + } + + void TopologicalSolverEnvironment::setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod value) { + STORM_LOG_THROW(value != storm::solver::MinMaxMethod::Topological, storm::exceptions::InvalidArgumentException, "Can not use the topological solver as underlying solver of the topological solver."); + underlyingMinMaxMethodSetFromDefault = false; + underlyingMinMaxMethod = value; + } + + + +} diff --git a/src/storm/environment/solver/TopologicalSolverEnvironment.h b/src/storm/environment/solver/TopologicalSolverEnvironment.h new file mode 100644 index 000000000..594dd3d86 --- /dev/null +++ b/src/storm/environment/solver/TopologicalSolverEnvironment.h @@ -0,0 +1,31 @@ +#pragma once + +#include "storm/environment/solver/SolverEnvironment.h" + +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + + class TopologicalSolverEnvironment { + public: + + TopologicalSolverEnvironment(); + ~TopologicalSolverEnvironment(); + + storm::solver::EquationSolverType const& getUnderlyingEquationSolverType() const; + bool const& isUnderlyingEquationSolverTypeSetFromDefault() const; + void setUnderlyingEquationSolverType(storm::solver::EquationSolverType value); + + storm::solver::MinMaxMethod const& getUnderlyingMinMaxMethod() const; + bool const& isUnderlyingMinMaxMethodSetFromDefault() const; + void setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod value); + + private: + storm::solver::EquationSolverType underlyingEquationSolverType; + bool underlyingEquationSolverTypeSetFromDefault; + + storm::solver::MinMaxMethod underlyingMinMaxMethod; + bool underlyingMinMaxMethodSetFromDefault; + }; +} + diff --git a/src/storm/generator/CompressedState.cpp b/src/storm/generator/CompressedState.cpp index a785f1c79..175a753fa 100644 --- a/src/storm/generator/CompressedState.cpp +++ b/src/storm/generator/CompressedState.cpp @@ -46,6 +46,13 @@ namespace storm { template void unpackStateIntoEvaluator<double>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<double>& evaluator); storm::expressions::SimpleValuation unpackStateIntoValuation(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionManager const& manager); + CompressedState createOutOfBoundsState(VariableInformation const& varInfo, bool roundTo64Bit) { + CompressedState result(varInfo.getTotalBitOffset(roundTo64Bit)); + assert(varInfo.hasOutOfBoundsBit()); + result.set(varInfo.getOutOfBoundsBit()); + return result; + } + #ifdef STORM_HAVE_CARL template void unpackStateIntoEvaluator<storm::RationalNumber>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalNumber>& evaluator); template void unpackStateIntoEvaluator<storm::RationalFunction>(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionEvaluator<storm::RationalFunction>& evaluator); diff --git a/src/storm/generator/CompressedState.h b/src/storm/generator/CompressedState.h index 1a785dbaa..6965022f2 100644 --- a/src/storm/generator/CompressedState.h +++ b/src/storm/generator/CompressedState.h @@ -36,6 +36,8 @@ namespace storm { * @return A valuation that corresponds to the compressed state. */ storm::expressions::SimpleValuation unpackStateIntoValuation(CompressedState const& state, VariableInformation const& variableInformation, storm::expressions::ExpressionManager const& manager); + + CompressedState createOutOfBoundsState(VariableInformation const& varInfo, bool roundTo64Bit = true); } } diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index 7e49b0771..2df1784a1 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -15,6 +15,8 @@ #include "storm/storage/jani/ParallelComposition.h" #include "storm/storage/jani/CompositionInformationVisitor.h" +#include "storm/storage/sparse/JaniChoiceOrigins.h" + #include "storm/builder/jit/Distribution.h" #include "storm/utility/constants.h" @@ -50,7 +52,7 @@ namespace storm { // Now we are ready to initialize the variable information. this->checkValid(); - this->variableInformation = VariableInformation(model, this->parallelAutomata); + this->variableInformation = VariableInformation(model, this->parallelAutomata, options.isAddOutOfBoundsStateSet()); // Create a proper evalator. this->evaluator = std::make_unique<storm::expressions::ExpressionEvaluator<ValueType>>(model.getManager()); @@ -254,10 +256,15 @@ namespace storm { ++integerIt; } int_fast64_t assignedValue = this->evaluator->asInt(assignmentIt->getAssignedExpression()); - if (this->options.isExplorationChecksSet()) { + if (this->options.isAddOutOfBoundsStateSet()) { + if (assignedValue < integerIt->lowerBound || assignedValue > integerIt->upperBound) { + return this->outOfBoundsState; + } + } else if (this->options.isExplorationChecksSet()) { STORM_LOG_THROW(assignedValue >= integerIt->lowerBound, storm::exceptions::WrongFormatException, "The update " << assignmentIt->getExpressionVariable().getName() << " := " << assignmentIt->getAssignedExpression() << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getExpressionVariable().getName() << "'."); STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException, "The update " << assignmentIt->getExpressionVariable().getName() << " := " << assignmentIt->getAssignedExpression() << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getExpressionVariable().getName() << "'."); } + newState.setFromInt(integerIt->bitOffset, integerIt->bitWidth, assignedValue - integerIt->lowerBound); STORM_LOG_ASSERT(static_cast<int_fast64_t>(newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth)) + integerIt->lowerBound == assignedValue, "Writing to the bit vector bucket failed (read " << newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth) << " but wrote " << assignedValue << ")."); } @@ -313,6 +320,10 @@ namespace storm { // If the model is a deterministic model, we need to fuse the choices into one. if (this->isDeterministicModel() && totalNumberOfChoices > 1) { Choice<ValueType> globalChoice; + + if (this->options.isAddOverlappingGuardLabelSet()) { + this->overlappingGuardStates->push_back(stateToIdCallback(*this->state)); + } // For CTMCs, we need to keep track of the total exit rate to scale the action rewards later. For DTMCs // this is equal to the number of choices, which is why we initialize it like this here. @@ -338,6 +349,10 @@ namespace storm { for (uint_fast64_t rewardVariableIndex = 0; rewardVariableIndex < rewardVariables.size(); ++rewardVariableIndex) { stateActionRewards[rewardVariableIndex] += choice.getRewards()[rewardVariableIndex] * choice.getTotalMass() / totalExitRate; } + + if (this->options.isBuildChoiceOriginsSet() && choice.hasOriginData()) { + globalChoice.addOriginData(choice.getOriginData()); + } } globalChoice.addRewards(std::move(stateActionRewards)); @@ -408,7 +423,7 @@ namespace storm { checkGlobalVariableWritesValid(edgeCombination); } - std::vector<EdgeSet::const_iterator> iteratorList(edgeCombination.size()); + std::vector<EdgeSetWithIndices::const_iterator> iteratorList(edgeCombination.size()); // Initialize the list of iterators. for (size_t i = 0; i < edgeCombination.size(); ++i) { @@ -425,8 +440,15 @@ namespace storm { currentDistribution.add(state, storm::utility::one<ValueType>()); + EdgeIndexSet edgeIndices; for (uint_fast64_t i = 0; i < iteratorList.size(); ++i) { - storm::jani::Edge const& edge = **iteratorList[i]; + auto const& indexAndEdge = *iteratorList[i]; + + if (this->getOptions().isBuildChoiceOriginsSet()) { + edgeIndices.insert(model.encodeAutomatonAndEdgeIndices(edgeCombination[i].first, indexAndEdge.first)); + } + + storm::jani::Edge const& edge = *indexAndEdge.second; for (auto const& destination : edge.getDestinations()) { for (auto const& stateProbability : currentDistribution) { @@ -465,6 +487,11 @@ namespace storm { // Now create the actual distribution. Choice<ValueType>& choice = result.back(); + // Add the edge indices if requested. + if (this->getOptions().isBuildChoiceOriginsSet()) { + choice.addOriginData(boost::any(std::move(edgeIndices))); + } + // Add the rewards to the choice. choice.addRewards(std::move(stateActionRewards)); @@ -515,12 +542,17 @@ namespace storm { auto edgesIt = nonsychingEdges.second.find(locations[automatonIndex]); if (edgesIt != nonsychingEdges.second.end()) { - for (auto const& edge : edgesIt->second) { - if (!this->evaluator->asBool(edge->getGuard())) { + for (auto const& indexAndEdge : edgesIt->second) { + if (!this->evaluator->asBool(indexAndEdge.second->getGuard())) { continue; } - Choice<ValueType> choice = expandNonSynchronizingEdge(*edge, outputAndEdges.first ? outputAndEdges.first.get() : edge->getActionIndex(), automatonIndex, state, stateToIdCallback); + Choice<ValueType> choice = expandNonSynchronizingEdge(*indexAndEdge.second, outputAndEdges.first ? outputAndEdges.first.get() : indexAndEdge.second->getActionIndex(), automatonIndex, state, stateToIdCallback); + + if (this->getOptions().isBuildChoiceOriginsSet()) { + EdgeIndexSet edgeIndex { model.encodeAutomatonAndEdgeIndices(automatonIndex, indexAndEdge.first) }; + choice.addOriginData(boost::any(std::move(edgeIndex))); + } result.emplace_back(std::move(choice)); } } @@ -534,18 +566,18 @@ namespace storm { bool productiveCombination = true; for (auto const& automatonAndEdges : outputAndEdges.second) { uint64_t automatonIndex = automatonAndEdges.first; - EdgeSet enabledEdgesOfAutomaton; + EdgeSetWithIndices enabledEdgesOfAutomaton; bool atLeastOneEdge = false; auto edgesIt = automatonAndEdges.second.find(locations[automatonIndex]); if (edgesIt != automatonAndEdges.second.end()) { - for (auto const& edge : edgesIt->second) { - if (!this->evaluator->asBool(edge->getGuard())) { + for (auto const& indexAndEdge : edgesIt->second) { + if (!this->evaluator->asBool(indexAndEdge.second->getGuard())) { continue; } atLeastOneEdge = true; - enabledEdgesOfAutomaton.emplace_back(edge); + enabledEdgesOfAutomaton.emplace_back(indexAndEdge); } } @@ -560,7 +592,7 @@ namespace storm { if (productiveCombination) { std::vector<Choice<ValueType>> choices = expandSynchronizingEdgeCombination(automataEdgeSets, outputActionIndex, state, stateToIdCallback); - + for (auto const& choice : choices) { result.emplace_back(std::move(choice)); } @@ -575,8 +607,8 @@ namespace storm { void JaniNextStateGenerator<ValueType, StateType>::checkGlobalVariableWritesValid(AutomataEdgeSets const& enabledEdges) const { std::map<storm::expressions::Variable, uint64_t> writtenGlobalVariables; for (auto edgeSetIt = enabledEdges.begin(), edgeSetIte = enabledEdges.end(); edgeSetIt != edgeSetIte; ++edgeSetIt) { - for (auto const& edge : edgeSetIt->second) { - for (auto const& globalVariable : edge->getWrittenGlobalVariables()) { + for (auto const& indexAndEdge : edgeSetIt->second) { + for (auto const& globalVariable : indexAndEdge.second->getWrittenGlobalVariables()) { auto it = writtenGlobalVariables.find(globalVariable); auto index = std::distance(enabledEdges.begin(), edgeSetIt); @@ -707,8 +739,10 @@ namespace storm { this->parallelAutomata.push_back(automaton); LocationsAndEdges locationsAndEdges; + uint64_t edgeIndex = 0; for (auto const& edge : automaton.getEdges()) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); + ++edgeIndex; } AutomataAndEdges automataAndEdges; @@ -726,10 +760,12 @@ namespace storm { // Add edges with silent action. LocationsAndEdges locationsAndEdges; + uint64_t edgeIndex = 0; for (auto const& edge : parallelAutomata.back().get().getEdges()) { if (edge.getActionIndex() == storm::jani::Model::SILENT_ACTION_INDEX) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); } + ++edgeIndex; } if (!locationsAndEdges.empty()) { @@ -750,10 +786,12 @@ namespace storm { if (!storm::jani::SynchronizationVector::isNoActionInput(element)) { LocationsAndEdges locationsAndEdges; uint64_t actionIndex = this->model.getActionIndex(element); + uint64_t edgeIndex = 0; for (auto const& edge : parallelAutomata[automatonIndex].get().getEdges()) { if (edge.getActionIndex() == actionIndex) { - locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(&edge); + locationsAndEdges[edge.getSourceLocationIndex()].emplace_back(std::make_pair(edgeIndex, &edge)); } + ++edgeIndex; } if (locationsAndEdges.empty()) { atLeastOneEdge = false; @@ -773,6 +811,39 @@ namespace storm { STORM_LOG_TRACE("Number of synchronizations: " << this->edges.size() << "."); } + template<typename ValueType, typename StateType> + std::shared_ptr<storm::storage::sparse::ChoiceOrigins> JaniNextStateGenerator<ValueType, StateType>::generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const { + if (!this->getOptions().isBuildChoiceOriginsSet()) { + return nullptr; + } + + std::vector<uint_fast64_t> identifiers; + identifiers.reserve(dataForChoiceOrigins.size()); + + std::map<EdgeIndexSet, uint_fast64_t> edgeIndexSetToIdentifierMap; + // The empty edge set (i.e., the choices without origin) always has to get identifier getIdentifierForChoicesWithNoOrigin() -- which is assumed to be 0 + STORM_LOG_ASSERT(storm::storage::sparse::ChoiceOrigins::getIdentifierForChoicesWithNoOrigin() == 0, "The no origin identifier is assumed to be zero"); + edgeIndexSetToIdentifierMap.insert(std::make_pair(EdgeIndexSet(), 0)); + uint_fast64_t currentIdentifier = 1; + for (boost::any& originData : dataForChoiceOrigins) { + STORM_LOG_ASSERT(originData.empty() || boost::any_cast<EdgeIndexSet>(&originData) != nullptr, "Origin data has unexpected type: " << originData.type().name() << "."); + + EdgeIndexSet currentEdgeIndexSet = originData.empty() ? EdgeIndexSet() : boost::any_cast<EdgeIndexSet>(std::move(originData)); + auto insertionRes = edgeIndexSetToIdentifierMap.emplace(std::move(currentEdgeIndexSet), currentIdentifier); + identifiers.push_back(insertionRes.first->second); + if (insertionRes.second) { + ++currentIdentifier; + } + } + + std::vector<EdgeIndexSet> identifierToEdgeIndexSetMapping(currentIdentifier); + for (auto const& setIdPair : edgeIndexSetToIdentifierMap) { + identifierToEdgeIndexSetMapping[setIdPair.second] = setIdPair.first; + } + + return std::make_shared<storm::storage::sparse::JaniChoiceOrigins>(std::make_shared<storm::jani::Model>(model), std::move(identifiers), std::move(identifierToEdgeIndexSetMapping)); + } + template<typename ValueType, typename StateType> void JaniNextStateGenerator<ValueType, StateType>::checkValid() const { // If the program still contains undefined constants and we are not in a parametric setting, assemble an appropriate error message. diff --git a/src/storm/generator/JaniNextStateGenerator.h b/src/storm/generator/JaniNextStateGenerator.h index 594efc91c..bd6b0c922 100644 --- a/src/storm/generator/JaniNextStateGenerator.h +++ b/src/storm/generator/JaniNextStateGenerator.h @@ -1,5 +1,7 @@ #pragma once +#include <boost/container/flat_set.hpp> + #include "storm/generator/NextStateGenerator.h" #include "storm/storage/jani/Model.h" @@ -17,6 +19,7 @@ namespace storm { class JaniNextStateGenerator : public NextStateGenerator<ValueType, StateType> { public: typedef typename NextStateGenerator<ValueType, StateType>::StateToIdCallback StateToIdCallback; + typedef boost::container::flat_set<uint_fast64_t> EdgeIndexSet; JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options = NextStateGeneratorOptions()); @@ -32,6 +35,8 @@ namespace storm { virtual storm::models::sparse::StateLabeling label(storm::storage::sparse::StateStorage<StateType> const& stateStorage, std::vector<StateType> const& initialStateIndices = {}, std::vector<StateType> const& deadlockStateIndices = {}) override; + virtual std::shared_ptr<storm::storage::sparse::ChoiceOrigins> generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const override; + private: /*! * Retrieves the location index from the given state. @@ -79,12 +84,12 @@ namespace storm { */ Choice<ValueType> expandNonSynchronizingEdge(storm::jani::Edge const& edge, uint64_t outputActionIndex, uint64_t automatonIndex, CompressedState const& state, StateToIdCallback stateToIdCallback); - typedef std::vector<storm::jani::Edge const*> EdgeSet; - typedef std::unordered_map<uint64_t, EdgeSet> LocationsAndEdges; + typedef std::vector<std::pair<uint64_t, storm::jani::Edge const*>> EdgeSetWithIndices; + typedef std::unordered_map<uint64_t, EdgeSetWithIndices> LocationsAndEdges; typedef std::vector<std::pair<uint64_t, LocationsAndEdges>> AutomataAndEdges; typedef std::pair<boost::optional<uint64_t>, AutomataAndEdges> OutputAndEdges; - typedef std::pair<uint64_t, EdgeSet> AutomatonAndEdgeSet; + typedef std::pair<uint64_t, EdgeSetWithIndices> AutomatonAndEdgeSet; typedef std::vector<AutomatonAndEdgeSet> AutomataEdgeSets; std::vector<Choice<ValueType>> expandSynchronizingEdgeCombination(AutomataEdgeSets const& edgeCombination, uint64_t outputActionIndex, CompressedState const& state, StateToIdCallback stateToIdCallback); diff --git a/src/storm/generator/NextStateGenerator.cpp b/src/storm/generator/NextStateGenerator.cpp index 2be706715..3b3186b68 100644 --- a/src/storm/generator/NextStateGenerator.cpp +++ b/src/storm/generator/NextStateGenerator.cpp @@ -1,3 +1,5 @@ +#include <storm/exceptions/WrongFormatException.h> +#include <storm/exceptions/NotImplementedException.h> #include "storm/generator/NextStateGenerator.h" #include "storm/adapters/RationalFunctionAdapter.h" @@ -17,12 +19,22 @@ namespace storm { template<typename ValueType, typename StateType> NextStateGenerator<ValueType, StateType>::NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, VariableInformation const& variableInformation, NextStateGeneratorOptions const& options) : options(options), expressionManager(expressionManager.getSharedPointer()), variableInformation(variableInformation), evaluator(nullptr), state(nullptr) { - // Intentionally left empty. + if(variableInformation.hasOutOfBoundsBit()) { + outOfBoundsState = createOutOfBoundsState(variableInformation); + } + if (options.isAddOverlappingGuardLabelSet()) { + overlappingGuardStates = std::vector<uint64_t>(); + } } template<typename ValueType, typename StateType> NextStateGenerator<ValueType, StateType>::NextStateGenerator(storm::expressions::ExpressionManager const& expressionManager, NextStateGeneratorOptions const& options) : options(options), expressionManager(expressionManager.getSharedPointer()), variableInformation(), evaluator(nullptr), state(nullptr) { - // Intentionally left empty. + if(variableInformation.hasOutOfBoundsBit()) { + outOfBoundsState = createOutOfBoundsState(variableInformation); + } + if (options.isAddOverlappingGuardLabelSet()) { + overlappingGuardStates = std::vector<uint64_t>(); + } } template<typename ValueType, typename StateType> @@ -99,6 +111,20 @@ namespace storm { result.addLabelToState("deadlock", index); } } + + if (this->options.isAddOverlappingGuardLabelSet()) { + STORM_LOG_THROW(!result.containsLabel("overlap_guards"), storm::exceptions::WrongFormatException, "Label 'overlap_guards' is reserved when adding overlapping guard labels"); + result.addLabel("overlap_guards"); + for (auto index : overlappingGuardStates.get()) { + result.addLabelToState("overlap_guards", index); + } + } + + if (this->options.isAddOutOfBoundsStateSet() && stateStorage.stateToId.contains(outOfBoundsState)) { + STORM_LOG_THROW(!result.containsLabel("out_of_bounds"),storm::exceptions::WrongFormatException, "Label 'out_of_bounds' is reserved when adding out of bounds states."); + result.addLabel("out_of_bounds"); + result.addLabelToState("out_of_bounds", stateStorage.stateToId.getValue(outOfBoundsState)); + } return result; } @@ -156,6 +182,13 @@ namespace storm { return nullptr; } + template<typename ValueType, typename StateType> + void NextStateGenerator<ValueType, StateType>::remapStateIds(std::function<StateType(StateType const&)> const& remapping) { + if (overlappingGuardStates != boost::none) { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Remapping of Ids during model building is not supported for overlapping guard statements."); + } + } + template class NextStateGenerator<double>; #ifdef STORM_HAVE_CARL diff --git a/src/storm/generator/NextStateGenerator.h b/src/storm/generator/NextStateGenerator.h index 54f7f1024..7229ca802 100644 --- a/src/storm/generator/NextStateGenerator.h +++ b/src/storm/generator/NextStateGenerator.h @@ -66,6 +66,13 @@ namespace storm { NextStateGeneratorOptions const& getOptions() const; virtual std::shared_ptr<storm::storage::sparse::ChoiceOrigins> generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const; + + /*! + * Performs a remapping of all values stored by applying the given remapping. + * + * @param remapping The remapping to apply. + */ + void remapStateIds(std::function<StateType(StateType const&)> const& remapping); protected: /*! @@ -95,6 +102,12 @@ namespace storm { /// A comparator used to compare constants. storm::utility::ConstantsComparator<ValueType> comparator; + + /// A state that encodes the outOfBoundsState + CompressedState outOfBoundsState; + + /// A map that stores the indices of states with overlapping guards. + boost::optional<std::vector<uint64_t>> overlappingGuardStates; }; } } diff --git a/src/storm/generator/PrismNextStateGenerator.cpp b/src/storm/generator/PrismNextStateGenerator.cpp index f9cb0a102..61fe1e80f 100644 --- a/src/storm/generator/PrismNextStateGenerator.cpp +++ b/src/storm/generator/PrismNextStateGenerator.cpp @@ -33,7 +33,7 @@ namespace storm { // Only after checking validity of the program, we initialize the variable information. this->checkValid(); - this->variableInformation = VariableInformation(program); + this->variableInformation = VariableInformation(program, options.isAddOutOfBoundsStateSet()); // Create a proper evalator. this->evaluator = std::make_unique<storm::expressions::ExpressionEvaluator<ValueType>>(program.getManager()); @@ -229,6 +229,10 @@ namespace storm { // If the model is a deterministic model, we need to fuse the choices into one. if (this->isDeterministicModel() && totalNumberOfChoices > 1) { Choice<ValueType> globalChoice; + + if (this->options.isAddOverlappingGuardLabelSet()) { + this->overlappingGuardStates->push_back(stateToIdCallback(*this->state)); + } // For CTMCs, we need to keep track of the total exit rate to scale the action rewards later. For DTMCs // this is equal to the number of choices, which is why we initialize it like this here. @@ -318,7 +322,11 @@ namespace storm { ++integerIt; } int_fast64_t assignedValue = this->evaluator->asInt(assignmentIt->getExpression()); - if (this->options.isExplorationChecksSet()) { + if (this->options.isAddOutOfBoundsStateSet()) { + if (assignedValue < integerIt->lowerBound || assignedValue > integerIt->upperBound) { + return this->outOfBoundsState; + } + } else if (this->options.isExplorationChecksSet()) { STORM_LOG_THROW(assignedValue >= integerIt->lowerBound, storm::exceptions::WrongFormatException, "The update " << update << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getVariableName() << "'."); STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException, "The update " << update << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getVariableName() << "'."); } @@ -601,7 +609,6 @@ namespace storm { template<typename ValueType, typename StateType> std::shared_ptr<storm::storage::sparse::ChoiceOrigins> PrismNextStateGenerator<ValueType, StateType>::generateChoiceOrigins(std::vector<boost::any>& dataForChoiceOrigins) const { - if (!this->getOptions().isBuildChoiceOriginsSet()) { return nullptr; } diff --git a/src/storm/generator/VariableInformation.cpp b/src/storm/generator/VariableInformation.cpp index e691300c6..e4befba41 100644 --- a/src/storm/generator/VariableInformation.cpp +++ b/src/storm/generator/VariableInformation.cpp @@ -29,7 +29,16 @@ namespace storm { // Intentionally left empty. } - VariableInformation::VariableInformation(storm::prism::Program const& program) : totalBitOffset(0) { + VariableInformation::VariableInformation(storm::prism::Program const& program, bool outOfBoundsState) : totalBitOffset(0) { + if(outOfBoundsState) { + outOfBoundsBit = 0; + ++totalBitOffset; + } else { + outOfBoundsBit = boost::none; + } + + + for (auto const& booleanVariable : program.getGlobalBooleanVariables()) { booleanVariables.emplace_back(booleanVariable.getExpressionVariable(), totalBitOffset, true); ++totalBitOffset; @@ -37,6 +46,7 @@ namespace storm { for (auto const& integerVariable : program.getGlobalIntegerVariables()) { int_fast64_t lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt(); int_fast64_t upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt(); + STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException, "Lower bound must not be above upper bound"); uint_fast64_t bitwidth = static_cast<uint_fast64_t>(std::ceil(std::log2(upperBound - lowerBound + 1))); integerVariables.emplace_back(integerVariable.getExpressionVariable(), lowerBound, upperBound, totalBitOffset, bitwidth, true); totalBitOffset += bitwidth; @@ -49,6 +59,7 @@ namespace storm { for (auto const& integerVariable : module.getIntegerVariables()) { int_fast64_t lowerBound = integerVariable.getLowerBoundExpression().evaluateAsInt(); int_fast64_t upperBound = integerVariable.getUpperBoundExpression().evaluateAsInt(); + STORM_LOG_THROW(lowerBound <= upperBound, storm::exceptions::WrongFormatException, "Lower bound must not be above upper bound"); uint_fast64_t bitwidth = static_cast<uint_fast64_t>(std::ceil(std::log2(upperBound - lowerBound + 1))); integerVariables.emplace_back(integerVariable.getExpressionVariable(), lowerBound, upperBound, totalBitOffset, bitwidth); totalBitOffset += bitwidth; @@ -58,7 +69,7 @@ namespace storm { sortVariables(); } - VariableInformation::VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata) : totalBitOffset(0) { + VariableInformation::VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata, bool outOfBoundsState) : totalBitOffset(0) { // Check that the model does not contain non-transient unbounded integer or non-transient real variables. STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains global non-transient real variables."); STORM_LOG_THROW(!model.getGlobalVariables().containsNonTransientUnboundedIntegerVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient unbounded integer variables."); @@ -66,6 +77,14 @@ namespace storm { STORM_LOG_THROW(!automaton.getVariables().containsNonTransientUnboundedIntegerVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient unbounded integer variables in automaton '" << automaton.getName() << "'."); STORM_LOG_THROW(!automaton.getVariables().containsNonTransientRealVariables(), storm::exceptions::InvalidArgumentException, "Cannot build model from JANI model that contains non-transient real variables in automaton '" << automaton.getName() << "'."); } + if(outOfBoundsState) { + outOfBoundsBit = 0; + ++totalBitOffset; + } else { + outOfBoundsBit = boost::none; + } + + for (auto const& variable : model.getGlobalVariables().getBooleanVariables()) { if (!variable.isTransient()) { @@ -114,11 +133,21 @@ namespace storm { uint_fast64_t VariableInformation::getTotalBitOffset(bool roundTo64Bit) const { uint_fast64_t result = totalBitOffset; - if (roundTo64Bit) { + if (roundTo64Bit & ((result & ((1ull << 6) - 1)) != 0)) { result = ((result >> 6) + 1) << 6; } return result; } + + bool VariableInformation::hasOutOfBoundsBit() const { + return outOfBoundsBit != boost::none; + } + + uint64_t VariableInformation::getOutOfBoundsBit() const { + assert(hasOutOfBoundsBit()); + return outOfBoundsBit.get(); + } + void VariableInformation::sortVariables() { // Sort the variables so we can make some assumptions when iterating over them (in the next-state generators). diff --git a/src/storm/generator/VariableInformation.h b/src/storm/generator/VariableInformation.h index 764881e80..fac200d1a 100644 --- a/src/storm/generator/VariableInformation.h +++ b/src/storm/generator/VariableInformation.h @@ -3,6 +3,7 @@ #include <vector> #include <boost/container/flat_map.hpp> +#include <boost/optional/optional.hpp> #include "storm/storage/expressions/Variable.h" @@ -74,8 +75,8 @@ namespace storm { // A structure storing information about the used variables of the program. struct VariableInformation { - VariableInformation(storm::prism::Program const& program); - VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata); + VariableInformation(storm::prism::Program const& program, bool outOfBoundsState = false); + VariableInformation(storm::jani::Model const& model, std::vector<std::reference_wrapper<storm::jani::Automaton const>> const& parallelAutomata, bool outOfBoundsState = false); VariableInformation() = default; uint_fast64_t getTotalBitOffset(bool roundTo64Bit = false) const; @@ -91,8 +92,14 @@ namespace storm { /// The integer variables. std::vector<IntegerVariableInformation> integerVariables; - + + bool hasOutOfBoundsBit() const; + + uint64_t getOutOfBoundsBit() const; + private: + boost::optional<uint64_t> outOfBoundsBit; + /*! * Sorts the variables to establish a known ordering. */ diff --git a/src/storm/modelchecker/CheckTask.h b/src/storm/modelchecker/CheckTask.h index 093c40ca8..45f2a9bc3 100644 --- a/src/storm/modelchecker/CheckTask.h +++ b/src/storm/modelchecker/CheckTask.h @@ -211,7 +211,7 @@ namespace storm { /*! * Sets whether to produce schedulers (if supported). */ - void setProduceSchedulers(bool produceSchedulers) { + void setProduceSchedulers(bool produceSchedulers = true) { this->produceSchedulers = produceSchedulers; } diff --git a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp index 81281a2cd..01ea1feda 100644 --- a/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp @@ -332,12 +332,12 @@ namespace storm { } if (isRewardFormula) { - storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractModel, abstractModel.getTransitionMatrix(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybe, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>(), startValues); + storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractModel, abstractModel.getTransitionMatrix(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybe, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), startValues); result.first = std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.getReachableStates(), values); result.second = result.first->clone(); } else { - storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractModel, abstractModel.getTransitionMatrix(), maybe, qualitativeResults.getProb1Min().getStates(), storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>(), startValues); + storm::dd::Add<DdType, ValueType> values = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractModel, abstractModel.getTransitionMatrix(), maybe, qualitativeResults.getProb1Min().getStates(), startValues); result.first = std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(abstractModel.getReachableStates(), values); result.second = result.first->clone(); @@ -371,20 +371,20 @@ namespace storm { uint64_t abstractionPlayer = this->getAbstractionPlayer(); if (isRewardFormula) { - result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), minStartValues); + result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Min().getStates() && abstractModel.getReachableStates(), minStartValues); if (abstractionPlayer == 0) { result.second = result.first->clone(); } else { - result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Max().getStates() && abstractModel.getReachableStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); + result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), abstractModel.getTransitionMatrix().notZero(), checkTask->isRewardModelSet() ? abstractModel.getRewardModel(checkTask->getRewardModel()) : abstractModel.getRewardModel(""), maybeMin, targetStates.getStates(), !qualitativeResults.getProb1Max().getStates() && abstractModel.getReachableStates(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); } } else { - result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), maybeMin, qualitativeResults.getProb1Min().getStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), minStartValues); + result.first = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, abstractionPlayer == 1 ? storm::OptimizationDirection::Minimize : checkTask->getOptimizationDirection(), abstractModel, abstractModel.getTransitionMatrix(), maybeMin, qualitativeResults.getProb1Min().getStates(), minStartValues); if (abstractionPlayer == 0) { result.second = result.first->clone(); } else { - result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), maybeMax, qualitativeResults.getProb1Max().getStates(), storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); + result.second = storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, storm::OptimizationDirection::Maximize, abstractModel, abstractModel.getTransitionMatrix(), maybeMax, qualitativeResults.getProb1Max().getStates(), maybeMax.ite(result.first->asSymbolicQuantitativeCheckResult<DdType, ValueType>().getValueVector(), abstractModel.getManager().template getAddZero<ValueType>())); } } @@ -488,7 +488,7 @@ namespace storm { auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> @@ -598,7 +598,7 @@ namespace storm { } STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> @@ -644,7 +644,7 @@ namespace storm { auto timeInMilliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); STORM_LOG_DEBUG("Computed qualitative solution in " << timeInMilliseconds << "ms."); - return result; + return std::move(result); // move() required by, e.g., clang 3.8 } template<typename ModelType> diff --git a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h index 9af7c3a8b..4fe5af95f 100644 --- a/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h +++ b/src/storm/modelchecker/abstraction/BisimulationAbstractionRefinementModelChecker.h @@ -11,7 +11,7 @@ namespace storm { } namespace dd { - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> class BisimulationDecomposition; } @@ -47,7 +47,7 @@ namespace storm { ModelType const& model; /// The bisimulation object that maintains and refines the model. - std::unique_ptr<storm::dd::BisimulationDecomposition<DdType, ValueType>> bisimulation; + std::unique_ptr<storm::dd::BisimulationDecomposition<DdType, ValueType, ValueType>> bisimulation; /// Maintains the last abstract model that was returned. std::shared_ptr<storm::models::Model<ValueType>> lastAbstractModel; diff --git a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp index 36af17be0..f2cb7a3d2 100644 --- a/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp +++ b/src/storm/modelchecker/abstraction/GameBasedMdpModelChecker.cpp @@ -131,7 +131,7 @@ namespace storm { std::unique_ptr<CheckResult> result; if (checkTask.isBoundSet()) { - // Despite having a bound, we create a quanitative result so that the next layer can perform the comparison. + // Despite having a bound, we create a quantitative result so that the next layer can perform the comparison. if (player2Direction == storm::OptimizationDirection::Minimize) { if (storm::logic::isLowerBound(checkTask.getBoundComparisonType())) { @@ -342,6 +342,11 @@ namespace storm { } else { abstractor = std::make_shared<storm::abstraction::jani::JaniMenuGameAbstractor<Type, ValueType>>(preprocessedModel.asJaniModel(), smtSolverFactory); } + if (!constraintExpression.isTrue()) { + abstractor->addTerminalStates(!constraintExpression); + } + abstractor->addTerminalStates(targetStateExpression); + abstractor->setTargetStates(targetStateExpression); // Create a refiner that can be used to refine the abstraction when needed. storm::abstraction::MenuGameRefiner<Type, ValueType> refiner(*abstractor, smtSolverFactory->create(preprocessedModel.getManager())); @@ -361,7 +366,7 @@ namespace storm { auto abstractionStart = std::chrono::high_resolution_clock::now(); storm::abstraction::MenuGame<Type, ValueType> game = abstractor->abstract(); auto abstractionEnd = std::chrono::high_resolution_clock::now(); - STORM_LOG_DEBUG("Abstraction in iteration " << iterations << " has " << game.getNumberOfStates() << " (player 1) states and " << game.getNumberOfTransitions() << " transitions (computed in " << std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd - abstractionStart).count() << "ms)."); + STORM_LOG_DEBUG("Abstraction in iteration " << iterations << " has " << game.getNumberOfStates() << " (player 1) states, " << game.getNumberOfTransitions() << " transitions, " << game.getBottomStates().getNonZeroCount() << " bottom states (computed in " << std::chrono::duration_cast<std::chrono::milliseconds>(abstractionEnd - abstractionStart).count() << "ms)."); // (2) Prepare transition matrix BDD and target state BDD for later use. storm::dd::Bdd<Type> transitionMatrixBdd = game.getTransitionMatrix().toBdd(); diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp index dd6b2e8c1..4d2507288 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -17,12 +17,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { + HybridCtmcCslModelChecker<ModelType>::HybridCtmcCslModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -53,7 +48,7 @@ namespace storm { SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -72,7 +67,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -95,7 +90,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - return storm::modelchecker::helper::HybridCtmcCslHelper::computeBoundedUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), lowerBound, upperBound, *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeBoundedUntilProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), lowerBound, upperBound); } template<typename ModelType> @@ -103,7 +98,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported."); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeInstantaneousRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeInstantaneousRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>()); } template<typename ModelType> @@ -111,7 +106,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, "Currently step-bounded and reward-bounded properties on CTMCs are not supported."); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeCumulativeRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeCumulativeRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>()); } template<typename ModelType> @@ -120,12 +115,12 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), *linearEquationSolverFactory); + return storm::modelchecker::helper::HybridCtmcCslHelper::computeLongRunAverageRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel("")); } // Explicitly instantiate the model checker. diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h index 19189f361..f66f3c10e 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h @@ -20,7 +20,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridCtmcCslModelChecker(ModelType const& model); - explicit HybridCtmcCslModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -41,8 +40,6 @@ namespace storm { template<typename CValueType = ValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type = 0> bool canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const; - // An object that is used for solving linear equations and performing matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp index c9467b9fe..52d49815e 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -24,12 +24,7 @@ namespace storm { namespace modelchecker { template <typename SparseCtmcModelType> - SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model) : SparsePropositionalModelChecker<SparseCtmcModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template <typename SparseCtmcModelType> - SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<SparseCtmcModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { + SparseCtmcCslModelChecker<SparseCtmcModelType>::SparseCtmcCslModelChecker(SparseCtmcModelType const& model) : SparsePropositionalModelChecker<SparseCtmcModelType>(model) { // Intentionally left empty. } @@ -72,7 +67,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), this->getModel().getExitRateVector(), checkTask.isQualitativeSet(), lowerBound, upperBound, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), this->getModel().getExitRateVector(), checkTask.isQualitativeSet(), lowerBound, upperBound); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -81,7 +76,7 @@ namespace storm { storm::logic::NextFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -92,7 +87,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -100,7 +95,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -108,7 +103,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, "Currently step-bounded and reward-bounded properties on CTMCs are not supported."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<double>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -118,7 +113,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -129,14 +124,14 @@ namespace storm { ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); storm::storage::SparseMatrix<ValueType> probabilityMatrix = storm::modelchecker::helper::SparseCtmcCslHelper::computeProbabilityMatrix(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector()); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, subResult.getTruthValuesVector(), &this->getModel().getExitRateVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, subResult.getTruthValuesVector(), &this->getModel().getExitRateVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template <typename SparseCtmcModelType> std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { storm::storage::SparseMatrix<ValueType> probabilityMatrix = storm::modelchecker::helper::SparseCtmcCslHelper::computeProbabilityMatrix(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector()); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), &this->getModel().getExitRateVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), probabilityMatrix, checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), &this->getModel().getExitRateVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -146,7 +141,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityTimes(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeReachabilityTimes(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h index 86a43778e..9bf94fe93 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h @@ -20,7 +20,6 @@ namespace storm { typedef typename SparseCtmcModelType::RewardModelType RewardModelType; explicit SparseCtmcCslModelChecker(SparseCtmcModelType const& model); - explicit SparseCtmcCslModelChecker(SparseCtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -42,8 +41,6 @@ namespace storm { template<typename CValueType = ValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type = 0> bool canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const; - // An object that is used for solving linear equations and performing matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp index 026c1fa5c..74c976fd6 100644 --- a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp @@ -22,12 +22,7 @@ namespace storm { namespace modelchecker { template<typename SparseMarkovAutomatonModelType> - SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model), minMaxLinearEquationSolverFactory(std::move(minMaxLinearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename SparseMarkovAutomatonModelType> - SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model), minMaxLinearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { + SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model) : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model) { // Intentionally left empty. } @@ -66,7 +61,7 @@ namespace storm { upperBound = storm::utility::infinity<double>(); } - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound)); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -78,7 +73,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -90,7 +85,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -103,7 +98,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -111,7 +106,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute long run average rewards in non-closed Markov automaton."); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } @@ -123,7 +118,7 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityTimes(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper::computeReachabilityTimes(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } diff --git a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 57b1a63a6..60cf49d37 100644 --- a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseMarkovAutomatonModelType::ValueType ValueType; typedef typename SparseMarkovAutomatonModelType::RewardModelType RewardModelType; - explicit SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolver); explicit SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const& model); // The implemented methods of the AbstractModelChecker interface. @@ -30,9 +29,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving solvers for systems of linear equations that are the result of nondeterministic choices. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> minMaxLinearEquationSolverFactory; }; } } diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp index 7713719ed..d76a28884 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.cpp @@ -18,6 +18,8 @@ #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "storm/utility/Stopwatch.h" + #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -27,9 +29,9 @@ namespace storm { namespace helper { template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { - return HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), rewardModel.divideStateRewardVector(exitRateVector), targetStates, qualitative, linearEquationSolverFactory); + return HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), rewardModel.divideStateRewardVector(exitRateVector), targetStates, qualitative); } template<storm::dd::DdType DdType, class ValueType> @@ -38,16 +40,16 @@ namespace storm { } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + return HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, model, computeProbabilityMatrix(rateMatrix, exitRateVector), phiStates, psiStates, qualitative); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound) { // If the time bounds are [0, inf], we rather call untimed reachability. if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) { - return computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative, linearEquationSolverFactory); + return computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative); } // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0 @@ -79,16 +81,20 @@ namespace storm { // Compute the vector that is to be added as a compensation for removing the absorbing states. storm::dd::Add<DdType, ValueType> b = (statesWithProbabilityGreater0NonPsi.template toAdd<ValueType>() * rateMatrix * psiStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>()).sumAbstract(model.getColumnVariables()) / model.getManager().getConstant(uniformizationRate); + storm::utility::Stopwatch conversionWatch(true); + // Create an ODD for the translation to an explicit representation. storm::dd::Odd odd = statesWithProbabilityGreater0NonPsi.createOdd(); // Convert the symbolic parts to their explicit representation. storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitB = b.toVector(odd); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); // Finally compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound, uniformizationRate, values); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), (psiStates || !statesWithProbabilityGreater0) && model.getReachableStates(), @@ -98,7 +104,7 @@ namespace storm { // Start by computing the (unbounded) reachability probabilities of reaching psi states while // staying in phi states. - std::unique_ptr<CheckResult> unboundedResult = computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> unboundedResult = computeUntilProbabilities(env, model, rateMatrix, exitRateVector, phiStates, psiStates, qualitative); // Compute the set of relevant states. storm::dd::Bdd<DdType> relevantStates = statesWithProbabilityGreater0 && phiStates; @@ -106,12 +112,18 @@ namespace storm { // Filter the unbounded result such that it only contains values for the relevant states. unboundedResult->filter(SymbolicQualitativeCheckResult<DdType>(model.getReachableStates(), relevantStates)); + storm::utility::Stopwatch conversionWatch; + // Build an ODD for the relevant states. + conversionWatch.start(); storm::dd::Odd odd = relevantStates.createOdd(); + conversionWatch.stop(); std::vector<ValueType> result; if (unboundedResult->isHybridQuantitativeCheckResult()) { + conversionWatch.start(); std::unique_ptr<CheckResult> explicitUnboundedResult = unboundedResult->asHybridQuantitativeCheckResult<DdType, ValueType>().toExplicitQuantitativeCheckResult(); + conversionWatch.stop(); result = std::move(explicitUnboundedResult->asExplicitQuantitativeCheckResult<ValueType>().getValueVector()); } else { STORM_LOG_THROW(unboundedResult->isSymbolicQuantitativeCheckResult(), storm::exceptions::InvalidStateException, "Expected check result of different type."); @@ -123,10 +135,13 @@ namespace storm { // Compute the uniformized matrix. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, relevantStates, uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Compute the transient probabilities. - result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, result, linearEquationSolverFactory); + result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, result); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !relevantStates && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), relevantStates, odd, result)); } else { @@ -146,13 +161,15 @@ namespace storm { storm::dd::Add<DdType, ValueType> b = (statesWithProbabilityGreater0NonPsi.template toAdd<ValueType>() * rateMatrix * psiStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>()).sumAbstract(model.getColumnVariables()) / model.getManager().getConstant(uniformizationRate); // Build an ODD for the relevant states and translate the symbolic parts to their explicit representation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = statesWithProbabilityGreater0NonPsi.createOdd(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitB = b.toVector(odd); - + conversionWatch.stop(); + // Compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNonZeroCount(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound - lowerBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities(env, explicitUniformizedMatrix, &explicitB, upperBound - lowerBound, uniformizationRate, values); // Transform the explicit result to a hybrid check result, so we can easily convert it to // a symbolic qualitative format. @@ -164,13 +181,15 @@ namespace storm { // Filter the unbounded result such that it only contains values for the relevant states. hybridResult.filter(SymbolicQualitativeCheckResult<DdType>(model.getReachableStates(), relevantStates)); - + // Build an ODD for the relevant states. + conversionWatch.start(); odd = relevantStates.createOdd(); std::unique_ptr<CheckResult> explicitResult = hybridResult.toExplicitQuantitativeCheckResult(); + conversionWatch.stop(); std::vector<ValueType> newSubresult = std::move(explicitResult->asExplicitQuantitativeCheckResult<ValueType>().getValueVector()); - + // Then compute the transient probabilities of being in such a state after t time units. For this, // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix. uniformizationRate = 1.02 * (relevantStates.template toAdd<ValueType>() * exitRateVector).getMax(); @@ -185,19 +204,26 @@ namespace storm { // Finally, we compute the second set of transient probabilities. uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, relevantStates, uniformizationRate); + conversionWatch.start(); explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - - newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !relevantStates && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), relevantStates, odd, newSubresult)); } else { // In this case, the interval is of the form [t, t] with t != 0, t != inf. + storm::utility::Stopwatch conversionWatch; + // Build an ODD for the relevant states. + conversionWatch.start(); storm::dd::Odd odd = statesWithProbabilityGreater0.createOdd(); - + std::vector<ValueType> newSubresult = psiStates.template toAdd<ValueType>().toVector(odd); - + conversionWatch.stop(); + // Then compute the transient probabilities of being in such a state after t time units. For this, // we must re-uniformize the CTMC, so we need to compute the second uniformized matrix. ValueType uniformizationRate = 1.02 * (statesWithProbabilityGreater0.template toAdd<ValueType>() * exitRateVector).getMax(); @@ -205,9 +231,12 @@ namespace storm { // Finally, we compute the second set of transient probabilities. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, statesWithProbabilityGreater0, uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - - newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + newSubresult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType>(model.getReachableStates(), !statesWithProbabilityGreater0 && model.getReachableStates(), model.getManager().template getAddZero<ValueType>(), statesWithProbabilityGreater0, odd, newSubresult)); } @@ -219,18 +248,22 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch; + // Create ODD for the translation. + conversionWatch.start(); storm::dd::Odd odd = model.getReachableStates().createOdd(); + conversionWatch.stop(); // Initialize result to state rewards of the model. std::vector<ValueType> result = rewardModel.getStateRewardVector().toVector(odd); @@ -242,20 +275,24 @@ namespace storm { storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, model.getReachableStates(), uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); - result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, result, linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, result); } return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, result)); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing instantaneous rewards is unsupported for this value type."); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -270,55 +307,72 @@ namespace storm { ValueType uniformizationRate = 1.02 * exitRateVector.getMax(); STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive."); + storm::utility::Stopwatch conversionWatch; + // Create ODD for the translation. + conversionWatch.start(); storm::dd::Odd odd = model.getReachableStates().createOdd(); + conversionWatch.stop(); // Compute the uniformized matrix. storm::dd::Add<DdType, ValueType> uniformizedMatrix = computeUniformizedMatrix(model, rateMatrix, exitRateVector, model.getReachableStates(), uniformizationRate); + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitUniformizedMatrix = uniformizedMatrix.toMatrix(odd, odd); + conversionWatch.stop(); // Then compute the state reward vector to use in the computation. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, model.getColumnVariables(), exitRateVector, false); + conversionWatch.start(); std::vector<ValueType> explicitTotalRewardVector = totalRewardVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Finally, compute the transient probabilities. - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType, true>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, explicitTotalRewardVector, linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeTransientProbabilities<ValueType, true>(env, explicitUniformizedMatrix, nullptr, timeBound, uniformizationRate, explicitTotalRewardVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing cumulative rewards is unsupported for this value type."); } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates) { storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); + storm::utility::Stopwatch conversionWatch(true); + // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, psiStates.toVector(odd), &explicitExitRateVector, linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, psiStates.toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, class ValueType> - std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel) { STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); storm::dd::Add<DdType, ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); + storm::utility::Stopwatch conversionWatch(true); + // Create ODD for the translation. storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = probabilityMatrix.toMatrix(odd, odd); std::vector<ValueType> explicitExitRateVector = exitRateVector.toVector(odd); - - std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, model.getColumnVariables(), exitRateVector, true).toVector(odd), &explicitExitRateVector, linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + std::vector<ValueType> result = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, model.getColumnVariables(), exitRateVector, true).toVector(odd), &explicitExitRateVector); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } @@ -349,50 +403,50 @@ namespace storm { // Explicit instantiations. // Cudd, double. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::CUDD> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& phiStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::CUDD> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::CUDD, double> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::CUDD, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::CUDD, double> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::CUDD, double> const& model, storm::dd::Add<storm::dd::DdType::CUDD, double> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::CUDD, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::CUDD> const& maybeStates, double uniformizationRate); // Sylvan, double. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, double> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, double> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, double> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, double> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, double> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, double uniformizationRate); // Sylvan, rational number. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, storm::RationalNumber uniformizationRate); // Sylvan, rational function. - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative, double lowerBound, double upperBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, double timeBound); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& phiStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& targetStates, bool qualitative); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& psiStates); template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nextStates); - template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::unique_ptr<CheckResult> HybridCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, typename storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::RewardModelType const& rewardModel); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> HybridCtmcCslHelper::computeProbabilityMatrix(storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& rateMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector); template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> HybridCtmcCslHelper::computeUniformizedMatrix(storm::models::symbolic::Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction> const& model, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& transitionMatrix, storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> const& exitRateVector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& maybeStates, storm::RationalFunction uniformizationRate); diff --git a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h index 5e27a0709..8814ca9a7 100644 --- a/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h +++ b/src/storm/modelchecker/csl/helper/HybridCtmcCslHelper.h @@ -21,37 +21,37 @@ namespace storm { class HybridCtmcCslHelper { public: template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, double lowerBound, double upperBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, double timeBound); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& psiStates); template<storm::dd::DdType DdType, typename ValueType> static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, storm::dd::Bdd<DdType> const& nextStates); template<storm::dd::DdType DdType, typename ValueType> - static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Ctmc<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& rateMatrix, storm::dd::Add<DdType, ValueType> const& exitRateVector, typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType const& rewardModel); /*! * Converts the given rate-matrix into a time-abstract probability matrix. diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index 90d556133..99bad8ce1 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -9,6 +9,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/storage/StronglyConnectedComponentDecomposition.h" @@ -29,13 +30,13 @@ namespace storm { namespace modelchecker { namespace helper { template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound) { uint_fast64_t numberOfStates = rateMatrix.getRowCount(); // If the time bounds are [0, inf], we rather call untimed reachability. if (storm::utility::isZero(lowerBound) && upperBound == storm::utility::infinity<ValueType>()) { - return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative, linearEquationSolverFactory); + return computeUntilProbabilities(env, std::move(goal), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative); } // From this point on, we know that we have to solve a more complicated problem [t, t'] with either t != 0 @@ -80,7 +81,7 @@ namespace storm { // Finally compute the transient probabilities. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound, uniformizationRate, values); result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); storm::utility::vector::setVectorValues(result, statesWithProbabilityGreater0NonPsi, subresult); @@ -90,7 +91,7 @@ namespace storm { // Start by computing the (unbounded) reachability probabilities of reaching psi states while // staying in phi states. - result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative, linearEquationSolverFactory); + result = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), rateMatrix, backwardTransitions, exitRates, phiStates, psiStates, qualitative); // Determine the set of states that must be considered further. storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates; @@ -108,7 +109,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates); // Compute the transient probabilities. - subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult, linearEquationSolverFactory); + subResult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, subResult); // Fill in the correct values. storm::utility::vector::setVectorValues(result, ~relevantStates, storm::utility::zero<ValueType>()); @@ -138,7 +139,7 @@ namespace storm { // Start by computing the transient probabilities of reaching a psi state in time t' - t. std::vector<ValueType> values(statesWithProbabilityGreater0NonPsi.getNumberOfSetBits(), storm::utility::zero<ValueType>()); - std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound - lowerBound, uniformizationRate, values, linearEquationSolverFactory); + std::vector<ValueType> subresult = computeTransientProbabilities(env, uniformizedMatrix, &b, upperBound - lowerBound, uniformizationRate, values); storm::storage::BitVector relevantStates = statesWithProbabilityGreater0 & phiStates; std::vector<ValueType> newSubresult = std::vector<ValueType>(relevantStates.getNumberOfSetBits()); @@ -156,7 +157,7 @@ namespace storm { // Finally, we compute the second set of transient probabilities. uniformizedMatrix = computeUniformizedMatrix(rateMatrix, relevantStates, uniformizationRate, exitRates); - newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); // Fill in the correct values. result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); @@ -179,7 +180,7 @@ namespace storm { // Finally, we compute the second set of transient probabilities. storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, statesWithProbabilityGreater0, uniformizationRate, exitRates); - newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult, linearEquationSolverFactory); + newSubresult = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, lowerBound, uniformizationRate, newSubresult); // Fill in the correct values. result = std::vector<ValueType>(numberOfStates, storm::utility::zero<ValueType>()); @@ -196,22 +197,22 @@ namespace storm { } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&, storm::storage::BitVector const&, std::vector<ValueType> const&, bool, double, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&, storm::storage::BitVector const&, std::vector<ValueType> const&, bool, double, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative, linearEquationSolverFactory); + std::vector<ValueType> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) { + return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, std::move(goal), computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates, linearEquationSolverFactory); + std::vector<ValueType> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates) { + return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates); } template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -230,19 +231,19 @@ namespace storm { STORM_LOG_THROW(uniformizationRate > 0, storm::exceptions::InvalidStateException, "The uniformization rate must be positive."); storm::storage::SparseMatrix<ValueType> uniformizedMatrix = computeUniformizedMatrix(rateMatrix, storm::storage::BitVector(numberOfStates, true), uniformizationRate, exitRateVector); - result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result, linearEquationSolverFactory); + result = computeTransientProbabilities<ValueType>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, result); } return result; } template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing instantaneous rewards is unsupported for this value type."); } template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -269,16 +270,16 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(rateMatrix, exitRateVector); // Finally, compute the transient probabilities. - return computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, linearEquationSolverFactory); + return computeTransientProbabilities<ValueType, true>(env, uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector); } template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double, storm::solver::LinearEquationSolverFactory<ValueType> const&) { + std::vector<ValueType> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const&, std::vector<ValueType> const&, RewardModelType const&, double) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing cumulative rewards is unsupported for this value type."); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative) { // Compute expected time on CTMC by reduction to DTMC with rewards. storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); @@ -294,11 +295,11 @@ namespace storm { } } - return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative, linearEquationSolverFactory); + return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative) { STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector); @@ -325,11 +326,11 @@ namespace storm { totalRewardVector = rewardModel.getStateActionRewardVector(); } - return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative, linearEquationSolverFactory); + return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, std::move(goal), probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector) { // If there are no goal states, we avoid the computation and directly return zero. uint_fast64_t numberOfStates = probabilityMatrix.getRowCount(); @@ -352,30 +353,28 @@ namespace storm { } return zero; }, - exitRateVector, - linearEquationSolverFactory); + exitRateVector); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector) { // Only compute the result if the model has a state-based reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); - return computeLongRunAverageRewards(env, std::move(goal), probabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, *exitRateVector), exitRateVector, linearEquationSolverFactory); + return computeLongRunAverageRewards(env, std::move(goal), probabilityMatrix, rewardModel.getTotalRewardVector(probabilityMatrix, *exitRateVector), exitRateVector); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector) { return computeLongRunAverages<ValueType>(env, std::move(goal), probabilityMatrix, [&stateRewardVector] (storm::storage::sparse::state_type const& state) -> ValueType { return stateRewardVector[state]; }, - exitRateVector, - linearEquationSolverFactory); + exitRateVector); } template <typename ValueType> - std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory){ + std::vector<ValueType> SparseCtmcCslHelper::computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector){ uint_fast64_t numberOfStates = probabilityMatrix.getRowCount(); // Start by decomposing the CTMC into its BSCCs. @@ -492,7 +491,9 @@ namespace storm { { // Check solver requirements - STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; + auto requirements = linearEquationSolverFactory.getRequirements(env); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // Check whether we have the right input format for the solver. STORM_LOG_THROW(linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem, storm::exceptions::FormatUnsupportedBySolverException, "The selected solver does not support the required format."); std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(bsccEquationSystem)); @@ -563,8 +564,10 @@ namespace storm { rewardSolution = std::vector<ValueType>(rewardEquationSystemMatrix.getColumnCount(), one); { + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; // Check solver requirements - STORM_LOG_THROW(linearEquationSolverFactory.getRequirements(env).empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + auto requirements = linearEquationSolverFactory.getRequirements(env); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // Check whether we have the right input format for the solver. STORM_LOG_THROW(linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem, storm::exceptions::FormatUnsupportedBySolverException, "The selected solver does not support the required format."); std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(rewardEquationSystemMatrix)); @@ -622,7 +625,7 @@ namespace storm { } template<typename ValueType, bool useMixedPoissonProbabilities, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values) { ValueType lambda = timeBound * uniformizationRate; @@ -671,18 +674,16 @@ namespace storm { } } - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(uniformizedMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->setCachingEnabled(true); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, uniformizedMatrix); if (!useMixedPoissonProbabilities && foxGlynnResult.left > 1) { // Perform the matrix-vector multiplications (without adding). - solver->repeatedMultiply(values, addVector, foxGlynnResult.left - 1); + multiplier->repeatedMultiply(env, values, addVector, foxGlynnResult.left - 1); } else if (useMixedPoissonProbabilities) { std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&uniformizationRate] (ValueType const& a, ValueType const& b) { return a + b / uniformizationRate; }; // For the iterations below the left truncation point, we need to add and scale the result with the uniformization rate. for (uint_fast64_t index = 1; index < startingIteration; ++index) { - solver->repeatedMultiply(values, nullptr, 1); + multiplier->multiply(env, values, nullptr, values); storm::utility::vector::applyPointwise(result, values, result, addAndScale); } } @@ -692,7 +693,7 @@ namespace storm { ValueType weight = 0; std::function<ValueType(ValueType const&, ValueType const&)> addAndScale = [&weight] (ValueType const& a, ValueType const& b) { return a + weight * b; }; for (uint_fast64_t index = startingIteration; index <= foxGlynnResult.right; ++index) { - solver->repeatedMultiply(values, addVector, 1); + multiplier->multiply(env, values, addVector, values); weight = foxGlynnResult.weights[index - foxGlynnResult.left]; storm::utility::vector::applyPointwise(result, values, result, addAndScale); @@ -721,7 +722,7 @@ namespace storm { for (uint_fast64_t row = 0; row < generatorMatrix.getRowCount(); ++row) { for (auto& entry : generatorMatrix.getRow(row)) { if (entry.getColumn() == row) { - entry.setValue(-exitRates[row]); + entry.setValue(-exitRates[row] + entry.getValue()); } } } @@ -730,58 +731,58 @@ namespace storm { } - template std::vector<double> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<double> const& exitRates, bool qualitative, double lowerBound, double upperBound); - template std::vector<double> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& nextStates); - template std::vector<double> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound); - template std::vector<double> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); - template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, std::vector<double> const& stateRewardVector, std::vector<double> const* exitRateVector, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<double> const* exitRateVector); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, std::vector<double> const* exitRateVector); + template std::vector<double> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& probabilityMatrix, std::vector<double> const& stateRewardVector, std::vector<double> const* exitRateVector); - template std::vector<double> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound); template storm::storage::SparseMatrix<double> SparseCtmcCslHelper::computeUniformizedMatrix(storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::BitVector const& maybeStates, double uniformizationRate, std::vector<double> const& exitRates); - template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& uniformizedMatrix, std::vector<double> const* addVector, double timeBound, double uniformizationRate, std::vector<double> values, storm::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory); + template std::vector<double> SparseCtmcCslHelper::computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<double> const& uniformizedMatrix, std::vector<double> const* addVector, double timeBound, double uniformizationRate, std::vector<double> values); #ifdef STORM_HAVE_CARL - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const& exitRates, bool qualitative, double lowerBound, double upperBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const& exitRates, bool qualitative, double lowerBound, double upperBound); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& nextStates); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& nextStates); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalNumber> const& rewardModel, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalFunction> const& rewardModel, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalNumber> const& rewardModel, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, storm::models::sparse::StandardRewardModel<RationalFunction> const& rewardModel, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, std::vector<storm::RationalNumber> const& stateRewardVector, std::vector<storm::RationalNumber> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, std::vector<storm::RationalFunction> const& stateRewardVector, std::vector<storm::RationalFunction> const* exitRateVector, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& probabilityMatrix, std::vector<storm::RationalNumber> const& stateRewardVector, std::vector<storm::RationalNumber> const* exitRateVector); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& probabilityMatrix, std::vector<storm::RationalFunction> const& stateRewardVector, std::vector<storm::RationalFunction> const* exitRateVector); - template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalNumber> const& linearEquationSolverFactory); - template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, double timeBound); + template std::vector<storm::RationalFunction> SparseCtmcCslHelper::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalFunction>&& goal, storm::storage::SparseMatrix<storm::RationalFunction> const& rateMatrix, std::vector<storm::RationalFunction> const& exitRateVector, storm::models::sparse::StandardRewardModel<storm::RationalFunction> const& rewardModel, double timeBound); template storm::storage::SparseMatrix<double> SparseCtmcCslHelper::computeProbabilityMatrix(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRates); template storm::storage::SparseMatrix<storm::RationalNumber> SparseCtmcCslHelper::computeProbabilityMatrix(storm::storage::SparseMatrix<storm::RationalNumber> const& rateMatrix, std::vector<storm::RationalNumber> const& exitRates); diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h index e1e6f3c43..28125c7c9 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.h @@ -19,43 +19,43 @@ namespace storm { class SparseCtmcCslHelper { public: template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound); template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound); template <typename ValueType> - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); template <typename ValueType> - static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates); template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative); template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, RewardModelType const& rewardModel, std::vector<ValueType> const* exitRateVector); template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::vector<ValueType> const& stateRewardVector, std::vector<ValueType> const* exitRateVector); template <typename ValueType> - static std::vector<ValueType> computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityTimes(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& targetStates, bool qualitative); /*! * Computes the matrix representing the transitions of the uniformized CTMC. @@ -84,7 +84,7 @@ namespace storm { * @return The vector of transient probabilities. */ template<typename ValueType, bool useMixedPoissonProbabilities = false, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeTransientProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values); /*! * Converts the given rate-matrix into a time-abstract probability matrix. @@ -108,7 +108,7 @@ namespace storm { private: template <typename ValueType> - static std::vector<ValueType> computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverages(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, std::function<ValueType (storm::storage::sparse::state_type const& state)> const& valueGetter, std::vector<ValueType> const* exitRateVector); }; } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp index ad3db92f0..8eb688d55 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp @@ -21,8 +21,6 @@ #include "storm/storage/expressions/Expression.h" #include "storm/storage/expressions/ExpressionManager.h" -#include "storm/utility/numerical.h" - #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/LpSolver.h" @@ -34,9 +32,353 @@ namespace storm { namespace modelchecker { namespace helper { + + template<typename ValueType> + void calculateUnifPlusVector(Environment const& env, uint64_t k, uint64_t state, uint64_t const kind, ValueType lambda, uint64_t numberOfProbabilisticChoices, std::vector<std::vector<ValueType>> const & relativeReachability, OptimizationDirection dir, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const& poisson, bool cycleFree) { + + if (unifVectors[kind][k][state] != -1) { + // Result already calculated. + return; + } + + auto numberOfStates = fullTransitionMatrix.getRowGroupCount(); + uint64_t N = unifVectors[kind].size() - 1; + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + ValueType res; + + // First case, k==N, independent from kind of state. + if (k == N) { + unifVectors[kind][k][state] = storm::utility::zero<ValueType>(); + return; + } + + // Goal state, independent from kind of state. + if (psiStates[state]) { + if (kind == 0) { + // Vd + res = storm::utility::zero<ValueType>(); + for (uint64_t i = k; i < N; ++i){ + if (i >= poisson.left && i <= poisson.right) { + ValueType between = poisson.weights[i - poisson.left]; + res += between; + } + } + unifVectors[kind][k][state] = res; + } else { + // WU + unifVectors[kind][k][state] = storm::utility::one<ValueType>(); + } + return; + } + + // Markovian non-goal state. + if (markovianStates[state]) { + res = storm::utility::zero<ValueType>(); + for (auto const& element : fullTransitionMatrix.getRow(rowGroupIndices[state])) { + uint64_t to = element.getColumn(); + if (unifVectors[kind][k+1][to] == -1) { + calculateUnifPlusVector(env, k+1, to, kind, lambda, numberOfProbabilisticChoices, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + } + res += element.getValue()*unifVectors[kind][k+1][to]; + } + unifVectors[kind][k][state]=res; + return; + } + + // Probabilistic non-goal state. + if (cycleFree) { + // If the model is cycle free, do "slight value iteration". (What is that?) + res = -1; + for (uint64_t i = rowGroupIndices[state]; i < rowGroupIndices[state + 1]; ++i) { + auto row = fullTransitionMatrix.getRow(i); + ValueType between = 0; + for (auto const& element : row) { + uint64_t successor = element.getColumn(); + + // This should never happen, right? The model has no cycles, and therefore also no self-loops. + if (successor == state) { + continue; + } + + if (unifVectors[kind][k][successor] == -1) { + calculateUnifPlusVector(env, k, successor, kind, lambda, numberOfProbabilisticChoices, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + } + between += element.getValue() * unifVectors[kind][k][successor]; + } + if (maximize(dir)) { + res = storm::utility::max(res, between); + } else { + if (res != -1) { + res = storm::utility::min(res, between); + } else { + res = between; + } + } + } + unifVectors[kind][k][state] = res; + return; + } + + // If we arrived at this point, the model is not cycle free. Use the solver to solve the unterlying equation system. + uint64_t numberOfProbabilisticStates = numberOfStates - markovianStates.getNumberOfSetBits(); + std::vector<ValueType> b(numberOfProbabilisticChoices, storm::utility::zero<ValueType>()); + std::vector<ValueType> x(numberOfProbabilisticStates, storm::utility::zero<ValueType>()); + + // Compute right-hand side vector b. + uint64_t row = 0; + for (uint64_t i = 0; i < numberOfStates; ++i) { + if (markovianStates[i]) { + continue; + } - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + for (auto j = rowGroupIndices[i]; j < rowGroupIndices[i + 1]; j++) { + uint64_t stateCount = 0; + res = storm::utility::zero<ValueType>(); + for (auto const& element : fullTransitionMatrix.getRow(j)) { + auto successor = element.getColumn(); + if (!markovianStates[successor]) { + continue; + } + + if (unifVectors[kind][k][successor] == -1) { + calculateUnifPlusVector(env, k, successor, kind, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + } + res = res + relativeReachability[j][stateCount] * unifVectors[kind][k][successor]; + ++stateCount; + } + + b[row] = res; + ++row; + } + } + + // Solve the equation system. + solver->solveEquations(env, dir, x, b); + + // Expand the solution for the probabilistic states to all states. + storm::utility::vector::setVectorValues(unifVectors[kind][k], ~markovianStates, x); + } + + template <typename ValueType> + void calculateVu(Environment const& env, std::vector<std::vector<ValueType>> const& relativeReachability, OptimizationDirection dir, uint64_t k, uint64_t state, uint64_t const kind, ValueType lambda, uint64_t numberOfProbabilisticStates, std::vector<std::vector<std::vector<ValueType>>>& unifVectors, storm::storage::SparseMatrix<ValueType> const& fullTransitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> const& solver, storm::utility::numerical::FoxGlynnResult<ValueType> const & poisson, bool cycleFree) { + + // Avoiding multiple computation of the same value. + if (unifVectors[1][k][state] != -1) { + return; + } + uint64_t N = unifVectors[1].size() - 1; + + ValueType res = storm::utility::zero<ValueType>(); + for (uint64_t i = k; i < N; ++i) { + if (unifVectors[2][N-1-(i-k)][state] == -1) { + calculateUnifPlusVector(env, N-1-(i-k), state, 2, lambda, numberOfProbabilisticStates, relativeReachability, dir, unifVectors, fullTransitionMatrix, markovianStates, psiStates, solver, poisson, cycleFree); + } + if (i >= poisson.left && i <= poisson.right) { + res += poisson.weights[i - poisson.left] * unifVectors[2][N-1-(i-k)][state]; + } + } + unifVectors[1][k][state] = res; + } + + template <typename ValueType> + void eliminateProbabilisticSelfLoops(storm::storage::SparseMatrix<ValueType>& transitionMatrix, storm::storage::BitVector const& markovianStates) { + auto const& rowGroupIndices = transitionMatrix.getRowGroupIndices(); + + for (uint64_t i = 0; i < transitionMatrix.getRowGroupCount(); ++i) { + if (markovianStates[i]) { + continue; + } + + for (uint64_t j = rowGroupIndices[i]; j < rowGroupIndices[i + 1]; j++) { + ValueType selfLoop = storm::utility::zero<ValueType>(); + for (auto const& element: transitionMatrix.getRow(j)){ + if (element.getColumn() == i) { + selfLoop += element.getValue(); + } + } + + if (storm::utility::isZero(selfLoop)) { + continue; + } + + for (auto& element : transitionMatrix.getRow(j)) { + if (element.getColumn() != i) { + if (!storm::utility::isOne(selfLoop)) { + element.setValue(element.getValue() / (storm::utility::one<ValueType>() - selfLoop)); + } + } else { + element.setValue(storm::utility::zero<ValueType>()); + } + } + } + } + } + + template<typename ValueType> + std::vector<ValueType> computeBoundedUntilProbabilitiesUnifPlus(Environment const& env, OptimizationDirection dir, std::pair<double, double> const& boundsPair, std::vector<ValueType> const& exitRateVector, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates) { + STORM_LOG_TRACE("Using UnifPlus to compute bounded until probabilities."); + + // Obtain bit vectors to identify different kind of states. + storm::storage::BitVector allStates(markovianStates.size(), true); + storm::storage::BitVector probabilisticStates = ~markovianStates; + + // Searching for SCCs in probabilistic fragment to decide which algorithm is applied. + storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(transitionMatrix, probabilisticStates, true, false); + bool cycleFree = sccDecomposition.empty(); + + // Vectors to store computed vectors. + std::vector<std::vector<std::vector<ValueType>>> unifVectors(3); + + // Transitions from goal states will be ignored. However, we mark them as non-probabilistic to make sure + // we do not apply the MDP algorithm to them. + storm::storage::BitVector markovianAndGoalStates = markovianStates | psiStates; + probabilisticStates &= ~psiStates; + + std::vector<ValueType> mutableExitRates = exitRateVector; + + // Extend the transition matrix with diagonal entries so we can change them easily during the uniformization step. + typename storm::storage::SparseMatrix<ValueType> fullTransitionMatrix = transitionMatrix.getSubmatrix(true, allStates, allStates, true); + + // Eliminate self-loops of probabilistic states. Is this really needed for the "slight value iteration" process? + eliminateProbabilisticSelfLoops(fullTransitionMatrix, markovianAndGoalStates); + typename storm::storage::SparseMatrix<ValueType> probMatrix; + uint64_t numberOfProbabilisticChoices = 0; + if (!probabilisticStates.empty()) { + probMatrix = fullTransitionMatrix.getSubmatrix(true, probabilisticStates, probabilisticStates, true); + numberOfProbabilisticChoices = probMatrix.getRowCount(); + } + + // Get row grouping of transition matrix. + auto const& rowGroupIndices = fullTransitionMatrix.getRowGroupIndices(); + + // (1) define/declare horizon, epsilon, kappa, N, lambda, maxNorm + uint64_t numberOfStates = fullTransitionMatrix.getRowGroupCount(); + double T = boundsPair.second; + // TODO: make kappa a parameter. + ValueType kappa = storm::utility::one<ValueType>() / 10; + ValueType epsilon = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision(); + ValueType lambda = exitRateVector[0]; + for (ValueType const& rate : exitRateVector) { + lambda = std::max(rate, lambda); + } + STORM_LOG_TRACE("Initial lambda is " << lambda << "."); + uint64_t N; + ValueType maxNorm = storm::utility::zero<ValueType>(); + + // Compute the relative reachability vectors and create solver for models with SCCs. + std::vector<std::vector<ValueType>> relativeReachabilities(transitionMatrix.getRowCount()); + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver; + if (!cycleFree) { + for (uint64_t i = 0; i < numberOfStates; i++) { + if (markovianAndGoalStates[i]) { + continue; + } + + for (auto j = rowGroupIndices[i]; j < rowGroupIndices[i + 1]; ++j) { + for (auto const& element : fullTransitionMatrix.getRow(j)) { + if (markovianAndGoalStates[element.getColumn()]) { + relativeReachabilities[j].push_back(element.getValue()); + } + } + } + } + + // Create solver. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); + requirements.clearBounds(); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); + + if (numberOfProbabilisticChoices > 0) { + solver = minMaxLinearEquationSolverFactory.create(env, probMatrix); + solver->setHasUniqueSolution(); + solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); + solver->setRequirementsChecked(); + solver->setCachingEnabled(true); + } + } + + // Loop until result is within precision bound. + std::vector<ValueType> init(numberOfStates, -1); + do { + maxNorm = storm::utility::zero<ValueType>(); + + // (2) update parameter + N = storm::utility::ceil(lambda * T * std::exp(2) - storm::utility::log(kappa * epsilon)); + + // (3) uniform - just applied to Markovian states. + for (uint64_t i = 0; i < fullTransitionMatrix.getRowGroupCount(); i++) { + if (!markovianAndGoalStates[i] || psiStates[i]) { + continue; + } + + // As the current state is Markovian, its branching probabilities are stored within one row. + uint64_t markovianRowIndex = rowGroupIndices[i]; + + if (mutableExitRates[i] == lambda) { + // Already uniformized. + continue; + } + + auto markovianRow = fullTransitionMatrix.getRow(markovianRowIndex); + ValueType oldExitRate = mutableExitRates[i]; + ValueType newExitRate = lambda; + for (auto& v : markovianRow) { + if (v.getColumn() == i) { + ValueType newSelfLoop = newExitRate - oldExitRate + v.getValue() * oldExitRate; + ValueType newRate = newSelfLoop / newExitRate; + v.setValue(newRate); + } else { + ValueType oldProbability = v.getValue(); + ValueType newProbability = oldProbability * oldExitRate / newExitRate; + v.setValue(newProbability); + } + } + mutableExitRates[i] = newExitRate; + } + + // Compute poisson distribution. + storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda * T, epsilon * kappa / 100); + + // Scale the weights so they sum to one. + for (auto& element : foxGlynnResult.weights) { + element /= foxGlynnResult.totalWeight; + } + + // (4) Define vectors/matrices. + std::vector<std::vector<ValueType>> v = std::vector<std::vector<ValueType>>(N + 1, init); + + unifVectors[0] = v; + unifVectors[1] = v; + unifVectors[2] = v; + + // Define 0=vd, 1=vu, 2=wu. + // (5) Compute vectors and maxNorm. + for (uint64_t i = 0; i < numberOfStates; ++i) { + for (uint64_t k = N; k <= N; --k) { + calculateUnifPlusVector(env, k, i, 0, lambda, numberOfProbabilisticChoices, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + calculateUnifPlusVector(env, k, i, 2, lambda, numberOfProbabilisticChoices, relativeReachabilities, dir, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + calculateVu(env, relativeReachabilities, dir, k, i, 1, lambda, numberOfProbabilisticChoices, unifVectors, fullTransitionMatrix, markovianAndGoalStates, psiStates, solver, foxGlynnResult, cycleFree); + } + } + + // Only iterate over result vector, as the results can only get more precise. + for (uint64_t i = 0; i < numberOfStates; i++){ + ValueType diff = storm::utility::abs(unifVectors[0][0][i] - unifVectors[1][0][i]); + maxNorm = std::max(maxNorm, diff); + } + + // (6) Double lambda. + lambda *= 2; + STORM_LOG_TRACE("Increased lambda to " << lambda << ", max diff is " << maxNorm << "."); + + } while (maxNorm > epsilon * (1 - kappa)); + + return unifVectors[0][0]; + } + + template <typename ValueType> + void computeBoundedReachabilityProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps) { // Start by computing four sparse matrices: // * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states. @@ -101,13 +443,14 @@ namespace storm { } } } - + // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); - + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); + std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, aProbabilistic); solver->setHasUniqueSolution(); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); @@ -126,10 +469,10 @@ namespace storm { // Start by (re-)computing bProbabilistic = bProbabilisticFixed + aProbabilisticToMarkovian * vMarkovian. aProbabilisticToMarkovian.multiplyWithVector(markovianNonGoalValues, bProbabilistic); storm::utility::vector::addVectors(bProbabilistic, bProbabilisticFixed, bProbabilistic); - + // Now perform the inner value iteration for probabilistic states. solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); - + // (Re-)compute bMarkovian = bMarkovianFixed + aMarkovianToProbabilistic * vProbabilistic. aMarkovianToProbabilistic.multiplyWithVector(probabilisticNonGoalValues, bMarkovian); storm::utility::vector::addVectors(bMarkovian, bMarkovianFixed, bMarkovian); @@ -151,21 +494,17 @@ namespace storm { solver->solveEquations(env, dir, probabilisticNonGoalValues, bProbabilistic); } } - - template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { - STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded reachability probabilities is unsupported for this value type."); - } + + template <typename ValueType> + std::vector<ValueType> computeBoundedUntilProbabilitiesImca(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { + STORM_LOG_TRACE("Using IMCA's technique to compute bounded until probabilities."); - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { - uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); - + // 'Unpack' the bounds to make them more easily accessible. double lowerBound = boundsPair.first; double upperBound = boundsPair.second; - + // (1) Compute the accuracy we need to achieve the required error bound. ValueType maxExitRate = 0; for (auto value : exitRateVector) { @@ -185,7 +524,7 @@ namespace storm { std::vector<ValueType> vProbabilistic(probabilisticNonGoalStates.getNumberOfSetBits()); std::vector<ValueType> vMarkovian(markovianNonGoalStates.getNumberOfSetBits()); - computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, psiStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps, minMaxLinearEquationSolverFactory); + computeBoundedReachabilityProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, psiStates, markovianNonGoalStates, probabilisticNonGoalStates, vMarkovian, vProbabilistic, delta, numberOfSteps); // (4) If the lower bound of interval was non-zero, we need to take the current values as the starting values for a subsequent value iteration. if (lowerBound != storm::utility::zero<ValueType>()) { @@ -203,7 +542,7 @@ namespace storm { STORM_LOG_INFO("Performing " << numberOfSteps << " iterations (delta=" << delta << ") for interval [0, " << lowerBound << "]." << std::endl); // Compute the bounded reachability for interval [0, b-a]. - computeBoundedReachabilityProbabilities(env, dir, transitionMatrix, exitRateVector, storm::storage::BitVector(numberOfStates), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps, minMaxLinearEquationSolverFactory); + computeBoundedReachabilityProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, storm::storage::BitVector(numberOfStates), markovianStates, ~markovianStates, vAllMarkovian, vAllProbabilistic, delta, numberOfSteps); // Create the result vector out of vAllProbabilistic and vAllMarkovian and return it. std::vector<ValueType> result(numberOfStates, storm::utility::zero<ValueType>()); @@ -220,20 +559,32 @@ namespace storm { return result; } } + + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type> + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { + + auto const& settings = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>(); + if (settings.getMarkovAutomatonBoundedReachabilityMethod() == storm::settings::modules::MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::Imca) { + return computeBoundedUntilProbabilitiesImca(env, dir, transitionMatrix, exitRateVector, markovianStates, psiStates, boundsPair); + } else { + STORM_LOG_ASSERT(settings.getMarkovAutomatonBoundedReachabilityMethod() == storm::settings::modules::MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::UnifPlus, "Unknown solution method."); + + return computeBoundedUntilProbabilitiesUnifPlus(env, dir, boundsPair, exitRateVector, transitionMatrix, markovianStates, psiStates); + } + } template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair) { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Computing bounded until probabilities is unsupported for this value type."); } - template<typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { - return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative) { + return std::move(storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, dir, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, false).values); } template <typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates) { // Get a reward model where the state rewards are scaled accordingly std::vector<ValueType> stateRewardWeights(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); @@ -243,11 +594,11 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalActionRewardVector(transitionMatrix, stateRewardWeights); RewardModelType scaledRewardModel(boost::none, std::move(totalRewardVector)); - return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, scaledRewardModel, psiStates, false, false, minMaxLinearEquationSolverFactory).values; + return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, scaledRewardModel, psiStates, false, false).values; } template<typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -267,12 +618,12 @@ namespace storm { storm::utility::vector::setVectorValues(stateRewards, markovianStates & psiStates, storm::utility::one<ValueType>()); storm::models::sparse::StandardRewardModel<ValueType> rewardModel(std::move(stateRewards)); - return computeLongRunAverageRewards(env, dir, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, rewardModel, minMaxLinearEquationSolverFactory); + return computeLongRunAverageRewards(env, dir, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, rewardModel); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -301,7 +652,7 @@ namespace storm { } // Compute the LRA value for the current MEC. - lraValuesForEndComponents.push_back(computeLraForMaximalEndComponent(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec, minMaxLinearEquationSolverFactory)); + lraValuesForEndComponents.push_back(computeLraForMaximalEndComponent(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec)); } // For fast transition rewriting, we build some auxiliary data structures. @@ -403,9 +754,10 @@ namespace storm { std::vector<ValueType> x(numberOfSspStates); // Check for requirements of the solver. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, sspMatrix); solver->setHasUniqueSolution(); @@ -429,7 +781,7 @@ namespace storm { } template <typename ValueType> - std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates) { // Get a reward model representing expected sojourn times std::vector<ValueType> rewardValues(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); @@ -438,11 +790,11 @@ namespace storm { } storm::models::sparse::StandardRewardModel<ValueType> rewardModel(boost::none, std::move(rewardValues)); - return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, rewardModel, psiStates, false, false, minMaxLinearEquationSolverFactory).values; + return SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, dir, transitionMatrix, backwardTransitions, rewardModel, psiStates, false, false).values; } template<typename ValueType, typename RewardModelType> - ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // If the mec only consists of a single state, we compute the LRA value directly if (++mec.begin() == mec.end()) { @@ -462,7 +814,7 @@ namespace storm { if (method == storm::solver::LraMethod::LinearProgramming) { return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec); } else if (method == storm::solver::LraMethod::ValueIteration) { - return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec, minMaxLinearEquationSolverFactory); + return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -534,7 +886,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // Initialize data about the mec @@ -616,9 +968,10 @@ namespace storm { // Check for requirements of the solver. // The solution is unique as we assume non-zeno MAs. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir, true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, dir); requirements.clearLowerBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); auto solver = minMaxLinearEquationSolverFactory.create(env, std::move(aProbabilistic)); solver->setLowerBound(storm::utility::zero<ValueType>()); @@ -661,45 +1014,41 @@ namespace storm { } - template std::vector<double> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& psiStates); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel); - template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - - template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<double>& markovianNonGoalValues, std::vector<double>& probabilisticNonGoalValues, double delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - - template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); + + template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template double SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& psiStates); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel); - template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - - template void SparseMarkovAutomatonCslHelper::computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<storm::RationalNumber>& markovianNonGoalValues, std::vector<storm::RationalNumber>& probabilisticNonGoalValues, storm::RationalNumber delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMarkovAutomatonCslHelper::computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); - template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); - template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template storm::RationalNumber SparseMarkovAutomatonCslHelper::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); } } diff --git a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h index 655f6ebf2..fbfeaa7dd 100644 --- a/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h +++ b/src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h @@ -1,6 +1,6 @@ -#ifndef STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ -#define STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ +#pragma once +#include <storm/utility/numerical.h> #include "storm/storage/BitVector.h" #include "storm/storage/MaximalEndComponent.h" #include "storm/solver/OptimizationDirection.h" @@ -16,36 +16,29 @@ namespace storm { class SparseMarkovAutomatonCslHelper { public: - + template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); - + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); + template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair); template <typename ValueType> - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates); - template <typename ValueType> - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); template <typename ValueType, typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel); template <typename ValueType> - static std::vector<ValueType> computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityTimes(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates); private: - template <typename ValueType, typename std::enable_if<storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); - - template <typename ValueType, typename std::enable_if<!storm::NumberTraits<ValueType>::SupportsExponential, int>::type = 0> - static void computeBoundedReachabilityProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint64_t numberOfSteps, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); - /*! * Computes the long-run average value for the given maximal end component of a Markov automaton. * @@ -59,20 +52,17 @@ namespace storm { * @param rewardModel The considered reward model * @param actionRewards The action rewards (earned instantaneously). * @param mec The maximal end component to consider for computing the long-run average. - * @param minMaxLinearEquationSolverFactory The factory for creating MinMaxLinearEquationSolvers (if needed by the performed method * @return The long-run average of being in a goal state for the given MEC. */ template <typename ValueType, typename RewardModelType> - static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template <typename ValueType, typename RewardModelType> static ValueType computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template <typename ValueType, typename RewardModelType> - static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); }; } } } - -#endif /* STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_ */ diff --git a/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp b/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp index c5dc5e036..73e880662 100644 --- a/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp +++ b/src/storm/modelchecker/exploration/SparseExplorationModelChecker.cpp @@ -341,7 +341,7 @@ namespace storm { }); } else if (explorationInformation.useProbabilityHeuristic()) { std::transform(row.begin(), row.end(), probabilities.begin(), - [&bounds, &explorationInformation] (storm::storage::MatrixEntry<StateType, ValueType> const& entry) { + [] (storm::storage::MatrixEntry<StateType, ValueType> const& entry) { return entry.getValue(); }); } diff --git a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp index ae03a7d9e..5a65bd502 100644 --- a/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp +++ b/src/storm/modelchecker/multiobjective/constraintbased/SparseCbAchievabilityQuery.cpp @@ -9,6 +9,7 @@ #include "storm/utility/vector.h" #include "storm/utility/solver.h" #include "storm/utility/Stopwatch.h" +#include "storm/utility/ExpressionHelper.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" @@ -99,11 +100,13 @@ namespace storm { for (auto& var : expectedChoiceVariables) { solver->add(var.getExpression() >= zero); } - storm::expressions::Expression bottomStateSum = zero; + std::vector<storm::expressions::Expression> bottomStateVarsAsExpression; + bottomStateVarsAsExpression.reserve(bottomStateVariables.size()); for (auto& var : bottomStateVariables) { solver->add(var.getExpression() >= zero); - bottomStateSum = bottomStateSum + var.getExpression(); + bottomStateVarsAsExpression.push_back(var.getExpression()); } + auto bottomStateSum = storm::utility::ExpressionHelper(this->expressionManager).sum(std::move(bottomStateVarsAsExpression)); solver->add(bottomStateSum == one); // assert that the "incoming" value of each state equals the "outgoing" value @@ -138,12 +141,16 @@ namespace storm { STORM_LOG_THROW(obj.formula->hasBound(), storm::exceptions::InvalidOperationException, "Invoked achievability query but no bound was specified for at least one objective."); STORM_LOG_THROW(obj.formula->asRewardOperatorFormula().hasRewardModelName(), storm::exceptions::InvalidOperationException, "Expected reward operator with a reward model name. Got " << *obj.formula << " instead."); std::vector<ValueType> rewards = getActionBasedExpectedRewards(obj.formula->asRewardOperatorFormula().getRewardModelName()); - storm::expressions::Expression objValue = zero; + + // Get the sum of all objective values + std::vector<storm::expressions::Expression> objectiveValues; for (uint_fast64_t choice = 0; choice < rewards.size(); ++choice) { if (!storm::utility::isZero(rewards[choice])) { - objValue = objValue + (this->expressionManager->rational(rewards[choice]) * expectedChoiceVariables[choice].getExpression()); + objectiveValues.push_back(this->expressionManager->rational(rewards[choice]) * expectedChoiceVariables[choice].getExpression()); } } + auto objValue = storm::utility::ExpressionHelper(this->expressionManager).sum(std::move(objectiveValues)); + // We need to actually evaluate the threshold as rational number. Otherwise a threshold like '<=16/9' might be considered as 1 due to integer division storm::expressions::Expression threshold = this->expressionManager->rational(obj.formula->getThreshold().evaluateAsRational()); switch (obj.formula->getBound().comparisonType) { diff --git a/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp b/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp index 10276ffa6..bb18e9385 100644 --- a/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp +++ b/src/storm/modelchecker/multiobjective/multiObjectiveModelChecking.cpp @@ -1,7 +1,7 @@ #include "storm/modelchecker/multiobjective/multiObjectiveModelChecking.h" #include "storm/utility/macros.h" - +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" @@ -74,8 +74,8 @@ namespace storm { result = query->check(env); - if(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().isExportPlotSet()) { - query->exportPlotOfCurrentApproximation(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getExportPlotDirectory()); + if (env.modelchecker().multi().isExportPlotSet()) { + query->exportPlotOfCurrentApproximation(env); } break; } diff --git a/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp index cc748983d..f5137b0a7 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/RewardBoundedMdpPcaaWeightVectorChecker.cpp @@ -295,7 +295,7 @@ namespace storm { cachedData.linEqSolver->setUpperBound(*obj.upperResultBound); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); cachedData.linEqSolver->solveEquations(env, x, cachedData.bLinEq); auto resultIt = result.begin(); for (auto const& state : epochModel.epochInStates) { @@ -331,7 +331,7 @@ namespace storm { cachedData.minMaxSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); cachedData.minMaxSolver->setRequirementsChecked(true); cachedData.minMaxSolver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp index 409bd9ba9..b8ac5fe2d 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaAchievabilityQuery.cpp @@ -7,9 +7,8 @@ #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/GeneralSettings.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" + #include "storm/exceptions/InvalidOperationException.h" @@ -57,7 +56,7 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> bool SparsePcaaAchievabilityQuery<SparseModelType, GeometryValueType>::checkAchievability(Environment const& env) { // repeatedly refine the over/ under approximation until the threshold point is either in the under approx. or not in the over approx. - while(!this->maxStepsPerformed()){ + while(!this->maxStepsPerformed(env)){ WeightVector separatingVector = this->findSeparatingVector(thresholds); this->updateWeightedPrecision(separatingVector); this->performRefinementStep(env, std::move(separatingVector)); diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp index fe7a7b367..93c04e527 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaParetoQuery.cpp @@ -7,10 +7,7 @@ #include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" -#include "storm/settings/modules/GeneralSettings.h" - +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" namespace storm { namespace modelchecker { @@ -19,20 +16,19 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::SparsePcaaParetoQuery(SparseMultiObjectivePreprocessorResult<SparseModelType>& preprocessorResult) : SparsePcaaQuery<SparseModelType, GeometryValueType>(preprocessorResult) { STORM_LOG_ASSERT(preprocessorResult.queryType==SparseMultiObjectivePreprocessorResult<SparseModelType>::QueryType::Pareto, "Invalid query Type"); + } + + template <class SparseModelType, typename GeometryValueType> + std::unique_ptr<CheckResult> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::check(Environment const& env) { // Set the precision of the weight vector checker - typename SparseModelType::ValueType weightedPrecision = storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); + typename SparseModelType::ValueType weightedPrecision = storm::utility::convertNumber<typename SparseModelType::ValueType>(env.modelchecker().multi().getPrecision()); weightedPrecision /= storm::utility::sqrt(storm::utility::convertNumber<typename SparseModelType::ValueType, uint_fast64_t>(this->objectives.size())); // multiobjPrecision / sqrt(numObjectives) is the largest possible value for which termination is guaranteed. // Lets be a little bit more precise to reduce the number of required iterations. weightedPrecision *= storm::utility::convertNumber<typename SparseModelType::ValueType>(0.9); this->weightVectorChecker->setWeightedPrecision(weightedPrecision); - - } - - template <class SparseModelType, typename GeometryValueType> - std::unique_ptr<CheckResult> SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::check(Environment const& env) { - + // refine the approximation exploreSetOfAchievablePoints(env); @@ -55,13 +51,13 @@ namespace storm { void SparsePcaaParetoQuery<SparseModelType, GeometryValueType>::exploreSetOfAchievablePoints(Environment const& env) { //First consider the objectives individually - for(uint_fast64_t objIndex = 0; objIndex<this->objectives.size() && !this->maxStepsPerformed(); ++objIndex) { + for(uint_fast64_t objIndex = 0; objIndex<this->objectives.size() && !this->maxStepsPerformed(env); ++objIndex) { WeightVector direction(this->objectives.size(), storm::utility::zero<GeometryValueType>()); direction[objIndex] = storm::utility::one<GeometryValueType>(); this->performRefinementStep(env, std::move(direction)); } - while(!this->maxStepsPerformed()) { + while(!this->maxStepsPerformed(env)) { // Get the halfspace of the underApproximation with maximal distance to a vertex of the overApproximation std::vector<storm::storage::geometry::Halfspace<GeometryValueType>> underApproxHalfspaces = this->underApproximation->getHalfspaces(); std::vector<Point> overApproxVertices = this->overApproximation->getVertices(); @@ -76,7 +72,7 @@ namespace storm { } } } - if(farestDistance < storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())) { + if(farestDistance < storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision())) { // Goal precision reached! return; } diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp index 538752ab2..4df353cdd 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp @@ -8,9 +8,7 @@ #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" -#include "storm/settings/modules/GeneralSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/exceptions/InvalidOperationException.h" @@ -99,7 +97,7 @@ namespace storm { // We don't care for the optimizing objective at this point this->diracWeightVectorsToBeChecked.set(indexOfOptimizingObjective, false); - while(!this->maxStepsPerformed()){ + while(!this->maxStepsPerformed(env)){ WeightVector separatingVector = this->findSeparatingVector(thresholds); this->updateWeightedPrecisionInAchievabilityPhase(separatingVector); this->performRefinementStep(env, std::move(separatingVector)); @@ -150,10 +148,10 @@ namespace storm { // the supremum over all strategies. Hence, one could combine a scheduler inducing the optimum value (but possibly violating strict // thresholds) and (with very low probability) a scheduler that satisfies all (possibly strict) thresholds. GeometryValueType result = storm::utility::zero<GeometryValueType>(); - while(!this->maxStepsPerformed()) { + while(!this->maxStepsPerformed(env)) { if (this->refinementSteps.empty()) { // We did not make any refinement steps during the checkAchievability phase (e.g., because there is only one objective). - this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())); + this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(env.modelchecker().multi().getPrecision())); WeightVector separatingVector = directionOfOptimizingObjective; this->performRefinementStep(env, std::move(separatingVector)); } @@ -165,7 +163,7 @@ namespace storm { optimizationRes = this->overApproximation->intersection(thresholdsAsPolytope)->optimize(directionOfOptimizingObjective); if (optimizationRes.second) { GeometryValueType precisionOfResult = optimizationRes.first[indexOfOptimizingObjective] - result; - if (precisionOfResult < storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision())) { + if (precisionOfResult < storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision())) { // Goal precision reached! return result; } else { @@ -176,7 +174,7 @@ namespace storm { thresholds[indexOfOptimizingObjective] = result + storm::utility::one<GeometryValueType>(); } WeightVector separatingVector = this->findSeparatingVector(thresholds); - this->updateWeightedPrecisionInImprovingPhase(separatingVector); + this->updateWeightedPrecisionInImprovingPhase(env, separatingVector); this->performRefinementStep(env, std::move(separatingVector)); } STORM_LOG_ERROR("Could not reach the desired precision: Exceeded maximum number of refinement steps"); @@ -185,11 +183,11 @@ namespace storm { template <class SparseModelType, typename GeometryValueType> - void SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::updateWeightedPrecisionInImprovingPhase(WeightVector const& weights) { + void SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::updateWeightedPrecisionInImprovingPhase(Environment const& env, WeightVector const& weights) { STORM_LOG_THROW(!storm::utility::isZero(weights[this->indexOfOptimizingObjective]), exceptions::UnexpectedException, "The chosen weight-vector gives zero weight for the objective that is to be optimized."); // If weighs[indexOfOptimizingObjective] is low, the computation of the weightVectorChecker needs to be more precise. // Our heuristic ensures that if p is the new vertex of the under-approximation, then max{ eps | p' = p + (0..0 eps 0..0) is in the over-approximation } <= multiobjective_precision/0.9 - GeometryValueType weightedPrecision = weights[this->indexOfOptimizingObjective] * storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()); + GeometryValueType weightedPrecision = weights[this->indexOfOptimizingObjective] * storm::utility::convertNumber<GeometryValueType>(env.modelchecker().multi().getPrecision()); // Normalize by division with the Euclidean Norm of the weight-vector weightedPrecision /= storm::utility::sqrt(storm::utility::vector::dotProduct(weights, weights)); weightedPrecision *= storm::utility::convertNumber<GeometryValueType>(0.9); diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h index 164a87f21..234e6f291 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.h @@ -45,7 +45,7 @@ namespace storm { * Updates the precision of the weightVectorChecker w.r.t. the provided weights */ void updateWeightedPrecisionInAchievabilityPhase(WeightVector const& weights); - void updateWeightedPrecisionInImprovingPhase(WeightVector const& weights); + void updateWeightedPrecisionInImprovingPhase(Environment const& env, WeightVector const& weights); /* * Given that the thresholds are achievable, this function further refines the approximations and returns the optimized value diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp index 2164665e0..ef7e50d80 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.cpp @@ -5,8 +5,7 @@ #include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/modelchecker/multiobjective/Objective.h" -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/storage/geometry/Hyperrectangle.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" @@ -126,9 +125,9 @@ namespace storm { } template <class SparseModelType, typename GeometryValueType> - bool SparsePcaaQuery<SparseModelType, GeometryValueType>::maxStepsPerformed() const { - return storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().isMaxStepsSet() && - this->refinementSteps.size() >= storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getMaxSteps(); + bool SparsePcaaQuery<SparseModelType, GeometryValueType>::maxStepsPerformed(Environment const& env) const { + return env.modelchecker().multi().isMaxStepsSet() && + this->refinementSteps.size() >= env.modelchecker().multi().getMaxSteps(); } @@ -191,7 +190,7 @@ namespace storm { } template<typename SparseModelType, typename GeometryValueType> - void SparsePcaaQuery<SparseModelType, GeometryValueType>::exportPlotOfCurrentApproximation(std::string const& destinationDir) const { + void SparsePcaaQuery<SparseModelType, GeometryValueType>::exportPlotOfCurrentApproximation(Environment const& env) const { STORM_LOG_ERROR_COND(objectives.size()==2, "Exporting plot requested but this is only implemented for the two-dimensional case."); @@ -223,35 +222,33 @@ namespace storm { std::vector<std::string> columnHeaders = {"x", "y"}; std::vector<std::vector<double>> pointsForPlotting; - underApproxVertices = transformedUnderApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(underApproxVertices.size()); - for(auto const& v : underApproxVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); - } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "underapproximation.csv", pointsForPlotting, columnHeaders); - - pointsForPlotting.clear(); - overApproxVertices = transformedOverApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(overApproxVertices.size()); - for(auto const& v : overApproxVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathUnderApproximation()) { + underApproxVertices = transformedUnderApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); + pointsForPlotting.reserve(underApproxVertices.size()); + for(auto const& v : underApproxVertices) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathUnderApproximation().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "overapproximation.csv", pointsForPlotting, columnHeaders); - pointsForPlotting.clear(); - pointsForPlotting.reserve(paretoPoints.size()); - for(auto const& v : paretoPoints) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathOverApproximation()) { + pointsForPlotting.clear(); + overApproxVertices = transformedOverApprox->intersection(boundariesAsPolytope)->getVerticesInClockwiseOrder(); + pointsForPlotting.reserve(overApproxVertices.size()); + for(auto const& v : overApproxVertices) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathOverApproximation().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "paretopoints.csv", pointsForPlotting, columnHeaders); - pointsForPlotting.clear(); - auto boundVertices = boundariesAsPolytope->getVerticesInClockwiseOrder(); - pointsForPlotting.reserve(4); - for(auto const& v : boundVertices) { - pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + if (env.modelchecker().multi().getPlotPathParetoPoints()) { + pointsForPlotting.clear(); + pointsForPlotting.reserve(paretoPoints.size()); + for(auto const& v : paretoPoints) { + pointsForPlotting.push_back(storm::utility::vector::convertNumericVector<double>(v)); + } + storm::utility::exportDataToCSVFile<double, std::string>(env.modelchecker().multi().getPlotPathParetoPoints().get(), pointsForPlotting, columnHeaders); } - storm::utility::exportDataToCSVFile<double, std::string>(destinationDir + "boundaries.csv", pointsForPlotting, columnHeaders); } #ifdef STORM_HAVE_CARL diff --git a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h index d92f0ccee..630503a08 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h +++ b/src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuery.h @@ -38,7 +38,7 @@ namespace storm { * Note that the approximations will be intersected with a (sufficiently large) hyperrectangle in order to ensure that the polytopes are bounded * This only works for 2 dimensional queries. */ - void exportPlotOfCurrentApproximation(std::string const& destinationDir) const; + void exportPlotOfCurrentApproximation(Environment const& env) const; protected: @@ -87,7 +87,7 @@ namespace storm { /* * Returns true iff the maximum number of refinement steps (as possibly specified in the settings) has been reached */ - bool maxStepsPerformed() const; + bool maxStepsPerformed(Environment const& env) const; /* * Transforms the given point (or polytope) to values w.r.t. the original model/formula (e.g. negates values for minimizing objectives). diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp index 8505ab035..d43db0d5c 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardMaPcaaWeightVectorChecker.cpp @@ -303,7 +303,7 @@ namespace storm { result->solver->setHasUniqueSolution(true); result->solver->setTrackScheduler(true); result->solver->setCachingEnabled(true); - auto req = result->solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, true); + auto req = result->solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, false); boost::optional<ValueType> lowerBound = this->computeWeightedResultBound(true, weightVector, storm::storage::BitVector(weightVector.size(), true)); if (lowerBound) { result->solver->setLowerBound(lowerBound.get()); @@ -314,7 +314,7 @@ namespace storm { result->solver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the MinMaxSolver was not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); result->solver->setRequirementsChecked(true); result->solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp index bd93a44ef..3dd8e8988 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.cpp @@ -179,22 +179,21 @@ namespace storm { solver->setTrackScheduler(true); solver->setHasUniqueSolution(true); solver->setOptimizationDirection(storm::solver::OptimizationDirection::Maximize); - auto req = solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize, true); - setBoundsToSolver(*solver, req.requiresLowerBounds(), req.requiresUpperBounds(), weightVector, objectivesWithNoUpperTimeBound, ecQuotient->matrix, ecQuotient->rowsWithSumLessOne, ecQuotient->auxChoiceValues); + auto req = solver->getRequirements(env, storm::solver::OptimizationDirection::Maximize); + setBoundsToSolver(*solver, req.lowerBounds(), req.upperBounds(), weightVector, objectivesWithNoUpperTimeBound, ecQuotient->matrix, ecQuotient->rowsWithSumLessOne, ecQuotient->auxChoiceValues); if (solver->hasLowerBound()) { req.clearLowerBounds(); } if (solver->hasUpperBound()) { req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solver->setRequirementsChecked(true); // Use the (0...0) vector as initial guess for the solution. std::fill(ecQuotient->auxStateValues.begin(), ecQuotient->auxStateValues.end(), storm::utility::zero<ValueType>()); solver->solveEquations(env, ecQuotient->auxStateValues, ecQuotient->auxChoiceValues); - this->weightedResult = std::vector<ValueType>(transitionMatrix.getRowGroupCount()); transformReducedSolutionToOriginalModel(ecQuotient->matrix, ecQuotient->auxStateValues, solver->getSchedulerChoices(), ecQuotient->ecqToOriginalChoiceMapping, ecQuotient->originalToEcqStateMapping, this->weightedResult, this->optimalChoices); @@ -267,17 +266,15 @@ namespace storm { solver->clearBounds(); storm::storage::BitVector submatrixRowsWithSumLessOne = deterministicMatrix.getRowFilter(maybeStates, maybeStates) % maybeStates; submatrixRowsWithSumLessOne.complement(); - this->setBoundsToSolver(*solver, req.requiresLowerBounds(), req.requiresUpperBounds(), objIndex, submatrix, submatrixRowsWithSumLessOne, b); + this->setBoundsToSolver(*solver, req.lowerBounds(), req.upperBounds(), objIndex, submatrix, submatrixRowsWithSumLessOne, b); if (solver->hasLowerBound()) { req.clearLowerBounds(); } if (solver->hasUpperBound()) { req.clearUpperBounds(); } - - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the LinearEquationSolver was not met."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); solver->solveEquations(env, x, b); - // Set the result for this objective accordingly storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x); } diff --git a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h index 2f0a27f33..b28a80ac6 100644 --- a/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h +++ b/src/storm/modelchecker/multiobjective/pcaa/StandardPcaaWeightVectorChecker.h @@ -37,8 +37,6 @@ namespace storm { StandardPcaaWeightVectorChecker(SparseMultiObjectivePreprocessorResult<SparseModelType> const& preprocessorResult); - virtual ~StandardPcaaWeightVectorChecker() = default; - /*! * - computes the optimal expected reward w.r.t. the weighted sum of the rewards of the individual objectives * - extracts the scheduler that induces this optimum diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp index 208dfcfd4..94b7ca4e1 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp @@ -26,12 +26,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { + HybridDtmcPrctlModelChecker<ModelType>::HybridDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -48,7 +43,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -56,7 +51,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -76,21 +71,21 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -98,7 +93,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } @@ -108,12 +103,12 @@ namespace storm { std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); } template<typename ModelType> std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel("")); } template class HybridDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::CUDD, double>>; diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h index 2b69dda58..d76ae69ac 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h @@ -18,7 +18,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridDtmcPrctlModelChecker(ModelType const& model); - explicit HybridDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -33,9 +32,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp index 12524aed6..6ae7ea4bc 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp @@ -32,12 +32,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { + HybridMdpPrctlModelChecker<ModelType>::HybridMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -64,7 +59,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -73,7 +68,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -95,7 +90,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> @@ -103,7 +98,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> @@ -111,7 +106,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -120,7 +115,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h index cff28c1ca..246a991d5 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h @@ -25,7 +25,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit HybridMdpPrctlModelChecker(ModelType const& model); - explicit HybridMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -38,9 +37,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp index 36e6eb9a2..4a746bf07 100644 --- a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp @@ -24,12 +24,7 @@ namespace storm { namespace modelchecker { template<typename SparseDtmcModelType> - SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename SparseDtmcModelType> - SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model) : SparsePropositionalModelChecker<SparseDtmcModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ValueType>>()) { + SparseDtmcPrctlModelChecker<SparseDtmcModelType>::SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model) : SparsePropositionalModelChecker<SparseDtmcModelType>(model) { // Intentionally left empty. } @@ -49,7 +44,7 @@ namespace storm { opInfo.bound = checkTask.getBound(); } auto formula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(checkTask.getFormula().asSharedPointer(), opInfo); - auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula, *linearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(!pathFormula.hasLowerBound() && pathFormula.hasUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have single upper time bound."); @@ -58,7 +53,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), checkTask.getHint()); std::unique_ptr<CheckResult> result = std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); return result; } @@ -69,7 +64,7 @@ namespace storm { storm::logic::NextFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(env, this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -80,7 +75,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -89,7 +84,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -103,11 +98,11 @@ namespace storm { opInfo.bound = checkTask.getBound(); } auto formula = std::make_shared<storm::logic::RewardOperatorFormula>(checkTask.getFormula().asSharedPointer(), checkTask.getRewardModel(), opInfo); - auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula, *linearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeRewardBoundedValues(env, this->getModel(), formula); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -116,7 +111,7 @@ namespace storm { std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -125,7 +120,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -134,15 +129,14 @@ namespace storm { storm::logic::StateFormula const& stateFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), nullptr, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), nullptr); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template<typename SparseDtmcModelType> std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), nullptr, *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), nullptr); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); - } template<typename SparseDtmcModelType> @@ -156,7 +150,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -171,7 +165,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } diff --git a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index c4284218a..ebc7d39a3 100644 --- a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseDtmcModelType::RewardModelType RewardModelType; explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model); - explicit SparseDtmcPrctlModelChecker(SparseDtmcModelType const& model, std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -34,9 +33,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeConditionalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::ConditionalFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp index bb51f372d..074a679b6 100644 --- a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp @@ -31,12 +31,7 @@ namespace storm { namespace modelchecker { template<typename SparseMdpModelType> - SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model) : SparsePropositionalModelChecker<SparseMdpModelType>(model), minMaxLinearEquationSolverFactory(std::make_unique<storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename SparseMdpModelType> - SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& minMaxLinearEquationSolverFactory) : SparsePropositionalModelChecker<SparseMdpModelType>(model), minMaxLinearEquationSolverFactory(std::move(minMaxLinearEquationSolverFactory)) { + SparseMdpPrctlModelChecker<SparseMdpModelType>::SparseMdpPrctlModelChecker(SparseMdpModelType const& model) : SparsePropositionalModelChecker<SparseMdpModelType>(model) { // Intentionally left empty. } @@ -67,7 +62,7 @@ namespace storm { } auto formula = std::make_shared<storm::logic::ProbabilityOperatorFormula>(checkTask.getFormula().asSharedPointer(), opInfo); helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(this->getModel(), formula); - auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates(), *minMaxLinearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(!pathFormula.hasLowerBound() && pathFormula.hasUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have single upper time bound."); @@ -76,7 +71,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), checkTask.getHint()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -87,7 +82,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -99,7 +94,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), checkTask.getHint()); std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values))); if (checkTask.isProduceSchedulersSet() && ret.scheduler) { result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler)); @@ -113,7 +108,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret))); } @@ -130,7 +125,7 @@ namespace storm { ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); - return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector()); } template<typename SparseMdpModelType> @@ -146,11 +141,11 @@ namespace storm { } auto formula = std::make_shared<storm::logic::RewardOperatorFormula>(checkTask.getFormula().asSharedPointer(), checkTask.getRewardModel(), opInfo); helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(this->getModel(), formula); - auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates(), *minMaxLinearEquationSolverFactory); + auto numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(env, checkTask.getOptimizationDirection(), rewardUnfolding, this->getModel().getInitialStates()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } else { STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } } @@ -160,7 +155,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } @@ -170,7 +165,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), *minMaxLinearEquationSolverFactory, checkTask.getHint()); + auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet(), checkTask.getHint()); std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values))); if (checkTask.isProduceSchedulersSet() && ret.scheduler) { result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler)); @@ -184,14 +179,14 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); - std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); } template<typename SparseMdpModelType> std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); - std::vector<ValueType> result = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel(), *minMaxLinearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getUniqueRewardModel()); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result))); } diff --git a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 84c6d7ddc..5ea9a010a 100644 --- a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { typedef typename SparseMdpModelType::RewardModelType RewardModelType; explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model); - explicit SparseMdpPrctlModelChecker(SparseMdpModelType const& model, std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>>&& MinMaxLinearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -33,9 +32,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::LongRunAverageRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> checkMultiObjectiveFormula(Environment const& env, CheckTask<storm::logic::MultiObjectiveFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving solvers for systems of linear equations that are the result of nondeterministic choices. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolverFactory<ValueType>> minMaxLinearEquationSolverFactory; }; } // namespace modelchecker } // namespace storm diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp index ec61ae28d..e8af30350 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp @@ -23,12 +23,7 @@ namespace storm { namespace modelchecker { template<typename ModelType> - SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ModelType> - SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::make_unique<storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType>>()) { + SymbolicDtmcPrctlModelChecker<ModelType>::SymbolicDtmcPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -45,7 +40,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -54,7 +49,7 @@ namespace storm { storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -76,7 +71,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType, ValueType>>(new SymbolicQuantitativeCheckResult<DdType, ValueType>(this->getModel().getReachableStates(), numericResult)); } @@ -84,7 +79,7 @@ namespace storm { std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType, ValueType>>(new SymbolicQuantitativeCheckResult<DdType, ValueType>(this->getModel().getReachableStates(), numericResult)); } @@ -92,7 +87,7 @@ namespace storm { std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } @@ -101,7 +96,7 @@ namespace storm { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); return std::make_unique<SymbolicQuantitativeCheckResult<DdType, ValueType>>(this->getModel().getReachableStates(), numericResult); } diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h index f0f09d965..311669bf7 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h @@ -16,7 +16,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit SymbolicDtmcPrctlModelChecker(ModelType const& model); - explicit SymbolicDtmcPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -28,9 +27,6 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp index e80ebaec8..3c813d001 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp @@ -21,13 +21,9 @@ namespace storm { namespace modelchecker { - template<typename ModelType> - SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } template<typename ModelType> - SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model), linearEquationSolverFactory(new storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>()) { + SymbolicMdpPrctlModelChecker<ModelType>::SymbolicMdpPrctlModelChecker(ModelType const& model) : SymbolicPropositionalModelChecker<ModelType>(model) { // Intentionally left empty. } @@ -45,7 +41,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -54,7 +50,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet()); } template<typename ModelType> @@ -76,7 +72,7 @@ namespace storm { std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula()); SymbolicQualitativeCheckResult<DdType> const& leftResult = leftResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& rightResult = rightResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), pathFormula.getNonStrictUpperBound<uint64_t>()); } template<typename ModelType> @@ -84,7 +80,7 @@ namespace storm { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getNonStrictBound<uint64_t>()); } template<typename ModelType> @@ -92,7 +88,7 @@ namespace storm { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>()); } template<typename ModelType> @@ -101,7 +97,7 @@ namespace storm { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); - return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), *this->linearEquationSolverFactory); + return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(env, checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector()); } template class SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>; diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h index a36358ba8..b116af0fc 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h @@ -17,7 +17,6 @@ namespace storm { static const storm::dd::DdType DdType = ModelType::DdType; explicit SymbolicMdpPrctlModelChecker(ModelType const& model); - explicit SymbolicMdpPrctlModelChecker(ModelType const& model, std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>>&& linearEquationSolverFactory); // The implemented methods of the AbstractModelChecker interface. virtual bool canHandle(CheckTask<storm::logic::Formula, ValueType> const& checkTask) const override; @@ -28,11 +27,7 @@ namespace storm { virtual std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override; - - private: - // An object that is used for retrieving linear equation solvers. - std::unique_ptr<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType>> linearEquationSolverFactory; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp index 280c5aaff..659a17cab 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp @@ -3,6 +3,7 @@ #include "storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/storage/dd/DdManager.h" #include "storm/storage/dd/Add.h" @@ -19,17 +20,18 @@ #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" +#include "storm/utility/Stopwatch.h" + #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/exceptions/UncheckedRequirementException.h" - namespace storm { namespace modelchecker { namespace helper { template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states."); @@ -45,8 +47,12 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -62,10 +68,11 @@ namespace storm { storm::dd::Add<DdType, ValueType> subvector = submatrix * prob1StatesAsColumn; subvector = subvector.sumAbstract(model.getColumnVariables()); + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); req.clearUpperBounds(); - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); // Check whether we need to create an equation system. bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; @@ -81,9 +88,12 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::convertNumber<ValueType>(0.5)); // Translate the symbolic matrix/vector to their explicit representations and solve the equation system. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitSubmatrix)); solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>()); solver->solveEquations(env, x, b); @@ -97,8 +107,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -110,7 +120,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound); @@ -120,8 +130,12 @@ namespace storm { // If there are maybe states, we need to perform matrix-vector multiplications. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -142,12 +156,15 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitSubmatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, &b, stepBound); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitSubmatrix); + multiplier->repeatedMultiply(env, x, &b, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getReachableStates() && !maybeStates, psiStates.template toAdd<ValueType>(), maybeStates, odd, x)); } else { @@ -156,10 +173,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch(true); + // Create the ODD for the translation between symbolic and explicit storage. storm::dd::Odd odd = model.getReachableStates().createOdd(); @@ -168,36 +187,42 @@ namespace storm { // Translate the symbolic matrix to its explicit representations. storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, nullptr, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiply(env, x, nullptr, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Compute the reward vector to add in each step based on the available reward models. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); - // Create the ODD for the translation between symbolic and explicit storage. - storm::dd::Odd odd = model.getReachableStates().createOdd(); - // Create the solution vector. std::vector<ValueType> x(model.getNumberOfStates(), storm::utility::zero<ValueType>()); + + storm::utility::Stopwatch conversionWatch(true); + + // Create the ODD for the translation between symbolic and explicit storage. + storm::dd::Odd odd = model.getReachableStates().createOdd(); // Translate the symbolic matrix/vector to their explicit representations. storm::storage::SparseMatrix<ValueType> explicitMatrix = transitionMatrix.toMatrix(odd, odd); std::vector<ValueType> b = totalRewardVector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(x, &b, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiply(env, x, &b, stepBound); // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); @@ -217,7 +242,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -237,8 +262,12 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -253,16 +282,17 @@ namespace storm { // Check the requirements of a linear equation solver // We might need to compute upper reward bounds for which the oneStepTargetProbabilities are needed. boost::optional<storm::dd::Add<DdType, ValueType>> oneStepTargetProbs; + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; auto req = linearEquationSolverFactory.getRequirements(env); req.clearLowerBounds(); - if (req.requiresUpperBounds()) { + if (req.upperBounds()) { storm::dd::Add<DdType, ValueType> targetStatesAsColumn = targetStates.template toAdd<ValueType>(); targetStatesAsColumn = targetStatesAsColumn.swapVariables(model.getRowColumnMetaVariablePairs()); oneStepTargetProbs = submatrix * targetStatesAsColumn; oneStepTargetProbs = oneStepTargetProbs->sumAbstract(model.getColumnVariables()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement of the linear equation solver could not be matched."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); // Check whether we need to create an equation system. bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; @@ -278,9 +308,12 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::convertNumber<ValueType>(0.5)); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); storm::storage::SparseMatrix<ValueType> explicitSubmatrix = submatrix.toMatrix(odd, odd); std::vector<ValueType> b = subvector.toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Create the upper bounds vector if one was requested. boost::optional<std::vector<ValueType>> upperBounds; if (oneStepTargetProbs) { @@ -306,22 +339,28 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates) { // Create ODD for the translation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); - std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, targetStates.toVector(odd), linearEquationSolverFactory); + std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageProbabilities(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, targetStates.toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridDtmcPrctlHelper<DdType, ValueType>::computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel) { // Create ODD for the translation. + storm::utility::Stopwatch conversionWatch(true); storm::dd::Odd odd = model.getReachableStates().createOdd(); storm::storage::SparseMatrix<ValueType> explicitProbabilityMatrix = model.getTransitionMatrix().toMatrix(odd, odd); - - std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(model.getTransitionMatrix(), model.getColumnVariables()).toVector(odd), linearEquationSolverFactory); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + std::vector<ValueType> result = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeLongRunAverageRewards(env, storm::solver::SolveGoal<ValueType>(), explicitProbabilityMatrix, rewardModel.getTotalRewardVector(model.getTransitionMatrix(), model.getColumnVariables()).toVector(odd)); return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), std::move(odd), std::move(result))); } diff --git a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h index 7bbee1795..67896c8bc 100644 --- a/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h @@ -23,23 +23,23 @@ namespace storm { public: typedef typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); - static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& targetStates); - static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeLongRunAverageRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel); }; diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp index ad1903d1c..cca377b9d 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp @@ -21,6 +21,9 @@ #include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" #include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" + +#include "storm/utility/Stopwatch.h" #include "storm/exceptions/InvalidPropertyException.h" #include "storm/exceptions/UncheckedRequirementException.h" @@ -122,7 +125,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. storm::dd::Bdd<DdType> transitionMatrixBdd = transitionMatrix.notZero(); @@ -146,23 +149,24 @@ namespace storm { // If we minimize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Minimize; // Check for requirements of the solver early so we can adjust the maybe state computation accordingly. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir, true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; SolverRequirementsData<ValueType> solverRequirementsData; bool extendMaybeStates = false; - if (!clearedRequirements.empty()) { - if (clearedRequirements.requiresNoEndComponents()) { + if (clearedRequirements.hasEnabledRequirement()) { + if (clearedRequirements.noEndComponents()) { STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearNoEndComponents(); } - if (clearedRequirements.requiresValidInitialScheduler()) { + if (clearedRequirements.validInitialScheduler()) { STORM_LOG_DEBUG("Scheduling valid scheduler computation, because the solver requires it."); clearedRequirements.clearValidInitialScheduler(); } clearedRequirements.clearBounds(); - STORM_LOG_THROW(clearedRequirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked."); } storm::dd::Bdd<DdType> extendedMaybeStates = maybeStates; @@ -172,8 +176,12 @@ namespace storm { extendedMaybeStates |= maybeStates.relationalProduct(transitionMatrixBdd.existsAbstract(model.getNondeterminismVariables()), model.getRowVariables(), model.getColumnVariables()); } + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = extendedMaybeStates.createOdd(); + conversionWatch.stop(); // Convert the maybe states BDD to an ADD. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -189,20 +197,21 @@ namespace storm { submatrix *= extendedMaybeStates.template toAdd<ValueType>().swapVariables(model.getRowColumnMetaVariablePairs()); // Only translate the matrix for now. + conversionWatch.start(); explicitRepresentation.first = submatrix.toMatrix(model.getNondeterminismVariables(), odd, odd); // Get all original maybe states in the extended matrix. solverRequirementsData.properMaybeStates = maybeStates.toVector(odd); - + // Compute the target states within the set of extended maybe states. storm::storage::BitVector targetStates = (extendedMaybeStates && statesWithProbability01.second).toVector(odd); - + conversionWatch.stop(); + // Eliminate the end components and remove the states that are not interesting (target or non-filter). eliminateEndComponentsAndExtendedStatesUntilProbabilities(explicitRepresentation, solverRequirementsData, targetStates); // The solution becomes unique after end components have been eliminated. uniqueSolution = true; - } else { // Then compute the vector that contains the one-step probabilities to a state with probability 1 for all // maybe states. @@ -215,13 +224,17 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Translate the symbolic matrix/vector to their explicit representations and solve the equation system. + conversionWatch.start(); explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); + conversionWatch.stop(); - if (requirements.requiresValidInitialScheduler()) { + if (requirements.validInitialScheduler()) { solverRequirementsData.initialScheduler = computeValidInitialSchedulerForUntilProbabilities<ValueType>(explicitRepresentation.first, explicitRepresentation.second); } } + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Create the solution vector. std::vector<ValueType> x(explicitRepresentation.first.getRowGroupCount(), storm::utility::zero<ValueType>()); @@ -238,7 +251,7 @@ namespace storm { solver->solveEquations(env, dir, x, explicitRepresentation.second); // If we included some target and non-filter states in the ODD, we need to expand the result from the solver. - if (requirements.requiresNoEndComponents() && solverRequirementsData.ecInformation) { + if (requirements.noEndComponents() && solverRequirementsData.ecInformation) { std::vector<ValueType> extendedVector(solverRequirementsData.properMaybeStates.getNumberOfSetBits()); solverRequirementsData.ecInformation.get().setValues(extendedVector, solverRequirementsData.properMaybeStates, x); x = std::move(extendedVector); @@ -258,8 +271,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Maximize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Maximize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -270,7 +283,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0; @@ -285,8 +298,12 @@ namespace storm { // If there are maybe states, we need to perform matrix-vector multiplications. if (!maybeStates.isZero()) { + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = maybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -307,10 +324,13 @@ namespace storm { std::vector<ValueType> x(maybeStates.getNonZeroCount(), storm::utility::zero<ValueType>()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd); - - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitRepresentation.first)); - solver->repeatedMultiply(env, dir, x, &explicitRepresentation.second, stepBound); + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); + multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new storm::modelchecker::HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getReachableStates() && !maybeStates, psiStates.template toAdd<ValueType>(), maybeStates, odd, x)); @@ -320,10 +340,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. storm::dd::Odd odd = model.getReachableStates().createOdd(); @@ -332,36 +354,42 @@ namespace storm { // Create the solution vector (and initialize it to the state rewards of the model). std::vector<ValueType> x = rewardModel.getStateRewardVector().toVector(odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitMatrix)); - solver->repeatedMultiply(env, dir, x, nullptr, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitMatrix); + multiplier->repeatedMultiplyAndReduce(env, dir, x, nullptr, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Compute the reward vector to add in each step based on the available reward models. storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); - // Create the ODD for the translation between symbolic and explicit storage. - storm::dd::Odd odd = model.getReachableStates().createOdd(); - // Create the solution vector. std::vector<ValueType> x(model.getNumberOfStates(), storm::utility::zero<ValueType>()); + + storm::utility::Stopwatch conversionWatch(true); + + // Create the ODD for the translation between symbolic and explicit storage. + storm::dd::Odd odd = model.getReachableStates().createOdd(); // Translate the symbolic matrix/vector to their explicit representations. std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = transitionMatrix.toMatrixVector(totalRewardVector, model.getNondeterminismVariables(), odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Perform the matrix-vector multiplication. - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, std::move(explicitRepresentation.first)); - solver->repeatedMultiply(env, dir, x, &explicitRepresentation.second, stepBound); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, explicitRepresentation.first); + multiplier->repeatedMultiplyAndReduce(env, dir, x, &explicitRepresentation.second, stepBound); + // Return a hybrid check result that stores the numerical values explicitly. return std::unique_ptr<CheckResult>(new HybridQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), model.getManager().getBddZero(), model.getManager().template getAddZero<ValueType>(), model.getReachableStates(), odd, x)); } @@ -487,7 +515,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -517,34 +545,39 @@ namespace storm { // If we maximize, we know that the solution to the equation system is unique. bool uniqueSolution = dir == storm::solver::OptimizationDirection::Maximize; // Check for requirements of the solver this early so we can adapt the maybe states accordingly. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir, true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env, uniqueSolution, dir); storm::solver::MinMaxLinearEquationSolverRequirements clearedRequirements = requirements; bool extendMaybeStates = false; - if (!clearedRequirements.empty()) { - if (clearedRequirements.requiresNoEndComponents()) { + if (clearedRequirements.hasEnabledRequirement()) { + if (clearedRequirements.noEndComponents()) { STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearNoEndComponents(); } - if (clearedRequirements.requiresValidInitialScheduler()) { + if (clearedRequirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearValidInitialScheduler(); } clearedRequirements.clearLowerBounds(); - if (clearedRequirements.requiresUpperBounds()) { + if (clearedRequirements.upperBounds()) { STORM_LOG_DEBUG("Computing upper bounds, because the solver requires it."); extendMaybeStates = true; clearedRequirements.clearUpperBounds(); } - STORM_LOG_THROW(clearedRequirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!clearedRequirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + clearedRequirements.getEnabledRequirementsAsString() + " not checked."); } // Compute the set of maybe states that we are required to keep in the translation to explicit. storm::dd::Bdd<DdType> requiredMaybeStates = extendMaybeStates ? maybeStatesWithTargetStates : maybeStates; + storm::utility::Stopwatch conversionWatch; + // Create the ODD for the translation between symbolic and explicit storage. + conversionWatch.start(); storm::dd::Odd odd = requiredMaybeStates.createOdd(); + conversionWatch.stop(); // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -559,31 +592,36 @@ namespace storm { // Then compute the reward vector to use in the computation. storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, choiceFilterAdd, submatrix, model.getColumnVariables()); + conversionWatch.start(); std::vector<uint_fast64_t> rowGroupSizes = (submatrix.notZero().existsAbstract(model.getColumnVariables()) || subvector.notZero()).template toAdd<uint_fast64_t>().sumAbstract(model.getNondeterminismVariables()).toVector(odd); + conversionWatch.stop(); // Finally cut away all columns targeting non-maybe states (or non-(maybe or target) states, respectively). submatrix *= extendMaybeStates ? maybeStatesWithTargetStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>() : maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Translate the symbolic matrix/vector to their explicit representations. + conversionWatch.start(); std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(std::move(rowGroupSizes), subvector, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), odd, odd); - + conversionWatch.stop(); + STORM_LOG_INFO("Converting symbolic matrix/vector to explicit representation done in " << conversionWatch.getTimeInMilliseconds() << "ms."); + // Fulfill the solver's requirements. SolverRequirementsData<ValueType> solverRequirementsData; if (extendMaybeStates) { storm::storage::BitVector targetStates = computeTargetStatesForReachabilityRewardsFromExplicitRepresentation(explicitRepresentation.first); solverRequirementsData.properMaybeStates = ~targetStates; - if (requirements.requiresNoEndComponents()) { - eliminateEndComponentsAndTargetStatesReachabilityRewards(explicitRepresentation, solverRequirementsData, targetStates, requirements.requiresUpperBounds()); + if (requirements.noEndComponents()) { + eliminateEndComponentsAndTargetStatesReachabilityRewards(explicitRepresentation, solverRequirementsData, targetStates, requirements.upperBounds()); // The solution becomes unique after end components have been eliminated. uniqueSolution = true; } else { - if (requirements.requiresValidInitialScheduler()) { + if (requirements.validInitialScheduler()) { // Compute a valid initial scheduler. solverRequirementsData.initialScheduler = computeValidInitialSchedulerForReachabilityRewards<ValueType>(explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates); } - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { solverRequirementsData.oneStepTargetProbabilities = computeOneStepTargetProbabilitiesFromExtendedExplicitRepresentation(explicitRepresentation.first, solverRequirementsData.properMaybeStates, targetStates); } @@ -603,7 +641,7 @@ namespace storm { solver->setHasUniqueSolution(uniqueSolution); // If the solver requires upper bounds, compute them now. - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { setUpperRewardBounds(*solver, dir, explicitRepresentation.first, explicitRepresentation.second, solverRequirementsData.oneStepTargetProbabilities.get()); } @@ -619,7 +657,7 @@ namespace storm { solver->solveEquations(env, dir, x, explicitRepresentation.second); // If we eliminated end components, we need to extend the solution vector. - if (requirements.requiresNoEndComponents() && solverRequirementsData.ecInformation) { + if (requirements.noEndComponents() && solverRequirementsData.ecInformation) { std::vector<ValueType> extendedVector(solverRequirementsData.properMaybeStates.getNumberOfSetBits()); solverRequirementsData.ecInformation.get().setValues(extendedVector, solverRequirementsData.properMaybeStates, x); x = std::move(extendedVector); diff --git a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h index 224830220..78ee1f7d3 100644 --- a/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h @@ -24,19 +24,19 @@ namespace storm { public: typedef typename storm::models::symbolic::NondeterministicModel<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative); }; } diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp index fd52e4437..03d3fb1a0 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp @@ -11,6 +11,7 @@ #include "storm/storage/ConsecutiveUint64DynamicPriorityQueue.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/hints/ExplicitModelCheckerHint.h" @@ -23,6 +24,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/utility/Stopwatch.h" #include "storm/utility/ProgressMeasurement.h" @@ -41,7 +43,7 @@ namespace storm { namespace modelchecker { namespace helper { template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); // If we identify the states that have probability 0 of reaching the target states, we can exclude them in the further analysis. @@ -68,10 +70,9 @@ namespace storm { // Create the vector with which to multiply. std::vector<ValueType> subresult(maybeStates.getNumberOfSetBits()); - // Perform the matrix vector multiplication as often as required by the formula bound. - goal.restrictRelevantValues(maybeStates); - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix), storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(subresult, &b, stepBound); + // Perform the matrix vector multiplication + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix); + multiplier->repeatedMultiply(env, subresult, &b, stepBound); // Set the values of the resulting vector accordingly. storm::utility::vector::setVectorValues(result, maybeStates, subresult); @@ -110,14 +111,15 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> analyzeNonTrivialDtmcEpochModel(Environment const& env, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>& linEqSolver, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { + std::vector<ValueType> analyzeNonTrivialDtmcEpochModel(Environment const& env, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>& linEqSolver, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { // Update some data for the case that the Matrix has changed if (epochModel.epochMatrixChanged) { x.assign(epochModel.epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); - linEqSolver = linearEquationSolverFactory.create(env, epochModel.epochMatrix, storm::solver::LinearEquationSolverTask::SolveEquations); + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; + linEqSolver = linearEquationSolverFactory.create(env, epochModel.epochMatrix); linEqSolver->setCachingEnabled(true); - auto req = linEqSolver->getRequirements(env, storm::solver::LinearEquationSolverTask::SolveEquations); + auto req = linEqSolver->getRequirements(env); if (lowerBound) { linEqSolver->setLowerBound(lowerBound.get()); req.clearLowerBounds(); @@ -126,7 +128,7 @@ namespace storm { linEqSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); } // Prepare the right hand side of the equation system @@ -149,13 +151,13 @@ namespace storm { } template<> - std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<storm::RationalFunction> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& linearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<storm::RationalFunction> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type."); return std::map<storm::storage::sparse::state_type, storm::RationalFunction>(); } template<typename ValueType, typename RewardModelType> - std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) { storm::utility::Stopwatch swAll(true), swBuild, swCheck; storm::modelchecker::helper::rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true> rewardUnfolding(model, rewardBoundedFormula); @@ -179,7 +181,8 @@ namespace storm { // In case of cdf export we store the necessary data. std::vector<std::vector<ValueType>> cdfData; - // Set the correct equation problem format + // Set the correct equation problem format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; rewardUnfolding.setEquationSystemFormatForEpochModel(linearEquationSolverFactory.getEquationProblemFormat(preciseEnv)); bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(preciseEnv) == solver::LinearEquationSolverProblemFormat::EquationSystem; @@ -195,7 +198,7 @@ namespace storm { if ((convertToEquationSystem && epochModel.epochMatrix.isIdentityMatrix()) || (!convertToEquationSystem && epochModel.epochMatrix.getEntryCount() == 0)) { rewardUnfolding.setSolutionForCurrentEpoch(analyzeTrivialDtmcEpochModel<ValueType>(epochModel)); } else { - rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialDtmcEpochModel<ValueType>(preciseEnv, epochModel, x, b, linEqSolver, linearEquationSolverFactory, lowerBound, upperBound)); + rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialDtmcEpochModel<ValueType>(preciseEnv, epochModel, x, b, linEqSolver, lowerBound, upperBound)); } swCheck.stop(); if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet() && !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) { @@ -242,7 +245,7 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); @@ -290,6 +293,7 @@ namespace storm { // In this case we have have to compute the probabilities. // Check whether we need to convert the input to equation system format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; // We can eliminate the rows and columns from the original transition probability matrix. @@ -328,9 +332,9 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative) { goal.oneMinus(); - std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative, linearEquationSolverFactory); + std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative); for (auto& entry : result) { entry = storm::utility::one<ValueType>() - entry; } @@ -338,19 +342,19 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { // Create the vector with which to multiply and initialize it correctly. std::vector<ValueType> result(transitionMatrix.getRowCount()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); // Perform one single matrix-vector multiplication. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(result, nullptr, 1); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->multiply(env, result, nullptr, result); return result; } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Initialize result to the null vector. std::vector<ValueType> result(transitionMatrix.getRowCount()); @@ -358,14 +362,14 @@ namespace storm { std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix); // Perform the matrix vector multiplication as often as required by the formula bound. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, transitionMatrix, storm::solver::LinearEquationSolverTask::Multiply); - solver->repeatedMultiply(result, &totalRewardVector, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiply(env, result, &totalRewardVector, stepBound); return result; } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount) { // Only compute the result if the model has a state-based reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -373,19 +377,28 @@ namespace storm { std::vector<ValueType> result = rewardModel.getStateRewardVector(); // Perform the matrix vector multiplication as often as required by the formula bound. - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(result, nullptr, stepCount); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiply(env, result, nullptr, stepCount); + return result; } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { - return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory, hint); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) { + + return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, + [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { + return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); + }, + targetStates, qualitative, + [&] () { + return rewardModel.getStatesWithZeroReward(transitionMatrix); + }, + hint); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) { return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) { @@ -393,7 +406,11 @@ namespace storm { storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector); return result; }, - targetStates, qualitative, linearEquationSolverFactory, hint); + targetStates, qualitative, + [&] () { + return storm::utility::vector::filterZero(totalStateRewardVector); + }, + hint); } // This function computes an upper bound on the reachability rewards (see Baier et al, CAV'17). @@ -410,24 +427,32 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>()); + // Determine which states have reward zero + storm::storage::BitVector rew0States; + if (storm::settings::getModule<storm::settings::modules::ModelCheckerSettings>().isFilterRewZeroSet()) { + rew0States = storm::utility::graph::performProb1(backwardTransitions, zeroRewardStatesGetter(), targetStates); + } else { + rew0States = targetStates; + } + // Determine which states have a reward that is less than infinity. storm::storage::BitVector maybeStates; if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) { maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates(); - storm::utility::vector::setVectorValues(result, ~(maybeStates | targetStates), storm::utility::infinity<ValueType>()); + storm::utility::vector::setVectorValues(result, ~(maybeStates | rew0States), storm::utility::infinity<ValueType>()); - STORM_LOG_INFO("Preprocessing: " << targetStates.getNumberOfSetBits() << " target states (" << maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << rew0States.getNumberOfSetBits() << " States with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining)."); } else { storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true); - storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, targetStates); + storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, rew0States); infinityStates.complement(); - maybeStates = ~(targetStates | infinityStates); + maybeStates = ~(rew0States | infinityStates); - STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << targetStates.getNumberOfSetBits() << " target states (" << maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << rew0States.getNumberOfSetBits() << " states with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining)."); storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::infinity<ValueType>()); } @@ -440,6 +465,7 @@ namespace storm { } else { if (!maybeStates.empty()) { // Check whether we need to convert the input to equation system format. + storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory; bool convertToEquationSystem = linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem; // In this case we have to compute the reward values for the remaining states. @@ -461,11 +487,11 @@ namespace storm { storm::solver::LinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env); boost::optional<std::vector<ValueType>> upperRewardBounds; requirements.clearLowerBounds(); - if (requirements.requiresUpperBounds()) { - upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, targetStates)); + if (requirements.upperBounds()) { + upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States)); requirements.clearUpperBounds(); } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "There are unchecked requirements of the solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); // If necessary, convert the matrix from the fixpoint notation to the form needed for the equation system. if (convertToEquationSystem) { @@ -492,27 +518,27 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, std::move(goal), transitionMatrix, psiStates, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates) { + return SparseCtmcCslHelper::computeLongRunAverageProbabilities<ValueType>(env, std::move(goal), transitionMatrix, psiStates, nullptr); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, std::move(goal), transitionMatrix, rewardModel, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel) { + return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType, RewardModelType>(env, std::move(goal), transitionMatrix, rewardModel, nullptr); } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { - return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, std::move(goal), transitionMatrix, stateRewards, nullptr, linearEquationSolverFactory); + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards) { + return SparseCtmcCslHelper::computeLongRunAverageRewards<ValueType>(env, std::move(goal), transitionMatrix, stateRewards, nullptr); } template<typename ValueType, typename RewardModelType> - typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards) { BaierTransformedModel result; // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined. - std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory); + std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false); result.beforeStates = storm::storage::BitVector(targetStates.size(), true); uint_fast64_t state = 0; @@ -644,13 +670,13 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative) { // Prepare result vector. std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); if (!conditionStates.empty()) { - BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none, linearEquationSolverFactory); + BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none); if (transformedModel.noTargetStates) { storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); @@ -668,7 +694,7 @@ namespace storm { newRelevantValues = transformedModel.getNewRelevantStates(); } goal.setRelevantValues(std::move(newRelevantValues)); - std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative); storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities); } @@ -678,12 +704,12 @@ namespace storm { } template<typename ValueType, typename RewardModelType> - std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { + std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative) { // Prepare result vector. std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>()); if (!conditionStates.empty()) { - BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix), linearEquationSolverFactory); + BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix)); if (transformedModel.noTargetStates) { storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>()); @@ -701,7 +727,7 @@ namespace storm { newRelevantValues = transformedModel.getNewRelevantStates(); } goal.setRelevantValues(std::move(newRelevantValues)); - std::vector<ValueType> conditionalRewards = computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory); + std::vector<ValueType> conditionalRewards = computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative); storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards); } } diff --git a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h index ead15de74..a4e2882bc 100644 --- a/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h @@ -28,36 +28,36 @@ namespace storm { class SparseDtmcPrctlHelper { public: - static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula); - static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates); - static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative); - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount); - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector, storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates); - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel); - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& stateRewards); - static std::vector<ValueType> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative); - static std::vector<ValueType> computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static std::vector<ValueType> computeConditionalRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative); private: - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); struct BaierTransformedModel { BaierTransformedModel() : noTargetStates(false) { @@ -74,7 +74,7 @@ namespace storm { bool noTargetStates; }; - static BaierTransformedModel computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); + static BaierTransformedModel computeBaierTransformation(Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards); }; } } diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp index dce686091..8c13c73c4 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp @@ -21,9 +21,11 @@ #include "storm/storage/Scheduler.h" #include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/LpSolver.h" #include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" @@ -48,7 +50,7 @@ namespace storm { namespace helper { template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint) { std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); // Determine the states that have 0 probability of reaching the target states. @@ -74,9 +76,8 @@ namespace storm { // Create the vector with which to multiply. std::vector<ValueType> subresult(maybeStates.getNumberOfSetBits()); - goal.restrictRelevantValues(maybeStates); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix)); - solver->repeatedMultiply(env, subresult, &b, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, submatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), subresult, &b, stepBound); // Set the values of the resulting vector accordingly. storm::utility::vector::setVectorValues(result, maybeStates, subresult); @@ -137,11 +138,12 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> analyzeNonTrivialMdpEpochModel(Environment const& env, OptimizationDirection dir, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>& minMaxSolver, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { + std::vector<ValueType> analyzeNonTrivialMdpEpochModel(Environment const& env, OptimizationDirection dir, typename rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>::EpochModel& epochModel, std::vector<ValueType>& x, std::vector<ValueType>& b, std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>& minMaxSolver, boost::optional<ValueType> const& lowerBound, boost::optional<ValueType> const& upperBound) { // Update some data for the case that the Matrix has changed if (epochModel.epochMatrixChanged) { x.assign(epochModel.epochMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; minMaxSolver = minMaxLinearEquationSolverFactory.create(env, epochModel.epochMatrix); minMaxSolver->setHasUniqueSolution(); minMaxSolver->setOptimizationDirection(dir); @@ -156,7 +158,7 @@ namespace storm { minMaxSolver->setUpperBound(upperBound.get()); req.clearUpperBounds(); } - STORM_LOG_THROW(req.empty(), storm::exceptions::UncheckedRequirementException, "At least one requirement was not checked."); + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); minMaxSolver->setRequirementsChecked(); } else { auto choicesTmp = minMaxSolver->getSchedulerChoices(); @@ -183,7 +185,7 @@ namespace storm { } template<typename ValueType> - std::map<storm::storage::sparse::state_type, ValueType> SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::map<storm::storage::sparse::state_type, ValueType> SparseMdpPrctlHelper<ValueType>::computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates) { storm::utility::Stopwatch swAll(true), swBuild, swCheck; // Get lower and upper bounds for the solution. @@ -217,7 +219,7 @@ namespace storm { if (epochModel.epochMatrix.getEntryCount() == 0) { rewardUnfolding.setSolutionForCurrentEpoch(analyzeTrivialMdpEpochModel<ValueType>(dir, epochModel)); } else { - rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialMdpEpochModel<ValueType>(preciseEnv, dir, epochModel, x, b, minMaxSolver, minMaxLinearEquationSolverFactory, lowerBound, upperBound)); + rewardUnfolding.setSolutionForCurrentEpoch(analyzeNonTrivialMdpEpochModel<ValueType>(preciseEnv, dir, epochModel, x, b, minMaxSolver, lowerBound, upperBound)); } swCheck.stop(); if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportCdfSet() && !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) { @@ -265,14 +267,14 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) { // Create the vector with which to multiply and initialize it correctly. std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(env, transitionMatrix); - solver->repeatedMultiply(env, dir, result, nullptr, 1); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->multiplyAndReduce(env, dir, result, nullptr, result); return result; } @@ -422,7 +424,7 @@ namespace storm { } template<typename ValueType> - SparseMdpHintType<ValueType> computeHints(Environment const& env, SolutionType const& type, ModelCheckerHint const& hint, storm::OptimizationDirection const& dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) { + SparseMdpHintType<ValueType> computeHints(Environment const& env, SolutionType const& type, ModelCheckerHint const& hint, storm::OptimizationDirection const& dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& maybeStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices = boost::none) { SparseMdpHintType<ValueType> result; // The solution to the min-max equation system is unique if we minimize until probabilities or @@ -433,11 +435,11 @@ namespace storm { // Check for requirements of the solver. bool hasSchedulerHint = hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasSchedulerHint(); - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, !hasSchedulerHint); - if (!requirements.empty()) { - + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, result.uniqueSolution, dir, hasSchedulerHint); + if (requirements.hasEnabledRequirement()) { // If the solver still requires no end-components, we have to eliminate them later. - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { STORM_LOG_ASSERT(!result.hasUniqueSolution(), "The solver requires to eliminate the end components although the solution is already assumed to be unique."); STORM_LOG_DEBUG("Scheduling EC elimination, because the solver requires it."); result.eliminateEndComponents = true; @@ -447,7 +449,7 @@ namespace storm { } // If the solver requires an initial scheduler, compute one now. - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); result.schedulerHint = computeValidSchedulerHint(env, type, transitionMatrix, backwardTransitions, maybeStates, phiStates, targetStates); requirements.clearValidInitialScheduler(); @@ -459,11 +461,11 @@ namespace storm { } else if (type == SolutionType::ExpectedRewards) { requirements.clearLowerBounds(); } - if (requirements.requiresUpperBounds()) { + if (requirements.upperBounds()) { result.computeUpperBounds = true; requirements.clearUpperBounds(); } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "There are unchecked requirements of the solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } else { STORM_LOG_DEBUG("Solver has no requirements."); } @@ -515,12 +517,13 @@ namespace storm { }; template<typename ValueType> - MaybeStateResult<ValueType> computeValuesForMaybeStates(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, SparseMdpHintType<ValueType>& hint) { + MaybeStateResult<ValueType> computeValuesForMaybeStates(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType>&& submatrix, std::vector<ValueType> const& b, bool produceScheduler, SparseMdpHintType<ValueType>& hint) { // Initialize the solution vector. std::vector<ValueType> x = hint.hasValueHint() ? std::move(hint.getValueHint()) : std::vector<ValueType>(submatrix.getRowGroupCount(), hint.hasLowerResultBound() ? hint.getLowerResultBound() : storm::utility::zero<ValueType>()); // Set up the solver. + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, std::move(submatrix)); solver->setRequirementsChecked(); solver->setHasUniqueSolution(hint.hasUniqueSolution()); @@ -546,7 +549,7 @@ namespace storm { if (solver->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { auto resultIt = x.begin(); for (auto const& entry : solver->getUpperBounds()) { - STORM_LOG_ASSERT(*resultIt <= entry, "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); + STORM_LOG_ASSERT(*resultIt <= entry + env.solver().minMax().getPrecision(), "Expecting result value for state " << std::distance(x.begin(), resultIt) << " to be <= " << entry << ", but got " << *resultIt << "."); ++resultIt; } } @@ -702,7 +705,7 @@ namespace storm { } template<typename ValueType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) { STORM_LOG_THROW(!qualitative || !produceScheduler, storm::exceptions::InvalidSettingsException, "Cannot produce scheduler when performing qualitative model checking only."); // Prepare resulting vector. @@ -732,7 +735,7 @@ namespace storm { // In this case we have have to compute the remaining probabilities. // Obtain proper hint information either from the provided hint or from requirements of the solver. - SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::UntilProbabilities, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, phiStates, qualitativeStateSets.statesWithProbability1, minMaxLinearEquationSolverFactory); + SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::UntilProbabilities, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, phiStates, qualitativeStateSets.statesWithProbability1); // Declare the components of the equation system we will solve. storm::storage::SparseMatrix<ValueType> submatrix; @@ -751,7 +754,7 @@ namespace storm { } // Now compute the results for the maybe states. - MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, minMaxLinearEquationSolverFactory, hintInformation); + MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation); // If we eliminated end components, we need to extract the result differently. if (ecInformation && ecInformation.get().getEliminatedEndComponents()) { @@ -780,7 +783,7 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, bool useMecBasedTechnique) { if (useMecBasedTechnique) { storm::storage::MaximalEndComponentDecomposition<ValueType> mecDecomposition(transitionMatrix, backwardTransitions, psiStates); storm::storage::BitVector statesInPsiMecs(transitionMatrix.getRowGroupCount()); @@ -790,10 +793,10 @@ namespace storm { } } - return std::move(computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false, minMaxLinearEquationSolverFactory).values); + return std::move(computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, psiStates, statesInPsiMecs, qualitative, false).values); } else { goal.oneMinus(); - std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false, minMaxLinearEquationSolverFactory).values; + std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), ~psiStates, qualitative, false).values; for (auto& element : result) { element = storm::utility::one<ValueType>() - element; } @@ -803,7 +806,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount) { // Only compute the result if the model has a state-based reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -811,15 +814,15 @@ namespace storm { // Initialize result to state rewards of the this->getModel(). std::vector<ValueType> result(rewardModel.getStateRewardVector()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(env, result, nullptr, stepCount); - + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, nullptr, stepCount); + return result; } template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -830,27 +833,34 @@ namespace storm { // Initialize result to the zero vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); - std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = storm::solver::configureMinMaxLinearEquationSolver(env, std::move(goal), minMaxLinearEquationSolverFactory, transitionMatrix); - solver->repeatedMultiply(env, result, &totalRewardVector, stepBound); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix); + multiplier->repeatedMultiplyAndReduce(env, goal.direction(), result, &totalRewardVector, stepBound); return result; } template<typename ValueType> template<typename RewardModelType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); return computeReachabilityRewardsHelper(env, std::move(goal), transitionMatrix, backwardTransitions, [&rewardModel] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates); }, - targetStates, qualitative, produceScheduler, minMaxLinearEquationSolverFactory, hint); + targetStates, qualitative, produceScheduler, + [&] () { + return rewardModel.getStatesWithZeroReward(transitionMatrix); + }, + [&] () { + return rewardModel.getChoicesWithZeroReward(transitionMatrix); + }, + hint); } #ifdef STORM_HAVE_CARL template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative) { // Only compute the result if the reward model is not empty. STORM_LOG_THROW(!intervalRewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); return computeReachabilityRewardsHelper(env, std::move(goal), transitionMatrix, backwardTransitions, \ @@ -862,12 +872,18 @@ namespace storm { result.push_back(lowerBoundOfIntervals ? interval.lower() : interval.upper()); } return result; - }, \ - targetStates, qualitative, false, minMaxLinearEquationSolverFactory).values; + }, + targetStates, qualitative, false, + [&] () { + return intervalRewardModel.getStatesWithFilter(transitionMatrix, [&](storm::Interval const& i) {return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());}); + }, + [&] () { + return intervalRewardModel.getChoicesWithFilter(transitionMatrix, [&](storm::Interval const& i) {return storm::utility::isZero(lowerBoundOfIntervals ? i.lower() : i.upper());}); + }).values; } template<> - std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::models::sparse::StandardRewardModel<storm::Interval> const&, bool, storm::storage::BitVector const&, bool, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const&) { + std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::storage::SparseMatrix<storm::RationalNumber> const&, storm::models::sparse::StandardRewardModel<storm::Interval> const&, bool, storm::storage::BitVector const&, bool) { STORM_LOG_THROW(false, storm::exceptions::IllegalFunctionCallException, "Computing reachability rewards is unsupported for this data type."); } #endif @@ -875,18 +891,32 @@ namespace storm { struct QualitativeStateSetsReachabilityRewards { storm::storage::BitVector maybeStates; storm::storage::BitVector infinityStates; + storm::storage::BitVector rewardZeroStates; }; template<typename ValueType> QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewardsFromHint(ModelCheckerHint const& hint, storm::storage::BitVector const& targetStates) { QualitativeStateSetsReachabilityRewards result; result.maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates(); - result.infinityStates = ~(result.maybeStates | targetStates); + + // Treat the states with reward zero/infinity. + std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(); + result.infinityStates = storm::storage::BitVector(result.maybeStates.size()); + result.rewardZeroStates = storm::storage::BitVector(result.maybeStates.size()); + storm::storage::BitVector nonMaybeStates = ~result.maybeStates; + for (auto const& state : nonMaybeStates) { + if (storm::utility::isZero(resultsForNonMaybeStates[state])) { + result.rewardZeroStates.set(state, true); + } else { + STORM_LOG_THROW(storm::utility::isInfinity(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException, "Expected that the result hint specifies probabilities in {0,infinity} for non-maybe states"); + result.infinityStates.set(state, true); + } + } return result; } template<typename ValueType> - QualitativeStateSetsReachabilityRewards computeQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates) { + QualitativeStateSetsReachabilityRewards computeQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { QualitativeStateSetsReachabilityRewards result; storm::storage::BitVector trueStates(transitionMatrix.getRowGroupCount(), true); if (goal.minimize()) { @@ -895,33 +925,43 @@ namespace storm { result.infinityStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates); } result.infinityStates.complement(); - result.maybeStates = ~(targetStates | result.infinityStates); + + if (storm::settings::getModule<storm::settings::modules::ModelCheckerSettings>().isFilterRewZeroSet()) { + if (goal.minimize()) { + result.rewardZeroStates = storm::utility::graph::performProb1E(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, trueStates, targetStates, zeroRewardChoicesGetter()); + } else { + result.rewardZeroStates = storm::utility::graph::performProb1A(transitionMatrix, transitionMatrix.getRowGroupIndices(), backwardTransitions, zeroRewardStatesGetter(), targetStates); + } + } else { + result.rewardZeroStates = targetStates; + } + result.maybeStates = ~(result.rewardZeroStates | result.infinityStates); return result; } template<typename ValueType> - QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, ModelCheckerHint const& hint) { + QualitativeStateSetsReachabilityRewards getQualitativeStateSetsReachabilityRewards(storm::solver::SolveGoal<ValueType> const& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, ModelCheckerHint const& hint, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) { return getQualitativeStateSetsReachabilityRewardsFromHint<ValueType>(hint, targetStates); } else { - return computeQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates); + return computeQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, zeroRewardStatesGetter, zeroRewardChoicesGetter); } } template<typename ValueType> - void extendScheduler(storm::storage::Scheduler<ValueType>& scheduler, storm::solver::SolveGoal<ValueType> const& goal, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& targetStates) { + void extendScheduler(storm::storage::Scheduler<ValueType>& scheduler, storm::solver::SolveGoal<ValueType> const& goal, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter) { // Finally, if we need to produce a scheduler, we also need to figure out the parts of the scheduler for - // the states with reward infinity. Moreover, we have to set some arbitrary choice for the remaining states - // to obtain a fully defined scheduler. - if (!goal.minimize()) { - storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.infinityStates, transitionMatrix, scheduler); - } else { + // the states with reward zero/infinity. + if (goal.minimize()) { + storm::utility::graph::computeSchedulerProb1E(qualitativeStateSets.rewardZeroStates, transitionMatrix, backwardTransitions, qualitativeStateSets.rewardZeroStates, targetStates, scheduler, zeroRewardChoicesGetter()); for (auto const& state : qualitativeStateSets.infinityStates) { scheduler.setChoice(0, state); } - } - for (auto const& state : targetStates) { - scheduler.setChoice(0, state); + } else { + storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.infinityStates, transitionMatrix, scheduler); + for (auto const& state : qualitativeStateSets.rewardZeroStates) { + scheduler.setChoice(0, state); + } } } @@ -949,21 +989,21 @@ namespace storm { } template<typename ValueType> - void computeFixedPointSystemReachabilityRewards(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) { + void computeFixedPointSystemReachabilityRewards(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, std::vector<ValueType>* oneStepTargetProbabilities = nullptr) { // Remove rows and columns from the original transition probability matrix for states whose reward values are already known. // If there are infinity states, we additionally have to remove choices of maybeState that lead to infinity. if (qualitativeStateSets.infinityStates.empty()) { submatrix = transitionMatrix.getSubmatrix(true, qualitativeStateSets.maybeStates, qualitativeStateSets.maybeStates, false); b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, qualitativeStateSets.maybeStates); if (oneStepTargetProbabilities) { - (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, targetStates); + (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowGroupSumVector(qualitativeStateSets.maybeStates, qualitativeStateSets.rewardZeroStates); } } else { submatrix = transitionMatrix.getSubmatrix(false, *selectedChoices, qualitativeStateSets.maybeStates, false); b = totalStateRewardVectorGetter(transitionMatrix.getRowCount(), transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true)); storm::utility::vector::filterVectorInPlace(b, *selectedChoices); if (oneStepTargetProbabilities) { - (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, targetStates); + (*oneStepTargetProbabilities) = transitionMatrix.getConstrainedRowSumVector(*selectedChoices, qualitativeStateSets.rewardZeroStates); } } @@ -972,7 +1012,7 @@ namespace storm { } template<typename ValueType> - boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, storm::storage::BitVector const& targetStates, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities) { + boost::optional<SparseMdpEndComponentInformation<ValueType>> computeFixedPointSystemReachabilityRewardsEliminateEndComponents(storm::solver::SolveGoal<ValueType>& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, QualitativeStateSetsReachabilityRewards const& qualitativeStateSets, boost::optional<storm::storage::BitVector> const& selectedChoices, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::SparseMatrix<ValueType>& submatrix, std::vector<ValueType>& b, boost::optional<std::vector<ValueType>>& oneStepTargetProbabilities) { // Start by computing the choices with reward 0, as we only want ECs within this fragment. storm::storage::BitVector zeroRewardChoices(transitionMatrix.getRowCount()); @@ -1019,7 +1059,7 @@ namespace storm { // Only do more work if there are actually end-components. if (doDecomposition && !endComponentDecomposition.empty()) { STORM_LOG_DEBUG("Eliminating " << endComponentDecomposition.size() << " ECs."); - SparseMdpEndComponentInformation<ValueType> result = SparseMdpEndComponentInformation<ValueType>::eliminateEndComponents(endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, oneStepTargetProbabilities ? &targetStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector, submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b); + SparseMdpEndComponentInformation<ValueType> result = SparseMdpEndComponentInformation<ValueType>::eliminateEndComponents(endComponentDecomposition, transitionMatrix, qualitativeStateSets.maybeStates, oneStepTargetProbabilities ? &qualitativeStateSets.rewardZeroStates : nullptr, selectedChoices ? &selectedChoices.get() : nullptr, &rewardVector, submatrix, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr, &b); // If the solve goal has relevant values, we need to adjust them. if (goal.hasRelevantValues()) { @@ -1037,7 +1077,7 @@ namespace storm { return result; } else { STORM_LOG_DEBUG("Not eliminating ECs as there are none."); - computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); + computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); return boost::none; } } @@ -1056,15 +1096,15 @@ namespace storm { } template<typename ValueType> - MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint) { + MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint) { // Prepare resulting vector. std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); // Determine which states have a reward that is infinity or less than infinity. - QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, hint); + QualitativeStateSetsReachabilityRewards qualitativeStateSets = getQualitativeStateSetsReachabilityRewards(goal, transitionMatrix, backwardTransitions, targetStates, hint, zeroRewardStatesGetter, zeroRewardChoicesGetter); - STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, " << targetStates.getNumberOfSetBits() << " target states (" << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining)."); + STORM_LOG_INFO("Preprocessing: " << qualitativeStateSets.infinityStates.getNumberOfSetBits() << " states with reward infinity, " << qualitativeStateSets.rewardZeroStates.getNumberOfSetBits() << " states with reward zero (" << qualitativeStateSets.maybeStates.getNumberOfSetBits() << " states remaining)."); storm::utility::vector::setVectorValues(result, qualitativeStateSets.infinityStates, storm::utility::infinity<ValueType>()); @@ -1091,7 +1131,7 @@ namespace storm { } // Obtain proper hint information either from the provided hint or from requirements of the solver. - SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~targetStates, targetStates, minMaxLinearEquationSolverFactory, selectedChoices); + SparseMdpHintType<ValueType> hintInformation = computeHints(env, SolutionType::ExpectedRewards, hint, goal.direction(), transitionMatrix, backwardTransitions, qualitativeStateSets.maybeStates, ~qualitativeStateSets.rewardZeroStates, qualitativeStateSets.rewardZeroStates, selectedChoices); // Declare the components of the equation system we will solve. storm::storage::SparseMatrix<ValueType> submatrix; @@ -1107,13 +1147,13 @@ namespace storm { // If the hint information tells us that we have to eliminate MECs, we do so now. boost::optional<SparseMdpEndComponentInformation<ValueType>> ecInformation; if (hintInformation.getEliminateEndComponents()) { - ecInformation = computeFixedPointSystemReachabilityRewardsEliminateEndComponents(goal, transitionMatrix, backwardTransitions, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities); + ecInformation = computeFixedPointSystemReachabilityRewardsEliminateEndComponents(goal, transitionMatrix, backwardTransitions, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities); // Make sure we are not supposed to produce a scheduler if we actually eliminate end components. STORM_LOG_THROW(!ecInformation || !ecInformation.get().getEliminatedEndComponents() || !produceScheduler, storm::exceptions::NotSupportedException, "Producing schedulers is not supported if end-components need to be eliminated for the solver."); } else { // Otherwise, we compute the standard equations. - computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, targetStates, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); + computeFixedPointSystemReachabilityRewards(goal, transitionMatrix, qualitativeStateSets, selectedChoices, totalStateRewardVectorGetter, submatrix, b, oneStepTargetProbabilities ? &oneStepTargetProbabilities.get() : nullptr); } // If we need to compute upper bounds, do so now. @@ -1123,7 +1163,7 @@ namespace storm { } // Now compute the results for the maybe states. - MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, minMaxLinearEquationSolverFactory, hintInformation); + MaybeStateResult<ValueType> resultForMaybeStates = computeValuesForMaybeStates(env, std::move(goal), std::move(submatrix), b, produceScheduler, hintInformation); // If we eliminated end components, we need to extract the result differently. if (ecInformation && ecInformation.get().getEliminatedEndComponents()) { @@ -1141,7 +1181,7 @@ namespace storm { // Extend scheduler with choices for the states in the qualitative state sets. if (produceScheduler) { - extendScheduler(*scheduler, goal, qualitativeStateSets, transitionMatrix, targetStates); + extendScheduler(*scheduler, goal, qualitativeStateSets, transitionMatrix, backwardTransitions, targetStates, zeroRewardChoicesGetter); } // Sanity check for created scheduler. @@ -1151,7 +1191,7 @@ namespace storm { } template<typename ValueType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates) { // If there are no goal states, we avoid the computation and directly return zero. if (psiStates.empty()) { @@ -1168,12 +1208,12 @@ namespace storm { std::vector<ValueType> stateRewards(psiStates.size(), storm::utility::zero<ValueType>()); storm::utility::vector::setVectorValues(stateRewards, psiStates, storm::utility::one<ValueType>()); storm::models::sparse::StandardRewardModel<ValueType> rewardModel(std::move(stateRewards)); - return computeLongRunAverageRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, minMaxLinearEquationSolverFactory); + return computeLongRunAverageRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel); } template<typename ValueType> template<typename RewardModelType> - std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel) { uint64_t numberOfStates = transitionMatrix.getRowGroupCount(); @@ -1192,7 +1232,7 @@ namespace storm { for (uint_fast64_t currentMecIndex = 0; currentMecIndex < mecDecomposition.size(); ++currentMecIndex) { storm::storage::MaximalEndComponent const& mec = mecDecomposition[currentMecIndex]; - lraValuesForEndComponents[currentMecIndex] = computeLraForMaximalEndComponent(env, goal.direction(), transitionMatrix, rewardModel, mec, minMaxLinearEquationSolverFactory); + lraValuesForEndComponents[currentMecIndex] = computeLraForMaximalEndComponent(env, goal.direction(), transitionMatrix, rewardModel, mec); // Gather information for later use. for (auto const& stateChoicesPair : mec) { @@ -1298,9 +1338,11 @@ namespace storm { storm::storage::SparseMatrix<ValueType> sspMatrix = sspMatrixBuilder.build(currentChoice, numberOfSspStates, numberOfSspStates); // Check for requirements of the solver. - storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction(), true); + storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType> minMaxLinearEquationSolverFactory; + storm::solver::MinMaxLinearEquationSolverRequirements requirements = minMaxLinearEquationSolverFactory.getRequirements(env, true, goal.direction()); requirements.clearBounds(); - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Cannot establish requirements for solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); + std::vector<ValueType> sspResult(numberOfSspStates); goal.restrictRelevantValues(statesNotContainedInAnyMec); @@ -1327,7 +1369,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // If the mec only consists of a single state, we compute the LRA value directly if (++mec.begin() == mec.end()) { @@ -1349,7 +1391,7 @@ namespace storm { if (method == storm::solver::LraMethod::LinearProgramming) { return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, rewardModel, mec); } else if (method == storm::solver::LraMethod::ValueIteration) { - return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, rewardModel, mec, minMaxLinearEquationSolverFactory); + return computeLraForMaximalEndComponentVI(env, dir, transitionMatrix, rewardModel, mec); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -1357,7 +1399,7 @@ namespace storm { template<typename ValueType> template<typename RewardModelType> - ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec) { // Initialize data about the mec storm::storage::BitVector mecStates(transitionMatrix.getRowGroupCount(), false); @@ -1421,12 +1463,11 @@ namespace storm { std::vector<ValueType> x(mecTransitions.getRowGroupCount(), storm::utility::zero<ValueType>()); std::vector<ValueType> xPrime = x; - auto solver = minMaxLinearEquationSolverFactory.create(env, std::move(mecTransitions)); - solver->setCachingEnabled(true); + auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, mecTransitions); ValueType maxDiff, minDiff; while (true) { // Compute the obtained rewards for the next step - solver->repeatedMultiply(env, dir, x, &choiceRewards, 1); + multiplier->multiplyAndReduce(env, dir, x, &choiceRewards, x); // update xPrime and check for convergence // to avoid large (and numerically unstable) x-values, we substract a reference value. @@ -1495,7 +1536,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<CheckResult> SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) { + std::unique_ptr<CheckResult> SparseMdpPrctlHelper<ValueType>::computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates) { std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now(); @@ -1531,7 +1572,7 @@ namespace storm { STORM_LOG_DEBUG("Computing probabilities to satisfy condition."); std::chrono::high_resolution_clock::time_point conditionStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, extendedConditionStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> conditionProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, extendedConditionStates, false, false).values); std::chrono::high_resolution_clock::time_point conditionEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed probabilities to satisfy for condition in " << std::chrono::duration_cast<std::chrono::milliseconds>(conditionEnd - conditionStart).count() << "ms."); @@ -1542,7 +1583,7 @@ namespace storm { STORM_LOG_DEBUG("Computing probabilities to reach target."); std::chrono::high_resolution_clock::time_point targetStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> targetProbabilities = std::move(computeUntilProbabilities(env, OptimizationDirection::Maximize, transitionMatrix, backwardTransitions, allStates, fixedTargetStates, false, false).values); std::chrono::high_resolution_clock::time_point targetEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed probabilities to reach target in " << std::chrono::duration_cast<std::chrono::milliseconds>(targetEnd - targetStart).count() << "ms."); @@ -1634,7 +1675,7 @@ namespace storm { } std::chrono::high_resolution_clock::time_point conditionalStart = std::chrono::high_resolution_clock::now(); - std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false, minMaxLinearEquationSolverFactory).values); + std::vector<ValueType> goalProbabilities = std::move(computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newBackwardTransitions, storm::storage::BitVector(newFailState + 1, true), newGoalStates, false, false).values); std::chrono::high_resolution_clock::time_point conditionalEnd = std::chrono::high_resolution_clock::now(); STORM_LOG_DEBUG("Computed conditional probabilities in transformed model in " << std::chrono::duration_cast<std::chrono::milliseconds>(conditionalEnd - conditionalStart).count() << "ms."); @@ -1642,22 +1683,22 @@ namespace storm { } template class SparseMdpPrctlHelper<double>; - template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint); - template std::vector<double> SparseMdpPrctlHelper<double>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); - template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory); + template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepCount); + template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound); + template MDPSparseModelCheckingHelperReturnType<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint); + template std::vector<double> SparseMdpPrctlHelper<double>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<double>&& goal, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel); + template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); + template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template double SparseMdpPrctlHelper<double>::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::MaximalEndComponent const& mec); #ifdef STORM_HAVE_CARL template class SparseMdpPrctlHelper<storm::RationalNumber>; - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint); - template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); - template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<storm::RationalNumber> const& minMaxLinearEquationSolverFactory); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepCount); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, uint_fast64_t stepBound); + template MDPSparseModelCheckingHelperReturnType<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint); + template std::vector<storm::RationalNumber> SparseMdpPrctlHelper<storm::RationalNumber>::computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<storm::RationalNumber>&& goal, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel); + template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); + template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); template storm::RationalNumber SparseMdpPrctlHelper<storm::RationalNumber>::computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::models::sparse::StandardRewardModel<storm::RationalNumber> const& rewardModel, storm::storage::MaximalEndComponent const& mec); #endif } diff --git a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h index b06b14192..920bb4d47 100644 --- a/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.h @@ -39,44 +39,44 @@ namespace storm { class SparseMdpPrctlHelper { public: - static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static std::vector<ValueType> computeStepBoundedUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::map<storm::storage::sparse::state_type, ValueType> computeRewardBoundedValues(Environment const& env, OptimizationDirection dir, rewardbounded::MultiDimensionalRewardUnfolding<ValueType, true>& rewardUnfolding, storm::storage::BitVector const& initialStates); - static std::vector<ValueType> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates); - static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeUntilProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint = ModelCheckerHint()); - static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, bool useMecBasedTechnique = false); + static std::vector<ValueType> computeGloballyProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, bool useMecBasedTechnique = false); template<typename RewardModelType> - static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeInstantaneousRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount); template<typename RewardModelType> - static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeCumulativeRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); template<typename RewardModelType> - static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint = ModelCheckerHint()); #ifdef STORM_HAVE_CARL - static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, bool lowerBoundOfIntervals, storm::storage::BitVector const& targetStates, bool qualitative); #endif - static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates); template<typename RewardModelType> - static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::vector<ValueType> computeLongRunAverageRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel); - static std::unique_ptr<CheckResult> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeConditionalProbabilities(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates); private: - static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory, ModelCheckerHint const& hint = ModelCheckerHint()); + static MDPSparseModelCheckingHelperReturnType<ValueType> computeReachabilityRewardsHelper(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter, std::function<storm::storage::BitVector()> const& zeroRewardChoicesGetter, ModelCheckerHint const& hint = ModelCheckerHint()); template<typename RewardModelType> - static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponent(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template<typename RewardModelType> - static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec, storm::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory); + static ValueType computeLraForMaximalEndComponentVI(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); template<typename RewardModelType> static ValueType computeLraForMaximalEndComponentLP(Environment const& env, OptimizationDirection dir, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::storage::MaximalEndComponent const& mec); diff --git a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp index 9993640bc..2b64db267 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp @@ -19,7 +19,7 @@ namespace storm { namespace helper { template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. STORM_LOG_TRACE("Found " << phiStates.getNonZeroCount() << " phi states and " << psiStates.getNonZeroCount() << " psi states."); @@ -35,7 +35,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeUntilProbabilities(env, model, transitionMatrix, maybeStates, statesWithProbability01.second, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return statesWithProbability01.second.template toAdd<ValueType>(); } @@ -43,7 +43,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -60,6 +60,7 @@ namespace storm { // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed // for solving the equation system (i.e. compute (I-A)). submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; if (linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem) { submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix; } @@ -73,8 +74,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { - storm::dd::Add<DdType, ValueType> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + storm::dd::Add<DdType, ValueType> result = computeUntilProbabilities(env, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result = result.getDdManager().template getAddOne<ValueType>() - result; return result; } @@ -86,7 +87,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(model, transitionMatrix.notZero(), phiStates, psiStates, stepBound); @@ -110,6 +111,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, submatrix, maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(model.getManager().template getAddZero<ValueType>(), &subvector, stepBound); @@ -120,7 +122,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -128,22 +130,24 @@ namespace storm { storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); return solver->multiply(model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound); } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(env, transitionMatrix, model.getReachableStates(), model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs()); return solver->multiply(rewardModel.getStateRewardVector(), nullptr, stepBound); } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -162,7 +166,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeReachabilityRewards(env, model, transitionMatrix, rewardModel, maybeStates, targetStates, infinityStates, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().getConstant(storm::utility::zero<ValueType>())); } @@ -170,7 +174,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + storm::dd::Add<DdType, ValueType> SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -185,6 +189,7 @@ namespace storm { // Finally cut away all columns targeting non-maybe states and convert the matrix into the matrix needed // for solving the equation system (i.e. compute (I-A)). submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); + storm::solver::GeneralSymbolicLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; if (linearEquationSolverFactory.getEquationProblemFormat(env) == storm::solver::LinearEquationSolverProblemFormat::EquationSystem) { submatrix = (model.getRowColumnIdentity() * maybeStatesAdd) - submatrix; } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h index dc6307db1..995936786 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h @@ -20,23 +20,23 @@ namespace storm { public: typedef typename storm::models::symbolic::Model<DdType, ValueType>::RewardModelType RewardModelType; - static storm::dd::Add<DdType, ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeBoundedUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static storm::dd::Add<DdType, ValueType> computeNextProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeUntilProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeGloballyProbabilities(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static storm::dd::Add<DdType, ValueType> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeCumulativeRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static storm::dd::Add<DdType, ValueType> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static storm::dd::Add<DdType, ValueType> computeInstantaneousRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::SymbolicLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static storm::dd::Add<DdType, ValueType> computeReachabilityRewards(Environment const& env, storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); }; } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp index 523ba2711..d5c9fea6e 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp +++ b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp @@ -45,7 +45,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -65,6 +65,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Now solve the resulting equation system. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); if (storm::solver::minimize(dir)) { @@ -74,20 +75,20 @@ namespace storm { // Check requirements of solver. storm::solver::MinMaxLinearEquationSolverRequirements requirements = solver->getRequirements(env, dir); boost::optional<storm::dd::Bdd<DdType>> initialScheduler; - if (!requirements.empty()) { - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.hasEnabledRequirement()) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); initialScheduler = computeValidSchedulerHint(EquationSystemType::UntilProbabilities, model, transitionMatrix, maybeStates, statesWithProbability1); requirements.clearValidInitialScheduler(); } requirements.clearBounds(); - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { // Check whether there are end components if (storm::utility::graph::performProb0E(model, transitionMatrix.notZero(), maybeStates, !maybeStates && model.getReachableStates()).isZero()) { requirements.clearNoEndComponents(); } } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Could not establish requirements of solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } if (initialScheduler) { solver->setInitialScheduler(initialScheduler.get()); @@ -101,7 +102,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 and 1 of satisfying the until-formula. std::pair<storm::dd::Bdd<DdType>, storm::dd::Bdd<DdType>> statesWithProbability01; @@ -121,7 +122,7 @@ namespace storm { } else { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeUntilProbabilities(env, dir, model, transitionMatrix, maybeStates, statesWithProbability01.second, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeUntilProbabilities(env, dir, model, transitionMatrix, maybeStates, statesWithProbability01.second, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return std::unique_ptr<CheckResult>(new storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), statesWithProbability01.second.template toAdd<ValueType>())); } @@ -129,8 +130,8 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { - std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative, linearEquationSolverFactory); + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative) { + std::unique_ptr<CheckResult> result = computeUntilProbabilities(env, dir == OptimizationDirection::Minimize ? OptimizationDirection::Maximize : OptimizationDirection::Minimize, model, transitionMatrix, model.getReachableStates(), !psiStates && model.getReachableStates(), qualitative); result->asQuantitativeCheckResult<ValueType>().oneMinus(); return result; } @@ -147,7 +148,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound) { // We need to identify the states which have to be taken out of the matrix, i.e. all states that have // probability 0 or 1 of satisfying the until-formula. storm::dd::Bdd<DdType> statesWithProbabilityGreater0; @@ -174,7 +175,8 @@ namespace storm { // Finally cut away all columns targeting non-maybe states. submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); - + + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, model.getManager().template getAddZero<ValueType>(), &subvector, stepBound); @@ -185,11 +187,12 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(transitionMatrix, model.getReachableStates(), model.getIllegalMask(), model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, rewardModel.getStateRewardVector(), nullptr, stepBound); @@ -197,7 +200,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) { // Only compute the result if the model has at least one reward this->getModel(). STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -205,6 +208,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables()); // Perform the matrix-vector multiplication. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(model.getTransitionMatrix(), model.getReachableStates(), model.getIllegalMask(), model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); storm::dd::Add<DdType, ValueType> result = solver->multiply(dir, model.getManager().template getAddZero<ValueType>(), &totalRewardVector, stepBound); @@ -212,7 +216,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Create the matrix and the vector for the equation system. storm::dd::Add<DdType, ValueType> maybeStatesAdd = maybeStates.template toAdd<ValueType>(); @@ -232,6 +236,7 @@ namespace storm { submatrix *= maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs()); // Now solve the resulting equation system. + storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> linearEquationSolverFactory; std::unique_ptr<storm::solver::SymbolicMinMaxLinearEquationSolver<DdType, ValueType>> solver = linearEquationSolverFactory.create(submatrix, maybeStates, model.getIllegalMask() && maybeStates, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), model.getRowColumnMetaVariablePairs()); if (storm::solver::maximize(dir)) { @@ -241,20 +246,20 @@ namespace storm { // Check requirements of solver. storm::solver::MinMaxLinearEquationSolverRequirements requirements = solver->getRequirements(env, dir); boost::optional<storm::dd::Bdd<DdType>> initialScheduler; - if (!requirements.empty()) { - if (requirements.requires(storm::solver::MinMaxLinearEquationSolverRequirements::Element::ValidInitialScheduler)) { + if (requirements.hasEnabledRequirement()) { + if (requirements.validInitialScheduler()) { STORM_LOG_DEBUG("Computing valid scheduler, because the solver requires it."); initialScheduler = computeValidSchedulerHint(EquationSystemType::ExpectedRewards, model, transitionMatrix, maybeStates, targetStates); requirements.clearValidInitialScheduler(); } requirements.clearLowerBounds(); - if (requirements.requiresNoEndComponents()) { + if (requirements.noEndComponents()) { // Check whether there are end components if (storm::utility::graph::performProb0E(model, transitionMatrixBdd, maybeStates, !maybeStates && model.getReachableStates()).isZero()) { requirements.clearNoEndComponents(); } } - STORM_LOG_THROW(requirements.empty(), storm::exceptions::UncheckedRequirementException, "Could not establish requirements of solver."); + STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked."); } if (initialScheduler) { solver->setInitialScheduler(initialScheduler.get()); @@ -268,7 +273,7 @@ namespace storm { } template<storm::dd::DdType DdType, typename ValueType> - std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { + std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues) { // Only compute the result if there is at least one reward model. STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula."); @@ -289,7 +294,7 @@ namespace storm { // If there are maybe states, we need to solve an equation system. if (!maybeStates.isZero()) { - return computeReachabilityRewards(env, dir, model, transitionMatrix, transitionMatrixBdd, rewardModel, maybeStates, targetStates, infinityStates, linearEquationSolverFactory, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); + return computeReachabilityRewards(env, dir, model, transitionMatrix, transitionMatrixBdd, rewardModel, maybeStates, targetStates, infinityStates, startValues ? maybeStates.ite(startValues.get(), model.getManager().template getAddZero<ValueType>()) : model.getManager().template getAddZero<ValueType>()); } else { return std::unique_ptr<CheckResult>(new storm::modelchecker::SymbolicQuantitativeCheckResult<DdType, ValueType>(model.getReachableStates(), infinityStates.ite(model.getManager().getConstant(storm::utility::infinity<ValueType>()), model.getManager().template getAddZero<ValueType>()))); } diff --git a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h index c8737299c..e21342008 100644 --- a/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h +++ b/src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h @@ -24,23 +24,23 @@ namespace storm { public: typedef typename storm::models::symbolic::NondeterministicModel<DdType, ValueType>::RewardModelType RewardModelType; - static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, uint_fast64_t stepBound); static std::unique_ptr<CheckResult> computeNextProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& nextStates); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& phiStates, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeUntilProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& statesWithProbability1, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeGloballyProbabilities(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& psiStates, bool qualitative); - static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory); + static std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& targetStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); - static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<DdType, ValueType> const& linearEquationSolverFactory, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); + static std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, storm::dd::Bdd<DdType> const& transitionMatrixBdd, RewardModelType const& rewardModel, storm::dd::Bdd<DdType> const& maybeStates, storm::dd::Bdd<DdType> const& targetStates, storm::dd::Bdd<DdType> const& infinityStates, boost::optional<storm::dd::Add<DdType, ValueType>> const& startValues = boost::none); }; } diff --git a/src/storm/modelchecker/results/CheckResult.cpp b/src/storm/modelchecker/results/CheckResult.cpp index 9155057d3..26eb24946 100644 --- a/src/storm/modelchecker/results/CheckResult.cpp +++ b/src/storm/modelchecker/results/CheckResult.cpp @@ -162,6 +162,10 @@ namespace storm { SymbolicParetoCurveCheckResult<Type, ValueType> const& CheckResult::asSymbolicParetoCurveCheckResult() const { return dynamic_cast<SymbolicParetoCurveCheckResult<Type, ValueType> const&>(*this); } + + bool CheckResult::hasScheduler() const { + return false; + } // Explicitly instantiate the template functions. template QuantitativeCheckResult<double>& CheckResult::asQuantitativeCheckResult(); diff --git a/src/storm/modelchecker/results/CheckResult.h b/src/storm/modelchecker/results/CheckResult.h index 4edd2cb19..740a8269d 100644 --- a/src/storm/modelchecker/results/CheckResult.h +++ b/src/storm/modelchecker/results/CheckResult.h @@ -111,7 +111,9 @@ namespace storm { template <storm::dd::DdType Type, typename ValueType> SymbolicParetoCurveCheckResult<Type, ValueType> const& asSymbolicParetoCurveCheckResult() const; - + + virtual bool hasScheduler() const; + virtual std::ostream& writeToStream(std::ostream& out) const = 0; }; diff --git a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h index 131cf0cea..57be3266f 100644 --- a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h +++ b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h @@ -65,7 +65,7 @@ namespace storm { virtual ValueType average() const override; virtual ValueType sum() const override; - bool hasScheduler() const; + virtual bool hasScheduler() const override; void setScheduler(std::unique_ptr<storm::storage::Scheduler<ValueType>>&& scheduler); storm::storage::Scheduler<ValueType> const& getScheduler() const; storm::storage::Scheduler<ValueType>& getScheduler(); diff --git a/src/storm/models/Model.h b/src/storm/models/Model.h index 4f17fdf24..52dfec2b6 100644 --- a/src/storm/models/Model.h +++ b/src/storm/models/Model.h @@ -16,6 +16,7 @@ namespace storm { Model(ModelType const& modelType) : ModelBase(modelType) { // Intentionally left empty. } + }; diff --git a/src/storm/models/ModelBase.cpp b/src/storm/models/ModelBase.cpp index 226b4eecc..f73ba1bce 100644 --- a/src/storm/models/ModelBase.cpp +++ b/src/storm/models/ModelBase.cpp @@ -18,6 +18,10 @@ namespace storm { return this->getType() == modelType; } + bool ModelBase::isNondeterministicModel() const { + return this->isOfType(storm::models::ModelType::Mdp) || this->isOfType(storm::models::ModelType::MarkovAutomaton); + } + bool ModelBase::supportsParameters() const { return false; } diff --git a/src/storm/models/ModelBase.h b/src/storm/models/ModelBase.h index e816adac6..77fa5b60d 100644 --- a/src/storm/models/ModelBase.h +++ b/src/storm/models/ModelBase.h @@ -48,7 +48,7 @@ namespace storm { std::shared_ptr<ModelType const> as() const { return std::dynamic_pointer_cast<ModelType const>(this->shared_from_this()); } - + /*! * @brief Return the actual type of the model. * @@ -108,6 +108,13 @@ namespace storm { */ bool isOfType(storm::models::ModelType const& modelType) const; + /*! + * Returns true if the model is a nondeterministic model. + * + * @return True iff the model is a nondeterministic model. + */ + bool isNondeterministicModel() const; + /*! * Checks whether the model supports parameters. * diff --git a/src/storm/models/sparse/MarkovAutomaton.cpp b/src/storm/models/sparse/MarkovAutomaton.cpp index 9c077e2c4..587a28a7b 100644 --- a/src/storm/models/sparse/MarkovAutomaton.cpp +++ b/src/storm/models/sparse/MarkovAutomaton.cpp @@ -181,7 +181,7 @@ namespace storm { // Get number of choices in current state uint_fast64_t numberChoices = this->getTransitionMatrix().getRowGroupIndices()[state + 1] - this->getTransitionMatrix().getRowGroupIndices()[state]; if (isMarkovianState(state)) { - STORM_LOG_ASSERT(numberChoices == 1, "Wrong number of choices for markovian state."); + STORM_LOG_ASSERT(numberChoices == 1, "Wrong number of choices for Markovian state."); } if (numberChoices > 1) { STORM_LOG_ASSERT(isProbabilisticState(state), "State is not probabilistic."); @@ -211,7 +211,7 @@ namespace storm { storm::storage::FlexibleSparseMatrix<ValueType> flexibleMatrix(this->getTransitionMatrix()); storm::storage::FlexibleSparseMatrix<ValueType> flexibleBackwardTransitions(this->getTransitionMatrix().transpose()); storm::solver::stateelimination::StateEliminator<ValueType> stateEliminator(flexibleMatrix, flexibleBackwardTransitions); - + for (uint_fast64_t state = 0; state < this->getNumberOfStates(); ++state) { STORM_LOG_ASSERT(!this->isHybridState(state), "State is hybrid."); if (this->isProbabilisticState(state)) { @@ -220,7 +220,7 @@ namespace storm { STORM_LOG_TRACE("Flexible matrix after eliminating state " << state << ":" << std::endl << flexibleMatrix); } } - + // Create the rate matrix for the CTMC storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, 0, 0, false, false); // Remember state to keep @@ -230,7 +230,7 @@ namespace storm { // State is eliminated and can be discarded keepStates.set(state, false); } else { - STORM_LOG_ASSERT(this->isMarkovianState(state), "State is not markovian."); + STORM_LOG_ASSERT(this->isMarkovianState(state), "State is not Markovian."); // Copy transitions for (uint_fast64_t row = flexibleMatrix.getRowGroupIndices()[state]; row < flexibleMatrix.getRowGroupIndices()[state + 1]; ++row) { for (auto const& entry : flexibleMatrix.getRow(row)) { @@ -240,20 +240,20 @@ namespace storm { } } } - + storm::storage::SparseMatrix<ValueType> rateMatrix = transitionMatrixBuilder.build(); rateMatrix = rateMatrix.getSubmatrix(false, keepStates, keepStates, false); STORM_LOG_TRACE("New CTMC matrix:" << std::endl << rateMatrix); // Construct CTMC storm::models::sparse::StateLabeling stateLabeling = this->getStateLabeling().getSubLabeling(keepStates); - + //TODO update reward models and choice labels according to kept states STORM_LOG_WARN_COND(this->getRewardModels().empty(), "Conversion of MA to CTMC does not preserve rewards."); std::unordered_map<std::string, RewardModelType> rewardModels = this->getRewardModels(); STORM_LOG_WARN_COND(!this->hasChoiceLabeling(), "Conversion of MA to CTMC does not preserve choice labels."); STORM_LOG_WARN_COND(!this->hasStateValuations(), "Conversion of MA to CTMC does not preserve choice labels."); STORM_LOG_WARN_COND(!this->hasChoiceOrigins(), "Conversion of MA to CTMC does not preserve choice labels."); - + return std::make_shared<storm::models::sparse::Ctmc<ValueType, RewardModelType>>(std::move(rateMatrix), std::move(stateLabeling), std::move(rewardModels)); } diff --git a/src/storm/models/sparse/Model.cpp b/src/storm/models/sparse/Model.cpp index edeefb825..9ee91b5dd 100644 --- a/src/storm/models/sparse/Model.cpp +++ b/src/storm/models/sparse/Model.cpp @@ -74,9 +74,9 @@ namespace storm { STORM_LOG_THROW(!components.exitRates.is_initialized() || components.exitRates->size() == stateCount, storm::exceptions::IllegalArgumentException, "Size of exit rate vector does not match state count."); STORM_LOG_THROW(this->isOfType(ModelType::Ctmc) || components.markovianStates.is_initialized(), storm::exceptions::IllegalArgumentException, "Can not create Markov Automaton: no Markovian states given."); } else { - STORM_LOG_ERROR_COND(!components.rateTransitions && !components.exitRates.is_initialized(), "Rates specified for discrete-time model. The rates will be ignored."); + STORM_LOG_WARN_COND(!components.rateTransitions && !components.exitRates.is_initialized(), "Rates specified for discrete-time model. The rates will be ignored."); } - STORM_LOG_ERROR_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(), "Markovian states given for a model that is not a Markov automaton (will be ignored)."); + STORM_LOG_WARN_COND(this->isOfType(ModelType::MarkovAutomaton) || !components.markovianStates.is_initialized(), "Markovian states given for a model that is not a Markov automaton (will be ignored)."); } template<typename ValueType, typename RewardModelType> @@ -423,11 +423,7 @@ namespace storm { template<typename ValueType, typename RewardModelType> bool Model<ValueType, RewardModelType>::supportsParameters() const { -#ifdef STORM_HAVE_CARL return std::is_same<ValueType, storm::RationalFunction>::value; -#else - return false; -#endif } template<typename ValueType, typename RewardModelType> diff --git a/src/storm/models/sparse/StandardRewardModel.cpp b/src/storm/models/sparse/StandardRewardModel.cpp index ccf9b5d71..e37de0562 100644 --- a/src/storm/models/sparse/StandardRewardModel.cpp +++ b/src/storm/models/sparse/StandardRewardModel.cpp @@ -270,11 +270,17 @@ namespace storm { template<typename ValueType> template<typename MatrixValueType> storm::storage::BitVector StandardRewardModel<ValueType>::getStatesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const { - storm::storage::BitVector result = this->hasStateRewards() ? storm::utility::vector::filterZero(this->getStateRewardVector()) : storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true); + return getStatesWithFilter(transitionMatrix, storm::utility::isZero<ValueType>); + } + + template<typename ValueType> + template<typename MatrixValueType> + storm::storage::BitVector StandardRewardModel<ValueType>::getStatesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const { + storm::storage::BitVector result = this->hasStateRewards() ? storm::utility::vector::filter(this->getStateRewardVector(), filter) : storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true); if (this->hasStateActionRewards()) { for (uint_fast64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { for (uint_fast64_t row = transitionMatrix.getRowGroupIndices()[state]; row < transitionMatrix.getRowGroupIndices()[state+1]; ++row) { - if(!storm::utility::isZero(this->getStateActionRewardVector()[row])) { + if(!filter(this->getStateActionRewardVector()[row])) { result.set(state, false); break; } @@ -284,7 +290,7 @@ namespace storm { if (this->hasTransitionRewards()) { for (uint_fast64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { for (auto const& rewardMatrixEntry : this->getTransitionRewardMatrix().getRowGroup(state)) { - if(!storm::utility::isZero(rewardMatrixEntry.getValue())) { + if(!filter(rewardMatrixEntry.getValue())) { result.set(state, false); break; } @@ -293,19 +299,25 @@ namespace storm { } return result; } - + template<typename ValueType> template<typename MatrixValueType> storm::storage::BitVector StandardRewardModel<ValueType>::getChoicesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const { + return getChoicesWithFilter(transitionMatrix, storm::utility::isZero<ValueType>); + } + + template<typename ValueType> + template<typename MatrixValueType> + storm::storage::BitVector StandardRewardModel<ValueType>::getChoicesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const { storm::storage::BitVector result; if (this->hasStateActionRewards()) { - result = storm::utility::vector::filterZero(this->getStateActionRewardVector()); + result = storm::utility::vector::filter(this->getStateActionRewardVector(), filter); if (this->hasStateRewards()) { - result &= transitionMatrix.getRowFilter(storm::utility::vector::filterZero(this->getStateRewardVector())); + result &= transitionMatrix.getRowFilter(storm::utility::vector::filter(this->getStateRewardVector(), filter)); } } else { if (this->hasStateRewards()) { - result = transitionMatrix.getRowFilter(storm::utility::vector::filterZero(this->getStateRewardVector())); + result = transitionMatrix.getRowFilter(storm::utility::vector::filter(this->getStateRewardVector(), filter)); } else { result = storm::storage::BitVector(transitionMatrix.getRowCount(), true); } @@ -313,7 +325,7 @@ namespace storm { if (this->hasTransitionRewards()) { for (uint_fast64_t row = 0; row < transitionMatrix.getRowCount(); ++row) { for (auto const& rewardMatrixEntry : this->getTransitionRewardMatrix().getRow(row)) { - if(!storm::utility::isZero(rewardMatrixEntry.getValue())) { + if(!filter(rewardMatrixEntry.getValue())) { result.set(row, false); break; } @@ -396,7 +408,9 @@ namespace storm { template std::vector<double> StandardRewardModel<double>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& weights) const; template std::vector<double> StandardRewardModel<double>::getTotalActionRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& stateRewardWeights) const; template storm::storage::BitVector StandardRewardModel<double>::getStatesWithZeroReward(storm::storage::SparseMatrix<double> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<double>::getStatesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(double const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithZeroReward(storm::storage::SparseMatrix<double> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(double const&)> const& filter) const; template double StandardRewardModel<double>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<double> const& transitionMatrix, double const& stateRewardWeight, double const& actionRewardWeight) const; template void StandardRewardModel<double>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards, std::vector<double> const* weights); @@ -421,7 +435,9 @@ namespace storm { template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& weights) const; template std::vector<storm::RationalNumber> StandardRewardModel<storm::RationalNumber>::getTotalActionRewardVector(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<storm::RationalNumber> const& stateRewardWeights) const; template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getStatesWithZeroReward(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getStatesWithFilter(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::function<bool(storm::RationalNumber const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getChoicesWithZeroReward(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::function<bool(storm::RationalNumber const&)> const& filter) const; template storm::RationalNumber StandardRewardModel<storm::RationalNumber>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::RationalNumber const& stateRewardWeight, storm::RationalNumber const& actionRewardWeight) const; template void StandardRewardModel<storm::RationalNumber>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, bool reduceToStateRewards, std::vector<storm::RationalNumber> const* weights); template void StandardRewardModel<storm::RationalNumber>::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalNumber const & newValue); @@ -433,7 +449,9 @@ namespace storm { template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& weights) const; template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getStatesWithZeroReward(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getStatesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const; template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithZeroReward(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const; + template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const; template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalActionRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& stateRewardWeights) const; template storm::RationalFunction StandardRewardModel<storm::RationalFunction>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::RationalFunction const& stateRewardWeight, storm::RationalFunction const& actionRewardWeight) const; @@ -447,6 +465,8 @@ namespace storm { template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix) const; template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& weights) const; template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalActionRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& stateRewardWeights) const; + template storm::storage::BitVector StandardRewardModel<storm::Interval>::getStatesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(storm::Interval const&)> const& filter) const; + template storm::storage::BitVector StandardRewardModel<storm::Interval>::getChoicesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(storm::Interval const&)> const& filter) const; template void StandardRewardModel<storm::Interval>::setStateActionReward(uint_fast64_t choiceIndex, double const & newValue); template void StandardRewardModel<storm::Interval>::setStateActionReward(uint_fast64_t choiceIndex, storm::Interval const & newValue); template void StandardRewardModel<storm::Interval>::setStateReward(uint_fast64_t state, double const & newValue); diff --git a/src/storm/models/sparse/StandardRewardModel.h b/src/storm/models/sparse/StandardRewardModel.h index 33303f380..cdfce6038 100644 --- a/src/storm/models/sparse/StandardRewardModel.h +++ b/src/storm/models/sparse/StandardRewardModel.h @@ -253,6 +253,13 @@ namespace storm { template<typename MatrixValueType> storm::storage::BitVector getStatesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const; + /*! + * Returns the set of states for which all associated rewards (state, action or transition rewards) satisfy the given filter. + * @param transitionMatrix the transition matrix of the model (used to determine the actions and transitions that belong to a state) + */ + template<typename MatrixValueType> + storm::storage::BitVector getStatesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const; + /*! * Returns the set of choices at which all rewards (state-, action- and transition-rewards) are zero. * @@ -261,7 +268,14 @@ namespace storm { */ template<typename MatrixValueType> storm::storage::BitVector getChoicesWithZeroReward(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix) const; - + + /*! + * Returns the set of choices for which all associated rewards (state, action or transition rewards) satisfy the given filter. + * @param transitionMatrix the transition matrix of the model (used to determine the actions and transitions that belong to a state) + */ + template<typename MatrixValueType> + storm::storage::BitVector getChoicesWithFilter(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::function<bool(ValueType const&)> const& filter) const; + /*! * Sets the given value in the state-action reward vector at the given row. This assumes that the reward * model has state-action rewards. diff --git a/src/storm/models/sparse/StateLabeling.cpp b/src/storm/models/sparse/StateLabeling.cpp index e80556108..bcb00b7a9 100644 --- a/src/storm/models/sparse/StateLabeling.cpp +++ b/src/storm/models/sparse/StateLabeling.cpp @@ -50,7 +50,7 @@ namespace storm { } void StateLabeling::addLabelToState(std::string const& label, storm::storage::sparse::state_type state) { - return ItemLabeling::addLabelToItem(label, state); + ItemLabeling::addLabelToItem(label, state); } bool StateLabeling::getStateHasLabel(std::string const& label, storm::storage::sparse::state_type state) const { diff --git a/src/storm/models/symbolic/Ctmc.cpp b/src/storm/models/symbolic/Ctmc.cpp index e94079efc..4b05372be 100644 --- a/src/storm/models/symbolic/Ctmc.cpp +++ b/src/storm/models/symbolic/Ctmc.cpp @@ -84,11 +84,29 @@ namespace storm { return exitRates.get(); } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Ctmc<Type, NewValueType>> Ctmc<Type, ValueType>::toValueType() const { + typedef typename DeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Ctmc<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getExitRateVector().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Ctmc<storm::dd::DdType::CUDD, double>; template class Ctmc<storm::dd::DdType::Sylvan, double>; template class Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Ctmc<storm::dd::DdType::Sylvan, double>> Ctmc<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Ctmc<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Ctmc.h b/src/storm/models/symbolic/Ctmc.h index 68c4e7b35..0035e3ffb 100644 --- a/src/storm/models/symbolic/Ctmc.h +++ b/src/storm/models/symbolic/Ctmc.h @@ -141,6 +141,9 @@ namespace storm { */ storm::dd::Add<Type, ValueType> const& getExitRateVector() const; + template<typename NewValueType> + std::shared_ptr<Ctmc<Type, NewValueType>> toValueType() const; + private: mutable boost::optional<storm::dd::Add<Type, ValueType>> exitRates; }; diff --git a/src/storm/models/symbolic/Dtmc.cpp b/src/storm/models/symbolic/Dtmc.cpp index fdd478b71..2b4adb149 100644 --- a/src/storm/models/symbolic/Dtmc.cpp +++ b/src/storm/models/symbolic/Dtmc.cpp @@ -43,11 +43,29 @@ namespace storm { // Intentionally left empty. } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Dtmc<Type, NewValueType>> Dtmc<Type, ValueType>::toValueType() const { + typedef typename DeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Dtmc<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Dtmc<storm::dd::DdType::CUDD, double>; template class Dtmc<storm::dd::DdType::Sylvan, double>; template class Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Dtmc<storm::dd::DdType::Sylvan, double>> Dtmc<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Dtmc.h b/src/storm/models/symbolic/Dtmc.h index ebe837e1c..76a3e81ca 100644 --- a/src/storm/models/symbolic/Dtmc.h +++ b/src/storm/models/symbolic/Dtmc.h @@ -76,6 +76,10 @@ namespace storm { std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + template<typename NewValueType> + std::shared_ptr<Dtmc<Type, NewValueType>> toValueType() const; + }; } // namespace symbolic diff --git a/src/storm/models/symbolic/MarkovAutomaton.cpp b/src/storm/models/symbolic/MarkovAutomaton.cpp new file mode 100644 index 000000000..111890edd --- /dev/null +++ b/src/storm/models/symbolic/MarkovAutomaton.cpp @@ -0,0 +1,146 @@ +#include "storm/models/symbolic/MarkovAutomaton.h" + +#include "storm/storage/dd/DdManager.h" +#include "storm/storage/dd/Add.h" +#include "storm/storage/dd/Bdd.h" + +#include "storm/models/symbolic/StandardRewardModel.h" + +#include "storm/adapters/RationalFunctionAdapter.h" + +namespace storm { + namespace models { + namespace symbolic { + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType>::MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::expressions::Expression> labelToExpressionMap, + std::unordered_map<std::string, RewardModelType> const& rewardModels) + : NondeterministicModel<Type, ValueType>(storm::models::ModelType::MarkovAutomaton, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels), markovianMarker(markovianMarker) { + + // Compute all Markovian info. + computeMarkovianInfo(); + } + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType>::MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap, + std::unordered_map<std::string, RewardModelType> const& rewardModels) + : NondeterministicModel<Type, ValueType>(storm::models::ModelType::MarkovAutomaton, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToBddMap, rewardModels), markovianMarker(markovianMarker) { + + // Compute all Markovian info. + computeMarkovianInfo(); + } + + template<storm::dd::DdType Type, typename ValueType> + void MarkovAutomaton<Type, ValueType>::computeMarkovianInfo() { + // Compute the Markovian choices. + this->markovianChoices = this->getQualitativeTransitionMatrix() && this->markovianMarker; + + // Compute the probabilistic states. + std::set<storm::expressions::Variable> columnAndNondeterminsmVariables; + std::set_union(this->getColumnVariables().begin(), this->getColumnVariables().end(), this->getNondeterminismVariables().begin(), this->getNondeterminismVariables().end(), std::inserter(columnAndNondeterminsmVariables, columnAndNondeterminsmVariables.begin())); + this->probabilisticStates = (this->getQualitativeTransitionMatrix() && !markovianMarker).existsAbstract(columnAndNondeterminsmVariables); + + // Compute the Markovian states. + this->markovianStates = markovianChoices.existsAbstract(columnAndNondeterminsmVariables); + + // Compute the vector of exit rates. + this->exitRateVector = (this->getTransitionMatrix() * this->markovianMarker.template toAdd<ValueType>()).sumAbstract(columnAndNondeterminsmVariables); + + // Modify the transition matrix so all choices are probabilistic and the Markovian choices additionally + // have a rate. + this->transitionMatrix = this->transitionMatrix / this->markovianChoices.ite(this->exitRateVector, this->getManager().template getAddOne<ValueType>()); + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianMarker() const { + return this->markovianMarker; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianStates() const { + return this->markovianStates; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getMarkovianChoices() const { + return this->markovianChoices; + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Bdd<Type> const& MarkovAutomaton<Type, ValueType>::getProbabilisticStates() const { + return this->markovianStates; + } + + template<storm::dd::DdType Type, typename ValueType> + bool MarkovAutomaton<Type, ValueType>::hasHybridStates() const { + return !(this->probabilisticStates && this->markovianStates).isZero(); + } + + template<storm::dd::DdType Type, typename ValueType> + bool MarkovAutomaton<Type, ValueType>::isClosed() { + return !this->hasHybridStates(); + } + + template<storm::dd::DdType Type, typename ValueType> + MarkovAutomaton<Type, ValueType> MarkovAutomaton<Type, ValueType>::close() { + // Create the new transition matrix by deleting all Markovian transitions from probabilistic states. + storm::dd::Add<Type, ValueType> newTransitionMatrix = this->probabilisticStates.ite(this->getTransitionMatrix() * (!this->getMarkovianMarker()).template toAdd<ValueType>(), this->getTransitionMatrix() * this->getExitRateVector()); + + return MarkovAutomaton<Type, ValueType>(this->getManagerAsSharedPointer(), this->getMarkovianMarker(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), newTransitionMatrix, this->getRowVariables(), this->getRowExpressionAdapter(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), this->getLabelToExpressionMap(), this->getRewardModels()); + } + + template<storm::dd::DdType Type, typename ValueType> + storm::dd::Add<Type, ValueType> const& MarkovAutomaton<Type, ValueType>::getExitRateVector() const { + return this->exitRateVector; + } + + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<MarkovAutomaton<Type, NewValueType>> MarkovAutomaton<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<MarkovAutomaton<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getMarkovianMarker(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + } + + // Explicitly instantiate the template class. + template class MarkovAutomaton<storm::dd::DdType::CUDD, double>; + template class MarkovAutomaton<storm::dd::DdType::Sylvan, double>; + + template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<MarkovAutomaton<storm::dd::DdType::Sylvan, double>> MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; + template class MarkovAutomaton<storm::dd::DdType::Sylvan, storm::RationalFunction>; + + } // namespace symbolic + } // namespace models +} // namespace storm + diff --git a/src/storm/models/symbolic/MarkovAutomaton.h b/src/storm/models/symbolic/MarkovAutomaton.h new file mode 100644 index 000000000..e2e0f3369 --- /dev/null +++ b/src/storm/models/symbolic/MarkovAutomaton.h @@ -0,0 +1,114 @@ +#pragma once + +#include "storm/models/symbolic/NondeterministicModel.h" + +namespace storm { + namespace models { + namespace symbolic { + + /*! + * This class represents a discrete-time Markov decision process. + */ + template<storm::dd::DdType Type, typename ValueType = double> + class MarkovAutomaton : public NondeterministicModel<Type, ValueType> { + public: + typedef typename NondeterministicModel<Type, ValueType>::RewardModelType RewardModelType; + + MarkovAutomaton(MarkovAutomaton<Type, ValueType> const& other) = default; + MarkovAutomaton& operator=(MarkovAutomaton<Type, ValueType> const& other) = default; + MarkovAutomaton(MarkovAutomaton<Type, ValueType>&& other) = default; + MarkovAutomaton& operator=(MarkovAutomaton<Type, ValueType>&& other) = default; + + /*! + * Constructs a model from the given data. + * + * @param manager The manager responsible for the decision diagrams. + * @param markovianMarker A DD that can be used to split the Markovian and probabilistic behavior. + * @param reachableStates A DD representing the reachable states. + * @param initialStates A DD representing the initial states of the model. + * @param deadlockStates A DD representing the deadlock states of the model. + * @param transitionMatrix The matrix representing the transitions in the model as a probabilistic matrix. + * @param rowVariables The set of row meta variables used in the DDs. + * @param rowExpressionAdapter An object that can be used to translate expressions in terms of the row + * meta variables. + * @param columVariables The set of column meta variables used in the DDs. + * @param rowColumnMetaVariablePairs All pairs of row/column meta variables. + * @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model. + * @param labelToExpressionMap A mapping from label names to their defining expressions. + * @param rewardModels The reward models associated with the model. + */ + MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> rowExpressionAdapter, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::expressions::Expression> labelToExpressionMap = std::map<std::string, storm::expressions::Expression>(), + std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + /*! + * Constructs a model from the given data. + * + * @param manager The manager responsible for the decision diagrams. + * @param markovianMarker A DD that can be used to split the Markovian and probabilistic behavior. + * @param reachableStates A DD representing the reachable states. + * @param initialStates A DD representing the initial states of the model. + * @param deadlockStates A DD representing the deadlock states of the model. + * @param transitionMatrix The matrix representing the transitions in the model as a probabilistic matrix. + * @param rowVariables The set of row meta variables used in the DDs. + * @param columVariables The set of column meta variables used in the DDs. + * @param rowColumnMetaVariablePairs All pairs of row/column meta variables. + * @param nondeterminismVariables The meta variables used to encode the nondeterminism in the model. + * @param labelToBddMap A mapping from label names to their defining BDDs. + * @param rewardModels The reward models associated with the model. + */ + MarkovAutomaton(std::shared_ptr<storm::dd::DdManager<Type>> manager, + storm::dd::Bdd<Type> markovianMarker, + storm::dd::Bdd<Type> reachableStates, + storm::dd::Bdd<Type> initialStates, + storm::dd::Bdd<Type> deadlockStates, + storm::dd::Add<Type, ValueType> transitionMatrix, + std::set<storm::expressions::Variable> const& rowVariables, + std::set<storm::expressions::Variable> const& columnVariables, + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, + std::set<storm::expressions::Variable> const& nondeterminismVariables, + std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), + std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + + storm::dd::Bdd<Type> const& getMarkovianMarker() const; + storm::dd::Bdd<Type> const& getMarkovianStates() const; + storm::dd::Bdd<Type> const& getMarkovianChoices() const; + storm::dd::Bdd<Type> const& getProbabilisticStates() const; + + bool hasHybridStates() const; + bool isClosed(); + + MarkovAutomaton<Type, ValueType> close(); + + storm::dd::Add<Type, ValueType> const& getExitRateVector() const; + + template<typename NewValueType> + std::shared_ptr<MarkovAutomaton<Type, NewValueType>> toValueType() const; + + private: + /*! + * Computes the member data related to Markovian stuff. + */ + void computeMarkovianInfo(); + + storm::dd::Bdd<Type> markovianMarker; + storm::dd::Bdd<Type> markovianStates; + storm::dd::Bdd<Type> markovianChoices; + storm::dd::Bdd<Type> probabilisticStates; + storm::dd::Add<Type, ValueType> exitRateVector; + }; + + } // namespace symbolic + } // namespace models +} // namespace storm + diff --git a/src/storm/models/symbolic/Mdp.cpp b/src/storm/models/symbolic/Mdp.cpp index ee72d085e..65bd49769 100644 --- a/src/storm/models/symbolic/Mdp.cpp +++ b/src/storm/models/symbolic/Mdp.cpp @@ -28,7 +28,7 @@ namespace storm { : NondeterministicModel<Type, ValueType>(storm::models::ModelType::Mdp, manager, reachableStates, initialStates, deadlockStates, transitionMatrix, rowVariables, rowExpressionAdapter, columnVariables, rowColumnMetaVariablePairs, nondeterminismVariables, labelToExpressionMap, rewardModels) { // Intentionally left empty. } - + template<storm::dd::DdType Type, typename ValueType> Mdp<Type, ValueType>::Mdp(std::shared_ptr<storm::dd::DdManager<Type>> manager, storm::dd::Bdd<Type> reachableStates, @@ -45,11 +45,29 @@ namespace storm { // Intentionally left empty. } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<Mdp<Type, NewValueType>> Mdp<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<Mdp<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + } + // Explicitly instantiate the template class. template class Mdp<storm::dd::DdType::CUDD, double>; template class Mdp<storm::dd::DdType::Sylvan, double>; - + template class Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<Mdp<storm::dd::DdType::Sylvan, double>> Mdp<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class Mdp<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic diff --git a/src/storm/models/symbolic/Mdp.h b/src/storm/models/symbolic/Mdp.h index 771f0bd05..d8432ad49 100644 --- a/src/storm/models/symbolic/Mdp.h +++ b/src/storm/models/symbolic/Mdp.h @@ -83,6 +83,9 @@ namespace storm { std::map<std::string, storm::dd::Bdd<Type>> labelToBddMap = std::map<std::string, storm::dd::Bdd<Type>>(), std::unordered_map<std::string, RewardModelType> const& rewardModels = std::unordered_map<std::string, RewardModelType>()); + template<typename NewValueType> + std::shared_ptr<Mdp<Type, NewValueType>> toValueType() const; + }; } // namespace symbolic diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index 5364a4d4f..f7a9f367f 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -2,6 +2,12 @@ #include <boost/algorithm/string/join.hpp> +#include "storm/models/symbolic/Dtmc.h" +#include "storm/models/symbolic/Ctmc.h" +#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" +#include "storm/models/symbolic/StochasticTwoPlayerGame.h" + #include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/InvalidOperationException.h" @@ -9,6 +15,7 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/utility/constants.h" #include "storm/utility/macros.h" #include "storm/utility/dd.h" @@ -211,6 +218,11 @@ namespace storm { return labelToExpressionMap; } + template<storm::dd::DdType Type, typename ValueType> + std::map<std::string, storm::dd::Bdd<Type>> const& Model<Type, ValueType>::getLabelToBddMap() const { + return labelToBddMap; + } + template<storm::dd::DdType Type, typename ValueType> storm::dd::Add<Type, ValueType> Model<Type, ValueType>::getRowColumnIdentity() const { return (storm::utility::dd::getRowColumnDiagonal<Type>(this->getManager(), this->getRowColumnMetaVariablePairs()) && this->getReachableStates()).template toAdd<ValueType>(); @@ -342,10 +354,35 @@ namespace storm { out << "Variables: \t" << "rows: " << this->rowVariables.size() << " meta variables (" << rowVariableCount << " DD variables)" << ", columns: " << this->columnVariables.size() << " meta variables (" << columnVariableCount << " DD variables)"; } + template<storm::dd::DdType Type, typename ValueType> + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> const& Model<Type, ValueType>::getRowExpressionAdapter() const { + return this->rowExpressionAdapter; + } + template<storm::dd::DdType Type, typename ValueType> bool Model<Type, ValueType>::isSymbolicModel() const { return true; } + + template<storm::dd::DdType Type, typename ValueType> + bool Model<Type, ValueType>::supportsParameters() const { + return std::is_same<ValueType, storm::RationalFunction>::value; + } + + template<storm::dd::DdType Type, typename ValueType> + bool Model<Type, ValueType>::hasParameters() const { + if (!this->supportsParameters()) { + return false; + } + // Check for parameters + for (auto it = this->getTransitionMatrix().begin(false); it != this->getTransitionMatrix().end(); ++it) { + if (!storm::utility::isConstant((*it).second)) { + return true; + } + } + // Only constant values present + return false; + } template<storm::dd::DdType Type, typename ValueType> void Model<Type, ValueType>::addParameters(std::set<storm::RationalFunctionVariable> const& parameters) { @@ -367,11 +404,59 @@ namespace storm { return parameters; } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + typename std::enable_if<!std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type Model<Type, ValueType>::toValueType() const { + STORM_LOG_TRACE("Converting value type of symbolic model from " << typeid(ValueType).name() << " to " << typeid(NewValueType).name() << "."); + + // Make a huge branching here as we cannot make a templated function virtual. + if (this->getType() == storm::models::ModelType::Dtmc) { + return this->template as<storm::models::symbolic::Dtmc<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::Ctmc) { + return this->template as<storm::models::symbolic::Ctmc<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::Mdp) { + return this->template as<storm::models::symbolic::Mdp<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { + return this->template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()->template toValueType<NewValueType>(); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return this->template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>()->template toValueType<NewValueType>(); + } + + STORM_LOG_WARN("Could not convert value type of model."); + return nullptr; + } + + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + typename std::enable_if<std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type Model<Type, ValueType>::toValueType() const { + // Make a huge branching here as we cannot make a templated function virtual. + if (this->getType() == storm::models::ModelType::Dtmc) { + return std::make_shared<storm::models::symbolic::Dtmc<Type, ValueType>>(*this->template as<storm::models::symbolic::Dtmc<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::Ctmc) { + return std::make_shared<storm::models::symbolic::Ctmc<Type, ValueType>>(*this->template as<storm::models::symbolic::Ctmc<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::Mdp) { + return std::make_shared<storm::models::symbolic::Mdp<Type, ValueType>>(*this->template as<storm::models::symbolic::Mdp<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::MarkovAutomaton) { + return std::make_shared<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>(*this->template as<storm::models::symbolic::MarkovAutomaton<Type, ValueType>>()); + } else if (this->getType() == storm::models::ModelType::S2pg) { + return std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>(*this->template as<storm::models::symbolic::StochasticTwoPlayerGame<Type, ValueType>>()); + } + + STORM_LOG_WARN("Could not convert value type of model."); + return nullptr; + } + // Explicitly instantiate the template class. template class Model<storm::dd::DdType::CUDD, double>; template class Model<storm::dd::DdType::Sylvan, double>; - + + template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::CUDD, double>>>::type Model<storm::dd::DdType::CUDD, double>::toValueType<double>() const; + template class Model<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template typename std::enable_if<std::is_same<double, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type Model<storm::dd::DdType::Sylvan, double>::toValueType<double>() const; + template typename std::enable_if<std::is_same<storm::RationalNumber, storm::RationalNumber>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalNumber>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<storm::RationalNumber>() const; + template typename std::enable_if<std::is_same<storm::RationalFunction, storm::RationalFunction>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, storm::RationalFunction>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::toValueType<storm::RationalFunction>() const; + template typename std::enable_if<!std::is_same<storm::RationalNumber, double>::value, std::shared_ptr<Model<storm::dd::DdType::Sylvan, double>>>::type Model<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<double>() const; template class Model<storm::dd::DdType::Sylvan, storm::RationalFunction>; } // namespace symbolic } // namespace models diff --git a/src/storm/models/symbolic/Model.h b/src/storm/models/symbolic/Model.h index 2f39d3970..7b3500bd1 100644 --- a/src/storm/models/symbolic/Model.h +++ b/src/storm/models/symbolic/Model.h @@ -321,12 +321,28 @@ namespace storm { virtual bool isSymbolicModel() const override; + virtual bool supportsParameters() const override; + + /*! + * Checks whether the model has parameters. + * Performance warning: the worst-case complexity is linear in the number of transitions. + * + * @return True iff the model has parameters. + */ + virtual bool hasParameters() const override; + std::vector<std::string> getLabels() const; void addParameters(std::set<storm::RationalFunctionVariable> const& parameters); std::set<storm::RationalFunctionVariable> const& getParameters() const; + template<typename NewValueType> + typename std::enable_if<!std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type toValueType() const; + + template<typename NewValueType> + typename std::enable_if<std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type toValueType() const; + protected: /*! * Sets the transition matrix of the model. @@ -342,6 +358,13 @@ namespace storm { */ std::map<std::string, storm::expressions::Expression> const& getLabelToExpressionMap() const; + /*! + * Retrieves the mapping of labels to their defining expressions. + * + * @returns The mapping of labels to their defining expressions. + */ + std::map<std::string, storm::dd::Bdd<Type>> const& getLabelToBddMap() const; + /*! * Prints the information header (number of states and transitions) of the model to the specified stream. * @@ -371,16 +394,26 @@ namespace storm { */ virtual void printDdVariableInformationToStream(std::ostream& out) const; + protected: + /*! + * Retrieves the expression adapter of this model. + * + * @return The expression adapter. + */ + std::shared_ptr<storm::adapters::AddExpressionAdapter<Type, ValueType>> const& getRowExpressionAdapter() const; + private: // The manager responsible for the decision diagrams. std::shared_ptr<storm::dd::DdManager<Type>> manager; // A vector representing the reachable states of the model. storm::dd::Bdd<Type> reachableStates; - + + protected: // A matrix representing transition relation. storm::dd::Add<Type, ValueType> transitionMatrix; + private: // The meta variables used to encode the rows of the transition matrix. std::set<storm::expressions::Variable> rowVariables; diff --git a/src/storm/models/symbolic/StandardRewardModel.cpp b/src/storm/models/symbolic/StandardRewardModel.cpp index ffd94ad74..38bd56c5c 100644 --- a/src/storm/models/symbolic/StandardRewardModel.cpp +++ b/src/storm/models/symbolic/StandardRewardModel.cpp @@ -196,10 +196,17 @@ namespace storm { } } + template <storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + StandardRewardModel<Type, NewValueType> StandardRewardModel<Type, ValueType>::toValueType() const { + return StandardRewardModel<Type, NewValueType>(this->hasStateRewards() ? boost::make_optional(this->getStateRewardVector().template toValueType<NewValueType>()) : boost::none, this->hasStateActionRewards() ? boost::make_optional(this->getStateActionRewardVector().template toValueType<NewValueType>()) : boost::none, this->hasTransitionRewards() ? boost::make_optional(this->getTransitionRewardMatrix().template toValueType<NewValueType>()) : boost::none); + } + template class StandardRewardModel<storm::dd::DdType::CUDD, double>; template class StandardRewardModel<storm::dd::DdType::Sylvan, double>; template class StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template StandardRewardModel<storm::dd::DdType::Sylvan, double> StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType() const; template class StandardRewardModel<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/models/symbolic/StandardRewardModel.h b/src/storm/models/symbolic/StandardRewardModel.h index c16f144e5..3d705e448 100644 --- a/src/storm/models/symbolic/StandardRewardModel.h +++ b/src/storm/models/symbolic/StandardRewardModel.h @@ -212,6 +212,9 @@ namespace storm { */ void reduceToStateBasedRewards(storm::dd::Add<Type, ValueType> const& transitionMatrix, std::set<storm::expressions::Variable> const& rowVariables, std::set<storm::expressions::Variable> const& columnVariables, bool reduceToStateRewards); + template<typename NewValueType> + StandardRewardModel<Type, NewValueType> toValueType() const; + private: // The state reward vector. boost::optional<storm::dd::Add<Type, ValueType>> optionalStateRewardVector; diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp index b4b59e934..677d80912 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.cpp @@ -82,11 +82,30 @@ namespace storm { return player2Variables; } + template<storm::dd::DdType Type, typename ValueType> + template<typename NewValueType> + std::shared_ptr<StochasticTwoPlayerGame<Type, NewValueType>> StochasticTwoPlayerGame<Type, ValueType>::toValueType() const { + typedef typename NondeterministicModel<Type, NewValueType>::RewardModelType NewRewardModelType; + std::unordered_map<std::string, NewRewardModelType> newRewardModels; + + for (auto const& e : this->getRewardModels()) { + newRewardModels.emplace(e.first, e.second.template toValueType<NewValueType>()); + } + + auto newLabelToBddMap = this->getLabelToBddMap(); + newLabelToBddMap.erase("init"); + newLabelToBddMap.erase("deadlock"); + + return std::make_shared<StochasticTwoPlayerGame<Type, NewValueType>>(this->getManagerAsSharedPointer(), this->getReachableStates(), this->getInitialStates(), this->getDeadlockStates(), this->getTransitionMatrix().template toValueType<NewValueType>(), this->getRowVariables(), this->getColumnVariables(), this->getRowColumnMetaVariablePairs(), this->getPlayer1Variables(), this->getPlayer2Variables(), this->getNondeterminismVariables(), newLabelToBddMap, newRewardModels); + + } + // Explicitly instantiate the template class. template class StochasticTwoPlayerGame<storm::dd::DdType::CUDD, double>; template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, double>; #ifdef STORM_HAVE_CARL template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template std::shared_ptr<StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, double>> StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalNumber>::toValueType<double>() const; template class StochasticTwoPlayerGame<storm::dd::DdType::Sylvan, storm::RationalFunction>; #endif diff --git a/src/storm/models/symbolic/StochasticTwoPlayerGame.h b/src/storm/models/symbolic/StochasticTwoPlayerGame.h index d3f009593..569d258dd 100644 --- a/src/storm/models/symbolic/StochasticTwoPlayerGame.h +++ b/src/storm/models/symbolic/StochasticTwoPlayerGame.h @@ -117,6 +117,9 @@ namespace storm { */ storm::dd::Bdd<Type> getIllegalPlayer2Mask() const; + template<typename NewValueType> + std::shared_ptr<StochasticTwoPlayerGame<Type, NewValueType>> toValueType() const; + private: /*! * Prepare all illegal masks. diff --git a/src/storm/parser/DirectEncodingParser.cpp b/src/storm/parser/DirectEncodingParser.cpp index 45768f908..93d8a60f2 100644 --- a/src/storm/parser/DirectEncodingParser.cpp +++ b/src/storm/parser/DirectEncodingParser.cpp @@ -25,32 +25,6 @@ namespace storm { namespace parser { - template<typename ValueType> - void ValueParser<ValueType>::addParameter(std::string const& parameter) { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); - } - - template<> - void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) { - //STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions."); - storm::expressions::Variable var = manager->declareRationalVariable(parameter); - identifierMapping.emplace(var.getName(), var); - parser.setIdentifierMapping(identifierMapping); - STORM_LOG_TRACE("Added parameter: " << var.getName()); - } - - template<> - double ValueParser<double>::parseValue(std::string const& value) const { - return boost::lexical_cast<double>(value); - } - - template<> - storm::RationalFunction ValueParser<storm::RationalFunction>::parseValue(std::string const& value) const { - storm::RationalFunction rationalFunction = evaluator.asRational(parser.parseFromString(value)); - STORM_LOG_TRACE("Parsed expression: " << rationalFunction); - return rationalFunction; - } - template<typename ValueType, typename RewardModelType> std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> DirectEncodingParser<ValueType, RewardModelType>::parseModel(std::string const& filename) { @@ -66,26 +40,26 @@ namespace storm { bool sawParameters = false; size_t nrStates = 0; storm::models::ModelType type; - std::vector<std::string> rewardModelNames; - - std::shared_ptr<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>> modelComponents; + std::shared_ptr<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>> modelComponents; // Parse header - while(std::getline(file, line)) { - if(line.empty() || boost::starts_with(line, "//")) { + while (std::getline(file, line)) { + if (line.empty() || boost::starts_with(line, "//")) { continue; } if (boost::starts_with(line, "@type: ")) { + // Parse type STORM_LOG_THROW(!sawType, storm::exceptions::WrongFormatException, "Type declared twice"); type = storm::models::getModelType(line.substr(7)); STORM_LOG_TRACE("Model type: " << type); - STORM_LOG_THROW(type != storm::models::ModelType::MarkovAutomaton, storm::exceptions::NotSupportedException, "Markov Automata in DRN format are not supported (unclear indication of Markovian Choices in DRN format)"); STORM_LOG_THROW(type != storm::models::ModelType::S2pg, storm::exceptions::NotSupportedException, "Stochastic Two Player Games in DRN format are not supported."); sawType = true; - } - if(line == "@parameters") { + + } else if (line == "@parameters") { + // Parse parameters + STORM_LOG_THROW(!sawParameters, storm::exceptions::WrongFormatException, "Parameters declared twice"); std::getline(file, line); if (line != "") { std::vector<std::string> parameters; @@ -96,26 +70,28 @@ namespace storm { } } sawParameters = true; - } - if(line == "@reward_models") { + + } else if (line == "@reward_models") { + // Parse reward models STORM_LOG_THROW(rewardModelNames.size() == 0, storm::exceptions::WrongFormatException, "Reward model names declared twice"); std::getline(file, line); boost::split(rewardModelNames, line, boost::is_any_of("\t ")); - } - if(line == "@nr_states") { + } else if (line == "@nr_states") { + // Parse no. of states STORM_LOG_THROW(nrStates == 0, storm::exceptions::WrongFormatException, "Number states declared twice"); std::getline(file, line); - nrStates = boost::lexical_cast<size_t>(line); - - } - if(line == "@model") { + nrStates = NumberParser<size_t>::parse(line); + } else if (line == "@model") { + // Parse rest of the model STORM_LOG_THROW(sawType, storm::exceptions::WrongFormatException, "Type has to be declared before model."); STORM_LOG_THROW(sawParameters, storm::exceptions::WrongFormatException, "Parameters have to be declared before model."); - STORM_LOG_THROW(nrStates != 0, storm::exceptions::WrongFormatException, "Nr States has to be declared before model."); + STORM_LOG_THROW(nrStates != 0, storm::exceptions::WrongFormatException, "No. of states has to be declared before model."); // Construct model components modelComponents = parseStates(file, type, nrStates, valueParser, rewardModelNames); break; + } else { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse line '" << line << "'."); } } // Done parsing @@ -130,15 +106,21 @@ namespace storm { // Initialize auto modelComponents = std::make_shared<storm::storage::sparse::ModelComponents<ValueType, RewardModelType>>(); bool nonDeterministic = (type == storm::models::ModelType::Mdp || type == storm::models::ModelType::MarkovAutomaton); + bool continousTime = (type == storm::models::ModelType::Ctmc || type == storm::models::ModelType::MarkovAutomaton); storm::storage::SparseMatrixBuilder<ValueType> builder = storm::storage::SparseMatrixBuilder<ValueType>(0, 0, 0, false, nonDeterministic, 0); modelComponents->stateLabeling = storm::models::sparse::StateLabeling(stateSize); std::vector<std::vector<ValueType>> stateRewards; - + if (continousTime) { + modelComponents->exitRates = std::vector<ValueType>(stateSize); + if (type == storm::models::ModelType::MarkovAutomaton) { + modelComponents->markovianStates = storm::storage::BitVector(stateSize); + } + } // We parse rates for continuous time models. if (type == storm::models::ModelType::Ctmc) { modelComponents->rateTransitions = true; } - + // Iterate over all lines std::string line; size_t row = 0; @@ -154,34 +136,66 @@ namespace storm { } else { ++state; } - line = line.substr(6); - size_t parsedId; - size_t posId = line.find(" "); - if (posId != std::string::npos) { - parsedId = boost::lexical_cast<size_t>(line.substr(0, posId)); + STORM_LOG_TRACE("New state " << state); - // Parse rewards and labels - line = line.substr(posId+1); - // Check for rewards - if (boost::starts_with(line, "[")) { - // Rewards found - size_t posEndReward = line.find(']'); - STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing."); - std::string rewardsStr = line.substr(1, posEndReward-1); - STORM_LOG_TRACE("State rewards: " << rewardsStr); - std::vector<std::string> rewards; - boost::split(rewards, rewardsStr, boost::is_any_of(",")); - if (stateRewards.size() < rewards.size()) { - stateRewards.resize(rewards.size(), std::vector<ValueType>(stateSize, storm::utility::zero<ValueType>())); - } - auto stateRewardsIt = stateRewards.begin(); - for (auto const& rew : rewards) { - (*stateRewardsIt)[state] = valueParser.parseValue(rew); - ++stateRewardsIt; - } - line = line.substr(posEndReward+1); + // Parse state id + line = line.substr(6); // Remove "state " + std::string curString = line; + size_t posEnd = line.find(" "); + if (posEnd != std::string::npos) { + curString = line.substr(0, posEnd); + line = line.substr(posEnd+1); + } else { + line = ""; + } + size_t parsedId = NumberParser<size_t>::parse(curString); + STORM_LOG_ASSERT(state == parsedId, "State ids do not correspond."); + if (nonDeterministic) { + STORM_LOG_TRACE("new Row Group starts at " << row << "."); + builder.newRowGroup(row); + } + + if (type == storm::models::ModelType::Ctmc || type == storm::models::ModelType::MarkovAutomaton) { + // Parse exit rate for CTMC or MA + STORM_LOG_THROW(boost::starts_with(line, "!"), storm::exceptions::WrongFormatException, "Exit rate missing."); + line = line.substr(1); //Remove "!" + curString = line; + posEnd = line.find(" "); + if (posEnd != std::string::npos) { + curString = line.substr(0, posEnd); + line = line.substr(posEnd+1); + } else { + line = ""; + } + ValueType exitRate = valueParser.parseValue(curString); + if (type == storm::models::ModelType::MarkovAutomaton && !storm::utility::isZero<ValueType>(exitRate)) { + modelComponents->markovianStates.get().set(state); + } + STORM_LOG_TRACE("Exit rate " << exitRate); + modelComponents->exitRates.get()[state] = exitRate; + } + + if (boost::starts_with(line, "[")) { + // Parse rewards + size_t posEndReward = line.find(']'); + STORM_LOG_THROW(posEndReward != std::string::npos, storm::exceptions::WrongFormatException, "] missing."); + std::string rewardsStr = line.substr(1, posEndReward-1); + STORM_LOG_TRACE("State rewards: " << rewardsStr); + std::vector<std::string> rewards; + boost::split(rewards, rewardsStr, boost::is_any_of(",")); + if (stateRewards.size() < rewards.size()) { + stateRewards.resize(rewards.size(), std::vector<ValueType>(stateSize, storm::utility::zero<ValueType>())); + } + auto stateRewardsIt = stateRewards.begin(); + for (auto const& rew : rewards) { + (*stateRewardsIt)[state] = valueParser.parseValue(rew); + ++stateRewardsIt; } - // Check for labels + line = line.substr(posEndReward+1); + } + + // Parse labels + if (!line.empty()) { std::vector<std::string> labels; boost::split(labels, line, boost::is_any_of(" ")); for (std::string label : labels) { @@ -189,18 +203,10 @@ namespace storm { modelComponents->stateLabeling.addLabel(label); } modelComponents->stateLabeling.addLabelToState(label, state); - STORM_LOG_TRACE("New label: " << label); + STORM_LOG_TRACE("New label: '" << label << "'"); } - } else { - // Only state id given - parsedId = boost::lexical_cast<size_t>(line); - } - STORM_LOG_TRACE("New state " << state); - STORM_LOG_ASSERT(state == parsedId, "State ids do not correspond."); - if (nonDeterministic) { - STORM_LOG_TRACE("new Row Group starts at " << row << "."); - builder.newRowGroup(row); } + } else if (boost::starts_with(line, "\taction ")) { // New action if (firstAction) { @@ -208,8 +214,8 @@ namespace storm { } else { ++row; } - line = line.substr(8); STORM_LOG_TRACE("New action: " << row); + line = line.substr(8); //Remove "\taction " // Check for rewards if (boost::starts_with(line, "[")) { // Rewards found @@ -227,7 +233,7 @@ namespace storm { // New transition size_t posColon = line.find(":"); STORM_LOG_ASSERT(posColon != std::string::npos, "':' not found."); - size_t target = boost::lexical_cast<size_t>(line.substr(2, posColon-3)); + size_t target = NumberParser<size_t>::parse(line.substr(2, posColon-3)); std::string valueStr = line.substr(posColon+2); ValueType value = valueParser.parseValue(valueStr); STORM_LOG_TRACE("Transition " << row << " -> " << target << ": " << value); @@ -253,9 +259,7 @@ namespace storm { // Template instantiations. template class DirectEncodingParser<double>; - -#ifdef STORM_HAVE_CARL template class DirectEncodingParser<storm::RationalFunction>; -#endif + } // namespace parser } // namespace storm diff --git a/src/storm/parser/DirectEncodingParser.h b/src/storm/parser/DirectEncodingParser.h index db1bac12e..456445e1c 100644 --- a/src/storm/parser/DirectEncodingParser.h +++ b/src/storm/parser/DirectEncodingParser.h @@ -1,53 +1,14 @@ #ifndef STORM_PARSER_DIRECTENCODINGPARSER_H_ #define STORM_PARSER_DIRECTENCODINGPARSER_H_ +#include "storm/parser/ValueParser.h" #include "storm/models/sparse/Model.h" #include "storm/models/sparse/StandardRewardModel.h" -#include "storm/storage/expressions/ExpressionManager.h" -#include "storm/parser/ExpressionParser.h" -#include "storm/storage/expressions/ExpressionEvaluator.h" #include "storm/storage/sparse/ModelComponents.h" namespace storm { namespace parser { - /*! - * Parser for values according to their ValueType. - */ - template<typename ValueType> - class ValueParser { - public: - - ValueParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { - } - - /*! - * Parse ValueType from string. - * - * @param value String containing the value. - * - * @return ValueType - */ - ValueType parseValue(std::string const& value) const; - - /*! - * Add declaration of parameter. - * - * @param parameter New parameter. - */ - void addParameter(std::string const& parameter); - - private: - - std::shared_ptr<storm::expressions::ExpressionManager> manager; - - storm::parser::ExpressionParser parser; - - storm::expressions::ExpressionEvaluator<ValueType> evaluator; - - std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; - }; - /*! * Parser for models in the DRN format with explicit encoding. */ diff --git a/src/storm/parser/ExpressionCreator.cpp b/src/storm/parser/ExpressionCreator.cpp index 6266206ef..b96dd5080 100644 --- a/src/storm/parser/ExpressionCreator.cpp +++ b/src/storm/parser/ExpressionCreator.cpp @@ -120,11 +120,12 @@ namespace storm { return manager.boolean(false); } - storm::expressions::Expression ExpressionCreator::createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const { + storm::expressions::Expression ExpressionCreator::createPowerModuloExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const { if (this->createExpressions) { try { switch (operatorType) { case storm::expressions::OperatorType::Power: return e1 ^ e2; break; + case storm::expressions::OperatorType::Modulo: return e1 % e2; break; default: STORM_LOG_ASSERT(false, "Invalid operation."); break; } } catch (storm::exceptions::InvalidTypeException const& e) { diff --git a/src/storm/parser/ExpressionCreator.h b/src/storm/parser/ExpressionCreator.h index bf454c552..20bcc5854 100644 --- a/src/storm/parser/ExpressionCreator.h +++ b/src/storm/parser/ExpressionCreator.h @@ -67,7 +67,7 @@ namespace storm { storm::expressions::Expression createEqualsExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createPlusExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; - storm::expressions::Expression createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; + storm::expressions::Expression createPowerModuloExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2, bool& pass) const; storm::expressions::Expression createUnaryExpression(boost::optional<storm::expressions::OperatorType> const& operatorType, storm::expressions::Expression const& e1, bool& pass) const; storm::expressions::Expression createRationalLiteralExpression(storm::RationalNumber const& value, bool& pass) const; storm::expressions::Expression createIntegerLiteralExpression(int value, bool& pass) const; diff --git a/src/storm/parser/ExpressionParser.cpp b/src/storm/parser/ExpressionParser.cpp index f78e47d13..64e185b54 100644 --- a/src/storm/parser/ExpressionParser.cpp +++ b/src/storm/parser/ExpressionParser.cpp @@ -36,7 +36,7 @@ namespace boost { namespace storm { namespace parser { - ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool enableErrorHandling, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), infixPowerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), prefixPowerOperator_(), invalidIdentifiers_(invalidIdentifiers_) { + ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool enableErrorHandling, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), infixPowerModuloOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), prefixPowerModuloOperator_(), invalidIdentifiers_(invalidIdentifiers_) { expressionCreator = new ExpressionCreator(manager); @@ -58,11 +58,13 @@ namespace storm { minMaxExpression.name("min/max expression"); if (allowBacktracking) { - prefixPowerExpression = ((prefixPowerOperator_ >> qi::lit("(")) >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; + prefixPowerModuloExpression = ((prefixPowerModuloOperator_ >> qi::lit("(")) >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)] + | (qi::lit("func") >> qi::lit("(") >> prefixPowerModuloOperator_ >> qi::lit(",") >> expression >> qi::lit(",") >> expression >> qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; } else { - prefixPowerExpression = ((prefixPowerOperator_ >> qi::lit("(")) > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; + prefixPowerModuloExpression = ((prefixPowerModuloOperator_ >> qi::lit("(")) > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)] + | ((qi::lit("func") >> qi::lit("(")) > prefixPowerModuloOperator_ > qi::lit(",") > expression > qi::lit(",") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_2, qi::_1, qi::_3, qi::_pass)]; } - prefixPowerExpression.name("pow expression"); + prefixPowerModuloExpression.name("power/modulo expression"); identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionCreator::getIdentifierExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_pass)]; identifierExpression.name("identifier expression"); @@ -73,23 +75,23 @@ namespace storm { | qi::int_[qi::_val = phoenix::bind(&ExpressionCreator::createIntegerLiteralExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_pass)]; literalExpression.name("literal expression"); - atomicExpression = floorCeilExpression | prefixPowerExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | identifierExpression | literalExpression; + atomicExpression = floorCeilExpression | prefixPowerModuloExpression | minMaxExpression | (qi::lit("(") >> expression >> qi::lit(")")) | identifierExpression | literalExpression; atomicExpression.name("atomic expression"); unaryExpression = (-unaryOperator_ >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createUnaryExpression, phoenix::ref(*expressionCreator), qi::_1, qi::_2, qi::_pass)]; unaryExpression.name("unary expression"); if (allowBacktracking) { - infixPowerExpression = unaryExpression[qi::_val = qi::_1] >> -(infixPowerOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + infixPowerModuloExpression = unaryExpression[qi::_val = qi::_1] >> -(infixPowerModuloOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } else { - infixPowerExpression = unaryExpression[qi::_val = qi::_1] > -(infixPowerOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + infixPowerModuloExpression = unaryExpression[qi::_val = qi::_1] > -(infixPowerModuloOperator_ >> expression)[qi::_val = phoenix::bind(&ExpressionCreator::createPowerModuloExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } - infixPowerExpression.name("power expression"); + infixPowerModuloExpression.name("power/modulo expression"); if (allowBacktracking) { - multiplicationExpression = infixPowerExpression[qi::_val = qi::_1] >> *(multiplicationOperator_ >> infixPowerExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + multiplicationExpression = infixPowerModuloExpression[qi::_val = qi::_1] >> *(multiplicationOperator_ >> infixPowerModuloExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } else { - multiplicationExpression = infixPowerExpression[qi::_val = qi::_1] > *(multiplicationOperator_ > infixPowerExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; + multiplicationExpression = infixPowerModuloExpression[qi::_val = qi::_1] > *(multiplicationOperator_ > infixPowerModuloExpression)[qi::_val = phoenix::bind(&ExpressionCreator::createMultExpression, phoenix::ref(*expressionCreator), qi::_val, qi::_1, qi::_2, qi::_pass)]; } multiplicationExpression.name("multiplication expression"); @@ -196,7 +198,7 @@ namespace storm { try { // Start parsing. - bool succeeded = qi::phrase_parse(iter, last, *this, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, *this, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse expression '" << expressionString << "'."); STORM_LOG_DEBUG("Parsed expression successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/ExpressionParser.h b/src/storm/parser/ExpressionParser.h index da3282b1b..cb415c53e 100644 --- a/src/storm/parser/ExpressionParser.h +++ b/src/storm/parser/ExpressionParser.h @@ -18,6 +18,8 @@ namespace storm { template<typename NumberType> struct RationalPolicies : boost::spirit::qi::strict_real_policies<NumberType> { static const bool expect_dot = true; + static const bool allow_leading_dot = true; + static const bool allow_trailing_dot = false; template <typename It, typename Attr> static bool parse_nan(It&, It const&, Attr&) { return false; } @@ -149,15 +151,16 @@ namespace storm { // A parser used for recognizing the operators at the "multiplication" precedence level. multiplicationOperatorStruct multiplicationOperator_; - struct infixPowerOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { - infixPowerOperatorStruct() { + struct infixPowerModuloOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { + infixPowerModuloOperatorStruct() { add - ("^", storm::expressions::OperatorType::Power); + ("^", storm::expressions::OperatorType::Power) + ("%", storm::expressions::OperatorType::Modulo); } }; // A parser used for recognizing the operators at the "power" precedence level. - infixPowerOperatorStruct infixPowerOperator_; + infixPowerModuloOperatorStruct infixPowerModuloOperator_; struct unaryOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { unaryOperatorStruct() { @@ -192,15 +195,16 @@ namespace storm { // A parser used for recognizing the operators at the "min/max" precedence level. minMaxOperatorStruct minMaxOperator_; - struct prefixPowerOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { - prefixPowerOperatorStruct() { + struct prefixPowerModuloOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { + prefixPowerModuloOperatorStruct() { add - ("pow", storm::expressions::OperatorType::Power); + ("pow", storm::expressions::OperatorType::Power) + ("mod", storm::expressions::OperatorType::Modulo); } }; // A parser used for recognizing the operators at the "power" precedence level. - prefixPowerOperatorStruct prefixPowerOperator_; + prefixPowerModuloOperatorStruct prefixPowerModuloOperator_; ExpressionCreator* expressionCreator; @@ -218,8 +222,8 @@ namespace storm { qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> equalityExpression; qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression; qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression; - qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> prefixPowerExpression; - qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> infixPowerExpression; + qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> prefixPowerModuloExpression; + qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> infixPowerModuloExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression; qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression; diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index e592f141c..d8b9c2df2 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -5,7 +5,6 @@ #include "storm/parser/SpiritErrorHandler.h" #include "storm/storage/prism/Program.h" -#include "storm/storage/jani/Model.h" #include "storm/logic/Formulas.h" @@ -97,7 +96,7 @@ namespace storm { // Create grammar. try { // Start parsing. - bool succeeded = qi::phrase_parse(iter, last, *grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + bool succeeded = qi::phrase_parse(iter, last, *grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse formula."); STORM_LOG_DEBUG("Parsed formula successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/FormulaParserGrammar.cpp b/src/storm/parser/FormulaParserGrammar.cpp index 9e8191ad2..2cd8773c9 100644 --- a/src/storm/parser/FormulaParserGrammar.cpp +++ b/src/storm/parser/FormulaParserGrammar.cpp @@ -147,7 +147,7 @@ namespace storm { start = (qi::eps >> filterProperty[phoenix::push_back(qi::_val, qi::_1)] | qi::eps(phoenix::bind(&FormulaParserGrammar::areConstantDefinitionsAllowed, phoenix::ref(*this))) >> constantDefinition | qi::eps) - % +(qi::char_("\n;")) >> qi::skip(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; + % +(qi::char_("\n;")) >> qi::skip(storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; start.name("start"); // Enable the following lines to print debug output for most the rules. diff --git a/src/storm/parser/ImcaMarkovAutomatonParser.cpp b/src/storm/parser/ImcaMarkovAutomatonParser.cpp index 01cb93671..f55d09219 100644 --- a/src/storm/parser/ImcaMarkovAutomatonParser.cpp +++ b/src/storm/parser/ImcaMarkovAutomatonParser.cpp @@ -248,7 +248,7 @@ namespace storm { try { // Start parsing. ImcaParserGrammar<ValueType> grammar; - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), components); + bool succeeded = qi::phrase_parse(iter, last, grammar, storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), components); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse imca file."); STORM_LOG_DEBUG("Parsed imca file successfully."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { diff --git a/src/storm/parser/JaniParser.cpp b/src/storm/parser/JaniParser.cpp index 3de6bb2cc..725ab0a9d 100644 --- a/src/storm/parser/JaniParser.cpp +++ b/src/storm/parser/JaniParser.cpp @@ -140,9 +140,9 @@ namespace storm { auto prop = this->parseProperty(propertyEntry, globalVars, constants); properties.emplace(prop.getName(), prop); } catch (storm::exceptions::NotSupportedException const& ex) { - STORM_LOG_WARN("Cannot handle property " << ex.what()); + STORM_LOG_WARN("Cannot handle property: " << ex.what()); } catch (storm::exceptions::NotImplementedException const& ex) { - STORM_LOG_WARN("Cannot handle property " << ex.what()); + STORM_LOG_WARN("Cannot handle property: " << ex.what()); } } } @@ -168,7 +168,6 @@ namespace storm { if (piStructure.count("lower") > 0) { pi.lowerBound = parseExpression(piStructure.at("lower"), "Lower bound for property interval", {}, {}); // TODO substitute constants. - std::cout << "have lower bound" << std::endl; STORM_LOG_THROW(!pi.lowerBound.containsVariables(), storm::exceptions::NotSupportedException, "Only constant expressions are supported as lower bounds"); } if (piStructure.count("lower-exclusive") > 0) { @@ -177,7 +176,6 @@ namespace storm { } if (piStructure.count("upper") > 0) { - std::cout << "have upper bound" << std::endl; pi.upperBound = parseExpression(piStructure.at("upper"), "Upper bound for property interval", {}, {}); // TODO substitute constants. STORM_LOG_THROW(!pi.upperBound.containsVariables(), storm::exceptions::NotSupportedException, "Only constant expressions are supported as upper bounds"); @@ -433,6 +431,12 @@ namespace storm { assert(args.size() == 2); storm::logic::BinaryBooleanStateFormula::OperatorType oper = opString == "∧" ? storm::logic::BinaryBooleanStateFormula::OperatorType::And : storm::logic::BinaryBooleanStateFormula::OperatorType::Or; return std::make_shared<storm::logic::BinaryBooleanStateFormula const>(oper, args[0], args[1]); + } else if (opString == "⇒") { + assert(bound == boost::none); + std::vector<std::shared_ptr<storm::logic::Formula const>> args = parseBinaryFormulaArguments(propertyStructure, formulaContext, opString, globalVars, constants, ""); + assert(args.size() == 2); + std::shared_ptr<storm::logic::UnaryBooleanStateFormula const> tmp = std::make_shared<storm::logic::UnaryBooleanStateFormula const>(storm::logic::UnaryBooleanStateFormula::OperatorType::Not, args[0]); + return std::make_shared<storm::logic::BinaryBooleanStateFormula const>(storm::logic::BinaryBooleanStateFormula::OperatorType::Or, tmp, args[1]); } else if (opString == "¬") { assert(bound == boost::none); std::vector<std::shared_ptr<storm::logic::Formula const>> args = parseUnaryFormulaArgument(propertyStructure, formulaContext, opString, globalVars, constants, ""); @@ -514,12 +518,27 @@ namespace storm { } STORM_LOG_THROW(expressionStructure.count("states") == 1, storm::exceptions::InvalidJaniException, "Filter must have a states description"); - STORM_LOG_THROW(expressionStructure.at("states").count("op") > 0, storm::exceptions::NotImplementedException, "We only support properties where the filter has initial states"); - std::string statesDescr = getString(expressionStructure.at("states").at("op"), "Filtered states in property named " + name); - STORM_LOG_THROW(statesDescr == "initial", storm::exceptions::NotImplementedException, "Only initial states are allowed as set of states we are interested in."); + std::shared_ptr<storm::logic::Formula const> statesFormula; + if (expressionStructure.at("states").count("op") > 0) { + std::string statesDescr = getString(expressionStructure.at("states").at("op"), "Filtered states in property named " + name); + if (statesDescr == "initial") { + statesFormula = std::make_shared<storm::logic::AtomicLabelFormula>("init"); + } + } + if (!statesFormula) { + try { + // Try to parse the states as formula. + statesFormula = parseFormula(expressionStructure.at("states"), storm::logic::FormulaContext::Undefined, globalVars, constants, "Values of property " + name); + } catch (storm::exceptions::NotSupportedException const& ex) { + throw ex; + } catch (storm::exceptions::NotImplementedException const& ex) { + throw ex; + } + } + STORM_LOG_THROW(statesFormula, storm::exceptions::NotImplementedException, "Could not derive states formula."); STORM_LOG_THROW(expressionStructure.count("values") == 1, storm::exceptions::InvalidJaniException, "Values as input for a filter must be given"); auto formula = parseFormula(expressionStructure.at("values"), storm::logic::FormulaContext::Undefined, globalVars, constants, "Values of property " + name); - return storm::jani::Property(name, storm::jani::FilterExpression(formula, ft), comment); + return storm::jani::Property(name, storm::jani::FilterExpression(formula, ft, statesFormula), comment); } std::shared_ptr<storm::jani::Constant> JaniParser::parseConstant(json const& constantStructure, std::unordered_map<std::string, std::shared_ptr<storm::jani::Constant>> const& constants, std::string const& scopeDescription) { @@ -687,6 +706,9 @@ namespace storm { } STORM_LOG_THROW(lowerboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Lower bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed"); STORM_LOG_THROW(upperboundExpr.hasIntegerType(), storm::exceptions::InvalidJaniException, "Upper bound for bounded integer variable " << name << "(scope: " << scopeDescription << ") must be integer-typed"); + if(!lowerboundExpr.containsVariables() && !upperboundExpr.containsVariables()) { + STORM_LOG_THROW(lowerboundExpr.evaluateAsInt() <= upperboundExpr.evaluateAsInt(), storm::exceptions::InvalidJaniException, "Lower bound must not be larger than upper bound for bounded integer variable " << name << "(scope: " << scopeDescription << ")"); + } return storm::jani::makeBoundedIntegerVariable(name, expressionManager->declareIntegerVariable(exprManagerName), initVal, transientVar, lowerboundExpr, upperboundExpr); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Unsupported base " << basictype << " for bounded variable " << name << "(scope: " << scopeDescription << ") "); @@ -805,7 +827,7 @@ namespace storm { ensureBooleanType(arguments[1], opstring, 1, scopeDescription); return arguments[0] && arguments[1]; } else if (opstring == "⇒") { - arguments = parseUnaryExpressionArguments(expressionStructure, opstring, scopeDescription, globalVars, constants, localVars, returnNoneInitializedOnUnknownOperator); + arguments = parseBinaryExpressionArguments(expressionStructure, opstring, scopeDescription, globalVars, constants, localVars, returnNoneInitializedOnUnknownOperator); assert(arguments.size() == 2); if(!arguments[0].isInitialized() || !arguments[1].isInitialized()) { return storm::expressions::Expression(); diff --git a/src/storm/parser/MarkovAutomatonParser.cpp b/src/storm/parser/MarkovAutomatonParser.cpp index 0921556fd..829c7256f 100644 --- a/src/storm/parser/MarkovAutomatonParser.cpp +++ b/src/storm/parser/MarkovAutomatonParser.cpp @@ -25,36 +25,36 @@ namespace storm { // Parse the state labeling. storm::models::sparse::StateLabeling resultLabeling(storm::parser::SparseItemLabelingParser::parseAtomicPropositionLabeling(transitionMatrix.getColumnCount(), labelingFilename)); - // Cunstruct the result components - storm::storage::sparse::ModelComponents<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> componets(std::move(transitionMatrix), std::move(resultLabeling)); - componets.rateTransitions = true; - componets.markovianStates = std::move(transitionResult.markovianStates); - componets.exitRates = std::move(transitionResult.exitRates); + // Construct the result components + storm::storage::sparse::ModelComponents<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> components(std::move(transitionMatrix), std::move(resultLabeling)); + components.rateTransitions = true; + components.markovianStates = std::move(transitionResult.markovianStates); + components.exitRates = std::move(transitionResult.exitRates); // If given, parse the state rewards file. boost::optional<std::vector<RewardValueType>> stateRewards; if (!stateRewardFilename.empty()) { - stateRewards.reset(storm::parser::SparseStateRewardParser<RewardValueType>::parseSparseStateReward(componets.transitionMatrix.getColumnCount(), stateRewardFilename)); + stateRewards.reset(storm::parser::SparseStateRewardParser<RewardValueType>::parseSparseStateReward(components.transitionMatrix.getColumnCount(), stateRewardFilename)); } // Only parse transition rewards if a file is given. boost::optional<storm::storage::SparseMatrix<RewardValueType>> transitionRewards; if (!transitionRewardFilename.empty()) { - transitionRewards = std::move(storm::parser::NondeterministicSparseTransitionParser<RewardValueType>::parseNondeterministicTransitionRewards(transitionRewardFilename, componets.transitionMatrix)); + transitionRewards = std::move(storm::parser::NondeterministicSparseTransitionParser<RewardValueType>::parseNondeterministicTransitionRewards(transitionRewardFilename, components.transitionMatrix)); } if (stateRewards || transitionRewards) { - componets.rewardModels.insert(std::make_pair("", storm::models::sparse::StandardRewardModel<RewardValueType>(std::move(stateRewards), boost::none, std::move(transitionRewards)))); + components.rewardModels.insert(std::make_pair("", storm::models::sparse::StandardRewardModel<RewardValueType>(std::move(stateRewards), boost::none, std::move(transitionRewards)))); } // Only parse choice labeling if a file is given. boost::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling; if (!choiceLabelingFilename.empty()) { - componets.choiceLabeling = storm::parser::SparseItemLabelingParser::parseChoiceLabeling(componets.transitionMatrix.getRowCount(), choiceLabelingFilename, componets.transitionMatrix.getRowGroupIndices()); + components.choiceLabeling = storm::parser::SparseItemLabelingParser::parseChoiceLabeling(components.transitionMatrix.getRowCount(), choiceLabelingFilename, components.transitionMatrix.getRowGroupIndices()); } // generate the Markov Automaton. - return storm::models::sparse::MarkovAutomaton<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> (std::move(componets)); + return storm::models::sparse::MarkovAutomaton<ValueType, storm::models::sparse::StandardRewardModel<RewardValueType>> (std::move(components)); } template class MarkovAutomatonParser<double, double>; diff --git a/src/storm/parser/PrismParser.cpp b/src/storm/parser/PrismParser.cpp index 18f42d39c..ca59981cb 100644 --- a/src/storm/parser/PrismParser.cpp +++ b/src/storm/parser/PrismParser.cpp @@ -37,11 +37,13 @@ namespace storm { } storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool prismCompatibility) { - PositionIteratorType first(input.begin()); + bool hasByteOrderMark = input.size() >= 3 && input[0] == '\xEF' && input[1] == '\xBB' && input[2] == '\xBF'; + + PositionIteratorType first(hasByteOrderMark ? input.begin() + 3 : input.begin()); PositionIteratorType iter = first; PositionIteratorType last(input.end()); STORM_LOG_ASSERT(first != last, "Illegal input to PRISM parser."); - + // Create empty result; storm::prism::Program result; @@ -49,7 +51,8 @@ namespace storm { storm::parser::PrismParser grammar(filename, first, prismCompatibility); try { // Start first run. - bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + storm::spirit_encoding::space_type space; + bool succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in first pass."); STORM_LOG_DEBUG("First pass of parsing PRISM input finished."); @@ -58,7 +61,7 @@ namespace storm { iter = first; last = PositionIteratorType(input.end()); grammar.moveToSecondRun(); - succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); + succeeded = qi::phrase_parse(iter, last, grammar, space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result); STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in second pass."); } catch (qi::expectation_failure<PositionIteratorType> const& e) { // If the parser expected content different than the one provided, display information about the location of the error. @@ -113,7 +116,7 @@ namespace storm { booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > -((qi::lit("init") > expression_[qi::_a = qi::_1]) | qi::attr(manager->boolean(false))) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_a)]; booleanVariableDefinition.name("boolean variable definition"); - integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression_ > qi::lit("..") > expression_ > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression_[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)]; + integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")) > expression_ > qi::lit("..") > expression_ > qi::lit("]") > -(qi::lit("init") > expression_[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)]; integerVariableDefinition.name("integer variable definition"); variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]); diff --git a/src/storm/parser/SpiritParserDefinitions.h b/src/storm/parser/SpiritParserDefinitions.h index 412a6bc37..d48d7a7a6 100644 --- a/src/storm/parser/SpiritParserDefinitions.h +++ b/src/storm/parser/SpiritParserDefinitions.h @@ -6,6 +6,7 @@ // Include boost spirit. #define BOOST_SPIRIT_USE_PHOENIX_V3 +#define BOOST_SPIRIT_UNICODE #include <boost/typeof/typeof.hpp> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/phoenix.hpp> @@ -21,6 +22,10 @@ typedef std::string::const_iterator BaseIteratorType; typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType; typedef PositionIteratorType Iterator; -typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi)) Skipper; +namespace storm { + namespace spirit_encoding = boost::spirit::unicode; +} + +typedef BOOST_TYPEOF(storm::spirit_encoding::space_type() | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi)) Skipper; #endif /* STORM_PARSER_SPIRITPARSERDEFINITIONS_H_ */ diff --git a/src/storm/parser/ValueParser.cpp b/src/storm/parser/ValueParser.cpp new file mode 100644 index 000000000..17495b0d9 --- /dev/null +++ b/src/storm/parser/ValueParser.cpp @@ -0,0 +1,38 @@ +#include "storm/parser/ValueParser.h" + +#include "storm/exceptions/NotSupportedException.h" + +namespace storm { + namespace parser { + + template<typename ValueType> + void ValueParser<ValueType>::addParameter(std::string const& parameter) { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); + } + + template<> + void ValueParser<storm::RationalFunction>::addParameter(std::string const& parameter) { + storm::expressions::Variable var = manager->declareRationalVariable(parameter); + identifierMapping.emplace(var.getName(), var); + parser.setIdentifierMapping(identifierMapping); + STORM_LOG_TRACE("Added parameter: " << var.getName()); + } + + template<> + double ValueParser<double>::parseValue(std::string const& value) const { + return NumberParser<double>::parse(value); + } + + template<> + storm::RationalFunction ValueParser<storm::RationalFunction>::parseValue(std::string const& value) const { + storm::RationalFunction rationalFunction = evaluator.asRational(parser.parseFromString(value)); + STORM_LOG_TRACE("Parsed expression: " << rationalFunction); + return rationalFunction; + } + + // Template instantiations. + template class ValueParser<double>; + template class ValueParser<storm::RationalFunction>; + + } // namespace parser +} // namespace storm diff --git a/src/storm/parser/ValueParser.h b/src/storm/parser/ValueParser.h new file mode 100644 index 000000000..db948b75e --- /dev/null +++ b/src/storm/parser/ValueParser.h @@ -0,0 +1,71 @@ +#ifndef STORM_PARSER_VALUEPARSER_H_ +#define STORM_PARSER_VALUEPARSER_H_ + +#include "storm/storage/expressions/ExpressionManager.h" +#include "storm/parser/ExpressionParser.h" +#include "storm/storage/expressions/ExpressionEvaluator.h" +#include "storm/exceptions/WrongFormatException.h" + +namespace storm { + namespace parser { + /*! + * Parser for values according to their ValueType. + */ + template<typename ValueType> + class ValueParser { + public: + + /*! + * Constructor. + */ + ValueParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) { + } + + /*! + * Parse ValueType from string. + * + * @param value String containing the value. + * + * @return ValueType + */ + ValueType parseValue(std::string const& value) const; + + /*! + * Add declaration of parameter. + * + * @param parameter New parameter. + */ + void addParameter(std::string const& parameter); + + private: + + std::shared_ptr<storm::expressions::ExpressionManager> manager; + storm::parser::ExpressionParser parser; + storm::expressions::ExpressionEvaluator<ValueType> evaluator; + std::unordered_map<std::string, storm::expressions::Expression> identifierMapping; + }; + + template<typename NumberType> + class NumberParser { + public: + /*! + * Parse number from string. + * + * @param value String containing the value. + * + * @return NumberType. + */ + static NumberType parse(std::string const& value) { + try { + return boost::lexical_cast<NumberType>(value); + } + catch(boost::bad_lexical_cast &) { + STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Could not parse value '" << value << "' into " << typeid(NumberType).name() << "."); + } + } + }; + + } // namespace parser +} // namespace storm + +#endif /* STORM_PARSER_VALUEPARSER_H_ */ diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 188d1cba2..fc2b80b35 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -15,6 +15,7 @@ #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" +#include "storm/settings/modules/ModelCheckerSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/CounterexampleGeneratorSettings.h" #include "storm/settings/modules/CuddSettings.h" @@ -30,13 +31,14 @@ #include "storm/settings/modules/GlpkSettings.h" #include "storm/settings/modules/GurobiSettings.h" #include "storm/settings/modules/Smt2SmtSolverSettings.h" -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" #include "storm/settings/modules/ExplorationSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm/settings/modules/AbstractionSettings.h" #include "storm/settings/modules/JaniExportSettings.h" #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" +#include "storm/settings/modules/MultiplierSettings.h" #include "storm/utility/macros.h" #include "storm/utility/file.h" #include "storm/settings/Option.h" @@ -178,7 +180,10 @@ namespace storm { // Find longest option name. uint_fast64_t maxLength = getPrintLengthOfLongestOption(); for (auto const& moduleName : this->moduleNames) { - printHelpForModule(moduleName, maxLength); + // Only print for visible modules. + if (hasModule(moduleName, true)) { + printHelpForModule(moduleName, maxLength); + }; } } else { // Create a regular expression from the input hint. @@ -192,12 +197,15 @@ namespace storm { uint_fast64_t maxLengthModules = 0; for (auto const& moduleName : this->moduleNames) { if (std::regex_search(moduleName, hintRegex)) { - matchingModuleNames.push_back(moduleName); - maxLengthModules = std::max(maxLengthModules, getPrintLengthOfLongestOption(moduleName)); - - // Add all options of this module to the list of printed options so we don't print them twice. - auto optionIterator = this->moduleOptions.find(moduleName); - printedOptions.insert(optionIterator->second.begin(), optionIterator->second.end()); + if (hasModule(moduleName, true)) { + // Only consider visible modules. + matchingModuleNames.push_back(moduleName); + maxLengthModules = std::max(maxLengthModules, getPrintLengthOfLongestOption(moduleName)); + + // Add all options of this module to the list of printed options so we don't print them twice. + auto optionIterator = this->moduleOptions.find(moduleName); + printedOptions.insert(optionIterator->second.begin(), optionIterator->second.end()); + } } } @@ -282,8 +290,8 @@ namespace storm { std::unique_ptr<modules::ModuleSettings> const& settings = iterator->second; if (doRegister) { - // Now register the options of the module. this->moduleOptions.emplace(moduleName, std::vector<std::shared_ptr<Option>>()); + // Now register the options of the module. for (auto const& option : settings->getOptions()) { this->addOption(option); } @@ -317,6 +325,14 @@ namespace storm { addOptionToMap(option->getModuleName() + ":" + option->getShortName(), option, this->shortNameToOptions); } } + + bool SettingsManager::hasModule(std::string const& moduleName, bool checkHidden) const { + if (checkHidden) { + return this->moduleOptions.find(moduleName) != this->moduleOptions.end(); + } else { + return this->modules.find(moduleName) != this->modules.end(); + } + } modules::ModuleSettings const& SettingsManager::getModule(std::string const& moduleName) const { auto moduleIterator = this->modules.find(moduleName); @@ -513,6 +529,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::IOSettings>(); storm::settings::addModule<storm::settings::modules::BuildSettings>(); storm::settings::addModule<storm::settings::modules::CoreSettings>(); + storm::settings::addModule<storm::settings::modules::ModelCheckerSettings>(); storm::settings::addModule<storm::settings::modules::DebugSettings>(); storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>(); storm::settings::addModule<storm::settings::modules::CuddSettings>(); @@ -526,7 +543,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::BisimulationSettings>(); storm::settings::addModule<storm::settings::modules::GlpkSettings>(); storm::settings::addModule<storm::settings::modules::GurobiSettings>(); - storm::settings::addModule<storm::settings::modules::TopologicalValueIterationEquationSolverSettings>(); + storm::settings::addModule<storm::settings::modules::TopologicalEquationSolverSettings>(); storm::settings::addModule<storm::settings::modules::Smt2SmtSolverSettings>(); storm::settings::addModule<storm::settings::modules::ExplorationSettings>(); storm::settings::addModule<storm::settings::modules::ResourceSettings>(); @@ -534,6 +551,7 @@ namespace storm { storm::settings::addModule<storm::settings::modules::JaniExportSettings>(); storm::settings::addModule<storm::settings::modules::JitBuilderSettings>(); storm::settings::addModule<storm::settings::modules::MultiObjectiveSettings>(); + storm::settings::addModule<storm::settings::modules::MultiplierSettings>(); } } diff --git a/src/storm/settings/SettingsManager.h b/src/storm/settings/SettingsManager.h index 72ee1bd37..1ccb10bfa 100644 --- a/src/storm/settings/SettingsManager.h +++ b/src/storm/settings/SettingsManager.h @@ -102,7 +102,16 @@ namespace storm { * @param moduleSettings The settings of the module to add. */ void addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings, bool doRegister = true); - + + /*! + * Checks whether the module with the given name exists. + * + * @param moduleName The name of the module to search. + * @param checkHidden If true hidden modules are included in the search. + * @return True iff the module exists. + */ + bool hasModule(std::string const& moduleName, bool checkHidden = false) const; + /*! * Retrieves the settings of the module with the given name. * diff --git a/src/storm/settings/modules/AbstractionSettings.cpp b/src/storm/settings/modules/AbstractionSettings.cpp index 4835019d4..9570810f1 100644 --- a/src/storm/settings/modules/AbstractionSettings.cpp +++ b/src/storm/settings/modules/AbstractionSettings.cpp @@ -21,11 +21,12 @@ namespace storm { const std::string AbstractionSettings::precisionOptionName = "precision"; const std::string AbstractionSettings::pivotHeuristicOptionName = "pivot-heuristic"; const std::string AbstractionSettings::reuseResultsOptionName = "reuse"; + const std::string AbstractionSettings::restrictToRelevantStatesOptionName = "relevant"; AbstractionSettings::AbstractionSettings() : ModuleSettings(moduleName) { std::vector<std::string> methods = {"games", "bisimulation", "bisim"}; this->addOption(storm::settings::OptionBuilder(moduleName, methodOptionName, true, "Sets which abstraction-refinement method to use.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of themethod to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)) .setDefaultValueString("bisim").build()) .build()); @@ -64,6 +65,11 @@ namespace storm { .addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(reuseModes)) .setDefaultValueString("all").build()) .build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, restrictToRelevantStatesOptionName, true, "Sets whether to restrict to relevant states during the abstraction.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("value", "The value of the flag.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(onOff)) + .setDefaultValueString("off").build()) + .build()); } AbstractionSettings::Method AbstractionSettings::getAbstractionRefinementMethod() const { @@ -104,6 +110,10 @@ namespace storm { return this->getOption(useInterpolationOptionName).getArgumentByName("value").getValueAsString() == "on"; } + bool AbstractionSettings::isRestrictToRelevantStatesSet() const { + return this->getOption(restrictToRelevantStatesOptionName).getArgumentByName("value").getValueAsString() == "on"; + } + double AbstractionSettings::getPrecision() const { return this->getOption(precisionOptionName).getArgumentByName("value").getValueAsDouble(); } diff --git a/src/storm/settings/modules/AbstractionSettings.h b/src/storm/settings/modules/AbstractionSettings.h index 4d5827187..7c2a98f66 100644 --- a/src/storm/settings/modules/AbstractionSettings.h +++ b/src/storm/settings/modules/AbstractionSettings.h @@ -93,6 +93,13 @@ namespace storm { */ ReuseMode getReuseMode() const; + /*! + * Retrieves whether only relevant states are to be considered. + * + * @return True iff the option was set. + */ + bool isRestrictToRelevantStatesSet() const; + const static std::string moduleName; private: @@ -104,6 +111,7 @@ namespace storm { const static std::string precisionOptionName; const static std::string pivotHeuristicOptionName; const static std::string reuseResultsOptionName; + const static std::string restrictToRelevantStatesOptionName; }; } diff --git a/src/storm/settings/modules/BisimulationSettings.cpp b/src/storm/settings/modules/BisimulationSettings.cpp index 8ed66dbdf..0b7c219f5 100644 --- a/src/storm/settings/modules/BisimulationSettings.cpp +++ b/src/storm/settings/modules/BisimulationSettings.cpp @@ -15,11 +15,13 @@ namespace storm { const std::string BisimulationSettings::moduleName = "bisimulation"; const std::string BisimulationSettings::typeOptionName = "type"; const std::string BisimulationSettings::representativeOptionName = "repr"; + const std::string BisimulationSettings::originalVariablesOptionName = "origvars"; const std::string BisimulationSettings::quotientFormatOptionName = "quot"; const std::string BisimulationSettings::signatureModeOptionName = "sigmode"; const std::string BisimulationSettings::reuseOptionName = "reuse"; const std::string BisimulationSettings::initialPartitionOptionName = "init"; const std::string BisimulationSettings::refinementModeOptionName = "refine"; + const std::string BisimulationSettings::exactArithmeticDdOptionName = "ddexact"; BisimulationSettings::BisimulationSettings() : ModuleSettings(moduleName) { std::vector<std::string> types = { "strong", "weak" }; @@ -29,6 +31,8 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, quotientFormatOptionName, true, "Sets the format in which the quotient is extracted (only applies to DD-based bisimulation).").addArgument(storm::settings::ArgumentBuilder::createStringArgument("format", "The format of the quotient.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(quotTypes)).setDefaultValueString("dd").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, representativeOptionName, false, "Sets whether to use representatives in the quotient rather than block numbers.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, originalVariablesOptionName, false, "Sets whether to use the original variables in the quotient rather than the block variables.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, exactArithmeticDdOptionName, false, "Sets whether to use exact arithmetic in dd-based bisimulation.").build()); std::vector<std::string> signatureModes = { "eager", "lazy" }; this->addOption(storm::settings::OptionBuilder(moduleName, signatureModeOptionName, false, "Sets the signature computation mode.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "The mode to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(signatureModes)).setDefaultValueString("eager").build()).build()); @@ -78,6 +82,14 @@ namespace storm { return this->getOption(representativeOptionName).getHasOptionBeenSet(); } + bool BisimulationSettings::isUseOriginalVariablesSet() const { + return this->getOption(originalVariablesOptionName).getHasOptionBeenSet(); + } + + bool BisimulationSettings::useExactArithmeticInDdBisimulation() const { + return this->getOption(exactArithmeticDdOptionName).getHasOptionBeenSet(); + } + storm::dd::bisimulation::SignatureMode BisimulationSettings::getSignatureMode() const { std::string modeAsString = this->getOption(signatureModeOptionName).getArgumentByName("mode").getValueAsString(); if (modeAsString == "eager") { diff --git a/src/storm/settings/modules/BisimulationSettings.h b/src/storm/settings/modules/BisimulationSettings.h index a482263bc..c06713a8a 100644 --- a/src/storm/settings/modules/BisimulationSettings.h +++ b/src/storm/settings/modules/BisimulationSettings.h @@ -56,6 +56,20 @@ namespace storm { */ bool isUseRepresentativesSet() const; + /*! + * Retrieves whether the extracted quotient model is supposed to use the same variables as the original + * model. + * NOTE: only applies to DD-based bisimulation. + */ + bool isUseOriginalVariablesSet() const; + + /*! + * Retrieves whether exact arithmetic is to be used in symbolic bisimulation minimization. + * + * @return True iff exact arithmetic is to be used in symbolic bisimulation minimization. + */ + bool useExactArithmeticInDdBisimulation() const; + /*! * Retrieves the mode to compute signatures. */ @@ -85,12 +99,14 @@ namespace storm { // Define the string names of the options as constants. static const std::string typeOptionName; static const std::string representativeOptionName; + static const std::string originalVariablesOptionName; static const std::string quotientFormatOptionName; static const std::string signatureModeOptionName; static const std::string reuseOptionName; static const std::string initialPartitionOptionName; static const std::string refinementModeOptionName; static const std::string parallelismModeOptionName; + static const std::string exactArithmeticDdOptionName; }; } // namespace modules } // namespace settings diff --git a/src/storm/settings/modules/BuildSettings.cpp b/src/storm/settings/modules/BuildSettings.cpp index a813b08fa..536dd26ea 100644 --- a/src/storm/settings/modules/BuildSettings.cpp +++ b/src/storm/settings/modules/BuildSettings.cpp @@ -29,6 +29,7 @@ namespace storm { const std::string fullModelBuildOptionName = "buildfull"; const std::string buildChoiceLabelOptionName = "buildchoicelab"; const std::string buildStateValuationsOptionName = "buildstateval"; + const std::string buildOutOfBoundsStateOptionName = "buildoutofboundsstate"; BuildSettings::BuildSettings() : ModuleSettings(moduleName) { std::vector<std::string> explorationOrders = {"dfs", "bfs"}; @@ -42,6 +43,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, explorationOrderOptionName, false, "Sets which exploration order to use.").setShortName(explorationOrderOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the exploration order to choose.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(explorationOrders)).setDefaultValueString("bfs").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, explorationChecksOptionName, false, "If set, additional checks (if available) are performed during model exploration to debug the model.").setShortName(explorationChecksOptionShortName).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, buildOutOfBoundsStateOptionName, false, "If set, a state for out-of-bounds valuations is added").build()); } @@ -74,6 +76,10 @@ namespace storm { return this->getOption(buildStateValuationsOptionName).getHasOptionBeenSet(); } + bool BuildSettings::isBuildOutOfBoundsStateSet() const { + return this->getOption(buildOutOfBoundsStateOptionName).getHasOptionBeenSet(); + } + storm::builder::ExplorationOrder BuildSettings::getExplorationOrder() const { std::string explorationOrderAsString = this->getOption(explorationOrderOptionName).getArgumentByName("name").getValueAsString(); diff --git a/src/storm/settings/modules/BuildSettings.h b/src/storm/settings/modules/BuildSettings.h index 4ef0f5193..e9ec41dc1 100644 --- a/src/storm/settings/modules/BuildSettings.h +++ b/src/storm/settings/modules/BuildSettings.h @@ -75,6 +75,12 @@ namespace storm { */ bool isBuildStateValuationsSet() const; + /*! + * Retrieves whether out of bounds state should be added + * @return + */ + bool isBuildOutOfBoundsStateSet() const; + // The name of the module. static const std::string moduleName; diff --git a/src/storm/settings/modules/CoreSettings.cpp b/src/storm/settings/modules/CoreSettings.cpp index b01aee3f7..8419f209f 100644 --- a/src/storm/settings/modules/CoreSettings.cpp +++ b/src/storm/settings/modules/CoreSettings.cpp @@ -39,11 +39,11 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, counterexampleOptionName, false, "Generates a counterexample for the given PRCTL formulas if not satisfied by the model.").setShortName(counterexampleOptionShortName).build()); this->addOption(storm::settings::OptionBuilder(moduleName, dontFixDeadlockOptionName, false, "If the model contains deadlock states, they need to be fixed by setting this option.").setShortName(dontFixDeadlockOptionShortName).build()); - std::vector<std::string> engines = {"sparse", "hybrid", "dd", "expl", "abs"}; + std::vector<std::string> engines = {"sparse", "hybrid", "dd", "dd-to-sparse", "expl", "abs"}; this->addOption(storm::settings::OptionBuilder(moduleName, engineOptionName, false, "Sets which engine is used for model building and model checking.").setShortName(engineOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the engine to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(engines)).setDefaultValueString("sparse").build()).build()); - std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; + std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination", "topological"}; this->addOption(storm::settings::OptionBuilder(moduleName, eqSolverOptionName, false, "Sets which solver is preferred for solving systems of linear equations.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the solver to prefer.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); @@ -86,6 +86,8 @@ namespace storm { return storm::solver::EquationSolverType::Eigen; } else if (equationSolverName == "elimination") { return storm::solver::EquationSolverType::Elimination; + } else if (equationSolverName == "topological") { + return storm::solver::EquationSolverType::Topological; } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown equation solver '" << equationSolverName << "'."); } @@ -162,6 +164,8 @@ namespace storm { engine = CoreSettings::Engine::Hybrid; } else if (engineStr == "dd") { engine = CoreSettings::Engine::Dd; + } else if (engineStr == "dd-to-sparse") { + engine = CoreSettings::Engine::DdSparse; } else if (engineStr == "expl") { engine = CoreSettings::Engine::Exploration; } else if (engineStr == "abs") { diff --git a/src/storm/settings/modules/CoreSettings.h b/src/storm/settings/modules/CoreSettings.h index afd16cd78..8a07a48d0 100644 --- a/src/storm/settings/modules/CoreSettings.h +++ b/src/storm/settings/modules/CoreSettings.h @@ -28,7 +28,7 @@ namespace storm { public: // An enumeration of all engines. enum class Engine { - Sparse, Hybrid, Dd, Exploration, AbstractionRefinement + Sparse, Hybrid, Dd, DdSparse, Exploration, AbstractionRefinement }; /*! diff --git a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp index b33a332df..0eaf656bb 100644 --- a/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp +++ b/src/storm/settings/modules/CounterexampleGeneratorSettings.cpp @@ -16,13 +16,15 @@ namespace storm { const std::string CounterexampleGeneratorSettings::minimalCommandSetOptionName = "mincmd"; const std::string CounterexampleGeneratorSettings::encodeReachabilityOptionName = "encreach"; const std::string CounterexampleGeneratorSettings::schedulerCutsOptionName = "schedcuts"; - + const std::string CounterexampleGeneratorSettings::noDynamicConstraintsOptionName = "nodyn"; + CounterexampleGeneratorSettings::CounterexampleGeneratorSettings() : ModuleSettings(moduleName) { std::vector<std::string> techniques = {"maxsat", "milp"}; - this->addOption(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command set. Note that this requires the model to be given in a symbolic format.") + this->addOption(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command/edge set. Note that this requires the model to be given in a symbolic format.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used to derive the counterexample.").setDefaultValueString("maxsat").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(techniques)).build()).build()); - this->addOption(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based minimal command counterexample generation.").build()); - this->addOption(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based minimal command counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based counterexample generation.").build()); + this->addOption(storm::settings::OptionBuilder(moduleName, noDynamicConstraintsOptionName, true, "Disables the generation of dynamic constraints in the MAXSAT-based counterexample generation.").build()); } bool CounterexampleGeneratorSettings::isMinimalCommandSetGenerationSet() const { @@ -44,10 +46,14 @@ namespace storm { bool CounterexampleGeneratorSettings::isUseSchedulerCutsSet() const { return this->getOption(schedulerCutsOptionName).getHasOptionBeenSet(); } - + + bool CounterexampleGeneratorSettings::isUseDynamicConstraintsSet() const { + return !this->getOption(noDynamicConstraintsOptionName).getHasOptionBeenSet(); + } + bool CounterexampleGeneratorSettings::check() const { // Ensure that the model was given either symbolically or explicitly. - STORM_LOG_THROW(!isMinimalCommandSetGenerationSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isPrismInputSet(), storm::exceptions::InvalidSettingsException, "For the generation of a minimal command set, the model has to be specified in the PRISM format."); + STORM_LOG_THROW(!isMinimalCommandSetGenerationSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isPrismInputSet() || storm::settings::getModule<storm::settings::modules::IOSettings>().isJaniInputSet(), storm::exceptions::InvalidSettingsException, "For the generation of a minimal command set, the model has to be specified in the PRISM/JANI format."); if (isMinimalCommandSetGenerationSet()) { STORM_LOG_WARN_COND(isUseMaxSatBasedMinimalCommandSetGenerationSet() || !isEncodeReachabilitySet(), "Encoding reachability is only available for the MaxSat-based minimal command set generation, so selecting it has no effect."); diff --git a/src/storm/settings/modules/CounterexampleGeneratorSettings.h b/src/storm/settings/modules/CounterexampleGeneratorSettings.h index 03002c8f6..bdb0813a6 100644 --- a/src/storm/settings/modules/CounterexampleGeneratorSettings.h +++ b/src/storm/settings/modules/CounterexampleGeneratorSettings.h @@ -56,6 +56,13 @@ namespace storm { */ bool isUseSchedulerCutsSet() const; + /*! + * Retrieves whether to use the dynamic constraints in the MAXSAT-based technique. + * + * @return True iff dynamic constraints are to be used. + */ + bool isUseDynamicConstraintsSet() const; + bool check() const override; // The name of the module. @@ -66,6 +73,7 @@ namespace storm { static const std::string minimalCommandSetOptionName; static const std::string encodeReachabilityOptionName; static const std::string schedulerCutsOptionName; + static const std::string noDynamicConstraintsOptionName; }; } // namespace modules diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp index 15254ead1..186f0caf9 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.cpp @@ -18,10 +18,12 @@ namespace storm { const std::string MinMaxEquationSolverSettings::precisionOptionName = "precision"; const std::string MinMaxEquationSolverSettings::absoluteOptionName = "absolute"; const std::string MinMaxEquationSolverSettings::lraMethodOptionName = "lramethod"; + const std::string MinMaxEquationSolverSettings::markovAutomatonBoundedReachabilityMethodOptionName = "mamethod"; const std::string MinMaxEquationSolverSettings::valueIterationMultiplicationStyleOptionName = "vimult"; + const std::string MinMaxEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; MinMaxEquationSolverSettings::MinMaxEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "linear-programming", "lp", "ratsearch"}; + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "lp", "linear-programming", "rs", "ratsearch", "ii", "interval-iteration", "svi", "sound-value-iteration", "topological"}; this->addOption(storm::settings::OptionBuilder(moduleName, solvingMethodOptionName, false, "Sets which min/max linear equation solving technique is preferred.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a min/max linear equation solving technique.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("vi").build()).build()); @@ -35,9 +37,15 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, lraMethodOptionName, false, "Sets which method is preferred for computing long run averages.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a long run average computation method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(lraMethods)).setDefaultValueString("vi").build()).build()); + std::vector<std::string> maMethods = {"imca", "unifplus"}; + this->addOption(storm::settings::OptionBuilder(moduleName, markovAutomatonBoundedReachabilityMethodOptionName, true, "The method to use to solve bounded reachability queries on MAs.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(maMethods)).setDefaultValueString("unifplus").build()).build()); + std::vector<std::string> multiplicationStyles = {"gaussseidel", "regular", "gs", "r"}; this->addOption(storm::settings::OptionBuilder(moduleName, valueIterationMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for value iteration.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, intervalIterationSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); + } storm::solver::MinMaxMethod MinMaxEquationSolverSettings::getMinMaxEquationSolvingMethod() const { @@ -48,9 +56,16 @@ namespace storm { return storm::solver::MinMaxMethod::PolicyIteration; } else if (minMaxEquationSolvingTechnique == "linear-programming" || minMaxEquationSolvingTechnique == "lp") { return storm::solver::MinMaxMethod::LinearProgramming; - } else if (minMaxEquationSolvingTechnique == "ratsearch") { + } else if (minMaxEquationSolvingTechnique == "ratsearch" || minMaxEquationSolvingTechnique == "rs") { return storm::solver::MinMaxMethod::RationalSearch; + } else if (minMaxEquationSolvingTechnique == "interval-iteration" || minMaxEquationSolvingTechnique == "ii") { + return storm::solver::MinMaxMethod::IntervalIteration; + } else if (minMaxEquationSolvingTechnique == "sound-value-iteration" || minMaxEquationSolvingTechnique == "svi") { + return storm::solver::MinMaxMethod::SoundValueIteration; + } else if (minMaxEquationSolvingTechnique == "topological") { + return storm::solver::MinMaxMethod::Topological; } + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'."); } @@ -95,6 +110,14 @@ namespace storm { } STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown lra solving technique '" << lraMethodString << "'."); } + + MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod MinMaxEquationSolverSettings::getMarkovAutomatonBoundedReachabilityMethod() const { + std::string techniqueAsString = this->getOption(markovAutomatonBoundedReachabilityMethodOptionName).getArgumentByName("name").getValueAsString(); + if (techniqueAsString == "imca") { + return MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::Imca; + } + return MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod::UnifPlus; + } storm::solver::MultiplicationStyle MinMaxEquationSolverSettings::getValueIterationMultiplicationStyle() const { std::string multiplicationStyleString = this->getOption(valueIterationMultiplicationStyleOptionName).getArgumentByName("name").getValueAsString(); @@ -106,6 +129,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool MinMaxEquationSolverSettings::isForceIntervalIterationSymmetricUpdatesSet() const { + return this->getOption(intervalIterationSymmetricUpdatesOptionName).getHasOptionBeenSet(); + } + } } } diff --git a/src/storm/settings/modules/MinMaxEquationSolverSettings.h b/src/storm/settings/modules/MinMaxEquationSolverSettings.h index bc9697476..43d3d1b00 100644 --- a/src/storm/settings/modules/MinMaxEquationSolverSettings.h +++ b/src/storm/settings/modules/MinMaxEquationSolverSettings.h @@ -18,6 +18,9 @@ namespace storm { // An enumeration of all available convergence criteria. enum class ConvergenceCriterion { Absolute, Relative }; + // An enumeration of all available bounded reachability methods for MAs. + enum class MarkovAutomatonBoundedReachabilityMethod { Imca, UnifPlus }; + MinMaxEquationSolverSettings(); /*! @@ -90,6 +93,13 @@ namespace storm { */ storm::solver::LraMethod getLraMethod() const; + /*! + * Retrieves the method to be used for bounded reachability on MAs. + * + * @return The selected method. + */ + MarkovAutomatonBoundedReachabilityMethod getMarkovAutomatonBoundedReachabilityMethod() const; + /*! * Retrieves the multiplication style to use in the min-max methods. * @@ -97,6 +107,11 @@ namespace storm { */ storm::solver::MultiplicationStyle getValueIterationMultiplicationStyle() const; + /*! + * Retrievew whether updates in interval iteration have to be made symmetrically + */ + bool isForceIntervalIterationSymmetricUpdatesSet() const; + // The name of the module. static const std::string moduleName; @@ -107,7 +122,10 @@ namespace storm { static const std::string precisionOptionName; static const std::string absoluteOptionName; static const std::string lraMethodOptionName; + static const std::string markovAutomatonBoundedReachabilityMethodOptionName; static const std::string valueIterationMultiplicationStyleOptionName; + static const std::string intervalIterationSymmetricUpdatesOptionName; + static const std::string forceBoundsOptionName; }; } diff --git a/src/storm/settings/modules/ModelCheckerSettings.cpp b/src/storm/settings/modules/ModelCheckerSettings.cpp new file mode 100644 index 000000000..9d7646327 --- /dev/null +++ b/src/storm/settings/modules/ModelCheckerSettings.cpp @@ -0,0 +1,28 @@ +#include "storm/settings/modules/ModelCheckerSettings.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/SettingMemento.h" +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" + + +namespace storm { + namespace settings { + namespace modules { + + const std::string ModelCheckerSettings::moduleName = "modelchecker"; + const std::string ModelCheckerSettings::filterRewZeroOptionName = "filterrewzero"; + + ModelCheckerSettings::ModelCheckerSettings() : ModuleSettings(moduleName) { + this->addOption(storm::settings::OptionBuilder(moduleName, filterRewZeroOptionName, false, "If set, states with reward zero are filtered out, potentially reducing the size of the equation system").build()); + } + + bool ModelCheckerSettings::isFilterRewZeroSet() const { + return this->getOption(filterRewZeroOptionName).getHasOptionBeenSet(); + } + + } // namespace modules + } // namespace settings +} // namespace storm diff --git a/src/storm/settings/modules/ModelCheckerSettings.h b/src/storm/settings/modules/ModelCheckerSettings.h new file mode 100644 index 000000000..4c6a1dfd6 --- /dev/null +++ b/src/storm/settings/modules/ModelCheckerSettings.h @@ -0,0 +1,36 @@ +#pragma once + +#include "storm-config.h" +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/builder/ExplorationOrder.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the general settings. + */ + class ModelCheckerSettings : public ModuleSettings { + public: + + /*! + * Creates a new set of general settings. + */ + ModelCheckerSettings(); + + bool isFilterRewZeroSet() const; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string filterRewZeroOptionName; + }; + + } // namespace modules + } // namespace settings +} // namespace storm + diff --git a/src/storm/settings/modules/MultiplierSettings.cpp b/src/storm/settings/modules/MultiplierSettings.cpp new file mode 100644 index 000000000..d386bbf3a --- /dev/null +++ b/src/storm/settings/modules/MultiplierSettings.cpp @@ -0,0 +1,40 @@ +#include "storm/settings/modules/MultiplierSettings.h" + +#include "storm/settings/Option.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/OptionBuilder.h" + +#include "storm/utility/macros.h" +#include "storm/exceptions/IllegalArgumentValueException.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string MultiplierSettings::moduleName = "multiplier"; + const std::string MultiplierSettings::multiplierTypeOptionName = "type"; + + MultiplierSettings::MultiplierSettings() : ModuleSettings(moduleName) { + std::vector<std::string> multiplierTypes = {"native", "gmmxx"}; + this->addOption(storm::settings::OptionBuilder(moduleName, multiplierTypeOptionName, true, "Sets which type of multiplier is preferred.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplier.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplierTypes)).setDefaultValueString("gmmxx").build()).build()); + + } + + storm::solver::MultiplierType MultiplierSettings::getMultiplierType() const { + std::string type = this->getOption(multiplierTypeOptionName).getArgumentByName("name").getValueAsString(); + if (type == "native") { + return storm::solver::MultiplierType::Native; + } else if (type == "gmmxx") { + return storm::solver::MultiplierType::Gmmxx; + } + + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplier type '" << type << "'."); + } + + bool MultiplierSettings::isMultiplierTypeSetFromDefaultValue() const { + return !this->getOption(multiplierTypeOptionName).getArgumentByName("name").getHasBeenSet() || this->getOption(multiplierTypeOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + } + } +} diff --git a/src/storm/settings/modules/MultiplierSettings.h b/src/storm/settings/modules/MultiplierSettings.h new file mode 100644 index 000000000..ea5bfdd8c --- /dev/null +++ b/src/storm/settings/modules/MultiplierSettings.h @@ -0,0 +1,34 @@ +#pragma once + +#include "storm-config.h" +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/MultiplicationStyle.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the multiplier settings. + */ + class MultiplierSettings : public ModuleSettings { + public: + + MultiplierSettings(); + + storm::solver::MultiplierType getMultiplierType() const; + + bool isMultiplierTypeSetFromDefaultValue() const; + + // The name of the module. + static const std::string moduleName; + + private: + static const std::string multiplierTypeOptionName; + }; + + } + } +} diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.cpp b/src/storm/settings/modules/NativeEquationSolverSettings.cpp index 664818b97..3f0282f0a 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/storm/settings/modules/NativeEquationSolverSettings.cpp @@ -23,9 +23,10 @@ namespace storm { const std::string NativeEquationSolverSettings::precisionOptionName = "precision"; const std::string NativeEquationSolverSettings::absoluteOptionName = "absolute"; const std::string NativeEquationSolverSettings::powerMethodMultiplicationStyleOptionName = "powmult"; + const std::string NativeEquationSolverSettings::intervalIterationSymmetricUpdatesOptionName = "symmetricupdates"; NativeEquationSolverSettings::NativeEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "ratsearch" }; + std::vector<std::string> methods = { "jacobi", "gaussseidel", "sor", "walkerchae", "power", "sound-value-iteration", "svi", "interval-iteration", "ii", "ratsearch" }; this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(methods)).setDefaultValueString("jacobi").build()).build()); this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); @@ -39,6 +40,8 @@ namespace storm { std::vector<std::string> multiplicationStyles = {"gaussseidel", "regular", "gs", "r"}; this->addOption(storm::settings::OptionBuilder(moduleName, powerMethodMultiplicationStyleOptionName, false, "Sets which method multiplication style to prefer for the power method.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of a multiplication style.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(multiplicationStyles)).setDefaultValueString("gaussseidel").build()).build()); + + this->addOption(storm::settings::OptionBuilder(moduleName, intervalIterationSymmetricUpdatesOptionName, false, "If set, interval iteration performs an update on both, lower and upper bound in each iteration").build()); } bool NativeEquationSolverSettings::isLinearEquationSystemTechniqueSet() const { @@ -61,6 +64,10 @@ namespace storm { return storm::solver::NativeLinearEquationSolverMethod::WalkerChae; } else if (linearEquationSystemTechniqueAsString == "power") { return storm::solver::NativeLinearEquationSolverMethod::Power; + } else if (linearEquationSystemTechniqueAsString == "sound-value-iteration" || linearEquationSystemTechniqueAsString == "svi") { + return storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration; + } else if (linearEquationSystemTechniqueAsString == "interval-iteration" || linearEquationSystemTechniqueAsString == "ii") { + return storm::solver::NativeLinearEquationSolverMethod::IntervalIteration; } else if (linearEquationSystemTechniqueAsString == "ratsearch") { return storm::solver::NativeLinearEquationSolverMethod::RationalSearch; } @@ -105,6 +112,10 @@ namespace storm { STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown multiplication style '" << multiplicationStyleString << "'."); } + bool NativeEquationSolverSettings::isForceIntervalIterationSymmetricUpdatesSet() const { + return this->getOption(intervalIterationSymmetricUpdatesOptionName).getHasOptionBeenSet(); + } + bool NativeEquationSolverSettings::check() const { // This list does not include the precision, because this option is shared with other modules. bool optionSet = isLinearEquationSystemTechniqueSet() || isMaximalIterationCountSet() || isConvergenceCriterionSet(); diff --git a/src/storm/settings/modules/NativeEquationSolverSettings.h b/src/storm/settings/modules/NativeEquationSolverSettings.h index 32d3caed1..306e9750e 100644 --- a/src/storm/settings/modules/NativeEquationSolverSettings.h +++ b/src/storm/settings/modules/NativeEquationSolverSettings.h @@ -93,6 +93,11 @@ namespace storm { */ ConvergenceCriterion getConvergenceCriterion() const; + /*! + * Retrievew whether updates in interval iteration have to be made symmetrically + */ + bool isForceIntervalIterationSymmetricUpdatesSet() const; + /*! * Retrieves the multiplication style to use in the power method. * @@ -100,6 +105,11 @@ namespace storm { */ storm::solver::MultiplicationStyle getPowerMethodMultiplicationStyle() const; + /*! + * Retrieves whether the force bounds option has been set. + */ + bool isForceBoundsSet() const; + bool check() const override; // The name of the module. @@ -113,7 +123,10 @@ namespace storm { static const std::string maximalIterationsOptionShortName; static const std::string precisionOptionName; static const std::string absoluteOptionName; + static const std::string intervalIterationSymmetricUpdatesOptionName; static const std::string powerMethodMultiplicationStyleOptionName; + static const std::string forceBoundsOptionName; + }; } // namespace modules diff --git a/src/storm/settings/modules/SylvanSettings.h b/src/storm/settings/modules/SylvanSettings.h index b4eed806b..b218cbdfc 100644 --- a/src/storm/settings/modules/SylvanSettings.h +++ b/src/storm/settings/modules/SylvanSettings.h @@ -13,7 +13,7 @@ namespace storm { class SylvanSettings : public ModuleSettings { public: /*! - * Creates a new set of CUDD settings. + * Creates a new set of Sylvan settings. */ SylvanSettings(); diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp new file mode 100644 index 000000000..88a0c48fd --- /dev/null +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.cpp @@ -0,0 +1,105 @@ +#include "storm/settings/modules/TopologicalEquationSolverSettings.h" + + +#include "storm/settings/modules/CoreSettings.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/SettingMemento.h" +#include "storm/settings/Option.h" +#include "storm/settings/OptionBuilder.h" +#include "storm/settings/ArgumentBuilder.h" +#include "storm/settings/Argument.h" +#include "storm/solver/SolverSelectionOptions.h" + +#include "storm/storage/dd/DdType.h" + +#include "storm/utility/macros.h" +#include "storm/exceptions/IllegalArgumentValueException.h" +#include "storm/exceptions/InvalidOptionException.h" + +namespace storm { + namespace settings { + namespace modules { + + const std::string TopologicalEquationSolverSettings::moduleName = "topological"; + const std::string TopologicalEquationSolverSettings::underlyingEquationSolverOptionName = "eqsolver"; + const std::string TopologicalEquationSolverSettings::underlyingMinMaxMethodOptionName = "minmax"; + + TopologicalEquationSolverSettings::TopologicalEquationSolverSettings() : ModuleSettings(moduleName) { + std::vector<std::string> linearEquationSolver = {"gmm++", "native", "eigen", "elimination"}; + this->addOption(storm::settings::OptionBuilder(moduleName, underlyingEquationSolverOptionName, true, "Sets which solver is considered for solving the underlying equation systems.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used solver.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); + std::vector<std::string> minMaxSolvingTechniques = {"vi", "value-iteration", "pi", "policy-iteration", "lp", "linear-programming", "rs", "ratsearch", "ii", "interval-iteration", "svi", "sound-value-iteration"}; + this->addOption(storm::settings::OptionBuilder(moduleName, underlyingMinMaxMethodOptionName, true, "Sets which minmax method is considered for solving the underlying minmax equation systems.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the used min max method.").addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(minMaxSolvingTechniques)).setDefaultValueString("value-iteration").build()).build()); + } + + bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSet() const { + return this->getOption(underlyingEquationSolverOptionName).getHasOptionBeenSet(); + } + + bool TopologicalEquationSolverSettings::isUnderlyingEquationSolverTypeSetFromDefaultValue() const { + return !this->getOption(underlyingEquationSolverOptionName).getHasOptionBeenSet() || this->getOption(underlyingEquationSolverOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + + storm::solver::EquationSolverType TopologicalEquationSolverSettings::getUnderlyingEquationSolverType() const { + std::string equationSolverName = this->getOption(underlyingEquationSolverOptionName).getArgumentByName("name").getValueAsString(); + if (equationSolverName == "gmm++") { + return storm::solver::EquationSolverType::Gmmxx; + } else if (equationSolverName == "native") { + return storm::solver::EquationSolverType::Native; + } else if (equationSolverName == "eigen") { + return storm::solver::EquationSolverType::Eigen; + } else if (equationSolverName == "elimination") { + return storm::solver::EquationSolverType::Elimination; + } + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << equationSolverName << "'."); + } + + bool TopologicalEquationSolverSettings::isUnderlyingMinMaxMethodSet() const { + return this->getOption(underlyingMinMaxMethodOptionName).getHasOptionBeenSet(); + } + + bool TopologicalEquationSolverSettings::isUnderlyingMinMaxMethodSetFromDefaultValue() const { + return !this->getOption(underlyingMinMaxMethodOptionName).getHasOptionBeenSet() || this->getOption(underlyingMinMaxMethodOptionName).getArgumentByName("name").wasSetFromDefaultValue(); + } + + storm::solver::MinMaxMethod TopologicalEquationSolverSettings::getUnderlyingMinMaxMethod() const { + std::string minMaxEquationSolvingTechnique = this->getOption(underlyingMinMaxMethodOptionName).getArgumentByName("name").getValueAsString(); + if (minMaxEquationSolvingTechnique == "value-iteration" || minMaxEquationSolvingTechnique == "vi") { + return storm::solver::MinMaxMethod::ValueIteration; + } else if (minMaxEquationSolvingTechnique == "policy-iteration" || minMaxEquationSolvingTechnique == "pi") { + return storm::solver::MinMaxMethod::PolicyIteration; + } else if (minMaxEquationSolvingTechnique == "linear-programming" || minMaxEquationSolvingTechnique == "lp") { + return storm::solver::MinMaxMethod::LinearProgramming; + } else if (minMaxEquationSolvingTechnique == "ratsearch" || minMaxEquationSolvingTechnique == "rs") { + return storm::solver::MinMaxMethod::RationalSearch; + } else if (minMaxEquationSolvingTechnique == "interval-iteration" || minMaxEquationSolvingTechnique == "ii") { + return storm::solver::MinMaxMethod::IntervalIteration; + } else if (minMaxEquationSolvingTechnique == "sound-value-iteration" || minMaxEquationSolvingTechnique == "svi") { + return storm::solver::MinMaxMethod::SoundValueIteration; + } + + + + + STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown underlying equation solver '" << minMaxEquationSolvingTechnique << "'."); + } + + bool TopologicalEquationSolverSettings::check() const { + if (this->isUnderlyingEquationSolverTypeSet() && getUnderlyingEquationSolverType() == storm::solver::EquationSolverType::Topological) { + STORM_LOG_WARN("Underlying solver type of the topological solver can not be the topological solver."); + return false; + } + if (this->isUnderlyingMinMaxMethodSet() && getUnderlyingMinMaxMethod() == storm::solver::MinMaxMethod::Topological) { + STORM_LOG_WARN("Underlying minmax method of the topological solver can not be topological."); + return false; + } + return true; + } + + } // namespace modules + } // namespace settings +} // namespace storm + + diff --git a/src/storm/settings/modules/TopologicalEquationSolverSettings.h b/src/storm/settings/modules/TopologicalEquationSolverSettings.h new file mode 100644 index 000000000..f9ddefd78 --- /dev/null +++ b/src/storm/settings/modules/TopologicalEquationSolverSettings.h @@ -0,0 +1,77 @@ +#pragma once + +#include "storm/settings/modules/ModuleSettings.h" + +#include "storm/solver/SolverSelectionOptions.h" + +namespace storm { + namespace settings { + namespace modules { + + /*! + * This class represents the settings for the native equation solver. + */ + class TopologicalEquationSolverSettings : public ModuleSettings { + public: + + /*! + * Creates a new set of native equation solver settings. + */ + TopologicalEquationSolverSettings(); + + /*! + * Retrieves whether the underlying equation solver type has been set. + * + * @return True iff the linear equation system technique has been set. + */ + bool isUnderlyingEquationSolverTypeSet() const; + + /*! + * Retrieves whether the underlying equation solver type is set from its default value. + * + * @return True iff it was set from its default value. + */ + bool isUnderlyingEquationSolverTypeSetFromDefaultValue() const; + + /*! + * Retrieves the method that is to be used for solving systems of linear equations. + * + * @return The method to use. + */ + storm::solver::EquationSolverType getUnderlyingEquationSolverType() const; + + /*! + * Retrieves whether the underlying equation solver type has been set. + * + * @return True iff the linear equation system technique has been set. + */ + bool isUnderlyingMinMaxMethodSet() const; + + /*! + * Retrieves whether the underlying minmax method is set from its default value. + * + * @return True iff it was set from its default value. + */ + bool isUnderlyingMinMaxMethodSetFromDefaultValue() const; + + /*! + * Retrieves the method that is to be used for solving systems of linear equations. + * + * @return The method to use. + */ + storm::solver::MinMaxMethod getUnderlyingMinMaxMethod() const; + + bool check() const override; + + // The name of the module. + static const std::string moduleName; + + private: + // Define the string names of the options as constants. + static const std::string underlyingEquationSolverOptionName; + static const std::string underlyingMinMaxMethodOptionName; + }; + + } // namespace modules + } // namespace settings +} // namespace storm diff --git a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp b/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp deleted file mode 100644 index ead40d320..000000000 --- a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h" - -#include "storm/settings/Option.h" -#include "storm/settings/OptionBuilder.h" -#include "storm/settings/ArgumentBuilder.h" -#include "storm/settings/Argument.h" - -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/GeneralSettings.h" -#include "storm/solver/SolverSelectionOptions.h" - -namespace storm { - namespace settings { - namespace modules { - - const std::string TopologicalValueIterationEquationSolverSettings::moduleName = "topologicalValueIteration"; - const std::string TopologicalValueIterationEquationSolverSettings::maximalIterationsOptionName = "maxiter"; - const std::string TopologicalValueIterationEquationSolverSettings::maximalIterationsOptionShortName = "i"; - const std::string TopologicalValueIterationEquationSolverSettings::precisionOptionName = "precision"; - const std::string TopologicalValueIterationEquationSolverSettings::absoluteOptionName = "absolute"; - - TopologicalValueIterationEquationSolverSettings::TopologicalValueIterationEquationSolverSettings() : ModuleSettings(moduleName) { - - this->addOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, false, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(20000).build()).build()); - - this->addOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, false, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidatorDouble(ArgumentValidatorFactory::createDoubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - - this->addOption(storm::settings::OptionBuilder(moduleName, absoluteOptionName, false, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); - } - - bool TopologicalValueIterationEquationSolverSettings::isMaximalIterationCountSet() const { - return this->getOption(maximalIterationsOptionName).getHasOptionBeenSet(); - } - - uint_fast64_t TopologicalValueIterationEquationSolverSettings::getMaximalIterationCount() const { - return this->getOption(maximalIterationsOptionName).getArgumentByName("count").getValueAsUnsignedInteger(); - } - - bool TopologicalValueIterationEquationSolverSettings::isPrecisionSet() const { - return this->getOption(precisionOptionName).getHasOptionBeenSet(); - } - - double TopologicalValueIterationEquationSolverSettings::getPrecision() const { - return this->getOption(precisionOptionName).getArgumentByName("value").getValueAsDouble(); - } - - bool TopologicalValueIterationEquationSolverSettings::isConvergenceCriterionSet() const { - return this->getOption(absoluteOptionName).getHasOptionBeenSet(); - } - - TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion TopologicalValueIterationEquationSolverSettings::getConvergenceCriterion() const { - return this->getOption(absoluteOptionName).getHasOptionBeenSet() ? TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Absolute : TopologicalValueIterationEquationSolverSettings::ConvergenceCriterion::Relative; - } - - bool TopologicalValueIterationEquationSolverSettings::check() const { - return true; - } - - } // namespace modules - } // namespace settings -} // namespace storm diff --git a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h b/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h deleted file mode 100644 index 21006c3bd..000000000 --- a/src/storm/settings/modules/TopologicalValueIterationEquationSolverSettings.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ -#define STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ - -#include "storm/settings/modules/ModuleSettings.h" - -namespace storm { - namespace settings { - namespace modules { - - /*! - * This class represents the settings for topological value iteration. - */ - class TopologicalValueIterationEquationSolverSettings : public ModuleSettings { - public: - - // An enumeration of all available convergence criteria. - enum class ConvergenceCriterion { Absolute, Relative }; - - /*! - * Creates a new set of topological value iteration settings. - */ - TopologicalValueIterationEquationSolverSettings(); - - - /*! - * Retrieves whether the maximal iteration count has been set. - * - * @return True iff the maximal iteration count has been set. - */ - bool isMaximalIterationCountSet() const; - - /*! - * Retrieves the maximal number of iterations to perform until giving up on converging. - * - * @return The maximal iteration count. - */ - uint_fast64_t getMaximalIterationCount() const; - - /*! - * Retrieves whether the precision has been set. - * - * @return True iff the precision has been set. - */ - bool isPrecisionSet() const; - - /*! - * Retrieves the precision that is used for detecting convergence. - * - * @return The precision to use for detecting convergence. - */ - double getPrecision() const; - - /*! - * Retrieves whether the convergence criterion has been set. - * - * @return True iff the convergence criterion has been set. - */ - bool isConvergenceCriterionSet() const; - - /*! - * Retrieves the selected convergence criterion. - * - * @return The selected convergence criterion. - */ - ConvergenceCriterion getConvergenceCriterion() const; - - bool check() const override; - - // The name of the module. - static const std::string moduleName; - - private: - // Define the string names of the options as constants. - static const std::string techniqueOptionName; - static const std::string maximalIterationsOptionName; - static const std::string maximalIterationsOptionShortName; - static const std::string precisionOptionName; - static const std::string absoluteOptionName; - }; - - } // namespace modules - } // namespace settings -} // namespace storm - -#endif /* STORM_SETTINGS_MODULES_TOPOLOGICALVALUEITERATIONSETTINGS_H_ */ diff --git a/src/storm/solver/AbstractEquationSolver.cpp b/src/storm/solver/AbstractEquationSolver.cpp index d17a9041d..69a2d0fad 100644 --- a/src/storm/solver/AbstractEquationSolver.cpp +++ b/src/storm/solver/AbstractEquationSolver.cpp @@ -9,6 +9,7 @@ #include "storm/utility/constants.h" #include "storm/utility/macros.h" #include "storm/exceptions/UnmetRequirementException.h" +#include "storm/exceptions/InvalidOperationException.h" namespace storm { namespace solver { @@ -119,10 +120,33 @@ namespace storm { return lowerBound.get(); } + template<typename ValueType> + ValueType AbstractEquationSolver<ValueType>::getLowerBound(bool convertLocalBounds) const { + if (lowerBound) { + return lowerBound.get(); + } else if (convertLocalBounds) { + return *std::min_element(lowerBounds->begin(), lowerBounds->end()); + } + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "No lower bound available but some was requested."); + return ValueType(); + } + template<typename ValueType> ValueType const& AbstractEquationSolver<ValueType>::getUpperBound() const { return upperBound.get(); } + + template<typename ValueType> + ValueType AbstractEquationSolver<ValueType>::getUpperBound(bool convertLocalBounds) const { + if (upperBound) { + return upperBound.get(); + } else if (convertLocalBounds) { + return *std::max_element(upperBounds->begin(), upperBounds->end()); + } + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "No upper bound available but some was requested."); + return ValueType(); + } + template<typename ValueType> std::vector<ValueType> const& AbstractEquationSolver<ValueType>::getLowerBounds() const { @@ -249,11 +273,6 @@ namespace storm { } } - template<typename ValueType> - void AbstractEquationSolver<ValueType>::setPrecision(ValueType const& precision) { - STORM_LOG_DEBUG("Setting solver precision for a solver that does not support precisions."); - } - template class AbstractEquationSolver<double>; template class AbstractEquationSolver<float>; diff --git a/src/storm/solver/AbstractEquationSolver.h b/src/storm/solver/AbstractEquationSolver.h index d5000f8c7..9f9efb411 100644 --- a/src/storm/solver/AbstractEquationSolver.h +++ b/src/storm/solver/AbstractEquationSolver.h @@ -3,7 +3,7 @@ #include <memory> #include <chrono> - +#include <iostream> #include <boost/optional.hpp> #include "storm/solver/TerminationCondition.h" @@ -97,11 +97,25 @@ namespace storm { */ ValueType const& getLowerBound() const; + /*! + * Retrieves the lower bound (if there is any). + * If the given flag is true and if there are only local bounds, + * the minimum of the local bounds is returned. + */ + ValueType getLowerBound(bool convertLocalBounds) const; + /*! * Retrieves the upper bound (if there is any). */ ValueType const& getUpperBound() const; + /*! + * Retrieves the upper bound (if there is any). + * If the given flag is true and if there are only local bounds, + * the maximum of the local bounds is returned. + */ + ValueType getUpperBound(bool convertLocalBounds) const; + /*! * Retrieves a vector containing the lower bounds (if there are any). */ @@ -163,8 +177,6 @@ namespace storm { * Shows progress if this solver is asked to do so. */ void showProgressIterative(uint64_t iterations, boost::optional<uint64_t> const& bound = boost::none) const; - - virtual void setPrecision(ValueType const& precision); protected: /*! diff --git a/src/storm/solver/EigenLinearEquationSolver.cpp b/src/storm/solver/EigenLinearEquationSolver.cpp index 874d6f4c4..afbc88a3b 100644 --- a/src/storm/solver/EigenLinearEquationSolver.cpp +++ b/src/storm/solver/EigenLinearEquationSolver.cpp @@ -240,34 +240,6 @@ namespace storm { return true; } - template<typename ValueType> - void EigenLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - // Typedef the map-type so we don't have to spell it out. - typedef decltype(StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(b->data(), b->size())) MapType; - - auto eigenX = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(x.data(), x.size()); - auto eigenResult = StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(result.data(), result.size()); - - std::unique_ptr<MapType> eigenB; - if (b != nullptr) { - eigenB = std::make_unique<MapType>(StormEigen::Matrix<ValueType, StormEigen::Dynamic, 1>::Map(b->data(), b->size())); - } - - if (&x != &result) { - if (b != nullptr) { - eigenResult.noalias() = *eigenA * eigenX + *eigenB; - } else { - eigenResult.noalias() = *eigenA * eigenX; - } - } else { - if (b != nullptr) { - eigenResult = *eigenA * eigenX + *eigenB; - } else { - eigenResult = *eigenA * eigenX; - } - } - } - template<typename ValueType> LinearEquationSolverProblemFormat EigenLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; @@ -284,7 +256,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EigenLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EigenLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::EigenLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/EigenLinearEquationSolver.h b/src/storm/solver/EigenLinearEquationSolver.h index a6bbae91a..63768563a 100644 --- a/src/storm/solver/EigenLinearEquationSolver.h +++ b/src/storm/solver/EigenLinearEquationSolver.h @@ -20,8 +20,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; protected: @@ -43,7 +41,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; }; diff --git a/src/storm/solver/EliminationLinearEquationSolver.cpp b/src/storm/solver/EliminationLinearEquationSolver.cpp index 3e84b7f0c..2873c04c4 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.cpp +++ b/src/storm/solver/EliminationLinearEquationSolver.cpp @@ -93,23 +93,6 @@ namespace storm { return true; } - template<typename ValueType> - void EliminationLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (&x != &result) { - A->multiplyWithVector(x, result); - if (b != nullptr) { - storm::utility::vector::addVectors(result, *b, result); - } - } else { - // If the two vectors are aliases, we need to create a temporary. - std::vector<ValueType> tmp(result.size()); - A->multiplyWithVector(x, tmp); - if (b != nullptr) { - storm::utility::vector::addVectors(tmp, *b, result); - } - } - } - template<typename ValueType> LinearEquationSolverProblemFormat EliminationLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::FixedPointSystem; @@ -126,7 +109,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> EliminationLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::EliminationLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/EliminationLinearEquationSolver.h b/src/storm/solver/EliminationLinearEquationSolver.h index 60403336e..d3c3f5992 100644 --- a/src/storm/solver/EliminationLinearEquationSolver.h +++ b/src/storm/solver/EliminationLinearEquationSolver.h @@ -21,8 +21,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; protected: @@ -46,7 +44,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/GmmxxLinearEquationSolver.cpp b/src/storm/solver/GmmxxLinearEquationSolver.cpp index 0f517d5a9..83d5b6ef6 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.cpp +++ b/src/storm/solver/GmmxxLinearEquationSolver.cpp @@ -5,7 +5,6 @@ #include "storm/adapters/GmmxxAdapter.h" -#include "storm/solver/GmmxxMultiplier.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/utility/vector.h" @@ -116,35 +115,6 @@ namespace storm { return false; } - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - multiplier.multAdd(*gmmxxA, x, b, result); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - multiplier.multAddReduce(dir, rowGroupIndices, *gmmxxA, x, b, result, choices); - } - - template<typename ValueType> - bool GmmxxLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return true; - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - multiplier.multAddGaussSeidelBackward(*gmmxxA, x, b); - } - - template<typename ValueType> - void GmmxxLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { - multiplier.multAddReduceGaussSeidel(dir, rowGroupIndices, *gmmxxA, x, b, choices); - } - template<typename ValueType> LinearEquationSolverProblemFormat GmmxxLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { return LinearEquationSolverProblemFormat::EquationSystem; @@ -168,7 +138,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> GmmxxLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> GmmxxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::GmmxxLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/GmmxxLinearEquationSolver.h b/src/storm/solver/GmmxxLinearEquationSolver.h index bb08cf007..f288e9f58 100644 --- a/src/storm/solver/GmmxxLinearEquationSolver.h +++ b/src/storm/solver/GmmxxLinearEquationSolver.h @@ -5,10 +5,8 @@ #include "storm/utility/gmm.h" -#include "storm/solver/GmmxxMultiplier.h" - #include "storm/solver/LinearEquationSolver.h" -#include "SolverSelectionOptions.h" +#include "storm/solver/SolverSelectionOptions.h" namespace storm { namespace solver { @@ -27,12 +25,6 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual bool supportsGaussSeidelMultiplication() const override; - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const& env) const override; virtual void clearCache() const override; @@ -50,9 +42,6 @@ namespace storm { // The matrix in gmm++ format. std::unique_ptr<gmm::csr_matrix<ValueType>> gmmxxA; - // A multiplier object used to dispatch the multiplication calls. - GmmxxMultiplier<ValueType> multiplier; - // cached data obtained during solving mutable std::unique_ptr<gmm::ilu_precond<gmm::csr_matrix<ValueType>>> iluPreconditioner; mutable std::unique_ptr<gmm::diagonal_precond<gmm::csr_matrix<ValueType>>> diagonalPreconditioner; @@ -63,7 +52,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/GmmxxMultiplier.cpp b/src/storm/solver/GmmxxMultiplier.cpp index b05ef8bcc..a11675b75 100644 --- a/src/storm/solver/GmmxxMultiplier.cpp +++ b/src/storm/solver/GmmxxMultiplier.cpp @@ -2,6 +2,9 @@ #include "storm/adapters/RationalNumberAdapter.h" #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/storage/SparseMatrix.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" #include "storm/utility/constants.h" #include "storm/exceptions/NotSupportedException.h" @@ -11,60 +14,113 @@ namespace storm { namespace solver { - template<typename T> - GmmxxMultiplier<T>::GmmxxMultiplier() : storm::utility::VectorHelper<T>() { + template<typename ValueType> + GmmxxMultiplier<ValueType>::GmmxxMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { // Intentionally left empty. } - template<typename T> - void GmmxxMultiplier<T>::multAdd(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const { - if (this->parallelize()) { - multAddParallel(matrix, x, b, result); - } else { - if (b) { - gmm::mult_add(matrix, x, *b, result); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::initialize() const { + if (gmmMatrix.nrows() == 0) { + gmmMatrix = std::move(*storm::adapters::GmmxxAdapter<ValueType>().toGmmxxSparseMatrix(this->matrix)); + } + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::clearCache() const { + gmmMatrix = gmm::csr_matrix<ValueType>(); + Multiplier<ValueType>::clearCache(); + } + + template<typename ValueType> + bool GmmxxMultiplier<ValueType>::parallelize(Environment const& env) const { +#ifdef STORM_HAVE_INTELTBB + return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); +#else + return false; +#endif + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + initialize(); + std::vector<ValueType>* target = &result; + if (&x == &result) { + if (this->cachedVector) { + this->cachedVector->resize(x.size()); } else { - gmm::mult(matrix, x, result); + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); } + target = this->cachedVector.get(); + } + if (parallelize(env)) { + multAddParallel(x, b, *target); + } else { + multAdd(x, b, *target); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); } } - template<typename T> - void GmmxxMultiplier<T>::multAddGaussSeidelBackward(gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b) const { - STORM_LOG_ASSERT(matrix.nr == matrix.nc, "Expecting square matrix."); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + initialize(); + STORM_LOG_ASSERT(gmmMatrix.nr == gmmMatrix.nc, "Expecting square matrix."); if (b) { - gmm::mult_add_by_row_bwd(matrix, x, *b, x, gmm::abstract_dense()); + gmm::mult_add_by_row_bwd(gmmMatrix, x, *b, x, gmm::abstract_dense()); } else { - gmm::mult_by_row_bwd(matrix, x, x, gmm::abstract_dense()); + gmm::mult_by_row_bwd(gmmMatrix, x, x, gmm::abstract_dense()); } } - template<typename T> - void GmmxxMultiplier<T>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { - std::vector<T>* target = &result; - std::unique_ptr<std::vector<T>> temporary; + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + initialize(); + std::vector<ValueType>* target = &result; if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAddReduce'."); - temporary = std::make_unique<std::vector<T>>(x.size()); - target = temporary.get(); + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); } - - if (this->parallelize()) { - multAddReduceParallel(dir, rowGroupIndices, matrix, x, b, *target, choices); + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); } else { - multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, *target, choices); + multAddReduceHelper(dir, rowGroupIndices, x, b, *target, choices); + } + if (&x == &result) { + std::swap(result, *this->cachedVector); } } - template<typename T> - void GmmxxMultiplier<T>::multAddReduceGaussSeidel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b, std::vector<uint64_t>* choices) const { - multAddReduceHelper(dir, rowGroupIndices, matrix, x, b, x, choices); + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + initialize(); + multAddReduceHelper(dir, rowGroupIndices, x, b, x, choices); } - template<typename T> - void GmmxxMultiplier<T>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { - typedef std::vector<T> VectorType; - typedef gmm::csr_matrix<T> MatrixType; + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + initialize(); + value += vect_sp(gmm::mat_const_row(gmmMatrix, rowIndex), x, typename gmm::linalg_traits<gmm::csr_matrix<ValueType>>::storage_type(), typename gmm::linalg_traits<std::vector<ValueType>>::storage_type()); + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + if (b) { + gmm::mult_add(gmmMatrix, x, *b, result); + } else { + gmm::mult(gmmMatrix, x, result); + } + } + + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + typedef std::vector<ValueType> VectorType; + typedef gmm::csr_matrix<ValueType> MatrixType; typename gmm::linalg_traits<VectorType>::const_iterator add_it, add_ite; if (b) { @@ -72,7 +128,7 @@ namespace storm { add_ite = gmm::vect_begin(*b) - 1; } typename gmm::linalg_traits<VectorType>::iterator target_it = gmm::vect_end(result) - 1; - typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = mat_row_const_end(matrix) - 1; + typename gmm::linalg_traits<MatrixType>::const_row_iterator itr = mat_row_const_end(gmmMatrix) - 1; typename std::vector<uint64_t>::iterator choice_it; if (choices) { choice_it = choices->end() - 1; @@ -84,7 +140,7 @@ namespace storm { *choice_it = 0; } - T currentValue = storm::utility::zero<T>(); + ValueType currentValue = storm::utility::zero<ValueType>(); // Only multiply and reduce if the row group is not empty. if (*row_group_it != *(row_group_it + 1)) { @@ -103,7 +159,7 @@ namespace storm { --itr; for (uint64_t row = *row_group_it + 1, rowEnd = *(row_group_it + 1); row < rowEnd; ++row, --itr, --add_it) { - T newValue = b ? *add_it : storm::utility::zero<T>(); + ValueType newValue = b ? *add_it : storm::utility::zero<ValueType>(); newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); if (choices) { @@ -127,38 +183,42 @@ namespace storm { } template<> - void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<storm::RationalFunction> const& matrix, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { + void GmmxxMultiplier<storm::RationalFunction>::multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported for this data type."); } - template<typename T> - void GmmxxMultiplier<T>::multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const { + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB if (b) { - gmm::mult_add_parallel(matrix, x, *b, result); + gmm::mult_add_parallel(gmmMatrix, x, *b, result); } else { - gmm::mult_parallel(matrix, x, result); + gmm::mult_parallel(gmmMatrix, x, result); } #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAdd(matrix, x, b, result); + multAdd(x, b, result); #endif } #ifdef STORM_HAVE_INTELTBB - template<typename T> + template<typename ValueType> class TbbMultAddReduceFunctor { public: - TbbMultAddReduceFunctor(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) : dir(dir), rowGroupIndices(rowGroupIndices), matrix(matrix), x(x), b(b), result(result), choices(choices) { + TbbMultAddReduceFunctor(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) : dir(dir), rowGroupIndices(rowGroupIndices), matrix(matrix), x(x), b(b), result(result), choices(choices) { // Intentionally left empty. } void operator()(tbb::blocked_range<unsigned long> const& range) const { + typedef std::vector<ValueType> VectorType; + typedef gmm::csr_matrix<ValueType> MatrixType; + + bool min = dir == OptimizationDirection::Minimize; auto groupIt = rowGroupIndices.begin() + range.begin(); auto groupIte = rowGroupIndices.begin() + range.end(); - + auto itr = mat_row_const_begin(matrix) + *groupIt; - typename std::vector<T>::const_iterator bIt; + typename std::vector<ValueType>::const_iterator bIt; if (b) { bIt = b->begin() + *groupIt; } @@ -168,13 +228,14 @@ namespace storm { } auto resultIt = result.begin() + range.begin(); - + + // Variables for correctly tracking choices (only update if new choice is strictly better). + ValueType oldSelectedChoiceValue; + uint64_t selectedChoice; + + uint64_t currentRow = *groupIt; for (; groupIt != groupIte; ++groupIt, ++resultIt, ++choiceIt) { - if (choices) { - *choiceIt = 0; - } - - T currentValue = storm::utility::zero<T>(); + ValueType currentValue = storm::utility::zero<ValueType>(); // Only multiply and reduce if the row group is not empty. if (*groupIt != *(groupIt + 1)) { @@ -183,51 +244,62 @@ namespace storm { ++bIt; } - ++itr; + currentValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); - for (auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr) { - T newValue = vect_sp(gmm::linalg_traits<gmm::csr_matrix<T>>::row(itr), x, typename gmm::linalg_traits<gmm::csr_matrix<T>>::storage_type(), typename gmm::linalg_traits<std::vector<T>>::storage_type()); - if (b) { - newValue += *bIt; - ++bIt; + if (choices) { + selectedChoice = currentRow - *groupIt; + if (*choiceIt == selectedChoice) { + oldSelectedChoiceValue = currentValue; } + } + + ++itr; + ++currentRow; + + for (auto itre = mat_row_const_begin(matrix) + *(groupIt + 1); itr != itre; ++itr, ++bIt, ++currentRow) { + ValueType newValue = b ? *bIt : storm::utility::zero<ValueType>(); + newValue += vect_sp(gmm::linalg_traits<MatrixType>::row(itr), x); - if ((dir == OptimizationDirection::Minimize && newValue < currentValue) || (dir == OptimizationDirection::Maximize && newValue > currentValue)) { + if (min ? newValue < currentValue : newValue > currentValue) { currentValue = newValue; if (choices) { - *choiceIt = std::distance(mat_row_const_begin(matrix), itr) - *groupIt; + selectedChoice = currentRow - *groupIt; } } } } + // Finally write value to target vector. *resultIt = currentValue; + if (choices && (min ? currentValue < oldSelectedChoiceValue : currentValue > oldSelectedChoiceValue)) { + *choiceIt = selectedChoice; + } } } private: storm::solver::OptimizationDirection dir; std::vector<uint64_t> const& rowGroupIndices; - gmm::csr_matrix<T> const& matrix; - std::vector<T> const& x; - std::vector<T> const* b; - std::vector<T>& result; + gmm::csr_matrix<ValueType> const& matrix; + std::vector<ValueType> const& x; + std::vector<ValueType> const* b; + std::vector<ValueType>& result; std::vector<uint64_t>* choices; }; #endif - template<typename T> - void GmmxxMultiplier<T>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices) const { + template<typename ValueType> + void GmmxxMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB - tbb::parallel_for(tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 10), TbbMultAddReduceFunctor<T>(dir, rowGroupIndices, matrix, x, b, result, choices)); + tbb::parallel_for(tbb::blocked_range<unsigned long>(0, rowGroupIndices.size() - 1, 10), TbbMultAddReduceFunctor<ValueType>(dir, rowGroupIndices, this->gmmMatrix, x, b, result, choices)); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAddReduce(dir, rowGroupIndices, matrix, x, b, result, choices); + multAddReduceHelper(dir, rowGroupIndices, x, b, result, choices); #endif } template<> - void GmmxxMultiplier<storm::RationalFunction>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<storm::RationalFunction> const& matrix, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { + void GmmxxMultiplier<storm::RationalFunction>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction> const& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint64_t>* choices) const { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This operation is not supported."); } diff --git a/src/storm/solver/GmmxxMultiplier.h b/src/storm/solver/GmmxxMultiplier.h index 237f56b63..fdebd557d 100644 --- a/src/storm/solver/GmmxxMultiplier.h +++ b/src/storm/solver/GmmxxMultiplier.h @@ -1,30 +1,43 @@ #pragma once -#include "storm/utility/VectorHelper.h" +#include "storm/solver/Multiplier.h" #include "storm/adapters/GmmxxAdapter.h" #include "storm-config.h" namespace storm { + + namespace storage { + template<typename ValueType> + class SparseMatrix; + } + namespace solver { - template<class T> - class GmmxxMultiplier : public storm::utility::VectorHelper<T> { + template<typename ValueType> + class GmmxxMultiplier : public Multiplier<ValueType> { public: - GmmxxMultiplier(); + GmmxxMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + virtual ~GmmxxMultiplier() = default; - void multAdd(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const; - void multAddGaussSeidelBackward(gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b) const; + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; + virtual void clearCache() const override; + private: + void initialize() const; - void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduceGaussSeidel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T>& x, std::vector<T> const* b, std::vector<uint64_t>* choices = nullptr) const; + bool parallelize(Environment const& env) const; - void multAddParallel(gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result) const; - void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; - - private: - void multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, gmm::csr_matrix<T> const& matrix, std::vector<T> const& x, std::vector<T> const* b, std::vector<T>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + void multAddReduceHelper(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; + + mutable gmm::csr_matrix<ValueType> gmmMatrix; }; } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index fb71fa43f..51289fb52 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -1,3 +1,6 @@ +#include <functional> +#include <limits> + #include "storm/solver/IterativeMinMaxLinearEquationSolver.h" #include "storm/utility/ConstantsComparator.h" @@ -7,6 +10,7 @@ #include "storm/utility/KwekMehlhorn.h" #include "storm/utility/NumberTraits.h" +#include "storm/utility/Stopwatch.h" #include "storm/utility/vector.h" #include "storm/utility/macros.h" #include "storm/exceptions/InvalidEnvironmentException.h" @@ -19,23 +23,23 @@ namespace storm { namespace solver { template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty } template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A, std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A), std::move(linearEquationSolverFactory)) { + IterativeMinMaxLinearEquationSolver<ValueType>::IterativeMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { // Intentionally left empty. } template<typename ValueType> MinMaxMethod IterativeMinMaxLinearEquationSolver<ValueType>::getMethod(Environment const& env, bool isExactMode) const { - // Adjust the method if none was specified and we are using rational numbers. + // Adjust the method if none was specified and we want exact or sound computations. auto method = env.solver().minMax().getMethod(); if (isExactMode && method != MinMaxMethod::PolicyIteration && method != MinMaxMethod::RationalSearch) { @@ -45,8 +49,15 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } + } else if (env.solver().isForceSoundness() && method != MinMaxMethod::SoundValueIteration && method != MinMaxMethod::IntervalIteration && method != MinMaxMethod::PolicyIteration && method != MinMaxMethod::RationalSearch) { + if (env.solver().minMax().isMethodSetFromDefault()) { + STORM_LOG_INFO("Selecting 'sound value iteration' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); + method = MinMaxMethod::SoundValueIteration; + } else { + STORM_LOG_WARN("The selected solution method does not guarantee sound results."); + } } - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); + STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::SoundValueIteration || method == MinMaxMethod::IntervalIteration, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); return method; } @@ -55,11 +66,7 @@ namespace storm { bool result = false; switch (getMethod(env, storm::NumberTraits<ValueType>::IsExact)) { case MinMaxMethod::ValueIteration: - if (env.solver().isForceSoundness()) { - result = solveEquationsSoundValueIteration(env, dir, x, b); - } else { - result = solveEquationsValueIteration(env, dir, x, b); - } + result = solveEquationsValueIteration(env, dir, x, b); break; case MinMaxMethod::PolicyIteration: result = solveEquationsPolicyIteration(env, dir, x, b); @@ -67,6 +74,12 @@ namespace storm { case MinMaxMethod::RationalSearch: result = solveEquationsRationalSearch(env, dir, x, b); break; + case MinMaxMethod::IntervalIteration: + result = solveEquationsIntervalIteration(env, dir, x, b); + break; + case MinMaxMethod::SoundValueIteration: + result = solveEquationsSoundValueIteration(env, dir, x, b); + break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "This solver does not implement the selected solution method"); } @@ -114,19 +127,32 @@ namespace storm { // The solver that we will use throughout the procedure. std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver; // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } - + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + SolverStatus status = SolverStatus::InProgress; uint64_t iterations = 0; this->startMeasureProgress(); do { // Solve the equation system for the 'DTMC'. - solveInducedEquationSystem(environmentOfSolver ? *environmentOfSolver : env, solver, scheduler, x, subB, b); + solveInducedEquationSystem(environmentOfSolver, solver, scheduler, x, subB, b); // Go through the multiplication result and see whether we can improve any of the choices. bool schedulerImproved = false; @@ -193,26 +219,17 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - // Start by getting the requirements of the linear equation solver. - LinearEquationSolverTask linEqTask = LinearEquationSolverTask::Unspecified; - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::RationalSearch) { - if (!this->hasInitialScheduler() && assumeNoInitialScheduler) { - linEqTask = LinearEquationSolverTask::Multiply; - } - } - MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, linEqTask)); + // Check whether a linear equation solver is needed and potentially start with its requirements + bool needsLinEqSolver = false; + needsLinEqSolver |= method == MinMaxMethod::PolicyIteration; + needsLinEqSolver |= method == MinMaxMethod::ValueIteration && (this->hasInitialScheduler() || hasInitialScheduler); + MinMaxLinearEquationSolverRequirements requirements = needsLinEqSolver ? MinMaxLinearEquationSolverRequirements(this->linearEquationSolverFactory->getRequirements(env)) : MinMaxLinearEquationSolverRequirements(); if (method == MinMaxMethod::ValueIteration) { - if (env.solver().isForceSoundness()) { - // Interval iteration requires a unique solution and lower+upper bounds - if (!this->hasUniqueSolution()) { - requirements.requireNoEndComponents(); - } - requirements.requireBounds(); - } else if (!this->hasUniqueSolution()) { // Traditional value iteration has no requirements if the solution is unique. + if (!this->hasUniqueSolution()) { // Traditional value iteration has no requirements if the solution is unique. // Computing a scheduler is only possible if the solution is unique if (this->isTrackSchedulerSet()) { requirements.requireNoEndComponents(); @@ -226,6 +243,12 @@ namespace storm { } } } + } else if (method == MinMaxMethod::IntervalIteration) { + // Interval iteration requires a unique solution and lower+upper bounds + if (!this->hasUniqueSolution()) { + requirements.requireNoEndComponents(); + } + requirements.requireBounds(); } else if (method == MinMaxMethod::RationalSearch) { // Rational search needs to approach the solution from below. requirements.requireLowerBounds(); @@ -237,38 +260,40 @@ namespace storm { if (!this->hasUniqueSolution()) { requirements.requireValidInitialScheduler(); } + } else if (method == MinMaxMethod::SoundValueIteration) { + if (!this->hasUniqueSolution()) { + requirements.requireNoEndComponents(); + } + requirements.requireBounds(false); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unsupported technique for iterative MinMax linear equation solver."); } - return requirements; } template<typename ValueType> - typename IterativeMinMaxLinearEquationSolver<ValueType>::ValueIterationResult IterativeMinMaxLinearEquationSolver<ValueType>::performValueIteration(OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { + typename IterativeMinMaxLinearEquationSolver<ValueType>::ValueIterationResult IterativeMinMaxLinearEquationSolver<ValueType>::performValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { STORM_LOG_ASSERT(currentX != newX, "Vectors must not be aliased."); - // Get handle to linear equation solver. - storm::solver::LinearEquationSolver<ValueType> const& linearEquationSolver = *this->linEqSolverA; + // Get handle to multiplier. + storm::solver::Multiplier<ValueType> const& multiplier = *this->multiplierA; // Allow aliased multiplications. - bool useGaussSeidelMultiplication = linearEquationSolver.supportsGaussSeidelMultiplication() && multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; + bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; // Proceed with the iterations as long as the method did not converge or reach the maximum number of iterations. uint64_t iterations = currentIterations; - std::vector<ValueType>* originalX = currentX; - SolverStatus status = SolverStatus::InProgress; while (status == SolverStatus::InProgress) { // Compute x' = min/max(A*x + b). if (useGaussSeidelMultiplication) { // Copy over the current vector so we can modify it in-place. *newX = *currentX; - linearEquationSolver.multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *newX, &b); + multiplier.multiplyAndReduceGaussSeidel(env, dir, *newX, &b); } else { - linearEquationSolver.multiplyAndReduce(dir, this->A->getRowGroupIndices(), *currentX, &b, *newX); + multiplier.multiplyAndReduce(env, dir, *currentX, &b, *newX); } // Determine whether the method converged. @@ -285,19 +310,13 @@ namespace storm { this->showProgressIterative(iterations); } - // Swap the pointers so that the output is always in currentX. - if (originalX == newX) { - std::swap(currentX, newX); - } - return ValueIterationResult(iterations - currentIterations, status); } template<typename ValueType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -311,14 +330,27 @@ namespace storm { // Solve the equation system induced by the initial scheduler. std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolver; // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; - solveInducedEquationSystem(environmentOfSolver ? *environmentOfSolver : env, linEqSolver, this->getInitialScheduler(), x, *auxiliaryRowGroupVector, b); + solveInducedEquationSystem(environmentOfSolver, linEqSolver, this->getInitialScheduler(), x, *auxiliaryRowGroupVector, b); // If we were given an initial scheduler and are maximizing (minimizing), our current solution becomes // always less-or-equal (greater-or-equal) than the actual solution. guarantee = maximize(dir) ? SolverGuarantee::LessOrEqual : SolverGuarantee::GreaterOrEqual; @@ -344,7 +376,7 @@ namespace storm { std::vector<ValueType>* currentX = &x; this->startMeasureProgress(); - ValueIterationResult result = performValueIteration(dir, currentX, newX, b, storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), env.solver().minMax().getRelativeTerminationCriterion(), guarantee, 0, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); + ValueIterationResult result = performValueIteration(env, dir, currentX, newX, b, storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()), env.solver().minMax().getRelativeTerminationCriterion(), guarantee, 0, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); // Swap the result into the output x. if (currentX == auxiliaryRowGroupVector.get()) { @@ -356,7 +388,7 @@ namespace storm { // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); + this->multiplierA->multiplyAndReduce(env, dir, x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); } if (!this->isCachingEnabled()) { @@ -397,12 +429,11 @@ namespace storm { * Model Checker: Interval Iteration for Markov Decision Processes, CAV 2017). */ template<typename ValueType> - bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException, "Solver requires upper bound, but none was given."); - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -410,7 +441,7 @@ namespace storm { } // Allow aliased multiplications. - bool useGaussSeidelMultiplication = this->linEqSolverA->supportsGaussSeidelMultiplication() && env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; + bool useGaussSeidelMultiplication = env.solver().minMax().getMultiplicationStyle() == storm::solver::MultiplicationStyle::GaussSeidel; std::vector<ValueType>* lowerX = &x; this->createLowerBoundsVector(*lowerX); @@ -428,7 +459,7 @@ namespace storm { SolverStatus status = SolverStatus::InProgress; bool doConvergenceCheck = true; - bool useDiffs = this->hasRelevantValues(); + bool useDiffs = this->hasRelevantValues() && !env.solver().minMax().isSymmetricUpdatesSet(); std::vector<ValueType> oldValues; if (useGaussSeidelMultiplication && useDiffs) { oldValues.resize(this->getRelevantValues().getNumberOfSetBits()); @@ -454,22 +485,22 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *lowerX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *upperX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } } else { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *lowerX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(lowerX, tmp); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *upperX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -482,7 +513,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *lowerX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); } @@ -491,7 +522,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->linEqSolverA->multiplyAndReduceGaussSeidel(dir, this->A->getRowGroupIndices(), *upperX, &b); + this->multiplierA->multiplyAndReduceGaussSeidel(env, dir, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } @@ -499,14 +530,14 @@ namespace storm { } } else { if (maxLowerDiff >= maxUpperDiff) { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *lowerX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); lowerStep = true; } else { - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), *upperX, &b, *tmp); + this->multiplierA->multiplyAndReduce(env, dir, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -545,7 +576,7 @@ namespace storm { } reportStatus(status, iterations); - + // We take the means of the lower and upper bound so we guarantee the desired precision. ValueType two = storm::utility::convertNumber<ValueType>(2.0); storm::utility::vector::applyPointwise<ValueType, ValueType, ValueType>(*lowerX, *upperX, *lowerX, [&two] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / two; }); @@ -560,8 +591,73 @@ namespace storm { // If requested, we store the scheduler for retrieval. if (this->isTrackSchedulerSet()) { this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); - this->linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); + this->multiplierA->multiplyAndReduce(env, dir, x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); + } + + if (!this->isCachingEnabled()) { + clearCache(); + } + + return status == SolverStatus::Converged; + } + + template<typename ValueType> + bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + // Prepare the solution vectors and the helper. + assert(x.size() == this->A->getRowGroupCount()); + if (!this->auxiliaryRowGroupVector) { + this->auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(); + } + if (!this->soundValueIterationHelper) { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(*this->A, x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + } else { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(std::move(*this->soundValueIterationHelper), x, *this->auxiliaryRowGroupVector, env.solver().minMax().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision())); + } + + // Prepare initial bounds for the solution (if given) + if (this->hasLowerBound()) { + this->soundValueIterationHelper->setLowerBound(this->getLowerBound(true)); + } + if (this->hasUpperBound()) { + this->soundValueIterationHelper->setUpperBound(this->getUpperBound(true)); + } + + storm::storage::BitVector const* relevantValuesPtr = nullptr; + if (this->hasRelevantValues()) { + relevantValuesPtr = &this->getRelevantValues(); + } + + SolverStatus status = SolverStatus::InProgress; + this->startMeasureProgress(); + uint64_t iterations = 0; + + while (status == SolverStatus::InProgress && iterations < env.solver().minMax().getMaximalNumberOfIterations()) { + ++iterations; + this->soundValueIterationHelper->performIterationStep(dir, b); + if (this->soundValueIterationHelper->checkConvergenceUpdateBounds(dir, relevantValuesPtr)) { + status = SolverStatus::Converged; + } else { + // Update the status accordingly + if (this->hasCustomTerminationCondition() && this->soundValueIterationHelper->checkCustomTerminationCondition(this->getTerminationCondition())) { + status = SolverStatus::TerminatedEarly; + } else if (iterations >= env.solver().minMax().getMaximalNumberOfIterations()) { + status = SolverStatus::MaximalIterationsExceeded; + } + } + + // Potentially show progress. + this->showProgressIterative(iterations); + } + this->soundValueIterationHelper->setSolutionVector(); + + // If requested, we store the scheduler for retrieval. + if (this->isTrackSchedulerSet()) { + this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); + this->A->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *this->auxiliaryRowGroupVector, &this->schedulerChoices.get()); } + + reportStatus(status, iterations); if (!this->isCachingEnabled()) { clearCache(); @@ -617,11 +713,6 @@ namespace storm { return false; } - template<typename ValueType> - void IterativeMinMaxLinearEquationSolver<ValueType>::createLinearEquationSolver(Environment const& env) const { - this->linEqSolverA = this->linearEquationSolverFactory->create(env, *this->A, LinearEquationSolverTask::Multiply); - } - template<typename ValueType> template<typename ImpreciseType> typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && !NumberTraits<ValueType>::IsExact, bool>::type IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { @@ -632,9 +723,8 @@ namespace storm { std::vector<storm::RationalNumber> rationalX(x.size()); std::vector<storm::RationalNumber> rationalB = storm::utility::vector::convertNumericVector<storm::RationalNumber>(b); - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -662,9 +752,8 @@ namespace storm { typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && NumberTraits<ValueType>::IsExact, bool>::type IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Version for when the overall value type is exact and the same type is to be used for the imprecise part. - if (!this->linEqSolverA) { - this->createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } if (!auxiliaryRowGroupVector) { @@ -714,13 +803,14 @@ namespace storm { // Create imprecise solver from the imprecise data. IterativeMinMaxLinearEquationSolver<ImpreciseType> impreciseSolver(std::make_unique<storm::solver::GeneralLinearEquationSolverFactory<ImpreciseType>>()); impreciseSolver.setMatrix(impreciseA); - impreciseSolver.createLinearEquationSolver(env); impreciseSolver.setCachingEnabled(true); + impreciseSolver.multiplierA = storm::solver::MultiplierFactory<ImpreciseType>().create(env, impreciseA); bool converged = false; try { // Forward the call to the core rational search routine. converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, dir, impreciseSolver, *this->A, x, b, impreciseA, impreciseX, impreciseB, impreciseTmpX); + impreciseSolver.clearCache(); } catch (storm::exceptions::PrecisionExceededException const& e) { STORM_LOG_WARN("Precision of value type was exceeded, trying to recover by switching to rational arithmetic."); @@ -740,9 +830,8 @@ namespace storm { impreciseB = std::vector<ImpreciseType>(); impreciseA = storm::storage::SparseMatrix<ImpreciseType>(); - if (!this->linEqSolverA) { - createLinearEquationSolver(env); - this->linEqSolverA->setCachingEnabled(true); + if (!this->multiplierA) { + this->multiplierA = storm::solver::MultiplierFactory<ValueType>().create(env, *this->A); } // Forward the call to the core rational search routine, but now with our value type as the imprecise value type. @@ -791,7 +880,9 @@ namespace storm { template<typename ValueType> template<typename RationalType, typename ImpreciseType> bool IterativeMinMaxLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, OptimizationDirection dir, IterativeMinMaxLinearEquationSolver<ImpreciseType> const& impreciseSolver, storm::storage::SparseMatrix<RationalType> const& rationalA, std::vector<RationalType>& rationalX, std::vector<RationalType> const& rationalB, storm::storage::SparseMatrix<ImpreciseType> const& A, std::vector<ImpreciseType>& x, std::vector<ImpreciseType> const& b, std::vector<ImpreciseType>& tmpX) const { - + + std::vector<ImpreciseType> const* originalX = &x; + std::vector<ImpreciseType>* currentX = &x; std::vector<ImpreciseType>* newX = &tmpX; @@ -802,7 +893,7 @@ namespace storm { impreciseSolver.startMeasureProgress(); while (status == SolverStatus::InProgress && overallIterations < env.solver().minMax().getMaximalNumberOfIterations()) { // Perform value iteration with the current precision. - typename IterativeMinMaxLinearEquationSolver<ImpreciseType>::ValueIterationResult result = impreciseSolver.performValueIteration(dir, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), env.solver().minMax().getRelativeTerminationCriterion(), SolverGuarantee::LessOrEqual, overallIterations, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); + typename IterativeMinMaxLinearEquationSolver<ImpreciseType>::ValueIterationResult result = impreciseSolver.performValueIteration(env, dir, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), env.solver().minMax().getRelativeTerminationCriterion(), SolverGuarantee::LessOrEqual, overallIterations, env.solver().minMax().getMaximalNumberOfIterations(), env.solver().minMax().getMultiplicationStyle()); // At this point, the result of the imprecise value iteration is stored in the (imprecise) current x. @@ -833,6 +924,11 @@ namespace storm { } } + // Swap the two vectors if the current result is not in the original x. + if (currentX != originalX) { + std::swap(x, tmpX); + } + if (status == SolverStatus::InProgress && overallIterations == env.solver().minMax().getMaximalNumberOfIterations()) { status = SolverStatus::MaximalIterationsExceeded; } @@ -892,8 +988,8 @@ namespace storm { template<typename ValueType> void IterativeMinMaxLinearEquationSolver<ValueType>::reportStatus(SolverStatus status, uint64_t iterations) { switch (status) { - case SolverStatus::Converged: STORM_LOG_INFO("Iterative solver converged after " << iterations << " iterations."); break; - case SolverStatus::TerminatedEarly: STORM_LOG_INFO("Iterative solver terminated early after " << iterations << " iterations."); break; + case SolverStatus::Converged: STORM_LOG_TRACE("Iterative solver converged after " << iterations << " iterations."); break; + case SolverStatus::TerminatedEarly: STORM_LOG_TRACE("Iterative solver terminated early after " << iterations << " iterations."); break; case SolverStatus::MaximalIterationsExceeded: STORM_LOG_WARN("Iterative solver did not converge after " << iterations << " iterations."); break; default: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Iterative solver terminated unexpectedly."); @@ -902,45 +998,17 @@ namespace storm { template<typename ValueType> void IterativeMinMaxLinearEquationSolver<ValueType>::clearCache() const { + multiplierA.reset(); auxiliaryRowGroupVector.reset(); auxiliaryRowGroupVector2.reset(); - rowGroupOrdering.reset(); + soundValueIterationHelper.reset(); StandardMinMaxLinearEquationSolver<ValueType>::clearCache(); } - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>() { - // Intentionally left empty - } - - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(std::move(linearEquationSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - IterativeMinMaxLinearEquationSolverFactory<ValueType>::IterativeMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : StandardMinMaxLinearEquationSolverFactory<ValueType>(solverType) { - // Intentionally left empty - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> IterativeMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); - - auto method = env.solver().minMax().getMethod(); - STORM_LOG_THROW(method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch, storm::exceptions::InvalidEnvironmentException, "This solver does not support the selected method."); - - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - template class IterativeMinMaxLinearEquationSolver<double>; - template class IterativeMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class IterativeMinMaxLinearEquationSolver<storm::RationalNumber>; - template class IterativeMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h index f29fa0318..33da6e68e 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.h +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.h @@ -5,7 +5,9 @@ #include "storm/utility/NumberTraits.h" #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/StandardMinMaxLinearEquationSolver.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/solver/SolverStatus.h" @@ -26,7 +28,7 @@ namespace storm { virtual void clearCache() const override; - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override; private: @@ -37,7 +39,9 @@ namespace storm { bool valueImproved(OptimizationDirection dir, ValueType const& value1, ValueType const& value2) const; bool solveEquationsValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + bool solveEquationsIntervalIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; bool solveEquationsSoundValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + bool solveEquationsRationalSearch(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; template<typename RationalType, typename ImpreciseType> @@ -66,31 +70,22 @@ namespace storm { template <typename ValueTypePrime> friend class IterativeMinMaxLinearEquationSolver; - ValueIterationResult performValueIteration(OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; + ValueIterationResult performValueIteration(Environment const& env, OptimizationDirection dir, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maximalNumberOfIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; void createLinearEquationSolver(Environment const& env) const; + /// The factory used to obtain linear equation solvers. + std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; + // possibly cached data + mutable std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplierA; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector2; // A.rowGroupCount() entries - mutable std::unique_ptr<std::vector<uint64_t>> rowGroupOrdering; // A.rowGroupCount() entries + mutable std::unique_ptr<storm::solver::helper::SoundValueIterationHelper<ValueType>> soundValueIterationHelper; SolverStatus updateStatusIfNotConverged(SolverStatus status, std::vector<ValueType> const& x, uint64_t iterations, uint64_t maximalNumberOfIterations, SolverGuarantee const& guarantee) const; static void reportStatus(SolverStatus status, uint64_t iterations); }; - template<typename ValueType> - class IterativeMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - IterativeMinMaxLinearEquationSolverFactory(); - IterativeMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - IterativeMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - }; } } diff --git a/src/storm/solver/LinearEquationSolver.cpp b/src/storm/solver/LinearEquationSolver.cpp index caff69756..44eb42db0 100644 --- a/src/storm/solver/LinearEquationSolver.cpp +++ b/src/storm/solver/LinearEquationSolver.cpp @@ -7,6 +7,7 @@ #include "storm/solver/NativeLinearEquationSolver.h" #include "storm/solver/EigenLinearEquationSolver.h" #include "storm/solver/EliminationLinearEquationSolver.h" +#include "storm/solver/TopologicalLinearEquationSolver.h" #include "storm/utility/vector.h" @@ -30,89 +31,7 @@ namespace storm { } template<typename ValueType> - void LinearEquationSolver<ValueType>::repeatedMultiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if (!cachedRowVector) { - cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - // We enable caching for this. But remember how the old setting was - bool cachingWasEnabled = isCachingEnabled(); - setCachingEnabled(true); - - // Set up some temporary variables so that we can just swap pointers instead of copying the result after - // each iteration. - std::vector<ValueType>* currentX = &x; - std::vector<ValueType>* nextX = cachedRowVector.get(); - - // Now perform matrix-vector multiplication as long as we meet the bound. - this->startMeasureProgress(); - for (uint_fast64_t i = 0; i < n; ++i) { - this->multiply(*currentX, b, *nextX); - std::swap(nextX, currentX); - - // Potentially show progress. - this->showProgressIterative(i, n); - } - - // If we performed an odd number of repetitions, we need to swap the contents of currentVector and x, - // because the output is supposed to be stored in the input vector x. - if (currentX == cachedRowVector.get()) { - std::swap(x, *currentX); - } - - // restore the old caching setting - setCachingEnabled(cachingWasEnabled); - - if (!isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (!cachedRowVector) { - cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - // We enable caching for this. But remember how the old setting was - bool cachingWasEnabled = isCachingEnabled(); - setCachingEnabled(true); - - this->multiply(x, b, *cachedRowVector); - vectorHelper.reduceVector(dir, *cachedRowVector, result, rowGroupIndices, choices); - - // restore the old caching setting - setCachingEnabled(cachingWasEnabled); - - if (!isCachingEnabled()) { - clearCache(); - } - } - -#ifdef STORM_HAVE_CARL - template<> - void LinearEquationSolver<storm::RationalFunction>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<storm::RationalFunction>& x, std::vector<storm::RationalFunction> const* b, std::vector<storm::RationalFunction>& result, std::vector<uint_fast64_t>* choices ) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Reducing rational function vector is not supported."); - } -#endif - - template<typename ValueType> - bool LinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return false; - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This solver does not support the function 'multiplyGaussSeidel'."); - } - - template<typename ValueType> - void LinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "This solver does not support the function 'multiplyAndReduceGaussSeidel'."); - } - - template<typename ValueType> - LinearEquationSolverRequirements LinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + LinearEquationSolverRequirements LinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { return LinearEquationSolverRequirements(); } @@ -136,15 +55,15 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix, LinearEquationSolverTask const& task) const { - std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env, task); + std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const { + std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env); solver->setMatrix(matrix); return solver; } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix, LinearEquationSolverTask const& task) const { - std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env, task); + std::unique_ptr<LinearEquationSolver<ValueType>> LinearEquationSolverFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const { + std::unique_ptr<LinearEquationSolver<ValueType>> solver = this->create(env); solver->setMatrix(std::move(matrix)); return solver; } @@ -155,8 +74,8 @@ namespace storm { } template<typename ValueType> - LinearEquationSolverRequirements LinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { - return this->create(env)->getRequirements(env, task); + LinearEquationSolverRequirements LinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env) const { + return this->create(env)->getRequirements(env); } template<typename ValueType> @@ -164,9 +83,8 @@ namespace storm { // Intentionally left empty. } - template<> - std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<storm::RationalNumber>> GeneralLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type @@ -179,6 +97,7 @@ namespace storm { case EquationSolverType::Native: return std::make_unique<NativeLinearEquationSolver<storm::RationalNumber>>(); case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<storm::RationalNumber>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<storm::RationalNumber>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<storm::RationalNumber>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; @@ -186,7 +105,7 @@ namespace storm { } template<> - std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<storm::RationalFunction>> GeneralLinearEquationSolverFactory<storm::RationalFunction>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if it is not supported by this value type @@ -198,6 +117,7 @@ namespace storm { switch (type) { case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<storm::RationalFunction>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<storm::RationalFunction>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<storm::RationalFunction>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; @@ -205,11 +125,11 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<LinearEquationSolver<ValueType>> GeneralLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { EquationSolverType type = env.solver().getLinearEquationSolverType(); // Adjust the solver type if none was specified and we want sound computations - if (env.solver().isForceSoundness() && task != LinearEquationSolverTask::Multiply && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination) { + if (env.solver().isForceSoundness() && type != EquationSolverType::Native && type != EquationSolverType::Eigen && type != EquationSolverType::Elimination && type != EquationSolverType::Topological) { if (env.solver().isLinearEquationSolverTypeSetFromDefaultValue()) { type = EquationSolverType::Native; STORM_LOG_INFO("Selecting '" + toString(type) + "' as the linear equation solver to guarantee sound results. If you want to override this, please explicitly specify a different solver."); @@ -223,6 +143,7 @@ namespace storm { case EquationSolverType::Native: return std::make_unique<NativeLinearEquationSolver<ValueType>>(); case EquationSolverType::Eigen: return std::make_unique<EigenLinearEquationSolver<ValueType>>(); case EquationSolverType::Elimination: return std::make_unique<EliminationLinearEquationSolver<ValueType>>(); + case EquationSolverType::Topological: return std::make_unique<TopologicalLinearEquationSolver<ValueType>>(); default: STORM_LOG_THROW(false, storm::exceptions::InvalidEnvironmentException, "Unknown solver type."); return nullptr; diff --git a/src/storm/solver/LinearEquationSolver.h b/src/storm/solver/LinearEquationSolver.h index b4b49d627..525623781 100644 --- a/src/storm/solver/LinearEquationSolver.h +++ b/src/storm/solver/LinearEquationSolver.h @@ -8,7 +8,6 @@ #include "storm/solver/MultiplicationStyle.h" #include "storm/solver/LinearEquationSolverProblemFormat.h" #include "storm/solver/LinearEquationSolverRequirements.h" -#include "storm/solver/LinearEquationSolverTask.h" #include "storm/solver/OptimizationDirection.h" #include "storm/utility/VectorHelper.h" @@ -22,8 +21,7 @@ namespace storm { namespace solver { /*! - * An interface that represents an abstract linear equation solver. In addition to solving a system of linear - * equations, the functionality to repeatedly multiply a matrix with a given vector is provided. + * An interface that represents an abstract linear equation solver. */ template<class ValueType> class LinearEquationSolver : public AbstractEquationSolver<ValueType> { @@ -50,78 +48,6 @@ namespace storm { */ bool solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - /*! - * Performs on matrix-vector multiplication x' = A*x + b. - * - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param result The target vector into which to write the multiplication result. Its length must be equal - * to the number of rows of A. - */ - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups - * so that the resulting vector has the size of number of row groups of A. - * - * @param dir The direction for the reduction step. - * @param rowGroupIndices A vector storing the row groups over which to reduce. - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param result The target vector into which to write the multiplication result. Its length must be equal - * to the number of rows of A. - * @param choices If given, the choices made in the reduction process are written to this vector. - */ - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const; - - /*! - * Retrieves whether this solver offers the gauss-seidel style multiplications. - */ - virtual bool supportsGaussSeidelMultiplication() const; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b. It does so in a gauss-seidel style, i.e. reusing - * the new x' components in the further multiplication. - * - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - */ - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const; - - /*! - * Performs on matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups - * so that the resulting vector has the size of number of row groups of A. It does so in a gauss-seidel - * style, i.e. reusing the new x' components in the further multiplication. - * - * @param dir The direction for the reduction step. - * @param rowGroupIndices A vector storing the row groups over which to reduce. - * @param x The input vector with which to multiply the matrix. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal - * to the number of rows of A. - * @param choices If given, the choices made in the reduction process are written to this vector. - */ - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const; - - /*! - * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After - * performing the necessary multiplications, the result is written to the input vector x. Note that the - * matrix A has to be given upon construction time of the solver object. - * - * @param x The initial vector with which to perform matrix-vector multiplication. Its length must be equal - * to the number of columns of A. - * @param b If non-null, this vector is added after each multiplication. If given, its length must be equal - * to the number of rows of A. - * @param n The number of times to perform the multiplication. - */ - void repeatedMultiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const; - /*! * Retrieves the format in which this solver expects to solve equations. If the solver expects the equation * system format, it solves Ax = b. If it it expects a fixed point format, it solves Ax + b = x. @@ -132,7 +58,7 @@ namespace storm { * Retrieves the requirements of the solver under the current settings. Note that these requirements only * apply to solving linear equations and not to the matrix vector multiplications. */ - virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const; /*! * Sets whether some of the generated data during solver calls should be cached. @@ -187,7 +113,7 @@ namespace storm { * @param matrix The matrix that defines the equation system. * @return A pointer to the newly created solver. */ - std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) const; /*! * Creates a new linear equation solver instance with the given matrix. The caller gives up posession of the @@ -196,12 +122,12 @@ namespace storm { * @param matrix The matrix that defines the equation system. * @return A pointer to the newly created solver. */ - std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType>&& matrix) const; /*! * Creates an equation solver with the current settings, but without a matrix. */ - virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const = 0; + virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env) const = 0; /*! * Creates a copy of this factory. @@ -217,7 +143,7 @@ namespace storm { * Retrieves the requirements of the solver if it was created with the current settings. Note that these * requirements only apply to solving linear equations and not to the matrix vector multiplications. */ - LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const; + LinearEquationSolverRequirements getRequirements(Environment const& env) const; }; template<typename ValueType> @@ -227,7 +153,7 @@ namespace storm { using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; }; diff --git a/src/storm/solver/LinearEquationSolverRequirements.cpp b/src/storm/solver/LinearEquationSolverRequirements.cpp index 90662c6f9..445e776d7 100644 --- a/src/storm/solver/LinearEquationSolverRequirements.cpp +++ b/src/storm/solver/LinearEquationSolverRequirements.cpp @@ -3,52 +3,78 @@ namespace storm { namespace solver { - LinearEquationSolverRequirements::LinearEquationSolverRequirements() : lowerBounds(false), upperBounds(false) { + LinearEquationSolverRequirements::LinearEquationSolverRequirements() { // Intentionally left empty. } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireLowerBounds() { - lowerBounds = true; + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireLowerBounds(bool critical) { + lowerBoundsRequirement.enable(critical); return *this; } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireUpperBounds() { - upperBounds = true; + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireUpperBounds(bool critical) { + upperBoundsRequirement.enable(critical); return *this; } - LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireBounds() { - requireLowerBounds(); - requireUpperBounds(); + LinearEquationSolverRequirements& LinearEquationSolverRequirements::requireBounds(bool critical) { + requireLowerBounds(critical); + requireUpperBounds(critical); return *this; } - bool LinearEquationSolverRequirements::requiresLowerBounds() const { - return lowerBounds; + SolverRequirement const& LinearEquationSolverRequirements::lowerBounds() const { + return lowerBoundsRequirement; } - bool LinearEquationSolverRequirements::requiresUpperBounds() const { - return upperBounds; + SolverRequirement const& LinearEquationSolverRequirements::upperBounds() const { + return upperBoundsRequirement; } - bool LinearEquationSolverRequirements::requires(Element const& element) const { + SolverRequirement const& LinearEquationSolverRequirements::get(Element const& element) const { switch (element) { - case Element::LowerBounds: return lowerBounds; break; - case Element::UpperBounds: return upperBounds; break; + case Element::LowerBounds: return lowerBounds(); break; + case Element::UpperBounds: return upperBounds(); break; } } void LinearEquationSolverRequirements::clearLowerBounds() { - lowerBounds = false; + lowerBoundsRequirement.clear(); } void LinearEquationSolverRequirements::clearUpperBounds() { - upperBounds = false; + upperBoundsRequirement.clear(); } - bool LinearEquationSolverRequirements::empty() const { - return !lowerBounds && !upperBounds; + bool LinearEquationSolverRequirements::hasEnabledRequirement() const { + return lowerBoundsRequirement || upperBoundsRequirement; } + bool LinearEquationSolverRequirements::hasEnabledCriticalRequirement() const { + return lowerBoundsRequirement.isCritical() || upperBoundsRequirement.isCritical(); + } + + + std::string LinearEquationSolverRequirements::getEnabledRequirementsAsString() const { + std::string res = "["; + bool first = true; + if (lowerBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "lowerBounds"; + if (lowerBounds().isCritical()) { + res += "(mandatory)"; + } + } + if (upperBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "upperBounds"; + if (upperBounds().isCritical()) { + res += "(mandatory)"; + } + } + res += "]"; + return res; + } + } } diff --git a/src/storm/solver/LinearEquationSolverRequirements.h b/src/storm/solver/LinearEquationSolverRequirements.h index 8f5a126a7..a7e23d248 100644 --- a/src/storm/solver/LinearEquationSolverRequirements.h +++ b/src/storm/solver/LinearEquationSolverRequirements.h @@ -1,5 +1,9 @@ #pragma once +#include <string> + +#include "storm/solver/SolverRequirement.h" + namespace storm { namespace solver { @@ -14,22 +18,29 @@ namespace storm { LinearEquationSolverRequirements(); - LinearEquationSolverRequirements& requireLowerBounds(); - LinearEquationSolverRequirements& requireUpperBounds(); - LinearEquationSolverRequirements& requireBounds(); + LinearEquationSolverRequirements& requireLowerBounds(bool critical = true); + LinearEquationSolverRequirements& requireUpperBounds(bool critical = true); + LinearEquationSolverRequirements& requireBounds(bool critical = true); - bool requiresLowerBounds() const; - bool requiresUpperBounds() const; - bool requires(Element const& element) const; + SolverRequirement const& lowerBounds() const; + SolverRequirement const& upperBounds() const; + SolverRequirement const& get(Element const& element) const; void clearLowerBounds(); void clearUpperBounds(); - bool empty() const; + bool hasEnabledRequirement() const; + bool hasEnabledCriticalRequirement() const; + + /*! + * Checks whether there are no critical requirements left. + * In case there is a critical requirement left an exception is thrown. + */ + std::string getEnabledRequirementsAsString() const; private: - bool lowerBounds; - bool upperBounds; + SolverRequirement lowerBoundsRequirement; + SolverRequirement upperBoundsRequirement; }; } diff --git a/src/storm/solver/LinearEquationSolverTask.cpp b/src/storm/solver/LinearEquationSolverTask.cpp deleted file mode 100644 index 91783ae36..000000000 --- a/src/storm/solver/LinearEquationSolverTask.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "storm/solver/LinearEquationSolverTask.h" - -namespace storm { - namespace solver { - - std::ostream& operator<<(std::ostream& out, LinearEquationSolverTask const& task) { - switch (task) { - case LinearEquationSolverTask::Unspecified: out << "unspecified"; break; - case LinearEquationSolverTask::SolveEquations: out << "solve equations"; break; - case LinearEquationSolverTask::Multiply: out << "multiply"; break; - } - return out; - } - - } -} diff --git a/src/storm/solver/LinearEquationSolverTask.h b/src/storm/solver/LinearEquationSolverTask.h deleted file mode 100644 index 5d3a401dd..000000000 --- a/src/storm/solver/LinearEquationSolverTask.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <iostream> - -namespace storm { - namespace solver { - - enum class LinearEquationSolverTask { Unspecified, SolveEquations, Multiply }; - - std::ostream& operator<<(std::ostream& out, LinearEquationSolverTask const& style); - - } -} diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp index 80668c4fc..78bc75752 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.cpp @@ -10,17 +10,17 @@ namespace storm { namespace solver { template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A, std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(A), lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } template<typename ValueType> - LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A), std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { + LpMinMaxLinearEquationSolver<ValueType>::LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)), lpSolverFactory(std::move(lpSolverFactory)) { // Intentionally left empty. } @@ -111,50 +111,24 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements LpMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements LpMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { - MinMaxLinearEquationSolverRequirements requirements(this->linearEquationSolverFactory->getRequirements(env, LinearEquationSolverTask::Multiply)); + MinMaxLinearEquationSolverRequirements requirements; // In case we need to retrieve a scheduler, the solution has to be unique if (!this->hasUniqueSolution() && this->isTrackSchedulerSet()) { requirements.requireNoEndComponents(); } + requirements.requireBounds(false); + return requirements; } - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(), lpSolverFactory(std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()) { - // Intentionally left empty - } - - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(), lpSolverFactory(std::move(lpSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - LpMinMaxLinearEquationSolverFactory<ValueType>::LpMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory) : StandardMinMaxLinearEquationSolverFactory<ValueType>(std::move(linearEquationSolverFactory)), lpSolverFactory(std::move(lpSolverFactory)) { - // Intentionally left empty - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> LpMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::LinearProgramming, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - STORM_LOG_ASSERT(this->lpSolverFactory, "Lp solver factory not initialized."); - STORM_LOG_ASSERT(this->linearEquationSolverFactory, "Linear equation solver factory not initialized."); - - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone(), this->lpSolverFactory->clone()); - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - template class LpMinMaxLinearEquationSolver<double>; - template class LpMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class LpMinMaxLinearEquationSolver<storm::RationalNumber>; - template class LpMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/LpMinMaxLinearEquationSolver.h b/src/storm/solver/LpMinMaxLinearEquationSolver.h index df20e120f..72ba6871e 100644 --- a/src/storm/solver/LpMinMaxLinearEquationSolver.h +++ b/src/storm/solver/LpMinMaxLinearEquationSolver.h @@ -13,34 +13,19 @@ namespace storm { template<typename ValueType> class LpMinMaxLinearEquationSolver : public StandardMinMaxLinearEquationSolver<ValueType> { public: - LpMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); + LpMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; virtual void clearCache() const override; - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const override; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override; private: std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> lpSolverFactory; }; - template<typename ValueType> - class LpMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - LpMinMaxLinearEquationSolverFactory(); - LpMinMaxLinearEquationSolverFactory(std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - LpMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory, std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>>&& lpSolverFactory); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - private: - std::unique_ptr<storm::utility::solver::LpSolverFactory<ValueType>> lpSolverFactory; - }; } } diff --git a/src/storm/solver/MinMaxLinearEquationSolver.cpp b/src/storm/solver/MinMaxLinearEquationSolver.cpp index a061c451d..f7cbf4bfe 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolver.cpp @@ -5,6 +5,7 @@ #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/IterativeMinMaxLinearEquationSolver.h" #include "storm/solver/TopologicalMinMaxLinearEquationSolver.h" +#include "storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h" #include "storm/solver/LpMinMaxLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" @@ -39,12 +40,6 @@ namespace storm { solveEquations(env, convert(this->direction), x, b); } - template<typename ValueType> - void MinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType>* b, uint_fast64_t n) const { - STORM_LOG_THROW(isSet(this->direction), storm::exceptions::IllegalFunctionCallException, "Optimization direction not set."); - return repeatedMultiply(env, convert(this->direction), x, b, n); - } - template<typename ValueType> void MinMaxLinearEquationSolver<ValueType>::setOptimizationDirection(OptimizationDirection d) { direction = convert(d); @@ -136,7 +131,7 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const&, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { return MinMaxLinearEquationSolverRequirements(); } @@ -166,11 +161,11 @@ namespace storm { } template<typename ValueType> - MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, bool hasUniqueSolution, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& assumeNoInitialScheduler) const { + MinMaxLinearEquationSolverRequirements MinMaxLinearEquationSolverFactory<ValueType>::getRequirements(Environment const& env, bool hasUniqueSolution, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { // Create dummy solver and ask it for requirements. std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> solver = this->create(env); solver->setHasUniqueSolution(hasUniqueSolution); - return solver->getRequirements(env, direction, assumeNoInitialScheduler); + return solver->getRequirements(env, direction, hasInitialScheduler); } template<typename ValueType> @@ -196,12 +191,14 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> GeneralMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()); } else if (method == MinMaxMethod::Topological) { result = std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); + } else if (method == MinMaxMethod::TopologicalCuda) { + result = std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); } else if (method == MinMaxMethod::LinearProgramming) { - result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>(), std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()); + result = std::make_unique<LpMinMaxLinearEquationSolver<ValueType>>(std::make_unique<storm::utility::solver::LpSolverFactory<ValueType>>()); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } @@ -213,10 +210,12 @@ namespace storm { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> GeneralMinMaxLinearEquationSolverFactory<storm::RationalNumber>::create(Environment const& env) const { std::unique_ptr<MinMaxLinearEquationSolver<storm::RationalNumber>> result; auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { + if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch || method == MinMaxMethod::IntervalIteration || method == MinMaxMethod::SoundValueIteration) { result = std::make_unique<IterativeMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>()); } else if (method == MinMaxMethod::LinearProgramming) { - result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<GeneralLinearEquationSolverFactory<storm::RationalNumber>>(), std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); + result = std::make_unique<LpMinMaxLinearEquationSolver<storm::RationalNumber>>(std::make_unique<storm::utility::solver::LpSolverFactory<storm::RationalNumber>>()); + } else if (method == MinMaxMethod::Topological) { + result = std::make_unique<TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>>(); } else { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported technique."); } diff --git a/src/storm/solver/MinMaxLinearEquationSolver.h b/src/storm/solver/MinMaxLinearEquationSolver.h index cb442e0f4..00788089c 100644 --- a/src/storm/solver/MinMaxLinearEquationSolver.h +++ b/src/storm/solver/MinMaxLinearEquationSolver.h @@ -60,32 +60,6 @@ namespace storm { */ void solveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - /*! - * Performs (repeated) matrix-vector multiplication with the given parameters, i.e. computes - * x[i+1] = min/max(A*x[i] + b) until x[n], where x[0] = x. After each multiplication and addition, the - * minimal/maximal value out of each row group is selected to reduce the resulting vector to obtain the - * vector for the next iteration. Note that the matrix A has to be given upon construction time of the - * solver object. - * - * @param d For minimum, all the value of a group of rows is the taken as the minimum over all rows and as - * the maximum otherwise. - * @param x The initial vector that is to be multiplied with the matrix. This is also the output parameter, - * i.e. after the method returns, this vector will contain the computed values. - * @param b If not null, this vector is added after each multiplication. - * @param n Specifies the number of iterations the matrix-vector multiplication is performed. - * @param multiplyResult If non-null, this memory is used as a scratch memory. If given, the length of this - * vector must be equal to the number of rows of A. - * @return The result of the repeated matrix-vector multiplication as the content of the vector x. - */ - virtual void repeatedMultiply(Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n = 1) const = 0; - - /*! - * Behaves the same as the other variant of <code>multiply</code>, with the - * distinction that instead of providing the optimization direction as an argument, the internally set - * optimization direction is used. Note: this method can only be called after setting the optimization direction. - */ - virtual void repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType>* b , uint_fast64_t n) const; - /*! * Sets an optimization direction to use for calls to methods that do not explicitly provide one. */ @@ -167,7 +141,7 @@ namespace storm { * Retrieves the requirements of this solver for solving equations with the current settings. The requirements * are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ - virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const; + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const; /*! * Notifies the solver that the requirements for solving equations have been checked. If this has not been @@ -220,7 +194,7 @@ namespace storm { * Retrieves the requirements of the solver that would be created when calling create() right now. The * requirements are guaranteed to be ordered according to their appearance in the SolverRequirement type. */ - MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, bool hasUniqueSolution = false, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& assumeNoInitialScheduler = false) const; + MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, bool hasUniqueSolution = false, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const; void setRequirementsChecked(bool value = true); bool isRequirementsCheckedSet() const; diff --git a/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp b/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp index 005d57977..e16bbdf54 100644 --- a/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp +++ b/src/storm/solver/MinMaxLinearEquationSolverRequirements.cpp @@ -3,76 +3,76 @@ namespace storm { namespace solver { - MinMaxLinearEquationSolverRequirements::MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements) : noEndComponents(false), validInitialScheduler(false), lowerBounds(linearEquationSolverRequirements.requiresLowerBounds()), upperBounds(linearEquationSolverRequirements.requiresUpperBounds()) { + MinMaxLinearEquationSolverRequirements::MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements) : lowerBoundsRequirement(linearEquationSolverRequirements.lowerBounds()), upperBoundsRequirement(linearEquationSolverRequirements.upperBounds()) { // Intentionally left empty. } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireNoEndComponents() { - noEndComponents = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireNoEndComponents(bool critical) { + noEndComponentsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireValidInitialScheduler() { - validInitialScheduler = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireValidInitialScheduler(bool critical) { + validInitialSchedulerRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireLowerBounds() { - lowerBounds = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireLowerBounds(bool critical) { + lowerBoundsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireUpperBounds() { - upperBounds = true; + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireUpperBounds(bool critical) { + upperBoundsRequirement.enable(critical); return *this; } - MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireBounds() { - requireLowerBounds(); - requireUpperBounds(); + MinMaxLinearEquationSolverRequirements& MinMaxLinearEquationSolverRequirements::requireBounds(bool critical) { + requireLowerBounds(critical); + requireUpperBounds(critical); return *this; } - bool MinMaxLinearEquationSolverRequirements::requiresNoEndComponents() const { - return noEndComponents; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::noEndComponents() const { + return noEndComponentsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresValidInitialScheduler() const { - return validInitialScheduler; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::validInitialScheduler() const { + return validInitialSchedulerRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresLowerBounds() const { - return lowerBounds; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::lowerBounds() const { + return lowerBoundsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requiresUpperBounds() const { - return upperBounds; + SolverRequirement const& MinMaxLinearEquationSolverRequirements::upperBounds() const { + return upperBoundsRequirement; } - bool MinMaxLinearEquationSolverRequirements::requires(Element const& element) const { + SolverRequirement const& MinMaxLinearEquationSolverRequirements::get(Element const& element) const { switch (element) { - case Element::NoEndComponents: return noEndComponents; break; - case Element::ValidInitialScheduler: return validInitialScheduler; break; - case Element::LowerBounds: return lowerBounds; break; - case Element::UpperBounds: return upperBounds; break; + case Element::NoEndComponents: return noEndComponents(); break; + case Element::ValidInitialScheduler: return validInitialScheduler(); break; + case Element::LowerBounds: return lowerBounds(); break; + case Element::UpperBounds: return upperBounds(); break; } } void MinMaxLinearEquationSolverRequirements::clearNoEndComponents() { - noEndComponents = false; - validInitialScheduler = false; + noEndComponentsRequirement.clear(); + validInitialSchedulerRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearValidInitialScheduler() { - validInitialScheduler = false; + validInitialSchedulerRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearLowerBounds() { - lowerBounds = false; + lowerBoundsRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearUpperBounds() { - upperBounds = false; + upperBoundsRequirement.clear(); } void MinMaxLinearEquationSolverRequirements::clearBounds() { @@ -80,8 +80,47 @@ namespace storm { clearUpperBounds(); } - bool MinMaxLinearEquationSolverRequirements::empty() const { - return !noEndComponents && !validInitialScheduler && !lowerBounds && !upperBounds; + bool MinMaxLinearEquationSolverRequirements::hasEnabledRequirement() const { + return noEndComponentsRequirement || validInitialSchedulerRequirement || lowerBoundsRequirement || upperBoundsRequirement; + } + + bool MinMaxLinearEquationSolverRequirements::hasEnabledCriticalRequirement() const { + return noEndComponentsRequirement.isCritical() || validInitialSchedulerRequirement.isCritical() || lowerBoundsRequirement.isCritical() || upperBoundsRequirement.isCritical(); + } + + std::string MinMaxLinearEquationSolverRequirements::getEnabledRequirementsAsString() const { + std::string res = "["; + bool first = true; + if (noEndComponents()) { + if (!first) { res += ", "; } else {first = false;} + res += "NoEndComponents"; + if (noEndComponents().isCritical()) { + res += "(mandatory)"; + } + } + if (validInitialScheduler()) { + if (!first) { res += ", "; } else {first = false;} + res += "validInitialScheduler"; + if (validInitialScheduler().isCritical()) { + res += "(mandatory)"; + } + } + if (lowerBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "lowerBounds"; + if (lowerBounds().isCritical()) { + res += "(mandatory)"; + } + } + if (upperBounds()) { + if (!first) { res += ", "; } else {first = false;} + res += "upperBounds"; + if (upperBounds().isCritical()) { + res += "(mandatory)"; + } + } + res += "]"; + return res; } } diff --git a/src/storm/solver/MinMaxLinearEquationSolverRequirements.h b/src/storm/solver/MinMaxLinearEquationSolverRequirements.h index 33e3511ad..06ba623c1 100644 --- a/src/storm/solver/MinMaxLinearEquationSolverRequirements.h +++ b/src/storm/solver/MinMaxLinearEquationSolverRequirements.h @@ -1,6 +1,9 @@ #pragma once +#include <string> + #include "storm/solver/LinearEquationSolverRequirements.h" +#include "storm/solver/SolverRequirement.h" namespace storm { namespace solver { @@ -20,19 +23,21 @@ namespace storm { UpperBounds }; + // The type of a requirement. + MinMaxLinearEquationSolverRequirements(LinearEquationSolverRequirements const& linearEquationSolverRequirements = LinearEquationSolverRequirements()); - MinMaxLinearEquationSolverRequirements& requireNoEndComponents(); - MinMaxLinearEquationSolverRequirements& requireValidInitialScheduler(); - MinMaxLinearEquationSolverRequirements& requireLowerBounds(); - MinMaxLinearEquationSolverRequirements& requireUpperBounds(); - MinMaxLinearEquationSolverRequirements& requireBounds(); + MinMaxLinearEquationSolverRequirements& requireNoEndComponents(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireValidInitialScheduler(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireLowerBounds(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireUpperBounds(bool critical = true); + MinMaxLinearEquationSolverRequirements& requireBounds(bool critical = true); - bool requiresNoEndComponents() const; - bool requiresValidInitialScheduler() const; - bool requiresLowerBounds() const; - bool requiresUpperBounds() const; - bool requires(Element const& element) const; + SolverRequirement const& noEndComponents() const; + SolverRequirement const& validInitialScheduler() const; + SolverRequirement const& lowerBounds() const; + SolverRequirement const& upperBounds() const; + SolverRequirement const& get(Element const& element) const; void clearNoEndComponents(); void clearValidInitialScheduler(); @@ -40,13 +45,19 @@ namespace storm { void clearUpperBounds(); void clearBounds(); - bool empty() const; + bool hasEnabledRequirement() const; + bool hasEnabledCriticalRequirement() const; + + /*! + * Returns a string that enumerates the enabled requirements + */ + std::string getEnabledRequirementsAsString() const; private: - bool noEndComponents; - bool validInitialScheduler; - bool lowerBounds; - bool upperBounds; + SolverRequirement noEndComponentsRequirement; + SolverRequirement validInitialSchedulerRequirement; + SolverRequirement lowerBoundsRequirement; + SolverRequirement upperBoundsRequirement; }; } diff --git a/src/storm/solver/Multiplier.cpp b/src/storm/solver/Multiplier.cpp new file mode 100644 index 000000000..38d81fee4 --- /dev/null +++ b/src/storm/solver/Multiplier.cpp @@ -0,0 +1,95 @@ +#include "storm/solver/Multiplier.h" + +#include "storm-config.h" + +#include "storm/storage/SparseMatrix.h" + +#include "storm/adapters/RationalNumberAdapter.h" +#include "storm/adapters/RationalFunctionAdapter.h" + +#include "storm/utility/macros.h" +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/NativeMultiplier.h" +#include "storm/solver/GmmxxMultiplier.h" +#include "storm/environment/solver/MultiplierEnvironment.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + Multiplier<ValueType>::Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : matrix(matrix) { + // Intentionally left empty. + } + + template<typename ValueType> + void Multiplier<ValueType>::clearCache() const { + cachedVector.reset(); + } + + template<typename ValueType> + void Multiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { + multiplyAndReduce(env, dir, this->matrix.getRowGroupIndices(), x, b, result, choices); + } + + template<typename ValueType> + void Multiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + multiplyAndReduceGaussSeidel(env, dir, this->matrix.getRowGroupIndices(), x, b, choices); + } + + template<typename ValueType> + void Multiplier<ValueType>::repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { + for (uint64_t i = 0; i < n; ++i) { + multiply(env, x, b, x); + } + } + + template<typename ValueType> + void Multiplier<ValueType>::repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const { + for (uint64_t i = 0; i < n; ++i) { + multiplyAndReduce(env, dir, x, b, x); + } + } + + template<typename ValueType> + void Multiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + multiplyRow(rowIndex, x1, val1); + multiplyRow(rowIndex, x2, val2); + } + + template<typename ValueType> + std::unique_ptr<Multiplier<ValueType>> MultiplierFactory<ValueType>::create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix) { + auto type = env.solver().multiplier().getType(); + + // Adjust the multiplier type if an eqsolver was specified but not a multiplier + if (!env.solver().isLinearEquationSolverTypeSetFromDefaultValue() && env.solver().multiplier().isTypeSetFromDefault()) { + bool changed = false; + if (env.solver().getLinearEquationSolverType() == EquationSolverType::Gmmxx && type != MultiplierType::Gmmxx) { + type = MultiplierType::Gmmxx; + changed = true; + } else if (env.solver().getLinearEquationSolverType() == EquationSolverType::Native && type != MultiplierType::Native) { + type = MultiplierType::Native; + changed = true; + } + STORM_LOG_INFO_COND(!changed, "Selecting '" + toString(type) + "' as the multiplier type to match the selected equation solver. If you want to override this, please explicitly specify a different multiplier type."); + } + + switch (env.solver().multiplier().getType()) { + case MultiplierType::Gmmxx: + return std::make_unique<GmmxxMultiplier<ValueType>>(matrix); + case MultiplierType::Native: + return std::make_unique<NativeMultiplier<ValueType>>(matrix); + } + } + + template class Multiplier<double>; + template class MultiplierFactory<double>; + +#ifdef STORM_HAVE_CARL + template class Multiplier<storm::RationalNumber>; + template class MultiplierFactory<storm::RationalNumber>; + template class Multiplier<storm::RationalFunction>; + template class MultiplierFactory<storm::RationalFunction>; +#endif + + } +} diff --git a/src/storm/solver/Multiplier.h b/src/storm/solver/Multiplier.h new file mode 100644 index 000000000..a94934ae0 --- /dev/null +++ b/src/storm/solver/Multiplier.h @@ -0,0 +1,152 @@ +#pragma once + +#include <vector> +#include <memory> + +#include "storm/solver/OptimizationDirection.h" +#include "storm/solver/MultiplicationStyle.h" + +namespace storm { + + class Environment; + + namespace storage { + template<typename ValueType> + class SparseMatrix; + } + + namespace solver { + + template<typename ValueType> + class Multiplier { + public: + + Multiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + + virtual ~Multiplier() = default; + + /* + * Clears the currently cached data of this multiplier in order to free some memory. + */ + virtual void clearCache() const; + + /*! + * Performs a matrix-vector multiplication x' = A*x + b. + * + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + */ + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const = 0; + + /*! + * Performs a matrix-vector multiplication in gauss-seidel style. + * + * @param x The input/output vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + */ + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const = 0; + + /*! + * Performs a matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param rowGroupIndices A vector storing the row groups over which to reduce. + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + * @param choices If given, the choices made in the reduction process are written to this vector. + */ + void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const = 0; + + /*! + * Performs a matrix-vector multiplication in gauss-seidel style and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param rowGroupIndices A vector storing the row groups over which to reduce. + * @param x The input/output vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. Can be the same as the x vector. + * @param choices If given, the choices made in the reduction process are written to this vector. + */ + void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const = 0; + + /*! + * Performs repeated matrix-vector multiplication, using x[0] = x and x[i + 1] = A*x[i] + b. After + * performing the necessary multiplications, the result is written to the input vector x. Note that the + * matrix A has to be given upon construction time of the solver object. + * + * @param x The initial vector with which to perform matrix-vector multiplication. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after each multiplication. If given, its length must be equal + * to the number of rows of A. + * @param n The number of times to perform the multiplication. + */ + void repeatedMultiply(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; + + /*! + * Performs repeated matrix-vector multiplication x' = A*x + b and then minimizes/maximizes over the row groups + * so that the resulting vector has the size of number of row groups of A. + * + * @param dir The direction for the reduction step. + * @param x The input vector with which to multiply the matrix. Its length must be equal + * to the number of columns of A. + * @param b If non-null, this vector is added after the multiplication. If given, its length must be equal + * to the number of rows of A. + * @param result The target vector into which to write the multiplication result. Its length must be equal + * to the number of rows of A. + * @param n The number of times to perform the multiplication. + */ + void repeatedMultiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint64_t n) const; + + /*! + * Multiplies the row with the given index with x and adds the result to the provided value + * @param rowIndex The index of the considered row + * @param x The input vector with which the row is multiplied + * @param value The multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. + */ + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const = 0; + + /*! + * Multiplies the row with the given index with x1 and x2 and adds the given offset o1 and o2, respectively + * @param rowIndex The index of the considered row + * @param x1 The first input vector with which the row is multiplied. + * @param val1 The first multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. + * @param x2 The second input vector with which the row is multiplied. + * @param val2 The second multiplication result is added to this value. It shall not reffer to a value in x or in the Matrix. + */ + virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const; + + protected: + mutable std::unique_ptr<std::vector<ValueType>> cachedVector; + storm::storage::SparseMatrix<ValueType> const& matrix; + }; + + template<typename ValueType> + class MultiplierFactory { + public: + MultiplierFactory() = default; + ~MultiplierFactory() = default; + + std::unique_ptr<Multiplier<ValueType>> create(Environment const& env, storm::storage::SparseMatrix<ValueType> const& matrix); + + + }; + + } +} diff --git a/src/storm/solver/NativeLinearEquationSolver.cpp b/src/storm/solver/NativeLinearEquationSolver.cpp index d6de61266..ca0142249 100644 --- a/src/storm/solver/NativeLinearEquationSolver.cpp +++ b/src/storm/solver/NativeLinearEquationSolver.cpp @@ -1,5 +1,7 @@ #include "storm/solver/NativeLinearEquationSolver.h" +#include <limits> + #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/utility/ConstantsComparator.h" @@ -7,10 +9,13 @@ #include "storm/utility/NumberTraits.h" #include "storm/utility/constants.h" #include "storm/utility/vector.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" +#include "storm/solver/Multiplier.h" #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidEnvironmentException.h" #include "storm/exceptions/UnmetRequirementException.h" #include "storm/exceptions/PrecisionExceededException.h" +#include "storm/exceptions/NotSupportedException.h" namespace storm { namespace solver { @@ -90,6 +95,14 @@ namespace storm { return converged; } + template<typename ValueType> + NativeLinearEquationSolver<ValueType>::JacobiDecomposition::JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix<ValueType> const& A) { + auto decomposition = A.getJacobiDecomposition(); + this->LUMatrix = std::move(decomposition.first); + this->DVector = std::move(decomposition.second); + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, this->LUMatrix); + } + template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsJacobi(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (Jacobi)"); @@ -100,16 +113,13 @@ namespace storm { // Get a Jacobi decomposition of the matrix A. if (!jacobiDecomposition) { - jacobiDecomposition = std::make_unique<std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>>(A->getJacobiDecomposition()); + jacobiDecomposition = std::make_unique<JacobiDecomposition>(env, *A); } ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); uint64_t maxIter = env.solver().native().getMaximalNumberOfIterations(); bool relative = env.solver().native().getRelativeTerminationCriterion(); - storm::storage::SparseMatrix<ValueType> const& jacobiLU = jacobiDecomposition->first; - std::vector<ValueType> const& jacobiD = jacobiDecomposition->second; - std::vector<ValueType>* currentX = &x; std::vector<ValueType>* nextX = this->cachedRowVector.get(); @@ -121,10 +131,9 @@ namespace storm { this->startMeasureProgress(); while (!converged && !terminate && iterations < maxIter) { // Compute D^-1 * (b - LU * x) and store result in nextX. - multiplier.multAdd(jacobiLU, *currentX, nullptr, *nextX); - + jacobiDecomposition->multiplier->multiply(env, *currentX, nullptr, *nextX); storm::utility::vector::subtractVectors(b, *nextX, *nextX); - storm::utility::vector::multiplyVectorsPointwise(jacobiD, *nextX, *nextX); + storm::utility::vector::multiplyVectorsPointwise(jacobiDecomposition->DVector, *nextX, *nextX); // Now check if the process already converged within our precision. converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *nextX, precision, relative); @@ -156,10 +165,11 @@ namespace storm { } template<typename ValueType> - NativeLinearEquationSolver<ValueType>::WalkerChaeData::WalkerChaeData(storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB) : t(storm::utility::convertNumber<ValueType>(1000.0)) { + NativeLinearEquationSolver<ValueType>::WalkerChaeData::WalkerChaeData(Environment const& env, storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB) : t(storm::utility::convertNumber<ValueType>(1000.0)) { computeWalkerChaeMatrix(originalMatrix); computeNewB(originalB); precomputeAuxiliaryData(); + multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, this->matrix); } template<typename ValueType> @@ -218,7 +228,7 @@ namespace storm { // (1) Compute an equivalent equation system that has only non-negative coefficients. if (!walkerChaeData) { - walkerChaeData = std::make_unique<WalkerChaeData>(*this->A, b); + walkerChaeData = std::make_unique<WalkerChaeData>(env, *this->A, b); } // (2) Enlarge the vectors x and b to account for additional variables. @@ -235,14 +245,14 @@ namespace storm { std::vector<ValueType>* nextX = &walkerChaeData->newX; std::vector<ValueType> tmp = walkerChaeData->matrix.getRowSumVector(); - storm::utility::vector::applyPointwise(tmp, walkerChaeData->b, walkerChaeData->b, [this] (ValueType const& first, ValueType const& second) { return walkerChaeData->t * first + second; } ); + storm::utility::vector::applyPointwise(tmp, walkerChaeData->b, walkerChaeData->b, [this] (ValueType const& first, ValueType const& second) -> ValueType { return walkerChaeData->t * first + second; } ); // Add t to all entries of x. - storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) { return value + walkerChaeData->t; }); + storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) -> ValueType { return value + walkerChaeData->t; }); // Create a vector that always holds Ax. std::vector<ValueType> currentAx(x.size()); - multiplier.multAdd(walkerChaeData->matrix, *currentX, nullptr, currentAx); + walkerChaeData->multiplier->multiply(env, *currentX, nullptr, currentAx); // (3) Perform iterations until convergence. bool converged = false; @@ -253,7 +263,7 @@ namespace storm { walkerChaeData->matrix.performWalkerChaeStep(*currentX, walkerChaeData->columnSums, walkerChaeData->b, currentAx, *nextX); // Compute new Ax. - multiplier.multAdd(walkerChaeData->matrix, *nextX, nullptr, currentAx); + walkerChaeData->multiplier->multiply(env, *nextX, nullptr, currentAx); // Check for convergence. converged = storm::utility::vector::computeSquaredNorm2Difference(currentAx, walkerChaeData->b) <= squaredErrorBound; @@ -278,7 +288,7 @@ namespace storm { x.resize(this->A->getRowCount()); // Finalize solution vector. - storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) { return value - walkerChaeData->t; } ); + storm::utility::vector::applyPointwise(x, x, [this] (ValueType const& value) -> ValueType { return value - walkerChaeData->t; } ); if (!this->isCachingEnabled()) { clearCache(); @@ -294,38 +304,31 @@ namespace storm { } template<typename ValueType> - typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { + typename NativeLinearEquationSolver<ValueType>::PowerIterationResult NativeLinearEquationSolver<ValueType>::performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const { bool useGaussSeidelMultiplication = multiplicationStyle == storm::solver::MultiplicationStyle::GaussSeidel; - std::vector<ValueType>* originalX = currentX; - bool converged = false; bool terminate = this->terminateNow(*currentX, guarantee); uint64_t iterations = currentIterations; while (!converged && !terminate && iterations < maxIterations) { if (useGaussSeidelMultiplication) { *newX = *currentX; - this->multiplier.multAddGaussSeidelBackward(*this->A, *newX, &b); + this->multiplier->multiplyGaussSeidel(env, *newX, &b); } else { - this->multiplier.multAdd(*this->A, *currentX, &b, *newX); + this->multiplier->multiply(env, *currentX, &b, *newX); } - // Now check for termination. + // Check for convergence. converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative); + + // Check for termination. + std::swap(currentX, newX); + ++iterations; terminate = this->terminateNow(*currentX, guarantee); // Potentially show progress. this->showProgressIterative(iterations); - - // Set up next iteration. - std::swap(currentX, newX); - ++iterations; - } - - // Swap the pointers so that the output is always in currentX. - if (originalX == newX) { - std::swap(currentX, newX); } return PowerIterationResult(iterations - currentIterations, converged ? SolverStatus::Converged : (terminate ? SolverStatus::TerminatedEarly : SolverStatus::MaximalIterationsExceeded)); @@ -339,6 +342,9 @@ namespace storm { if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } std::vector<ValueType>* currentX = &x; SolverGuarantee guarantee = SolverGuarantee::None; if (this->hasCustomTerminationCondition()) { @@ -355,7 +361,7 @@ namespace storm { // Forward call to power iteration implementation. this->startMeasureProgress(); ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision()); - PowerIterationResult result = this->performPowerIteration(currentX, newX, b, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); + PowerIterationResult result = this->performPowerIteration(env, currentX, newX, b, precision, env.solver().native().getRelativeTerminationCriterion(), guarantee, 0, env.solver().native().getMaximalNumberOfIterations(), env.solver().native().getPowerMethodMultiplicationStyle()); // Swap the result in place. if (currentX == this->cachedRowVector.get()) { @@ -396,10 +402,10 @@ namespace storm { } template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundPower(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + bool NativeLinearEquationSolver<ValueType>::solveEquationsIntervalIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { STORM_LOG_THROW(this->hasLowerBound(), storm::exceptions::UnmetRequirementException, "Solver requires lower bound, but none was given."); STORM_LOG_THROW(this->hasUpperBound(), storm::exceptions::UnmetRequirementException, "Solver requires upper bound, but none was given."); - STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (SoundPower)"); + STORM_LOG_INFO("Solving linear equation system (" << x.size() << " rows) with NativeLinearEquationSolver (IntervalIteration)"); std::vector<ValueType>* lowerX = &x; this->createLowerBoundsVector(*lowerX); @@ -413,11 +419,15 @@ namespace storm { tmp = cachedRowVector2.get(); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } + bool converged = false; bool terminate = false; uint64_t iterations = 0; bool doConvergenceCheck = true; - bool useDiffs = this->hasRelevantValues(); + bool useDiffs = this->hasRelevantValues() && !env.solver().native().isSymmetricUpdatesSet(); std::vector<ValueType> oldValues; if (useGaussSeidelMultiplication && useDiffs) { oldValues.resize(this->getRelevantValues().getNumberOfSetBits()); @@ -444,22 +454,22 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *lowerX, &b); + this->multiplier->multiplyGaussSeidel(env, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *upperX, &b); + this->multiplier->multiplyGaussSeidel(env, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } } else { - this->multiplier.multAdd(*this->A, *lowerX, &b, *tmp); + this->multiplier->multiply(env, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); - this->multiplier.multAdd(*this->A, *upperX, &b, *tmp); + this->multiplier->multiply(env, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -472,7 +482,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*lowerX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *lowerX, &b); + this->multiplier->multiplyGaussSeidel(env, *lowerX, &b); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, this->getRelevantValues(), oldValues); } @@ -481,7 +491,7 @@ namespace storm { if (useDiffs) { preserveOldRelevantValues(*upperX, this->getRelevantValues(), oldValues); } - this->multiplier.multAddGaussSeidelBackward(*this->A, *upperX, &b); + this->multiplier->multiplyGaussSeidel(env, *upperX, &b); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, this->getRelevantValues(), oldValues); } @@ -489,14 +499,14 @@ namespace storm { } } else { if (maxLowerDiff >= maxUpperDiff) { - this->multiplier.multAdd(*this->A, *lowerX, &b, *tmp); + this->multiplier->multiply(env, *lowerX, &b, *tmp); if (useDiffs) { maxLowerDiff = computeMaxAbsDiff(*lowerX, *tmp, this->getRelevantValues()); } std::swap(tmp, lowerX); lowerStep = true; } else { - this->multiplier.multAdd(*this->A, *upperX, &b, *tmp); + this->multiplier->multiply(env, *upperX, &b, *tmp); if (useDiffs) { maxUpperDiff = computeMaxAbsDiff(*upperX, *tmp, this->getRelevantValues()); } @@ -537,7 +547,7 @@ namespace storm { } // We take the means of the lower and upper bound so we guarantee the desired precision. - storm::utility::vector::applyPointwise(*lowerX, *upperX, *lowerX, [] (ValueType const& a, ValueType const& b) { return (a + b) / storm::utility::convertNumber<ValueType>(2.0); }); + storm::utility::vector::applyPointwise(*lowerX, *upperX, *lowerX, [] (ValueType const& a, ValueType const& b) -> ValueType { return (a + b) / storm::utility::convertNumber<ValueType>(2.0); }); // Since we shuffled the pointer around, we need to write the actual results to the input/output vector x. if (&x == tmp) { @@ -549,12 +559,70 @@ namespace storm { if (!this->isCachingEnabled()) { clearCache(); } - this->logIterations(converged, terminate, iterations); return converged; } + + template<typename ValueType> + bool NativeLinearEquationSolver<ValueType>::solveEquationsSoundValueIteration(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + // Prepare the solution vectors and the helper. + assert(x.size() == this->A->getRowCount()); + if (!this->cachedRowVector) { + this->cachedRowVector = std::make_unique<std::vector<ValueType>>(); + } + if (!this->soundValueIterationHelper) { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(*this->A, x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + } else { + this->soundValueIterationHelper = std::make_unique<storm::solver::helper::SoundValueIterationHelper<ValueType>>(std::move(*this->soundValueIterationHelper), x, *this->cachedRowVector, env.solver().native().getRelativeTerminationCriterion(), storm::utility::convertNumber<ValueType>(env.solver().native().getPrecision())); + } + + // Prepare initial bounds for the solution (if given) + if (this->hasLowerBound()) { + this->soundValueIterationHelper->setLowerBound(this->getLowerBound(true)); + } + if (this->hasUpperBound()) { + this->soundValueIterationHelper->setUpperBound(this->getUpperBound(true)); + } + + storm::storage::BitVector const* relevantValuesPtr = nullptr; + if (this->hasRelevantValues()) { + relevantValuesPtr = &this->getRelevantValues(); + } + + bool converged = false; + bool terminate = false; + this->startMeasureProgress(); + uint64_t iterations = 0; + + while (!converged && iterations < env.solver().native().getMaximalNumberOfIterations()) { + this->soundValueIterationHelper->performIterationStep(b); + if (this->soundValueIterationHelper->checkConvergenceUpdateBounds(relevantValuesPtr)) { + converged = true; + } + + // Check whether we terminate early. + terminate = this->hasCustomTerminationCondition() && this->soundValueIterationHelper->checkCustomTerminationCondition(this->getTerminationCondition()); + + // Update environment variables. + ++iterations; + + // Potentially show progress. + this->showProgressIterative(iterations); + } + this->soundValueIterationHelper->setSolutionVector(); + + this->logIterations(converged, terminate, iterations); + + if (!this->isCachingEnabled()) { + clearCache(); + } + + return converged; + } + template<typename ValueType> bool NativeLinearEquationSolver<ValueType>::solveEquationsRationalSearch(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { return solveEquationsRationalSearchHelper<double>(env, x, b); @@ -601,6 +669,8 @@ namespace storm { bool relative = env.solver().native().getRelativeTerminationCriterion(); auto multiplicationStyle = env.solver().native().getPowerMethodMultiplicationStyle(); + std::vector<ImpreciseType> const* originalX = &x; + std::vector<ImpreciseType>* currentX = &x; std::vector<ImpreciseType>* newX = &tmpX; @@ -610,7 +680,7 @@ namespace storm { impreciseSolver.startMeasureProgress(); while (status == SolverStatus::InProgress && overallIterations < maxIter) { // Perform value iteration with the current precision. - typename NativeLinearEquationSolver<ImpreciseType>::PowerIterationResult result = impreciseSolver.performPowerIteration(currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), relative, SolverGuarantee::LessOrEqual, overallIterations, maxIter, multiplicationStyle); + typename NativeLinearEquationSolver<ImpreciseType>::PowerIterationResult result = impreciseSolver.performPowerIteration(env, currentX, newX, b, storm::utility::convertNumber<ImpreciseType, ValueType>(precision), relative, SolverGuarantee::LessOrEqual, overallIterations, maxIter, multiplicationStyle); // At this point, the result of the imprecise value iteration is stored in the (imprecise) current x. @@ -625,10 +695,10 @@ namespace storm { // Make sure that currentX and rationalX are not aliased. std::vector<RationalType>* temporaryRational = TemporaryHelper<RationalType, ImpreciseType>::getTemporary(rationalX, currentX, newX); - + // Sharpen solution and place it in the temporary rational. bool foundSolution = sharpen(p, rationalA, *currentX, rationalB, *temporaryRational); - + // After sharpen, if a solution was found, it is contained in the free rational. if (foundSolution) { @@ -641,6 +711,11 @@ namespace storm { } } + // Swap the two vectors if the current result is not in the original x. + if (currentX != originalX) { + std::swap(x, tmpX); + } + if (status == SolverStatus::InProgress && overallIterations == maxIter) { status = SolverStatus::MaximalIterationsExceeded; } @@ -663,6 +738,9 @@ namespace storm { if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Forward the call to the core rational search routine. bool converged = solveEquationsRationalSearchHelper<storm::RationalNumber, ImpreciseType>(env, *this, rationalA, rationalX, rationalB, *this->A, x, b, *this->cachedRowVector); @@ -685,14 +763,12 @@ namespace storm { typename std::enable_if<std::is_same<ValueType, ImpreciseType>::value && NumberTraits<ValueType>::IsExact, bool>::type NativeLinearEquationSolver<ValueType>::solveEquationsRationalSearchHelper(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { // Version for when the overall value type is exact and the same type is to be used for the imprecise part. - if (!this->linEqSolverA) { - this->linEqSolverA = this->linearEquationSolverFactory->create(*this->A); - this->linEqSolverA->setCachingEnabled(true); - } - if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); } + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Forward the call to the core rational search routine. bool converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, *this, *this->A, x, b, *this->A, *this->cachedRowVector, b, x); @@ -738,18 +814,22 @@ namespace storm { NativeLinearEquationSolver<ImpreciseType> impreciseSolver; impreciseSolver.setMatrix(impreciseA); impreciseSolver.setCachingEnabled(true); - + impreciseSolver.multiplier = storm::solver::MultiplierFactory<ImpreciseType>().create(env, impreciseA); + bool converged = false; try { // Forward the call to the core rational search routine. converged = solveEquationsRationalSearchHelper<ValueType, ImpreciseType>(env, impreciseSolver, *this->A, x, b, impreciseA, impreciseX, impreciseB, impreciseTmpX); + impreciseSolver.clearCache(); } catch (storm::exceptions::PrecisionExceededException const& e) { STORM_LOG_WARN("Precision of value type was exceeded, trying to recover by switching to rational arithmetic."); if (!this->cachedRowVector) { this->cachedRowVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); } - + if (!this->multiplier) { + this->multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, *A); + } // Translate the imprecise value iteration result to the one we are going to use from now on. auto targetIt = this->cachedRowVector->begin(); for (auto it = impreciseX.begin(), ite = impreciseX.end(); it != ite; ++it, ++targetIt) { @@ -828,9 +908,9 @@ namespace storm { } else { STORM_LOG_WARN("The selected solution method does not guarantee exact results."); } - } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::Power && method != NativeLinearEquationSolverMethod::RationalSearch) { + } else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundValueIteration && method != NativeLinearEquationSolverMethod::IntervalIteration && method != NativeLinearEquationSolverMethod::RationalSearch) { if (env.solver().native().isMethodSetFromDefault()) { - method = NativeLinearEquationSolverMethod::Power; + method = NativeLinearEquationSolverMethod::SoundValueIteration; STORM_LOG_INFO("Selecting '" + toString(method) + "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method."); } else { STORM_LOG_WARN("The selected solution method does not guarantee sound results."); @@ -852,11 +932,11 @@ namespace storm { case NativeLinearEquationSolverMethod::WalkerChae: return this->solveEquationsWalkerChae(env, x, b); case NativeLinearEquationSolverMethod::Power: - if (env.solver().isForceSoundness()) { - return this->solveEquationsSoundPower(env, x, b); - } else { - return this->solveEquationsPower(env, x, b); - } + return this->solveEquationsPower(env, x, b); + case NativeLinearEquationSolverMethod::SoundValueIteration: + return this->solveEquationsSoundValueIteration(env, x, b); + case NativeLinearEquationSolverMethod::IntervalIteration: + return this->solveEquationsIntervalIteration(env, x, b); case NativeLinearEquationSolverMethod::RationalSearch: return this->solveEquationsRationalSearch(env, x, b); } @@ -864,64 +944,10 @@ namespace storm { return false; } - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { - if (&x != &result) { - multiplier.multAdd(*A, x, b, result); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAdd(*A, x, b, *this->cachedRowVector); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { - if (&x != &result) { - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, result, choices); - } else { - // If the two vectors are aliases, we need to create a temporary. - if (!this->cachedRowVector) { - this->cachedRowVector = std::make_unique<std::vector<ValueType>>(getMatrixRowCount()); - } - - multiplier.multAddReduce(dir, rowGroupIndices, *A, x, b, *this->cachedRowVector, choices); - result.swap(*this->cachedRowVector); - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - } - - template<typename ValueType> - bool NativeLinearEquationSolver<ValueType>::supportsGaussSeidelMultiplication() const { - return true; - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - STORM_LOG_ASSERT(this->A->getRowCount() == this->A->getColumnCount(), "This function is only applicable for square matrices."); - multiplier.multAddGaussSeidelBackward(*A, x, b); - } - - template<typename ValueType> - void NativeLinearEquationSolver<ValueType>::multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { - multiplier.multAddReduceGaussSeidelBackward(dir, rowGroupIndices, *A, x, b, choices); - } - template<typename ValueType> LinearEquationSolverProblemFormat NativeLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::RationalSearch) { + if (method == NativeLinearEquationSolverMethod::Power || method == NativeLinearEquationSolverMethod::SoundValueIteration || method == NativeLinearEquationSolverMethod::RationalSearch || method == NativeLinearEquationSolverMethod::IntervalIteration) { return LinearEquationSolverProblemFormat::FixedPointSystem; } else { return LinearEquationSolverProblemFormat::EquationSystem; @@ -929,15 +955,15 @@ namespace storm { } template<typename ValueType> - LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env, LinearEquationSolverTask const& task) const { + LinearEquationSolverRequirements NativeLinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { LinearEquationSolverRequirements requirements; - if (task != LinearEquationSolverTask::Multiply) { - auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); - if (method == NativeLinearEquationSolverMethod::Power && env.solver().isForceSoundness()) { - requirements.requireBounds(); - } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { - requirements.requireLowerBounds(); - } + auto method = getMethod(env, storm::NumberTraits<ValueType>::IsExact); + if (method == NativeLinearEquationSolverMethod::IntervalIteration) { + requirements.requireBounds(); + } else if (method == NativeLinearEquationSolverMethod::RationalSearch) { + requirements.requireLowerBounds(); + } else if (method == NativeLinearEquationSolverMethod::SoundValueIteration) { + requirements.requireBounds(false); } return requirements; } @@ -947,6 +973,8 @@ namespace storm { jacobiDecomposition.reset(); cachedRowVector2.reset(); walkerChaeData.reset(); + multiplier.reset(); + soundValueIterationHelper.reset(); LinearEquationSolver<ValueType>::clearCache(); } @@ -961,7 +989,7 @@ namespace storm { } template<typename ValueType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> NativeLinearEquationSolverFactory<ValueType>::create(Environment const& env, LinearEquationSolverTask const& task) const { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> NativeLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { return std::make_unique<storm::solver::NativeLinearEquationSolver<ValueType>>(); } diff --git a/src/storm/solver/NativeLinearEquationSolver.h b/src/storm/solver/NativeLinearEquationSolver.h index 136c8f68f..0cc493535 100644 --- a/src/storm/solver/NativeLinearEquationSolver.h +++ b/src/storm/solver/NativeLinearEquationSolver.h @@ -8,6 +8,7 @@ #include "storm/solver/SolverSelectionOptions.h" #include "storm/solver/NativeMultiplier.h" #include "storm/solver/SolverStatus.h" +#include "storm/solver/helper/SoundValueIterationHelper.h" #include "storm/utility/NumberTraits.h" @@ -30,14 +31,8 @@ namespace storm { virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; - virtual void multiply(std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; - virtual void multiplyAndReduce(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual bool supportsGaussSeidelMultiplication() const override; - virtual void multiplyGaussSeidel(std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; - virtual void multiplyAndReduceGaussSeidel(OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; - virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; - virtual LinearEquationSolverRequirements getRequirements(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; virtual void clearCache() const override; @@ -57,7 +52,7 @@ namespace storm { template <typename ValueTypePrime> friend class NativeLinearEquationSolver; - PowerIterationResult performPowerIteration(std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; + PowerIterationResult performPowerIteration(Environment const& env, std::vector<ValueType>*& currentX, std::vector<ValueType>*& newX, std::vector<ValueType> const& b, ValueType const& precision, bool relative, SolverGuarantee const& guarantee, uint64_t currentIterations, uint64_t maxIterations, storm::solver::MultiplicationStyle const& multiplicationStyle) const; void logIterations(bool converged, bool terminate, uint64_t iterations) const; @@ -70,7 +65,8 @@ namespace storm { virtual bool solveEquationsJacobi(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsWalkerChae(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; - virtual bool solveEquationsSoundPower(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + virtual bool solveEquationsSoundValueIteration(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + virtual bool solveEquationsIntervalIteration(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; virtual bool solveEquationsRationalSearch(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; template<typename RationalType, typename ImpreciseType> @@ -94,14 +90,23 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const* A; // An object to dispatch all multiplication operations. - NativeMultiplier<ValueType> multiplier; + mutable std::unique_ptr<Multiplier<ValueType>> multiplier; // cached auxiliary data - mutable std::unique_ptr<std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>>> jacobiDecomposition; mutable std::unique_ptr<std::vector<ValueType>> cachedRowVector2; // A.getRowCount() rows + mutable std::unique_ptr<storm::solver::helper::SoundValueIterationHelper<ValueType>> soundValueIterationHelper; + + struct JacobiDecomposition { + JacobiDecomposition(Environment const& env, storm::storage::SparseMatrix<ValueType> const& A); + + storm::storage::SparseMatrix<ValueType> LUMatrix; + std::vector<ValueType> DVector; + std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplier; + }; + mutable std::unique_ptr<JacobiDecomposition> jacobiDecomposition; struct WalkerChaeData { - WalkerChaeData(storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB); + WalkerChaeData(Environment const& env, storm::storage::SparseMatrix<ValueType> const& originalMatrix, std::vector<ValueType> const& originalB); void computeWalkerChaeMatrix(storm::storage::SparseMatrix<ValueType> const& originalMatrix); void computeNewB(std::vector<ValueType> const& originalB); @@ -110,6 +115,7 @@ namespace storm { storm::storage::SparseMatrix<ValueType> matrix; std::vector<ValueType> b; ValueType t; + std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplier; // Auxiliary data. std::vector<ValueType> columnSums; @@ -123,7 +129,7 @@ namespace storm { public: using LinearEquationSolverFactory<ValueType>::create; - virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env, LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) const override; + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; diff --git a/src/storm/solver/NativeMultiplier.cpp b/src/storm/solver/NativeMultiplier.cpp index f5fc1d903..13b27c617 100644 --- a/src/storm/solver/NativeMultiplier.cpp +++ b/src/storm/solver/NativeMultiplier.cpp @@ -2,6 +2,10 @@ #include "storm-config.h" +#include "storm/environment/solver/MultiplierEnvironment.h" +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" + #include "storm/storage/SparseMatrix.h" #include "storm/adapters/RationalNumberAdapter.h" @@ -13,85 +17,118 @@ namespace storm { namespace solver { template<typename ValueType> - NativeMultiplier<ValueType>::NativeMultiplier() : storm::utility::VectorHelper<ValueType>() { + NativeMultiplier<ValueType>::NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix) : Multiplier<ValueType>(matrix) { // Intentionally left empty. } - + template<typename ValueType> - void NativeMultiplier<ValueType>::multAdd(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + bool NativeMultiplier<ValueType>::parallelize(Environment const& env) const { +#ifdef STORM_HAVE_INTELTBB + return storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseIntelTbbSet(); +#else + return false; +#endif + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { std::vector<ValueType>* target = &result; - std::unique_ptr<std::vector<ValueType>> temporary; if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAdd'."); - temporary = std::make_unique<std::vector<ValueType>>(x.size()); - target = temporary.get(); + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); } - - if (this->parallelize()) { - multAddParallel(matrix, x, b, result); + if (parallelize(env)) { + multAddParallel(x, b, *target); } else { - matrix.multiplyWithVector(x, result, b); + multAdd(x, b, *target); } - - if (target == temporary.get()) { - std::swap(result, *temporary); + if (&x == &result) { + std::swap(result, *this->cachedVector); } } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddGaussSeidelBackward(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { - matrix.multiplyWithVectorBackward(x, x, b); + void NativeMultiplier<ValueType>::multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const { + this->matrix.multiplyWithVectorBackward(x, x, b); } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + void NativeMultiplier<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices) const { std::vector<ValueType>* target = &result; - std::unique_ptr<std::vector<ValueType>> temporary; if (&x == &result) { - STORM_LOG_WARN("Using temporary in 'multAddReduce'."); - temporary = std::make_unique<std::vector<ValueType>>(x.size()); - target = temporary.get(); + if (this->cachedVector) { + this->cachedVector->resize(x.size()); + } else { + this->cachedVector = std::make_unique<std::vector<ValueType>>(x.size()); + } + target = this->cachedVector.get(); } - - if (this->parallelize()) { - multAddReduceParallel(dir, rowGroupIndices, matrix, x, b, *target, choices); + if (parallelize(env)) { + multAddReduceParallel(dir, rowGroupIndices, x, b, *target, choices); } else { - matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, *target, choices); + multAddReduce(dir, rowGroupIndices, x, b, *target, choices); } - - if (target == temporary.get()) { - std::swap(result, *temporary); + if (&x == &result) { + std::swap(result, *this->cachedVector); } } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices) const { - matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); + void NativeMultiplier<ValueType>::multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices) const { + this->matrix.multiplyAndReduceBackward(dir, rowGroupIndices, x, b, x, choices); } - + + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + value += entry.getValue() * x[entry.getColumn()]; + } + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const { + for (auto const& entry : this->matrix.getRow(rowIndex)) { + val1 += entry.getValue() * x1[entry.getColumn()]; + val2 += entry.getValue() * x2[entry.getColumn()]; + } + } + + template<typename ValueType> - void NativeMultiplier<ValueType>::multAddParallel(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + void NativeMultiplier<ValueType>::multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { + this->matrix.multiplyWithVector(x, result, b); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + this->matrix.multiplyAndReduce(dir, rowGroupIndices, x, b, result, choices); + } + + template<typename ValueType> + void NativeMultiplier<ValueType>::multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const { #ifdef STORM_HAVE_INTELTBB - matrix.multiplyWithVectorParallel(x, result, b); + this->matrix.multiplyWithVectorParallel(x, result, b); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAdd(matrix, x, b, result); + multAdd(x, b, result); #endif } template<typename ValueType> - void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { + void NativeMultiplier<ValueType>::multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices) const { #ifdef STORM_HAVE_INTELTBB - matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); + this->matrix.multiplyAndReduceParallel(dir, rowGroupIndices, x, b, result, choices); #else STORM_LOG_WARN("Storm was built without support for Intel TBB, defaulting to sequential version."); - multAddReduce(dir, rowGroupIndices, matrix, x, b, result, choices); + multAddReduce(dir, rowGroupIndices, x, b, result, choices); #endif } - template class NativeMultiplier<double>; - #ifdef STORM_HAVE_CARL template class NativeMultiplier<storm::RationalNumber>; template class NativeMultiplier<storm::RationalFunction>; diff --git a/src/storm/solver/NativeMultiplier.h b/src/storm/solver/NativeMultiplier.h index 01233b1ba..3d9e31a02 100644 --- a/src/storm/solver/NativeMultiplier.h +++ b/src/storm/solver/NativeMultiplier.h @@ -1,6 +1,6 @@ #pragma once -#include "storm/utility/VectorHelper.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/OptimizationDirection.h" @@ -13,18 +13,28 @@ namespace storm { namespace solver { template<typename ValueType> - class NativeMultiplier : public storm::utility::VectorHelper<ValueType> { + class NativeMultiplier : public Multiplier<ValueType> { public: - NativeMultiplier(); + NativeMultiplier(storm::storage::SparseMatrix<ValueType> const& matrix); + virtual ~NativeMultiplier() = default; - void multAdd(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddGaussSeidelBackward(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b) const; + virtual void multiply(Environment const& env, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const override; + virtual void multiplyGaussSeidel(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const* b) const override; + virtual void multiplyAndReduce(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyAndReduceGaussSeidel(Environment const& env, OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint_fast64_t>* choices = nullptr) const override; + virtual void multiplyRow(uint64_t const& rowIndex, std::vector<ValueType> const& x, ValueType& value) const override; + virtual void multiplyRow2(uint64_t const& rowIndex, std::vector<ValueType> const& x1, ValueType& val1, std::vector<ValueType> const& x2, ValueType& val2) const override; + + private: + bool parallelize(Environment const& env) const; + + void multAdd(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + + void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduce(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddReduceGaussSeidelBackward(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType> const* b, std::vector<uint64_t>* choices = nullptr) const; + void multAddParallel(std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; + void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; - void multAddParallel(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result) const; - void multAddReduceParallel(storm::solver::OptimizationDirection const& dir, std::vector<uint64_t> const& rowGroupIndices, storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType> const& x, std::vector<ValueType> const* b, std::vector<ValueType>& result, std::vector<uint64_t>* choices = nullptr) const; }; } diff --git a/src/storm/solver/SolveGoal.h b/src/storm/solver/SolveGoal.h index d93b86b91..9bd6f7e73 100644 --- a/src/storm/solver/SolveGoal.h +++ b/src/storm/solver/SolveGoal.h @@ -7,7 +7,6 @@ #include "storm/solver/OptimizationDirection.h" #include "storm/logic/ComparisonType.h" #include "storm/storage/BitVector.h" -#include "storm/solver/LinearEquationSolverTask.h" #include "storm/solver/LinearEquationSolver.h" #include "storm/solver/MinMaxLinearEquationSolver.h" @@ -111,8 +110,8 @@ namespace storm { } template<typename ValueType, typename MatrixType> - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(Environment const& env, SolveGoal<ValueType>&& goal, storm::solver::LinearEquationSolverFactory<ValueType> const& factory, MatrixType&& matrix, storm::solver::LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) { - std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = factory.create(env, std::forward<MatrixType>(matrix), task); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> configureLinearEquationSolver(Environment const& env, SolveGoal<ValueType>&& goal, storm::solver::LinearEquationSolverFactory<ValueType> const& factory, MatrixType&& matrix) { + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = factory.create(env, std::forward<MatrixType>(matrix)); if (goal.isBounded()) { solver->setTerminationCondition(std::make_unique<TerminateIfFilteredExtremumExceedsThreshold<ValueType>>(goal.relevantValues(), goal.boundIsStrict(), goal.thresholdValue(), goal.minimize())); } @@ -120,8 +119,8 @@ namespace storm { } template<typename MatrixType> - std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> configureLinearEquationSolver(Environment const& env, SolveGoal<storm::RationalFunction>&& goal, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& factory, MatrixType&& matrix, storm::solver::LinearEquationSolverTask const& task = LinearEquationSolverTask::Unspecified) { - std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> solver = factory.create(env, std::forward<MatrixType>(matrix), task); + std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> configureLinearEquationSolver(Environment const& env, SolveGoal<storm::RationalFunction>&& goal, storm::solver::LinearEquationSolverFactory<storm::RationalFunction> const& factory, MatrixType&& matrix) { + std::unique_ptr<storm::solver::LinearEquationSolver<storm::RationalFunction>> solver = factory.create(env, std::forward<MatrixType>(matrix)); return solver; } diff --git a/src/storm/solver/SolverRequirement.cpp b/src/storm/solver/SolverRequirement.cpp new file mode 100644 index 000000000..c898840aa --- /dev/null +++ b/src/storm/solver/SolverRequirement.cpp @@ -0,0 +1,32 @@ +#include "storm/solver/SolverRequirement.h" + +#include <vector> + +#include "storm/utility/vector.h" + +namespace storm { + namespace solver { + SolverRequirement::SolverRequirement() : enabled(false), critical(false) { + // Intentionally left empty + } + + SolverRequirement::operator bool() const { + return enabled; + } + + void SolverRequirement::enable(bool critical) { + this->enabled = true; + this->critical = critical; + } + + void SolverRequirement::clear() { + enabled = false; + critical = false; + } + + bool SolverRequirement::isCritical() const { + return this->critical; + } + + } +} diff --git a/src/storm/solver/SolverRequirement.h b/src/storm/solver/SolverRequirement.h new file mode 100644 index 000000000..cfdac2e18 --- /dev/null +++ b/src/storm/solver/SolverRequirement.h @@ -0,0 +1,39 @@ +#pragma once + +namespace storm { + namespace solver { + + class SolverRequirement { + public: + + SolverRequirement(); + SolverRequirement(SolverRequirement const& other) = default; + + /*! + * Returns true if this is a requirement of the considered solver. + */ + operator bool() const; + + /*! + * Enables this requirement. + * @param critical if set, it is assumed that the solver will fail in case this requirement is not met + */ + void enable(bool critical = true); + + /*! + * Clears this requirement. + */ + void clear(); + + /*! + * Returns true if the solver fails in case this requirement is not met. + */ + bool isCritical() const; + + private: + bool enabled; + bool critical; + }; + + } +} diff --git a/src/storm/solver/SolverSelectionOptions.cpp b/src/storm/solver/SolverSelectionOptions.cpp index 504f3e2a7..d50d4875f 100644 --- a/src/storm/solver/SolverSelectionOptions.cpp +++ b/src/storm/solver/SolverSelectionOptions.cpp @@ -14,6 +14,22 @@ namespace storm { return "topological"; case MinMaxMethod::RationalSearch: return "ratsearch"; + case MinMaxMethod::IntervalIteration: + return "intervaliteration"; + case MinMaxMethod::SoundValueIteration: + return "soundvalueiteration"; + case MinMaxMethod::TopologicalCuda: + return "topologicalcuda"; + } + return "invalid"; + } + + std::string toString(MultiplierType t) { + switch(t) { + case MultiplierType::Native: + return "Native"; + case MultiplierType::Gmmxx: + return "Gmmxx"; } return "invalid"; } @@ -50,6 +66,8 @@ namespace storm { return "Eigen"; case EquationSolverType::Elimination: return "Elimination"; + case EquationSolverType::Topological: + return "Topological"; } return "invalid"; } @@ -65,7 +83,7 @@ namespace storm { } std::string toString(NativeLinearEquationSolverMethod t) { - switch( t) { + switch(t) { case NativeLinearEquationSolverMethod::Jacobi: return "Jacobi"; case NativeLinearEquationSolverMethod::GaussSeidel: @@ -76,6 +94,10 @@ namespace storm { return "WalkerChae"; case NativeLinearEquationSolverMethod::Power: return "Power"; + case NativeLinearEquationSolverMethod::SoundValueIteration: + return "SoundValueIteration"; + case NativeLinearEquationSolverMethod::IntervalIteration: + return "IntervalIteration"; case NativeLinearEquationSolverMethod::RationalSearch: return "RationalSearch"; } diff --git a/src/storm/solver/SolverSelectionOptions.h b/src/storm/solver/SolverSelectionOptions.h index ed4605ecb..baea29dc1 100644 --- a/src/storm/solver/SolverSelectionOptions.h +++ b/src/storm/solver/SolverSelectionOptions.h @@ -6,15 +6,16 @@ namespace storm { namespace solver { - ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch) + ExtendEnumsWithSelectionField(MinMaxMethod, PolicyIteration, ValueIteration, LinearProgramming, Topological, RationalSearch, IntervalIteration, SoundValueIteration, TopologicalCuda) + ExtendEnumsWithSelectionField(MultiplierType, Native, Gmmxx) ExtendEnumsWithSelectionField(GameMethod, PolicyIteration, ValueIteration) ExtendEnumsWithSelectionField(LraMethod, LinearProgramming, ValueIteration) ExtendEnumsWithSelectionField(LpSolverType, Gurobi, Glpk, Z3) - ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination) + ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Eigen, Elimination, Topological) ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat) - ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, RationalSearch) + ExtendEnumsWithSelectionField(NativeLinearEquationSolverMethod, Jacobi, GaussSeidel, SOR, WalkerChae, Power, SoundValueIteration, IntervalIteration, RationalSearch) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverMethod, Bicgstab, Qmr, Gmres) ExtendEnumsWithSelectionField(GmmxxLinearEquationSolverPreconditioner, Ilu, Diagonal, None) ExtendEnumsWithSelectionField(EigenLinearEquationSolverMethod, SparseLU, Bicgstab, DGmres, Gmres) diff --git a/src/storm/solver/StandardGameSolver.cpp b/src/storm/solver/StandardGameSolver.cpp index 26d4cc3d0..6140a5c15 100644 --- a/src/storm/solver/StandardGameSolver.cpp +++ b/src/storm/solver/StandardGameSolver.cpp @@ -76,13 +76,34 @@ namespace storm { uint64_t maxIter = env.solver().game().getMaximalNumberOfIterations(); + // The linear equation solver should be at least as precise as this solver + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().game().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().game().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().game().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } + } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + // Solve the equation system induced by the two schedulers. storm::storage::SparseMatrix<ValueType> submatrix; getInducedMatrixVector(x, b, player1Choices, player2Choices, submatrix, subB); - if (this->linearEquationSolverFactory->getEquationProblemFormat(env) == LinearEquationSolverProblemFormat::EquationSystem) { + if (this->linearEquationSolverFactory->getEquationProblemFormat(environmentOfSolver) == LinearEquationSolverProblemFormat::EquationSystem) { submatrix.convertToEquationSystem(); } - auto submatrixSolver = linearEquationSolverFactory->create(env, std::move(submatrix)); + auto submatrixSolver = linearEquationSolverFactory->create(environmentOfSolver, std::move(submatrix)); if (this->lowerBound) { submatrixSolver->setLowerBound(this->lowerBound.get()); } if (this->upperBound) { submatrixSolver->setUpperBound(this->upperBound.get()); } submatrixSolver->setCachingEnabled(true); @@ -92,7 +113,7 @@ namespace storm { do { // Solve the equation system for the 'DTMC'. // FIXME: we need to remove the 0- and 1- states to make the solution unique. - submatrixSolver->solveEquations(env, x, subB); + submatrixSolver->solveEquations(environmentOfSolver, x, subB); bool schedulerImproved = extractChoices(player1Dir, player2Dir, x, b, *auxiliaryP2RowGroupVector, player1Choices, player2Choices); @@ -138,9 +159,8 @@ namespace storm { template<typename ValueType> bool StandardGameSolver<ValueType>::solveGameValueIteration(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - if(!linEqSolverPlayer2Matrix) { - linEqSolverPlayer2Matrix = linearEquationSolverFactory->create(env, player2Matrix, storm::solver::LinearEquationSolverTask::Multiply); - linEqSolverPlayer2Matrix->setCachingEnabled(true); + if (!multiplierPlayer2Matrix) { + multiplierPlayer2Matrix = storm::solver::MultiplierFactory<ValueType>().create(env, player2Matrix); } if (!auxiliaryP2RowVector) { @@ -183,7 +203,7 @@ namespace storm { Status status = Status::InProgress; while (status == Status::InProgress) { - multiplyAndReduce(player1Dir, player2Dir, *currentX, &b, *linEqSolverPlayer2Matrix, multiplyResult, reducedMultiplyResult, *newX); + multiplyAndReduce(env, player1Dir, player2Dir, *currentX, &b, *multiplierPlayer2Matrix, multiplyResult, reducedMultiplyResult, *newX); // Determine whether the method converged. if (storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *newX, precision, relative)) { @@ -221,9 +241,8 @@ namespace storm { template<typename ValueType> void StandardGameSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if(!linEqSolverPlayer2Matrix) { - linEqSolverPlayer2Matrix = linearEquationSolverFactory->create(env, player2Matrix, storm::solver::LinearEquationSolverTask::Multiply); - linEqSolverPlayer2Matrix->setCachingEnabled(true); + if (!multiplierPlayer2Matrix) { + multiplierPlayer2Matrix = storm::solver::MultiplierFactory<ValueType>().create(env, player2Matrix); } if (!auxiliaryP2RowVector) { @@ -237,7 +256,7 @@ namespace storm { std::vector<ValueType>& reducedMultiplyResult = *auxiliaryP2RowGroupVector; for (uint_fast64_t iteration = 0; iteration < n; ++iteration) { - multiplyAndReduce(player1Dir, player2Dir, x, b, *linEqSolverPlayer2Matrix, multiplyResult, reducedMultiplyResult, x); + multiplyAndReduce(env, player1Dir, player2Dir, x, b, *multiplierPlayer2Matrix, multiplyResult, reducedMultiplyResult, x); } if(!this->isCachingEnabled()) { @@ -246,9 +265,9 @@ namespace storm { } template<typename ValueType> - void StandardGameSolver<ValueType>::multiplyAndReduce(OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::LinearEquationSolver<ValueType> const& linEqSolver, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const { + void StandardGameSolver<ValueType>::multiplyAndReduce(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const { - linEqSolver.multiply(x, b, multiplyResult); + multiplier.multiply(env, x, b, multiplyResult); storm::utility::vector::reduceVectorMinOrMax(player2Dir, multiplyResult, p2ReducedMultiplyResult, player2Matrix.getRowGroupIndices()); @@ -383,7 +402,7 @@ namespace storm { template<typename ValueType> void StandardGameSolver<ValueType>::clearCache() const { - linEqSolverPlayer2Matrix.reset(); + multiplierPlayer2Matrix.reset(); auxiliaryP2RowVector.reset(); auxiliaryP2RowGroupVector.reset(); auxiliaryP1RowGroupVector.reset(); diff --git a/src/storm/solver/StandardGameSolver.h b/src/storm/solver/StandardGameSolver.h index 336be3911..e9e8060a7 100644 --- a/src/storm/solver/StandardGameSolver.h +++ b/src/storm/solver/StandardGameSolver.h @@ -1,6 +1,7 @@ #pragma once #include "storm/solver/LinearEquationSolver.h" +#include "storm/solver/Multiplier.h" #include "storm/solver/GameSolver.h" #include "SolverSelectionOptions.h" @@ -26,8 +27,7 @@ namespace storm { bool solveGameValueIteration(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; // Computes p2Matrix * x + b, reduces the result w.r.t. player 2 choices, and then reduces the result w.r.t. player 1 choices. - void multiplyAndReduce(OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, - storm::solver::LinearEquationSolver<ValueType> const& linEqSolver, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const; + void multiplyAndReduce(Environment const& env, OptimizationDirection player1Dir, OptimizationDirection player2Dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, storm::solver::Multiplier<ValueType> const& multiplier, std::vector<ValueType>& multiplyResult, std::vector<ValueType>& p2ReducedMultiplyResult, std::vector<ValueType>& p1ReducedMultiplyResult) const; // Solves the equation system given by the two choice selections void getInducedMatrixVector(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<uint_fast64_t> const& player1Choices, std::vector<uint_fast64_t> const& player2Choices, storm::storage::SparseMatrix<ValueType>& inducedMatrix, std::vector<ValueType>& inducedVector) const; @@ -43,7 +43,7 @@ namespace storm { }; // possibly cached data - mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolverPlayer2Matrix; + mutable std::unique_ptr<storm::solver::Multiplier<ValueType>> multiplierPlayer2Matrix; mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP2RowVector; // player2Matrix.rowCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP2RowGroupVector; // player2Matrix.rowGroupCount() entries mutable std::unique_ptr<std::vector<ValueType>> auxiliaryP1RowGroupVector; // player1Matrix.rowGroupCount() entries diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp index a8b042dc7..c2878cebb 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.cpp @@ -5,6 +5,7 @@ #include "storm/solver/EigenLinearEquationSolver.h" #include "storm/solver/NativeLinearEquationSolver.h" #include "storm/solver/EliminationLinearEquationSolver.h" +#include "storm/solver/TopologicalLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" @@ -17,17 +18,17 @@ namespace storm { namespace solver { template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), A(nullptr) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver() : A(nullptr) { // Intentionally left empty. } template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), localA(nullptr), A(&A) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(&A) { // Intentionally left empty. } template<typename ValueType> - StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : linearEquationSolverFactory(std::move(linearEquationSolverFactory)), localA(std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A))), A(localA.get()) { + StandardMinMaxLinearEquationSolver<ValueType>::StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A))), A(localA.get()) { // Intentionally left empty. } @@ -35,121 +36,20 @@ namespace storm { void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { this->localA = nullptr; this->A = &matrix; + this->clearCache(); } template<typename ValueType> void StandardMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); this->A = this->localA.get(); - } - - template<typename ValueType> - void StandardMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - if (!linEqSolverA) { - linEqSolverA = linearEquationSolverFactory->create(env, *A, LinearEquationSolverTask::Multiply); - linEqSolverA->setCachingEnabled(true); - } - - if (!auxiliaryRowGroupVector) { - auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); - } - - this->startMeasureProgress(); - for (uint64_t i = 0; i < n; ++i) { - linEqSolverA->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, b, *auxiliaryRowGroupVector); - std::swap(x, *auxiliaryRowGroupVector); - - // Potentially show progress. - this->showProgressIterative(i, n); - } - - if (!this->isCachingEnabled()) { - clearCache(); - } - } - - template<typename ValueType> - void StandardMinMaxLinearEquationSolver<ValueType>::clearCache() const { - linEqSolverA.reset(); - auxiliaryRowVector.reset(); - MinMaxLinearEquationSolver<ValueType>::clearCache(); - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory() : MinMaxLinearEquationSolverFactory<ValueType>(), linearEquationSolverFactory(std::make_unique<GeneralLinearEquationSolverFactory<ValueType>>()) { - // Intentionally left empty. - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory) : MinMaxLinearEquationSolverFactory<ValueType>(), linearEquationSolverFactory(std::move(linearEquationSolverFactory)) { - // Intentionally left empty. - } - - template<typename ValueType> - StandardMinMaxLinearEquationSolverFactory<ValueType>::StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : MinMaxLinearEquationSolverFactory<ValueType>() { - switch (solverType) { - case EquationSolverType::Gmmxx: linearEquationSolverFactory = std::make_unique<GmmxxLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Eigen: linearEquationSolverFactory = std::make_unique<EigenLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Native: linearEquationSolverFactory = std::make_unique<NativeLinearEquationSolverFactory<ValueType>>(); break; - case EquationSolverType::Elimination: linearEquationSolverFactory = std::make_unique<EliminationLinearEquationSolverFactory<ValueType>>(); break; - } - } - - template<> - StandardMinMaxLinearEquationSolverFactory<storm::RationalNumber>::StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType) : MinMaxLinearEquationSolverFactory<storm::RationalNumber>() { - switch (solverType) { - case EquationSolverType::Eigen: linearEquationSolverFactory = std::make_unique<EigenLinearEquationSolverFactory<storm::RationalNumber>>(); break; - case EquationSolverType::Elimination: linearEquationSolverFactory = std::make_unique<EliminationLinearEquationSolverFactory<storm::RationalNumber>>(); break; - default: - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Unsupported equation solver for this data type."); - } - } - - template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> StandardMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> result; - auto method = env.solver().minMax().getMethod(); - if (method == MinMaxMethod::ValueIteration || method == MinMaxMethod::PolicyIteration || method == MinMaxMethod::RationalSearch) { - result = std::make_unique<IterativeMinMaxLinearEquationSolver<ValueType>>(this->linearEquationSolverFactory->clone()); - } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "The selected min max method is not supported by this solver."); - } - result->setRequirementsChecked(this->isRequirementsCheckedSet()); - return result; - } - - template<typename ValueType> - GmmxxMinMaxLinearEquationSolverFactory<ValueType>::GmmxxMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Gmmxx) { - // Intentionally left empty. - } - - template<typename ValueType> - EigenMinMaxLinearEquationSolverFactory<ValueType>::EigenMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Eigen) { - // Intentionally left empty. - } - - template<typename ValueType> - NativeMinMaxLinearEquationSolverFactory<ValueType>::NativeMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Native) { - // Intentionally left empty. - } - - template<typename ValueType> - EliminationMinMaxLinearEquationSolverFactory<ValueType>::EliminationMinMaxLinearEquationSolverFactory() : StandardMinMaxLinearEquationSolverFactory<ValueType>(EquationSolverType::Elimination) { - // Intentionally left empty. + this->clearCache(); } template class StandardMinMaxLinearEquationSolver<double>; - template class StandardMinMaxLinearEquationSolverFactory<double>; - template class GmmxxMinMaxLinearEquationSolverFactory<double>; - template class EigenMinMaxLinearEquationSolverFactory<double>; - template class NativeMinMaxLinearEquationSolverFactory<double>; - template class EliminationMinMaxLinearEquationSolverFactory<double>; #ifdef STORM_HAVE_CARL template class StandardMinMaxLinearEquationSolver<storm::RationalNumber>; - template class StandardMinMaxLinearEquationSolverFactory<storm::RationalNumber>; - template class EigenMinMaxLinearEquationSolverFactory<storm::RationalNumber>; - template class EliminationMinMaxLinearEquationSolverFactory<storm::RationalNumber>; #endif } } diff --git a/src/storm/solver/StandardMinMaxLinearEquationSolver.h b/src/storm/solver/StandardMinMaxLinearEquationSolver.h index 580e89347..9e79f482b 100644 --- a/src/storm/solver/StandardMinMaxLinearEquationSolver.h +++ b/src/storm/solver/StandardMinMaxLinearEquationSolver.h @@ -12,29 +12,17 @@ namespace storm { template<typename ValueType> class StandardMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { public: - StandardMinMaxLinearEquationSolver(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A, std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); + StandardMinMaxLinearEquationSolver(); + explicit StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + explicit StandardMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; virtual ~StandardMinMaxLinearEquationSolver() = default; - virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; - - virtual void clearCache() const override; - protected: - // possibly cached data - mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolverA; - mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowVector; // A.rowCount() entries - mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowCount() entries - - /// The factory used to obtain linear equation solvers. - std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; - // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted // when the solver is destructed. std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; @@ -44,48 +32,5 @@ namespace storm { storm::storage::SparseMatrix<ValueType> const* A; }; - template<typename ValueType> - class StandardMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { - public: - StandardMinMaxLinearEquationSolverFactory(); - StandardMinMaxLinearEquationSolverFactory(std::unique_ptr<LinearEquationSolverFactory<ValueType>>&& linearEquationSolverFactory); - StandardMinMaxLinearEquationSolverFactory(EquationSolverType const& solverType); - - // Make the other create methods visible. - using MinMaxLinearEquationSolverFactory<ValueType>::create; - - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - - protected: - std::unique_ptr<LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; - - private: - void createLinearEquationSolverFactory() const; - }; - - template<typename ValueType> - class GmmxxMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - GmmxxMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class EigenMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - EigenMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class NativeMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - NativeMinMaxLinearEquationSolverFactory(); - }; - - template<typename ValueType> - class EliminationMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> { - public: - EliminationMinMaxLinearEquationSolverFactory(); - }; - } } diff --git a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp index b1501fd32..b599face7 100644 --- a/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicMinMaxLinearEquationSolver.cpp @@ -244,13 +244,26 @@ namespace storm { // If we were given an initial scheduler, we take its solution as the starting point. if (this->hasInitialScheduler()) { // The linear equation solver should be at least as precise as this solver - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } - localX = solveEquationsWithScheduler(environmentOfSolver ? *environmentOfSolver : env, this->getInitialScheduler(), x, b); + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; + localX = solveEquationsWithScheduler(environmentOfSolver, this->getInitialScheduler(), x, b); } else { localX = this->getLowerBoundsVector(); } @@ -311,20 +324,33 @@ namespace storm { // Initialize linear equation solver. // It should be at least as precise as this solver. - std::unique_ptr<storm::Environment> environmentOfSolver; - boost::optional<storm::RationalNumber> precOfSolver = env.solver().getPrecisionOfCurrentLinearEquationSolver(); - if (!storm::NumberTraits<ValueType>::IsExact && precOfSolver && precOfSolver.get() > env.solver().minMax().getPrecision()) { - environmentOfSolver = std::make_unique<storm::Environment>(env); - environmentOfSolver->solver().setLinearEquationSolverPrecision(env.solver().minMax().getPrecision()); + std::unique_ptr<storm::Environment> environmentOfSolverStorage; + auto precOfSolver = env.solver().getPrecisionOfLinearEquationSolver(env.solver().getLinearEquationSolverType()); + if (!storm::NumberTraits<ValueType>::IsExact) { + bool changePrecision = precOfSolver.first && precOfSolver.first.get() > env.solver().minMax().getPrecision(); + bool changeRelative = precOfSolver.second && !precOfSolver.second.get() && env.solver().minMax().getRelativeTerminationCriterion(); + if (changePrecision || changeRelative) { + environmentOfSolverStorage = std::make_unique<storm::Environment>(env); + boost::optional<storm::RationalNumber> newPrecision; + boost::optional<bool> newRelative; + if (changePrecision) { + newPrecision = env.solver().minMax().getPrecision(); + } + if (changeRelative) { + newRelative = true; + } + environmentOfSolverStorage->solver().setLinearEquationSolverPrecision(newPrecision, newRelative); + } } + storm::Environment const& environmentOfSolver = environmentOfSolverStorage ? *environmentOfSolverStorage : env; - std::unique_ptr<SymbolicLinearEquationSolver<DdType, ValueType>> linearEquationSolver = linearEquationSolverFactory->create(environmentOfSolver ? *environmentOfSolver : env, this->allRows, this->rowMetaVariables, this->columnMetaVariables, this->rowColumnMetaVariablePairs); + std::unique_ptr<SymbolicLinearEquationSolver<DdType, ValueType>> linearEquationSolver = linearEquationSolverFactory->create(environmentOfSolver, this->allRows, this->rowMetaVariables, this->columnMetaVariables, this->rowColumnMetaVariablePairs); this->forwardBounds(*linearEquationSolver); // Iteratively solve and improve the scheduler. uint64_t maxIter = env.solver().minMax().getMaximalNumberOfIterations(); while (!converged && iterations < maxIter) { - storm::dd::Add<DdType, ValueType> schedulerX = solveEquationsWithScheduler(environmentOfSolver ? *environmentOfSolver : env, *linearEquationSolver, scheduler, currentSolution, b, diagonal); + storm::dd::Add<DdType, ValueType> schedulerX = solveEquationsWithScheduler(environmentOfSolver, *linearEquationSolver, scheduler, currentSolution, b, diagonal); // Policy improvement step. storm::dd::Add<DdType, ValueType> choiceValues = this->A.multiplyMatrix(schedulerX.swapVariables(this->rowColumnMetaVariablePairs), this->columnMetaVariables) + b; diff --git a/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp b/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp index 4252b1483..7c25f0e35 100644 --- a/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp +++ b/src/storm/solver/SymbolicNativeLinearEquationSolver.cpp @@ -88,7 +88,7 @@ namespace storm { storm::dd::Add<DdType, ValueType> lu = diagonal.ite(manager.template getAddZero<ValueType>(), this->A); storm::dd::Add<DdType, ValueType> diagonalAdd = diagonal.template toAdd<ValueType>(); storm::dd::Add<DdType, ValueType> diag = diagonalAdd.multiplyMatrix(this->A, this->columnMetaVariables); - + storm::dd::Add<DdType, ValueType> scaledLu = lu / diag; storm::dd::Add<DdType, ValueType> scaledB = b / diag; diff --git a/src/storm/solver/TerminationCondition.cpp b/src/storm/solver/TerminationCondition.cpp index 745cc8a51..db3f12efd 100644 --- a/src/storm/solver/TerminationCondition.cpp +++ b/src/storm/solver/TerminationCondition.cpp @@ -4,12 +4,18 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/utility/macros.h" +#include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace solver { template<typename ValueType> - bool NoTerminationCondition<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminationCondition<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + return terminateNow([¤tValues] (uint64_t const& i) {return currentValues[i];}, guarantee); + } + + template<typename ValueType> + bool NoTerminationCondition<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { return false; } @@ -24,14 +30,17 @@ namespace storm { } template<typename ValueType> - bool TerminateIfFilteredSumExceedsThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredSumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::LessOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == filter.size(), "Vectors sizes mismatch."); - ValueType currentThreshold = storm::utility::vector::sum_if(currentValues, filter); - return strict ? currentThreshold > this->threshold : currentThreshold >= this->threshold; + ValueType sum = storm::utility::zero<ValueType>(); + for (auto pos : filter) { + sum += valueGetter(pos); + // Exiting this loop early is not possible as values might be negative + } + return strict ? sum > this->threshold : sum >= this->threshold; } template<typename ValueType> @@ -42,17 +51,47 @@ namespace storm { template<typename ValueType> TerminateIfFilteredExtremumExceedsThreshold<ValueType>::TerminateIfFilteredExtremumExceedsThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) { // Intentionally left empty. + STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set."); + cachedExtremumIndex = this->filter.getNextSetIndex(0); } template<typename ValueType> - bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredExtremumExceedsThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::LessOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == this->filter.size(), "Vectors sizes mismatch."); - ValueType currentValue = useMinimum ? storm::utility::vector::min_if(currentValues, this->filter) : storm::utility::vector::max_if(currentValues, this->filter); - return this->strict ? currentValue > this->threshold : currentValue >= this->threshold; + ValueType extremum = valueGetter(cachedExtremumIndex); + if (useMinimum && (this->strict ? extremum <= this->threshold : extremum < this->threshold)) { + // The extremum can only become smaller so we can return right now. + return false; + } + + if (useMinimum) { + if (this->strict) { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + if (extremum <= this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + if (extremum < this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + } + } + + return this->strict ? extremum > this->threshold : extremum >= this->threshold; } template<typename ValueType> @@ -62,18 +101,47 @@ namespace storm { template<typename ValueType> TerminateIfFilteredExtremumBelowThreshold<ValueType>::TerminateIfFilteredExtremumBelowThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum) : TerminateIfFilteredSumExceedsThreshold<ValueType>(filter, threshold, strict), useMinimum(useMinimum) { - // Intentionally left empty. + STORM_LOG_THROW(!this->filter.empty(), storm::exceptions::InvalidArgumentException, "Empty Filter; Can not take extremum over empty set."); + cachedExtremumIndex = this->filter.getNextSetIndex(0); } template<typename ValueType> - bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee) const { + bool TerminateIfFilteredExtremumBelowThreshold<ValueType>::terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee) const { if (guarantee != SolverGuarantee::GreaterOrEqual) { return false; } - STORM_LOG_ASSERT(currentValues.size() == this->filter.size(), "Vectors sizes mismatch."); - ValueType currentValue = useMinimum ? storm::utility::vector::min_if(currentValues, this->filter) : storm::utility::vector::max_if(currentValues, this->filter); - return this->strict ? currentValue < this->threshold : currentValue <= this->threshold; + ValueType extremum = valueGetter(cachedExtremumIndex); + if (!useMinimum && (this->strict ? extremum >= this->threshold : extremum > this->threshold)) { + // The extremum can only become larger so we can return right now. + return false; + } + + if (useMinimum) { + for (auto const& pos : this->filter) { + extremum = std::min(valueGetter(pos), extremum); + } + } else { + if (this->strict) { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + if (extremum >= this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } else { + for (auto const& pos : this->filter) { + extremum = std::max(valueGetter(pos), extremum); + if (extremum > this->threshold) { + cachedExtremumIndex = pos; + return false; + } + } + } + } + + return this->strict ? extremum < this->threshold : extremum <= this->threshold; } template<typename ValueType> @@ -81,10 +149,14 @@ namespace storm { return guarantee == SolverGuarantee::GreaterOrEqual; } + template class TerminationCondition<double>; + template class NoTerminationCondition<double>; template class TerminateIfFilteredSumExceedsThreshold<double>; template class TerminateIfFilteredExtremumExceedsThreshold<double>; template class TerminateIfFilteredExtremumBelowThreshold<double>; #ifdef STORM_HAVE_CARL + template class TerminationCondition<storm::RationalNumber>; + template class NoTerminationCondition<storm::RationalNumber>; template class TerminateIfFilteredSumExceedsThreshold<storm::RationalNumber>; template class TerminateIfFilteredExtremumExceedsThreshold<storm::RationalNumber>; template class TerminateIfFilteredExtremumBelowThreshold<storm::RationalNumber>; diff --git a/src/storm/solver/TerminationCondition.h b/src/storm/solver/TerminationCondition.h index a8e21697e..98402d1af 100644 --- a/src/storm/solver/TerminationCondition.h +++ b/src/storm/solver/TerminationCondition.h @@ -1,6 +1,6 @@ #pragma once -#include <vector> +#include <functional> #include "storm/solver/SolverGuarantee.h" #include "storm/storage/BitVector.h" @@ -15,7 +15,8 @@ namespace storm { /*! * Retrieves whether the guarantee provided by the solver for the current result is sufficient to terminate. */ - virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const = 0; + virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const; + virtual bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const = 0; /*! * Retrieves whether the termination criterion requires the given guarantee in order to decide termination. @@ -27,7 +28,7 @@ namespace storm { template<typename ValueType> class NoTerminationCondition : public TerminationCondition<ValueType> { public: - virtual bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + virtual bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; }; @@ -36,7 +37,7 @@ namespace storm { public: TerminateIfFilteredSumExceedsThreshold(storm::storage::BitVector const& filter, ValueType const& threshold, bool strict); - bool terminateNow(std::vector<ValueType> const& currentValues, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: @@ -50,11 +51,12 @@ namespace storm { public: TerminateIfFilteredExtremumExceedsThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum); - bool terminateNow(std::vector<ValueType> const& currentValue, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: bool useMinimum; + mutable uint64_t cachedExtremumIndex; }; template<typename ValueType> @@ -62,11 +64,12 @@ namespace storm { public: TerminateIfFilteredExtremumBelowThreshold(storm::storage::BitVector const& filter, bool strict, ValueType const& threshold, bool useMinimum); - bool terminateNow(std::vector<ValueType> const& currentValue, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; + bool terminateNow(std::function<ValueType(uint64_t const&)> const& valueGetter, SolverGuarantee const& guarantee = SolverGuarantee::None) const override; virtual bool requiresGuarantee(SolverGuarantee const& guarantee) const override; protected: bool useMinimum; + mutable uint64_t cachedExtremumIndex; }; } } diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp new file mode 100644 index 000000000..f31d1cde3 --- /dev/null +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.cpp @@ -0,0 +1,466 @@ +#include "storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h" + +#include "storm/utility/vector.h" +#include "storm/utility/graph.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" +#include "storm/exceptions/IllegalArgumentException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidEnvironmentException.h" + +#include "storm/environment/solver/MinMaxSolverEnvironment.h" + +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" + +#include "storm/utility/macros.h" +#include "storm-config.h" +#ifdef STORM_HAVE_CUDA +# include "cudaForStorm.h" +#endif + +namespace storm { + namespace solver { + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::TopologicalCudaMinMaxLinearEquationSolver() { + // Get the settings object to customize solving. + this->enableCuda = storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseCudaSet(); +#ifdef STORM_HAVE_CUDA + STORM_LOG_INFO_COND(this->enableCuda, "Option CUDA was not set, but the topological value iteration solver will use it anyways."); +#endif + } + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::TopologicalCudaMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : TopologicalCudaMinMaxLinearEquationSolver() { + this->setMatrix(A); + } + + template<typename ValueType> + void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { + this->localA = nullptr; + this->A = &matrix; + } + + template<typename ValueType> + void TopologicalCudaMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { + this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); + this->A = this->localA.get(); + } + + template<typename ValueType> + bool TopologicalCudaMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::TopologicalCuda, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); + + ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); + uint64_t maxIters = env.solver().minMax().getMaximalNumberOfIterations(); + bool relative = env.solver().minMax().getMaximalNumberOfIterations(); + +#ifdef GPU_USE_FLOAT +#define __FORCE_FLOAT_CALCULATION true +#else +#define __FORCE_FLOAT_CALCULATION false +#endif + if (__FORCE_FLOAT_CALCULATION && std::is_same<ValueType, double>::value) { + // FIXME: This actually allocates quite some storage, because of this conversion, is it really necessary? + storm::storage::SparseMatrix<float> newA = this->A->template toValueType<float>(); + + TopologicalCudaMinMaxLinearEquationSolver<float> newSolver(newA); + + std::vector<float> new_x = storm::utility::vector::toValueType<float>(x); + std::vector<float> const new_b = storm::utility::vector::toValueType<float>(b); + + bool callConverged = newSolver.solveEquations(env, dir, new_x, new_b); + + for (size_t i = 0, size = new_x.size(); i < size; ++i) { + x.at(i) = new_x.at(i); + } + return callConverged; + } + + // For testing only + if (sizeof(ValueType) == sizeof(double)) { + //std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl; + STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>"); + } else { + //std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl; + STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>"); + } + + // Now, we need to determine the SCCs of the MDP and perform a topological sort. + std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->A->getRowGroupIndices(); + + // Check if the decomposition is necessary +#ifdef STORM_HAVE_CUDA +#define __USE_CUDAFORSTORM_OPT true + size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(A->getRowCount()), nondeterministicChoiceIndices.size(), static_cast<size_t>(A->getEntryCount())); + size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); +#else +#define __USE_CUDAFORSTORM_OPT false + size_t const gpuSizeOfCompleteSystem = 0; + size_t const cudaFreeMemory = 0; +#endif + std::vector<std::pair<bool, storm::storage::StateBlock>> sccDecomposition; + if (__USE_CUDAFORSTORM_OPT && (gpuSizeOfCompleteSystem < cudaFreeMemory)) { + // Dummy output for SCC Times + //std::cout << "Computing the SCC Decomposition took 0ms" << std::endl; + +#ifdef STORM_HAVE_CUDA + STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA Equation Solver."); + + bool result = false; + size_t globalIterations = 0; + if (dir == OptimizationDirection::Minimize) { + result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); + } else { + result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); + } + STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + + bool converged = false; + if (!result) { + converged = false; + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); + throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; + } else { + converged = true; + } + + // Check if the solver converged and issue a warning otherwise. + if (converged) { + STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations."); + } else { + STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations."); + } +#else + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); + throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; +#endif + } else { + storm::storage::BitVector fullSystem(this->A->getRowGroupCount(), true); + storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(*this->A, fullSystem, false, false); + + STORM_LOG_THROW(sccDecomposition.size() > 0, storm::exceptions::IllegalArgumentException, "Can not solve given equation system as the SCC decomposition returned no SCCs."); + + storm::storage::SparseMatrix<ValueType> stronglyConnectedComponentsDependencyGraph = sccDecomposition.extractPartitionDependencyGraph(*this->A); + std::vector<uint_fast64_t> topologicalSort = storm::utility::graph::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); + + // Calculate the optimal distribution of sccs + std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, *this->A); + STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); + + std::vector<ValueType>* currentX = nullptr; + std::vector<ValueType>* swap = nullptr; + size_t currentMaxLocalIterations = 0; + size_t localIterations = 0; + size_t globalIterations = 0; + bool converged = true; + + // Iterate over all SCCs of the MDP as specified by the topological sort. This guarantees that an SCC is only + // solved after all SCCs it depends on have been solved. + for (auto sccIndexIt = optimalSccs.cbegin(); sccIndexIt != optimalSccs.cend() && converged; ++sccIndexIt) { + bool const useGpu = sccIndexIt->first; + storm::storage::StateBlock const& scc = sccIndexIt->second; + + // Generate a sub matrix + storm::storage::BitVector subMatrixIndices(this->A->getColumnCount(), scc.cbegin(), scc.cend()); + storm::storage::SparseMatrix<ValueType> sccSubmatrix = this->A->getSubmatrix(true, subMatrixIndices, subMatrixIndices); + std::vector<ValueType> sccSubB(sccSubmatrix.getRowCount()); + storm::utility::vector::selectVectorValues<ValueType>(sccSubB, subMatrixIndices, nondeterministicChoiceIndices, b); + std::vector<ValueType> sccSubX(sccSubmatrix.getColumnCount()); + std::vector<ValueType> sccSubXSwap(sccSubmatrix.getColumnCount()); + std::vector<ValueType> sccMultiplyResult(sccSubmatrix.getRowCount()); + + // Prepare the pointers for swapping in the calculation + currentX = &sccSubX; + swap = &sccSubXSwap; + + storm::utility::vector::selectVectorValues<ValueType>(sccSubX, subMatrixIndices, x); // x is getCols() large, where as b and multiplyResult are getRows() (nondet. choices times states) + std::vector<uint_fast64_t> sccSubNondeterministicChoiceIndices(sccSubmatrix.getColumnCount() + 1); + sccSubNondeterministicChoiceIndices.at(0) = 0; + + // Pre-process all dependent states + // Remove outgoing transitions and create the ChoiceIndices + uint_fast64_t innerIndex = 0; + uint_fast64_t outerIndex = 0; + for (uint_fast64_t state : scc) { + // Choice Indices + sccSubNondeterministicChoiceIndices.at(outerIndex + 1) = sccSubNondeterministicChoiceIndices.at(outerIndex) + (nondeterministicChoiceIndices[state + 1] - nondeterministicChoiceIndices[state]); + + for (auto rowGroupIt = nondeterministicChoiceIndices[state]; rowGroupIt != nondeterministicChoiceIndices[state + 1]; ++rowGroupIt) { + typename storm::storage::SparseMatrix<ValueType>::const_rows row = this->A->getRow(rowGroupIt); + for (auto rowIt = row.begin(); rowIt != row.end(); ++rowIt) { + if (!subMatrixIndices.get(rowIt->getColumn())) { + // This is an outgoing transition of a state in the SCC to a state not included in the SCC + // Subtracting Pr(tau) * x_other from b fixes that + sccSubB.at(innerIndex) = sccSubB.at(innerIndex) + (rowIt->getValue() * x.at(rowIt->getColumn())); + } + } + ++innerIndex; + } + ++outerIndex; + } + + // For the current SCC, we need to perform value iteration until convergence. + if (useGpu) { +#ifdef STORM_HAVE_CUDA + STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver."); + + //STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); + //STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); + //STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion()); + + bool result = false; + localIterations = 0; + if (dir == OptimizationDirection::Minimum) { + result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); + } else { + result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); + } + STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); + + if (!result) { + converged = false; + STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); + throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; + } else { + converged = true; + } + + // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep + // track of the maximum. + if (localIterations > currentMaxLocalIterations) { + currentMaxLocalIterations = localIterations; + } + globalIterations += localIterations; +#else + STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); + throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; +#endif + } else { + //std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl; + STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)"); + localIterations = 0; + converged = false; + while (!converged && localIterations < maxIters) { + // Compute x' = A*x + b. + sccSubmatrix.multiplyWithVector(*currentX, sccMultiplyResult); + storm::utility::vector::addVectors<ValueType>(sccMultiplyResult, sccSubB, sccMultiplyResult); + + //A.multiplyWithVector(scc, nondeterministicChoiceIndices, *currentX, multiplyResult); + //storm::utility::addVectors(scc, nondeterministicChoiceIndices, multiplyResult, b); + + /* + Versus: + A.multiplyWithVector(*currentX, *multiplyResult); + storm::utility::vector::addVectorsInPlace(*multiplyResult, b); + */ + + // Reduce the vector x' by applying min/max for all non-deterministic choices. + storm::utility::vector::reduceVectorMinOrMax<ValueType>(dir,sccMultiplyResult, *swap, sccSubNondeterministicChoiceIndices); + + // Determine whether the method converged. + // TODO: It seems that the equalModuloPrecision call that compares all values should have a higher + // running time. In fact, it is faster. This has to be investigated. + // converged = storm::utility::equalModuloPrecision(*currentX, *newX, scc, precision, relative); + converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *swap, precision, relative); + + // Update environment variables. + std::swap(currentX, swap); + + ++localIterations; + ++globalIterations; + } + STORM_LOG_INFO("Executed " << localIterations << " of max. " << maxIters << " Iterations."); + } + + + // The Result of this SCC has to be taken back into the main result vector + innerIndex = 0; + for (uint_fast64_t state : scc) { + x.at(state) = currentX->at(innerIndex); + ++innerIndex; + } + + // Since the pointers for swapping in the calculation point to temps they should not be valid anymore + currentX = nullptr; + swap = nullptr; + + // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep + // track of the maximum. + if (localIterations > currentMaxLocalIterations) { + currentMaxLocalIterations = localIterations; + } + } + + //std::cout << "Used a total of " << globalIterations << " iterations with a maximum of " << localIterations << " iterations in a single block." << std::endl; + + // Check if the solver converged and issue a warning otherwise. + if (converged) { + STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations."); + } else { + STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); + } + + return converged; + } + } + + template<typename ValueType> + std::vector<std::pair<bool, storm::storage::StateBlock>> + TopologicalCudaMinMaxLinearEquationSolver<ValueType>::getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const { + + (void)matrix; + + std::vector<std::pair<bool, storm::storage::StateBlock>> result; + +#ifdef STORM_HAVE_CUDA + // 95% to have a bit of padding + size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); + size_t lastResultIndex = 0; + + std::vector<uint_fast64_t> const& rowGroupIndices = matrix.getRowGroupIndices(); + + size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(matrix.getRowCount()), rowGroupIndices.size(), static_cast<size_t>(matrix.getEntryCount())); + size_t const gpuSizePerRowGroup = std::max(static_cast<size_t>(gpuSizeOfCompleteSystem / rowGroupIndices.size()), static_cast<size_t>(1)); + size_t const maxRowGroupsPerMemory = cudaFreeMemory / gpuSizePerRowGroup; + + size_t currentSize = 0; + size_t neededReserveSize = 0; + size_t startIndex = 0; + for (size_t i = 0; i < topologicalSort.size(); ++i) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[i]]; + size_t const currentSccSize = scc.size(); + + uint_fast64_t rowCount = 0; + uint_fast64_t entryCount = 0; + + for (auto sccIt = scc.cbegin(); sccIt != scc.cend(); ++sccIt) { + rowCount += matrix.getRowGroupSize(*sccIt); + entryCount += matrix.getRowGroupEntryCount(*sccIt); + } + + size_t sccSize = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(rowCount), scc.size(), static_cast<size_t>(entryCount)); + + if ((currentSize + sccSize) <= cudaFreeMemory) { + // There is enough space left in the current group + neededReserveSize += currentSccSize; + currentSize += sccSize; + } else { + // This would make the last open group to big for the GPU + + if (startIndex < i) { + if ((startIndex + 1) < i) { + // More than one component + std::vector<uint_fast64_t> tempGroups; + tempGroups.reserve(neededReserveSize); + + // Copy the first group to make inplace_merge possible + storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; + tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); + + if (((startIndex + 1) + 80) >= i) { + size_t lastSize = 0; + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + lastSize = tempGroups.size(); + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); + std::advance(middleIterator, lastSize); + std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); + } + } else { + // Use std::sort + for (size_t j = startIndex + 1; j < i; ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + } + std::sort(tempGroups.begin(), tempGroups.end()); + } + result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); + } else { + // Only one group, copy construct. + result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); + } + ++lastResultIndex; + } + + if (sccSize <= cudaFreeMemory) { + currentSize = sccSize; + neededReserveSize = currentSccSize; + startIndex = i; + } else { + // This group is too big to fit into the CUDA Memory by itself + result.push_back(std::make_pair(false, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[i]])))); + ++lastResultIndex; + + currentSize = 0; + neededReserveSize = 0; + startIndex = i + 1; + } + } + } + + size_t const topologicalSortSize = topologicalSort.size(); + if (startIndex < topologicalSortSize) { + if ((startIndex + 1) < topologicalSortSize) { + // More than one component + std::vector<uint_fast64_t> tempGroups; + tempGroups.reserve(neededReserveSize); + + // Copy the first group to make inplace_merge possible. + storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; + tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); + + // For set counts <= 80, in-place merge is faster. + if (((startIndex + 1) + 80) >= topologicalSortSize) { + size_t lastSize = 0; + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + lastSize = tempGroups.size(); + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); + std::advance(middleIterator, lastSize); + std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); + } + } else { + // Use std::sort + for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { + storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; + tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); + } + std::sort(tempGroups.begin(), tempGroups.end()); + } + result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); + } + else { + // Only one group, copy construct. + result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); + } + ++lastResultIndex; + } +#else + for (auto sccIndexIt = topologicalSort.cbegin(); sccIndexIt != topologicalSort.cend(); ++sccIndexIt) { + storm::storage::StateBlock const& scc = sccDecomposition[*sccIndexIt]; + result.push_back(std::make_pair(false, scc)); + } +#endif + return result; + } + + template<typename ValueType> + TopologicalCudaMinMaxLinearEquationSolverFactory<ValueType>::TopologicalCudaMinMaxLinearEquationSolverFactory(bool trackScheduler) { + // Intentionally left empty. + } + + template<typename ValueType> + std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> TopologicalCudaMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { + STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); + return std::make_unique<TopologicalCudaMinMaxLinearEquationSolver<ValueType>>(); + } + + // Explicitly instantiate the solver. + template class TopologicalCudaMinMaxLinearEquationSolver<double>; + + template class TopologicalCudaMinMaxLinearEquationSolverFactory<double>; + } // namespace solver +} // namespace storm diff --git a/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h new file mode 100644 index 000000000..7005d9d8f --- /dev/null +++ b/src/storm/solver/TopologicalCudaMinMaxLinearEquationSolver.h @@ -0,0 +1,152 @@ +#ifndef STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ +#define STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ + +#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" +#include "storm/storage/SparseMatrix.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/NotSupportedException.h" + +#include <utility> +#include <vector> + +#include "storm-config.h" +#ifdef STORM_HAVE_CUDA +#include "cudaForStorm.h" +#endif + +namespace storm { + namespace solver { + + /*! + * A class that uses SCC Decompositions to solve a min/max linear equation system. + */ + template<class ValueType> + class TopologicalCudaMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { + public: + TopologicalCudaMinMaxLinearEquationSolver(); + + /*! + * Constructs a min-max linear equation solver with parameters being set according to the settings + * object. + * + * @param A The matrix defining the coefficients of the linear equation system. + */ + TopologicalCudaMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + + virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; + virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; + + virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; + + private: + storm::storage::SparseMatrix<ValueType> const* A; + std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; + + bool enableCuda; + /*! + * Given a topological sort of a SCC Decomposition, this will calculate the optimal grouping of SCCs with respect to the size of the GPU memory. + */ + std::vector<std::pair<bool, storm::storage::StateBlock>> getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const; + }; + + template <typename IndexType, typename ValueType> + bool __basicValueIteration_mvReduce_minimize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>& x, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { + // + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); + } + template <> + inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_double_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + template <> + inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_float_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + + template <typename IndexType, typename ValueType> + bool __basicValueIteration_mvReduce_maximize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>&, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { + STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); + } + template <> + inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_double_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + template <> + inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + + (void)maxIterationCount; + (void)precision; + (void)relativePrecisionCheck; + (void)matrixRowIndices; + (void)columnIndicesAndValues; + (void)x; + (void)b; + (void)nondeterministicChoiceIndices; + (void)iterationCount; + +#ifdef STORM_HAVE_CUDA + return basicValueIteration_mvReduce_uint64_float_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); +#else + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); +#endif + } + + template<typename ValueType> + class TopologicalCudaMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { + public: + TopologicalCudaMinMaxLinearEquationSolverFactory(bool trackScheduler = false); + + protected: + virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; + }; + + } // namespace solver +} // namespace storm + +#endif /* STORM_SOLVER_TOPOLOGICALCUDAMINMAXLINEAREQUATIONSOLVER_H_ */ diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp new file mode 100644 index 000000000..7568f3c65 --- /dev/null +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -0,0 +1,264 @@ +#include "storm/solver/TopologicalLinearEquationSolver.h" + +#include "storm/environment/solver/TopologicalSolverEnvironment.h" + +#include "storm/utility/constants.h" +#include "storm/utility/vector.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" + +namespace storm { + namespace solver { + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver() : localA(nullptr), A(nullptr) { + // Intentionally left empty. + } + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : localA(nullptr), A(nullptr) { + this->setMatrix(A); + } + + template<typename ValueType> + TopologicalLinearEquationSolver<ValueType>::TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : localA(nullptr), A(nullptr) { + this->setMatrix(std::move(A)); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& A) { + localA.reset(); + this->A = &A; + clearCache(); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& A) { + localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(A)); + this->A = localA.get(); + clearCache(); + } + + template<typename ValueType> + storm::Environment TopologicalLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision) const { + storm::Environment subEnv(env); + subEnv.solver().setLinearEquationSolverType(env.solver().topological().getUnderlyingEquationSolverType(), env.solver().topological().isUnderlyingEquationSolverTypeSetFromDefault()); + if (adaptPrecision) { + STORM_LOG_ASSERT(this->longestSccChainSize, "Did not compute the longest SCC chain size although it is needed."); + auto subEnvPrec = subEnv.solver().getPrecisionOfLinearEquationSolver(subEnv.solver().getLinearEquationSolverType()); + subEnv.solver().setLinearEquationSolverPrecision(static_cast<storm::RationalNumber>(subEnvPrec.first.get() / storm::utility::convertNumber<storm::RationalNumber>(this->longestSccChainSize.get()))); + } + return subEnv; + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + + // For sound computations we need to increase the precision in each SCC + bool needAdaptPrecision = env.solver().isForceSoundness() && env.solver().getPrecisionOfLinearEquationSolver(env.solver().topological().getUnderlyingEquationSolverType()).first.is_initialized(); + + if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) { + STORM_LOG_TRACE("Creating SCC decomposition."); + createSortedSccDecomposition(needAdaptPrecision); + } + + // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) + needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->getMatrixRowCount()); + + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); + + STORM_LOG_INFO("Found " << this->sortedSccDecomposition->size() << "SCCs. Average size is " << static_cast<double>(this->getMatrixRowCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "."); + if (this->longestSccChainSize) { + STORM_LOG_INFO("Longest SCC chain size is " << this->longestSccChainSize.get() << "."); + } + + // Handle the case where there is just one large SCC + bool returnValue = true; + if (this->sortedSccDecomposition->size() == 1) { + returnValue = solveFullyConnectedEquationSystem(sccSolverEnvironment, x, b); + } else { + storm::storage::BitVector sccAsBitVector(x.size(), false); + for (auto const& scc : *this->sortedSccDecomposition) { + if (scc.isTrivial()) { + returnValue = solveTrivialScc(*scc.begin(), x, b) && returnValue; + } else { + sccAsBitVector.clear(); + for (auto const& state : scc) { + sccAsBitVector.set(state, true); + } + returnValue = solveScc(sccSolverEnvironment, sccAsBitVector, x, b) && returnValue; + } + } + } + + if (!this->isCachingEnabled()) { + clearCache(); + } + + + + + return returnValue; + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { + // Obtain the scc decomposition + this->sortedSccDecomposition = std::make_unique<storm::storage::StronglyConnectedComponentDecomposition<ValueType>>(*this->A); + if (needLongestChainSize) { + this->longestSccChainSize = 0; + this->sortedSccDecomposition->sortTopologically(*this->A, &(this->longestSccChainSize.get())); + } else { + this->sortedSccDecomposition->sortTopologically(*this->A); + } + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveTrivialScc(uint64_t const& sccState, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + ValueType& xi = globalX[sccState]; + xi = globalB[sccState]; + bool hasDiagonalEntry = false; + ValueType denominator; + for (auto const& entry : this->A->getRow(sccState)) { + if (entry.getColumn() == sccState) { + STORM_LOG_ASSERT(!storm::utility::isOne(entry.getValue()), "Diagonal entry of fix point system has value 1."); + hasDiagonalEntry = true; + denominator = storm::utility::one<ValueType>() - entry.getValue(); + } else { + xi += entry.getValue() * globalX[entry.getColumn()]; + } + } + + if (hasDiagonalEntry) { + xi /= denominator; + } + return true; + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + if (!this->sccSolver) { + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + this->sccSolver->setBoundsFromOtherSolver(*this); + if (this->sccSolver->getEquationProblemFormat(sccSolverEnvironment) == LinearEquationSolverProblemFormat::EquationSystem) { + // Convert the matrix to an equation system. Note that we need to insert diagonal entries. + storm::storage::SparseMatrix<ValueType> eqSysA(*this->A, true); + eqSysA.convertToEquationSystem(); + this->sccSolver->setMatrix(std::move(eqSysA)); + } else { + this->sccSolver->setMatrix(*this->A); + } + } + return this->sccSolver->solveEquations(sccSolverEnvironment, x, b); + } + + template<typename ValueType> + bool TopologicalLinearEquationSolver<ValueType>::solveScc(storm::Environment const& sccSolverEnvironment, storm::storage::BitVector const& scc, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + + // Set up the SCC solver + if (!this->sccSolver) { + this->sccSolver = GeneralLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + + // Matrix + bool asEquationSystem = this->sccSolver->getEquationProblemFormat(sccSolverEnvironment) == LinearEquationSolverProblemFormat::EquationSystem; + storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, scc, scc, asEquationSystem); + if (asEquationSystem) { + sccA.convertToEquationSystem(); + } + //std::cout << "Solving SCC " << scc << std::endl; + //std::cout << "Matrix is " << sccA << std::endl; + this->sccSolver->setMatrix(std::move(sccA)); + + // x Vector + auto sccX = storm::utility::vector::filterVector(globalX, scc); + + // b Vector + std::vector<ValueType> sccB; + sccB.reserve(scc.getNumberOfSetBits()); + for (auto const& row : scc) { + ValueType bi = globalB[row]; + for (auto const& entry : this->A->getRow(row)) { + if (!scc.get(entry.getColumn())) { + bi += entry.getValue() * globalX[entry.getColumn()]; + } + } + sccB.push_back(std::move(bi)); + } + + // lower/upper bounds + if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setLowerBound(this->getLowerBound()); + } else if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setLowerBounds(storm::utility::vector::filterVector(this->getLowerBounds(), scc)); + } + if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setUpperBound(this->getUpperBound()); + } else if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), scc)); + } + + //std::cout << "rhs is " << storm::utility::vector::toString(sccB) << std::endl; + //std::cout << "x is " << storm::utility::vector::toString(sccX) << std::endl; + + bool returnvalue = this->sccSolver->solveEquations(sccSolverEnvironment, sccX, sccB); + storm::utility::vector::setVectorValues(globalX, scc, sccX); + return returnvalue; + } + + template<typename ValueType> + LinearEquationSolverProblemFormat TopologicalLinearEquationSolver<ValueType>::getEquationProblemFormat(Environment const& env) const { + return LinearEquationSolverProblemFormat::FixedPointSystem; + } + + template<typename ValueType> + LinearEquationSolverRequirements TopologicalLinearEquationSolver<ValueType>::getRequirements(Environment const& env) const { + // Return the requirements of the underlying solver + return GeneralLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env)); + } + + template<typename ValueType> + void TopologicalLinearEquationSolver<ValueType>::clearCache() const { + sortedSccDecomposition.reset(); + longestSccChainSize = boost::none; + sccSolver.reset(); + LinearEquationSolver<ValueType>::clearCache(); + } + + template<typename ValueType> + uint64_t TopologicalLinearEquationSolver<ValueType>::getMatrixRowCount() const { + return this->A->getRowCount(); + } + + template<typename ValueType> + uint64_t TopologicalLinearEquationSolver<ValueType>::getMatrixColumnCount() const { + return this->A->getColumnCount(); + } + + template<typename ValueType> + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { + return std::make_unique<storm::solver::TopologicalLinearEquationSolver<ValueType>>(); + } + + template<typename ValueType> + std::unique_ptr<LinearEquationSolverFactory<ValueType>> TopologicalLinearEquationSolverFactory<ValueType>::clone() const { + return std::make_unique<TopologicalLinearEquationSolverFactory<ValueType>>(*this); + } + + // Explicitly instantiate the linear equation solver. + template class TopologicalLinearEquationSolver<double>; + template class TopologicalLinearEquationSolverFactory<double>; + +#ifdef STORM_HAVE_CARL + template class TopologicalLinearEquationSolver<storm::RationalNumber>; + template class TopologicalLinearEquationSolverFactory<storm::RationalNumber>; + + template class TopologicalLinearEquationSolver<storm::RationalFunction>; + template class TopologicalLinearEquationSolverFactory<storm::RationalFunction>; + +#endif + } +} diff --git a/src/storm/solver/TopologicalLinearEquationSolver.h b/src/storm/solver/TopologicalLinearEquationSolver.h new file mode 100644 index 000000000..4c754c44e --- /dev/null +++ b/src/storm/solver/TopologicalLinearEquationSolver.h @@ -0,0 +1,76 @@ +#pragma once + +#include "storm/solver/LinearEquationSolver.h" + +#include "storm/solver/SolverSelectionOptions.h" +#include "storm/solver/NativeMultiplier.h" +#include "storm/storage/StronglyConnectedComponentDecomposition.h" + +namespace storm { + + class Environment; + + namespace solver { + + template<typename ValueType> + class TopologicalLinearEquationSolver : public LinearEquationSolver<ValueType> { + public: + TopologicalLinearEquationSolver(); + TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); + TopologicalLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); + + virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& A) override; + virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& A) override; + + virtual LinearEquationSolverProblemFormat getEquationProblemFormat(storm::Environment const& env) const override; + virtual LinearEquationSolverRequirements getRequirements(Environment const& env) const override; + + virtual void clearCache() const override; + + protected: + virtual bool internalSolveEquations(storm::Environment const& env, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; + + private: + + virtual uint64_t getMatrixRowCount() const override; + virtual uint64_t getMatrixColumnCount() const override; + + storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision = false) const; + + // Creates an SCC decomposition and sorts the SCCs according to a topological sort. + void createSortedSccDecomposition(bool needLongestChainSize) const; + + // Solves the SCC with the given index + // ... for the case that the SCC is trivial + bool solveTrivialScc(uint64_t const& sccState, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + // ... for the case that there is just one large SCC + bool solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + // ... for the remaining cases (1 < scc.size() < x.size()) + bool solveScc(storm::Environment const& sccSolverEnvironment, storm::storage::BitVector const& scc, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + + // If the solver takes posession of the matrix, we store the moved matrix in this member, so it gets deleted + // when the solver is destructed. + std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; + + // A pointer to the original sparse matrix given to this solver. If the solver takes posession of the matrix + // the pointer refers to localA. + storm::storage::SparseMatrix<ValueType> const* A; + + // cached auxiliary data + mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; + mutable boost::optional<uint64_t> longestSccChainSize; + mutable std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> sccSolver; + }; + + template<typename ValueType> + class TopologicalLinearEquationSolverFactory : public LinearEquationSolverFactory<ValueType> { + public: + using LinearEquationSolverFactory<ValueType>::create; + + virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(Environment const& env) const override; + + virtual std::unique_ptr<LinearEquationSolverFactory<ValueType>> clone() const override; + + }; + } +} diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp index 9e33a4c9e..92692b966 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.cpp @@ -1,485 +1,305 @@ #include "storm/solver/TopologicalMinMaxLinearEquationSolver.h" +#include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" + +#include "storm/utility/constants.h" #include "storm/utility/vector.h" -#include "storm/utility/graph.h" -#include "storm/storage/StronglyConnectedComponentDecomposition.h" -#include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/InvalidEnvironmentException.h" +#include "storm/exceptions/UnexpectedException.h" +#include "storm/exceptions/UncheckedRequirementException.h" -#include "storm/environment/solver/MinMaxSolverEnvironment.h" +namespace storm { + namespace solver { -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/CoreSettings.h" + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() { + // Intentionally left empty. + } -#include "storm/utility/macros.h" -#include "storm-config.h" -#ifdef STORM_HAVE_CUDA -# include "cudaForStorm.h" -#endif + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : StandardMinMaxLinearEquationSolver<ValueType>(A) { + // Intentionally left empty. + } -namespace storm { - namespace solver { + template<typename ValueType> + TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A) : StandardMinMaxLinearEquationSolver<ValueType>(std::move(A)) { + // Intentionally left empty. + } template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver() { - // Get the settings object to customize solving. - this->enableCuda = storm::settings::getModule<storm::settings::modules::CoreSettings>().isUseCudaSet(); -#ifdef STORM_HAVE_CUDA - STORM_LOG_INFO_COND(this->enableCuda, "Option CUDA was not set, but the topological value iteration solver will use it anyways."); -#endif + storm::Environment TopologicalMinMaxLinearEquationSolver<ValueType>::getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision) const { + storm::Environment subEnv(env); + subEnv.solver().minMax().setMethod(env.solver().topological().getUnderlyingMinMaxMethod(), env.solver().topological().isUnderlyingMinMaxMethodSetFromDefault()); + if (adaptPrecision) { + STORM_LOG_ASSERT(this->longestSccChainSize, "Did not compute the longest SCC chain size although it is needed."); + storm::RationalNumber subEnvPrec = subEnv.solver().minMax().getPrecision() / storm::utility::convertNumber<storm::RationalNumber>(this->longestSccChainSize.get()); + subEnv.solver().minMax().setPrecision(subEnvPrec); + } + return subEnv; } template<typename ValueType> - TopologicalMinMaxLinearEquationSolver<ValueType>::TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A) : TopologicalMinMaxLinearEquationSolver() { - this->setMatrix(A); + bool TopologicalMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + STORM_LOG_ASSERT(x.size() == this->A->getRowGroupCount(), "Provided x-vector has invalid size."); + STORM_LOG_ASSERT(b.size() == this->A->getRowCount(), "Provided b-vector has invalid size."); + + // For sound computations we need to increase the precision in each SCC + bool needAdaptPrecision = env.solver().isForceSoundness(); + + if (!this->sortedSccDecomposition || (needAdaptPrecision && !this->longestSccChainSize)) { + STORM_LOG_TRACE("Creating SCC decomposition."); + createSortedSccDecomposition(needAdaptPrecision); + } + + // We do not need to adapt the precision if all SCCs are trivial (i.e., the system is acyclic) + needAdaptPrecision = needAdaptPrecision && (this->sortedSccDecomposition->size() != this->A->getRowGroupCount()); + + storm::Environment sccSolverEnvironment = getEnvironmentForUnderlyingSolver(env, needAdaptPrecision); + + STORM_LOG_INFO("Found " << this->sortedSccDecomposition->size() << " SCC(s). Average size is " << static_cast<double>(this->A->getRowGroupCount()) / static_cast<double>(this->sortedSccDecomposition->size()) << "."); + if (this->longestSccChainSize) { + STORM_LOG_INFO("Longest SCC chain size is " << this->longestSccChainSize.get()); + } + + bool returnValue = true; + if (this->sortedSccDecomposition->size() == 1) { + // Handle the case where there is just one large SCC + returnValue = solveFullyConnectedEquationSystem(sccSolverEnvironment, dir, x, b); + } else { + if (this->isTrackSchedulerSet()) { + if (this->schedulerChoices) { + this->schedulerChoices.get().resize(x.size()); + } else { + this->schedulerChoices = std::vector<uint64_t>(x.size()); + } + } + storm::storage::BitVector sccRowGroupsAsBitVector(x.size(), false); + storm::storage::BitVector sccRowsAsBitVector(b.size(), false); + for (auto const& scc : *this->sortedSccDecomposition) { + if (scc.isTrivial()) { + returnValue = solveTrivialScc(*scc.begin(), dir, x, b) && returnValue; + } else { + sccRowGroupsAsBitVector.clear(); + sccRowsAsBitVector.clear(); + for (auto const& group : scc) { + sccRowGroupsAsBitVector.set(group, true); + for (uint64_t row = this->A->getRowGroupIndices()[group]; row < this->A->getRowGroupIndices()[group + 1]; ++row) { + sccRowsAsBitVector.set(row, true); + } + } + returnValue = solveScc(sccSolverEnvironment, dir, sccRowGroupsAsBitVector, sccRowsAsBitVector, x, b) && returnValue; + } + } + + // If requested, we store the scheduler for retrieval. + if (this->isTrackSchedulerSet()) { + if (!auxiliaryRowGroupVector) { + auxiliaryRowGroupVector = std::make_unique<std::vector<ValueType>>(this->A->getRowGroupCount()); + } + this->schedulerChoices = std::vector<uint_fast64_t>(this->A->getRowGroupCount()); + this->A->multiplyAndReduce(dir, this->A->getRowGroupIndices(), x, &b, *auxiliaryRowGroupVector.get(), &this->schedulerChoices.get()); + } + } + + if (!this->isCachingEnabled()) { + clearCache(); + } + + return returnValue; } template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) { - this->localA = nullptr; - this->A = &matrix; + void TopologicalMinMaxLinearEquationSolver<ValueType>::createSortedSccDecomposition(bool needLongestChainSize) const { + // Obtain the scc decomposition + this->sortedSccDecomposition = std::make_unique<storm::storage::StronglyConnectedComponentDecomposition<ValueType>>(*this->A); + if (needLongestChainSize) { + this->longestSccChainSize = 0; + this->sortedSccDecomposition->sortTopologically(*this->A, &(this->longestSccChainSize.get())); + } else { + this->sortedSccDecomposition->sortTopologically(*this->A); + } } template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) { - this->localA = std::make_unique<storm::storage::SparseMatrix<ValueType>>(std::move(matrix)); - this->A = this->localA.get(); + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveTrivialScc(uint64_t const& sccState, OptimizationDirection dir, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { + ValueType& xi = globalX[sccState]; + bool firstRow = true; + uint64_t bestRow; + + for (uint64_t row = this->A->getRowGroupIndices()[sccState]; row < this->A->getRowGroupIndices()[sccState + 1]; ++row) { + ValueType rowValue = globalB[row]; + bool hasDiagonalEntry = false; + ValueType denominator; + for (auto const& entry : this->A->getRow(row)) { + if (entry.getColumn() == sccState) { + STORM_LOG_ASSERT(!storm::utility::isOne(entry.getValue()), "Diagonal entry of fix point system has value 1."); + hasDiagonalEntry = true; + denominator = storm::utility::one<ValueType>() - entry.getValue(); + } else { + rowValue += entry.getValue() * globalX[entry.getColumn()]; + } + } + if (hasDiagonalEntry) { + rowValue /= denominator; + } + if (firstRow) { + xi = std::move(rowValue); + bestRow = row; + firstRow = false; + } else { + if (minimize(dir)) { + if (rowValue < xi) { + xi = std::move(rowValue); + bestRow = row; + } + } else { + if (rowValue > xi) { + xi = std::move(rowValue); + bestRow = row; + } + } + } + } + if (this->isTrackSchedulerSet()) { + this->schedulerChoices.get()[sccState] = bestRow - this->A->getRowGroupIndices()[sccState]; + } + //std::cout << "Solved trivial scc " << sccState << " with result " << globalX[sccState] << std::endl; + return true; } template<typename ValueType> - bool TopologicalMinMaxLinearEquationSolver<ValueType>::internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - - ValueType precision = storm::utility::convertNumber<ValueType>(env.solver().minMax().getPrecision()); - uint64_t maxIters = env.solver().minMax().getMaximalNumberOfIterations(); - bool relative = env.solver().minMax().getMaximalNumberOfIterations(); - -#ifdef GPU_USE_FLOAT -#define __FORCE_FLOAT_CALCULATION true -#else -#define __FORCE_FLOAT_CALCULATION false -#endif - if (__FORCE_FLOAT_CALCULATION && std::is_same<ValueType, double>::value) { - // FIXME: This actually allocates quite some storage, because of this conversion, is it really necessary? - storm::storage::SparseMatrix<float> newA = this->A->template toValueType<float>(); - - TopologicalMinMaxLinearEquationSolver<float> newSolver(newA); - - std::vector<float> new_x = storm::utility::vector::toValueType<float>(x); - std::vector<float> const new_b = storm::utility::vector::toValueType<float>(b); - - bool callConverged = newSolver.solveEquations(env, dir, new_x, new_b); - - for (size_t i = 0, size = new_x.size(); i < size; ++i) { - x.at(i) = new_x.at(i); - } - return callConverged; - } - - // For testing only - if (sizeof(ValueType) == sizeof(double)) { - //std::cout << "<<< Using CUDA-DOUBLE Kernels >>>" << std::endl; - STORM_LOG_INFO("<<< Using CUDA-DOUBLE Kernels >>>"); - } else { - //std::cout << "<<< Using CUDA-FLOAT Kernels >>>" << std::endl; - STORM_LOG_INFO("<<< Using CUDA-FLOAT Kernels >>>"); - } - - // Now, we need to determine the SCCs of the MDP and perform a topological sort. - std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = this->A->getRowGroupIndices(); - - // Check if the decomposition is necessary -#ifdef STORM_HAVE_CUDA -#define __USE_CUDAFORSTORM_OPT true - size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(A->getRowCount()), nondeterministicChoiceIndices.size(), static_cast<size_t>(A->getEntryCount())); - size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); -#else -#define __USE_CUDAFORSTORM_OPT false - size_t const gpuSizeOfCompleteSystem = 0; - size_t const cudaFreeMemory = 0; -#endif - std::vector<std::pair<bool, storm::storage::StateBlock>> sccDecomposition; - if (__USE_CUDAFORSTORM_OPT && (gpuSizeOfCompleteSystem < cudaFreeMemory)) { - // Dummy output for SCC Times - //std::cout << "Computing the SCC Decomposition took 0ms" << std::endl; - -#ifdef STORM_HAVE_CUDA - STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA Equation Solver."); - - bool result = false; - size_t globalIterations = 0; - if (dir == OptimizationDirection::Minimize) { - result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); - } else { - result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, A->rowIndications, A->columnsAndValues, x, b, nondeterministicChoiceIndices, globalIterations); - } - STORM_LOG_INFO("Executed " << globalIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); - - bool converged = false; - if (!result) { - converged = false; - STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); - throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; - } else { - converged = true; - } - - // Check if the solver converged and issue a warning otherwise. - if (converged) { - STORM_LOG_INFO("Iterative solver converged after " << globalIterations << " iterations."); - } else { - STORM_LOG_WARN("Iterative solver did not converged after " << globalIterations << " iterations."); - } -#else - STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); - throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; -#endif - } else { - storm::storage::BitVector fullSystem(this->A->getRowGroupCount(), true); - storm::storage::StronglyConnectedComponentDecomposition<ValueType> sccDecomposition(*this->A, fullSystem, false, false); - - STORM_LOG_THROW(sccDecomposition.size() > 0, storm::exceptions::IllegalArgumentException, "Can not solve given equation system as the SCC decomposition returned no SCCs."); - - storm::storage::SparseMatrix<ValueType> stronglyConnectedComponentsDependencyGraph = sccDecomposition.extractPartitionDependencyGraph(*this->A); - std::vector<uint_fast64_t> topologicalSort = storm::utility::graph::getTopologicalSort(stronglyConnectedComponentsDependencyGraph); - - // Calculate the optimal distribution of sccs - std::vector<std::pair<bool, storm::storage::StateBlock>> optimalSccs = this->getOptimalGroupingFromTopologicalSccDecomposition(sccDecomposition, topologicalSort, *this->A); - STORM_LOG_INFO("Optimized SCC Decomposition, originally " << topologicalSort.size() << " SCCs, optimized to " << optimalSccs.size() << " SCCs."); - - std::vector<ValueType>* currentX = nullptr; - std::vector<ValueType>* swap = nullptr; - size_t currentMaxLocalIterations = 0; - size_t localIterations = 0; - size_t globalIterations = 0; - bool converged = true; - - // Iterate over all SCCs of the MDP as specified by the topological sort. This guarantees that an SCC is only - // solved after all SCCs it depends on have been solved. - for (auto sccIndexIt = optimalSccs.cbegin(); sccIndexIt != optimalSccs.cend() && converged; ++sccIndexIt) { - bool const useGpu = sccIndexIt->first; - storm::storage::StateBlock const& scc = sccIndexIt->second; - - // Generate a sub matrix - storm::storage::BitVector subMatrixIndices(this->A->getColumnCount(), scc.cbegin(), scc.cend()); - storm::storage::SparseMatrix<ValueType> sccSubmatrix = this->A->getSubmatrix(true, subMatrixIndices, subMatrixIndices); - std::vector<ValueType> sccSubB(sccSubmatrix.getRowCount()); - storm::utility::vector::selectVectorValues<ValueType>(sccSubB, subMatrixIndices, nondeterministicChoiceIndices, b); - std::vector<ValueType> sccSubX(sccSubmatrix.getColumnCount()); - std::vector<ValueType> sccSubXSwap(sccSubmatrix.getColumnCount()); - std::vector<ValueType> sccMultiplyResult(sccSubmatrix.getRowCount()); - - // Prepare the pointers for swapping in the calculation - currentX = &sccSubX; - swap = &sccSubXSwap; - - storm::utility::vector::selectVectorValues<ValueType>(sccSubX, subMatrixIndices, x); // x is getCols() large, where as b and multiplyResult are getRows() (nondet. choices times states) - std::vector<uint_fast64_t> sccSubNondeterministicChoiceIndices(sccSubmatrix.getColumnCount() + 1); - sccSubNondeterministicChoiceIndices.at(0) = 0; - - // Pre-process all dependent states - // Remove outgoing transitions and create the ChoiceIndices - uint_fast64_t innerIndex = 0; - uint_fast64_t outerIndex = 0; - for (uint_fast64_t state : scc) { - // Choice Indices - sccSubNondeterministicChoiceIndices.at(outerIndex + 1) = sccSubNondeterministicChoiceIndices.at(outerIndex) + (nondeterministicChoiceIndices[state + 1] - nondeterministicChoiceIndices[state]); - - for (auto rowGroupIt = nondeterministicChoiceIndices[state]; rowGroupIt != nondeterministicChoiceIndices[state + 1]; ++rowGroupIt) { - typename storm::storage::SparseMatrix<ValueType>::const_rows row = this->A->getRow(rowGroupIt); - for (auto rowIt = row.begin(); rowIt != row.end(); ++rowIt) { - if (!subMatrixIndices.get(rowIt->getColumn())) { - // This is an outgoing transition of a state in the SCC to a state not included in the SCC - // Subtracting Pr(tau) * x_other from b fixes that - sccSubB.at(innerIndex) = sccSubB.at(innerIndex) + (rowIt->getValue() * x.at(rowIt->getColumn())); - } - } - ++innerIndex; - } - ++outerIndex; - } - - // For the current SCC, we need to perform value iteration until convergence. - if (useGpu) { -#ifdef STORM_HAVE_CUDA - STORM_LOG_THROW(resetCudaDevice(), storm::exceptions::InvalidStateException, "Could not reset CUDA Device, can not use CUDA-based equation solver."); - - //STORM_LOG_INFO("Device has " << getTotalCudaMemory() << " Bytes of Memory with " << getFreeCudaMemory() << "Bytes free (" << (static_cast<double>(getFreeCudaMemory()) / static_cast<double>(getTotalCudaMemory())) * 100 << "%)."); - //STORM_LOG_INFO("We will allocate " << (sizeof(uint_fast64_t)* sccSubmatrix.rowIndications.size() + sizeof(uint_fast64_t)* sccSubmatrix.columnsAndValues.size() * 2 + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubX.size() + sizeof(double)* sccSubB.size() + sizeof(double)* sccSubB.size() + sizeof(uint_fast64_t)* sccSubNondeterministicChoiceIndices.size()) << " Bytes."); - //STORM_LOG_INFO("The CUDA Runtime Version is " << getRuntimeCudaVersion()); - - bool result = false; - localIterations = 0; - if (dir == OptimizationDirection::Minimum) { - result = __basicValueIteration_mvReduce_minimize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); - } else { - result = __basicValueIteration_mvReduce_maximize<uint_fast64_t, ValueType>(maxIters, precision, relative, sccSubmatrix.rowIndications, sccSubmatrix.columnsAndValues, *currentX, sccSubB, sccSubNondeterministicChoiceIndices, localIterations); - } - STORM_LOG_INFO("Executed " << localIterations << " of max. " << maximalNumberOfIterations << " Iterations on GPU."); - - if (!result) { - converged = false; - STORM_LOG_ERROR("An error occurred in the CUDA Plugin. Can not continue."); - throw storm::exceptions::InvalidStateException() << "An error occurred in the CUDA Plugin. Can not continue."; - } else { - converged = true; - } - - // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep - // track of the maximum. - if (localIterations > currentMaxLocalIterations) { - currentMaxLocalIterations = localIterations; - } - globalIterations += localIterations; -#else - STORM_LOG_ERROR("The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"); - throw storm::exceptions::InvalidStateException() << "The useGpu Flag of a SCC was set, but this version of storm does not support CUDA acceleration. Internal Error!"; -#endif - } else { - //std::cout << "WARNING: Using CPU based TopoSolver! (double)" << std::endl; - STORM_LOG_INFO("Performance Warning: Using CPU based TopoSolver! (double)"); - localIterations = 0; - converged = false; - while (!converged && localIterations < maxIters) { - // Compute x' = A*x + b. - sccSubmatrix.multiplyWithVector(*currentX, sccMultiplyResult); - storm::utility::vector::addVectors<ValueType>(sccMultiplyResult, sccSubB, sccMultiplyResult); - - //A.multiplyWithVector(scc, nondeterministicChoiceIndices, *currentX, multiplyResult); - //storm::utility::addVectors(scc, nondeterministicChoiceIndices, multiplyResult, b); - - /* - Versus: - A.multiplyWithVector(*currentX, *multiplyResult); - storm::utility::vector::addVectorsInPlace(*multiplyResult, b); - */ - - // Reduce the vector x' by applying min/max for all non-deterministic choices. - storm::utility::vector::reduceVectorMinOrMax<ValueType>(dir,sccMultiplyResult, *swap, sccSubNondeterministicChoiceIndices); - - // Determine whether the method converged. - // TODO: It seems that the equalModuloPrecision call that compares all values should have a higher - // running time. In fact, it is faster. This has to be investigated. - // converged = storm::utility::equalModuloPrecision(*currentX, *newX, scc, precision, relative); - converged = storm::utility::vector::equalModuloPrecision<ValueType>(*currentX, *swap, precision, relative); - - // Update environment variables. - std::swap(currentX, swap); - - ++localIterations; - ++globalIterations; - } - STORM_LOG_INFO("Executed " << localIterations << " of max. " << maxIters << " Iterations."); - } - - - // The Result of this SCC has to be taken back into the main result vector - innerIndex = 0; - for (uint_fast64_t state : scc) { - x.at(state) = currentX->at(innerIndex); - ++innerIndex; - } - - // Since the pointers for swapping in the calculation point to temps they should not be valid anymore - currentX = nullptr; - swap = nullptr; - - // As the "number of iterations" of the full method is the maximum of the local iterations, we need to keep - // track of the maximum. - if (localIterations > currentMaxLocalIterations) { - currentMaxLocalIterations = localIterations; - } - } - - //std::cout << "Used a total of " << globalIterations << " iterations with a maximum of " << localIterations << " iterations in a single block." << std::endl; - - // Check if the solver converged and issue a warning otherwise. - if (converged) { - STORM_LOG_INFO("Iterative solver converged after " << currentMaxLocalIterations << " iterations."); - } else { - STORM_LOG_WARN("Iterative solver did not converged after " << currentMaxLocalIterations << " iterations."); - } - - return converged; - } + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const { + if (!this->sccSolver) { + this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + this->sccSolver->setMatrix(*this->A); + this->sccSolver->setHasUniqueSolution(this->hasUniqueSolution()); + this->sccSolver->setBoundsFromOtherSolver(*this); + this->sccSolver->setTrackScheduler(this->isTrackSchedulerSet()); + if (this->hasInitialScheduler()) { + auto choices = this->getInitialScheduler(); + this->sccSolver->setInitialScheduler(std::move(choices)); + } + auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); + if (req.upperBounds() && this->hasUpperBound()) { + req.clearUpperBounds(); + } + if (req.lowerBounds() && this->hasLowerBound()) { + req.clearLowerBounds(); + } + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); + this->sccSolver->setRequirementsChecked(true); + + bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, x, b); + if (this->isTrackSchedulerSet()) { + this->schedulerChoices = this->sccSolver->getSchedulerChoices(); + } + return res; } - - template<typename ValueType> - std::vector<std::pair<bool, storm::storage::StateBlock>> - TopologicalMinMaxLinearEquationSolver<ValueType>::getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const { - - (void)matrix; - - std::vector<std::pair<bool, storm::storage::StateBlock>> result; - -#ifdef STORM_HAVE_CUDA - // 95% to have a bit of padding - size_t const cudaFreeMemory = static_cast<size_t>(getFreeCudaMemory() * 0.95); - size_t lastResultIndex = 0; - - std::vector<uint_fast64_t> const& rowGroupIndices = matrix.getRowGroupIndices(); - - size_t const gpuSizeOfCompleteSystem = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(matrix.getRowCount()), rowGroupIndices.size(), static_cast<size_t>(matrix.getEntryCount())); - size_t const gpuSizePerRowGroup = std::max(static_cast<size_t>(gpuSizeOfCompleteSystem / rowGroupIndices.size()), static_cast<size_t>(1)); - size_t const maxRowGroupsPerMemory = cudaFreeMemory / gpuSizePerRowGroup; - - size_t currentSize = 0; - size_t neededReserveSize = 0; - size_t startIndex = 0; - for (size_t i = 0; i < topologicalSort.size(); ++i) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[i]]; - size_t const currentSccSize = scc.size(); - - uint_fast64_t rowCount = 0; - uint_fast64_t entryCount = 0; - - for (auto sccIt = scc.cbegin(); sccIt != scc.cend(); ++sccIt) { - rowCount += matrix.getRowGroupSize(*sccIt); - entryCount += matrix.getRowGroupEntryCount(*sccIt); - } - - size_t sccSize = basicValueIteration_mvReduce_uint64_double_calculateMemorySize(static_cast<size_t>(rowCount), scc.size(), static_cast<size_t>(entryCount)); - - if ((currentSize + sccSize) <= cudaFreeMemory) { - // There is enough space left in the current group - neededReserveSize += currentSccSize; - currentSize += sccSize; - } else { - // This would make the last open group to big for the GPU - - if (startIndex < i) { - if ((startIndex + 1) < i) { - // More than one component - std::vector<uint_fast64_t> tempGroups; - tempGroups.reserve(neededReserveSize); - - // Copy the first group to make inplace_merge possible - storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; - tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); - - if (((startIndex + 1) + 80) >= i) { - size_t lastSize = 0; - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - lastSize = tempGroups.size(); - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); - std::advance(middleIterator, lastSize); - std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); - } - } else { - // Use std::sort - for (size_t j = startIndex + 1; j < i; ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - } - std::sort(tempGroups.begin(), tempGroups.end()); - } - result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); - } else { - // Only one group, copy construct. - result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); - } - ++lastResultIndex; - } - - if (sccSize <= cudaFreeMemory) { - currentSize = sccSize; - neededReserveSize = currentSccSize; - startIndex = i; - } else { - // This group is too big to fit into the CUDA Memory by itself - result.push_back(std::make_pair(false, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[i]])))); - ++lastResultIndex; - - currentSize = 0; - neededReserveSize = 0; - startIndex = i + 1; - } - } - } - - size_t const topologicalSortSize = topologicalSort.size(); - if (startIndex < topologicalSortSize) { - if ((startIndex + 1) < topologicalSortSize) { - // More than one component - std::vector<uint_fast64_t> tempGroups; - tempGroups.reserve(neededReserveSize); - - // Copy the first group to make inplace_merge possible. - storm::storage::StateBlock const& scc_first = sccDecomposition[topologicalSort[startIndex]]; - tempGroups.insert(tempGroups.cend(), scc_first.cbegin(), scc_first.cend()); - - // For set counts <= 80, in-place merge is faster. - if (((startIndex + 1) + 80) >= topologicalSortSize) { - size_t lastSize = 0; - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - lastSize = tempGroups.size(); - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - std::vector<uint_fast64_t>::iterator middleIterator = tempGroups.begin(); - std::advance(middleIterator, lastSize); - std::inplace_merge(tempGroups.begin(), middleIterator, tempGroups.end()); - } - } else { - // Use std::sort - for (size_t j = startIndex + 1; j < topologicalSort.size(); ++j) { - storm::storage::StateBlock const& scc = sccDecomposition[topologicalSort[j]]; - tempGroups.insert(tempGroups.cend(), scc.cbegin(), scc.cend()); - } - std::sort(tempGroups.begin(), tempGroups.end()); - } - result.push_back(std::make_pair(true, storm::storage::StateBlock(tempGroups.cbegin(), tempGroups.cend()))); - } - else { - // Only one group, copy construct. - result.push_back(std::make_pair(true, storm::storage::StateBlock(std::move(sccDecomposition[topologicalSort[startIndex]])))); - } - ++lastResultIndex; - } -#else - for (auto sccIndexIt = topologicalSort.cbegin(); sccIndexIt != topologicalSort.cend(); ++sccIndexIt) { - storm::storage::StateBlock const& scc = sccDecomposition[*sccIndexIt]; - result.push_back(std::make_pair(false, scc)); - } -#endif - return result; - } - + template<typename ValueType> - void TopologicalMinMaxLinearEquationSolver<ValueType>::repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const { - std::unique_ptr<std::vector<ValueType>> multiplyResult = std::make_unique<std::vector<ValueType>>(this->A->getRowCount()); + bool TopologicalMinMaxLinearEquationSolver<ValueType>::solveScc(storm::Environment const& sccSolverEnvironment, OptimizationDirection dir, storm::storage::BitVector const& sccRowGroups, storm::storage::BitVector const& sccRows, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const { - // Now perform matrix-vector multiplication as long as we meet the bound of the formula. - for (uint_fast64_t i = 0; i < n; ++i) { - this->A->multiplyWithVector(x, *multiplyResult); - - // Add b if it is non-null. - if (b != nullptr) { - storm::utility::vector::addVectors(*multiplyResult, *b, *multiplyResult); + // Set up the SCC solver + if (!this->sccSolver) { + this->sccSolver = GeneralMinMaxLinearEquationSolverFactory<ValueType>().create(sccSolverEnvironment); + this->sccSolver->setCachingEnabled(true); + } + this->sccSolver->setHasUniqueSolution(this->hasUniqueSolution()); + this->sccSolver->setTrackScheduler(this->isTrackSchedulerSet()); + + // SCC Matrix + storm::storage::SparseMatrix<ValueType> sccA = this->A->getSubmatrix(true, sccRowGroups, sccRowGroups); + //std::cout << "Matrix is " << sccA << std::endl; + this->sccSolver->setMatrix(std::move(sccA)); + + // x Vector + auto sccX = storm::utility::vector::filterVector(globalX, sccRowGroups); + + // b Vector + std::vector<ValueType> sccB; + sccB.reserve(sccRows.getNumberOfSetBits()); + for (auto const& row : sccRows) { + ValueType bi = globalB[row]; + for (auto const& entry : this->A->getRow(row)) { + if (!sccRowGroups.get(entry.getColumn())) { + bi += entry.getValue() * globalX[entry.getColumn()]; + } } - - // Reduce the vector x' by applying min/max for all non-deterministic choices as given by the topmost - // element of the min/max operator stack. - storm::utility::vector::reduceVectorMinOrMax(dir, *multiplyResult, x, this->A->getRowGroupIndices()); + sccB.push_back(std::move(bi)); } - } + + // initial scheduler + if (this->hasInitialScheduler()) { + auto sccInitChoices = storm::utility::vector::filterVector(this->getInitialScheduler(), sccRowGroups); + this->sccSolver->setInitialScheduler(std::move(sccInitChoices)); + } + + // lower/upper bounds + if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setLowerBound(this->getLowerBound()); + } else if (this->hasLowerBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setLowerBounds(storm::utility::vector::filterVector(this->getLowerBounds(), sccRowGroups)); + } + if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Global)) { + this->sccSolver->setUpperBound(this->getUpperBound()); + } else if (this->hasUpperBound(storm::solver::AbstractEquationSolver<ValueType>::BoundType::Local)) { + this->sccSolver->setUpperBounds(storm::utility::vector::filterVector(this->getUpperBounds(), sccRowGroups)); + } + + // Requirements + auto req = this->sccSolver->getRequirements(sccSolverEnvironment, dir); + if (req.upperBounds() && this->hasUpperBound()) { + req.clearUpperBounds(); + } + if (req.lowerBounds() && this->hasLowerBound()) { + req.clearLowerBounds(); + } + if (req.validInitialScheduler() && this->hasInitialScheduler()) { + req.clearValidInitialScheduler(); + } + STORM_LOG_THROW(!req.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException, "Solver requirements " + req.getEnabledRequirementsAsString() + " not checked."); + this->sccSolver->setRequirementsChecked(true); + // Invoke scc solver + bool res = this->sccSolver->solveEquations(sccSolverEnvironment, dir, sccX, sccB); + //std::cout << "rhs is " << storm::utility::vector::toString(sccB) << std::endl; + //std::cout << "x is " << storm::utility::vector::toString(sccX) << std::endl; + + // Set Scheduler choices + if (this->isTrackSchedulerSet()) { + storm::utility::vector::setVectorValues(this->schedulerChoices.get(), sccRowGroups, this->sccSolver->getSchedulerChoices()); + } + + // Set solution + storm::utility::vector::setVectorValues(globalX, sccRowGroups, sccX); + + return res; + } + template<typename ValueType> - TopologicalMinMaxLinearEquationSolverFactory<ValueType>::TopologicalMinMaxLinearEquationSolverFactory(bool trackScheduler) { - // Intentionally left empty. + MinMaxLinearEquationSolverRequirements TopologicalMinMaxLinearEquationSolver<ValueType>::getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction, bool const& hasInitialScheduler) const { + // Return the requirements of the underlying solver + return GeneralMinMaxLinearEquationSolverFactory<ValueType>().getRequirements(getEnvironmentForUnderlyingSolver(env), this->hasUniqueSolution(), direction, hasInitialScheduler); } template<typename ValueType> - std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> TopologicalMinMaxLinearEquationSolverFactory<ValueType>::create(Environment const& env) const { - STORM_LOG_THROW(env.solver().minMax().getMethod() == MinMaxMethod::Topological, storm::exceptions::InvalidEnvironmentException, "This min max solver does not support the selected technique."); - return std::make_unique<TopologicalMinMaxLinearEquationSolver<ValueType>>(); + void TopologicalMinMaxLinearEquationSolver<ValueType>::clearCache() const { + sortedSccDecomposition.reset(); + longestSccChainSize = boost::none; + sccSolver.reset(); + auxiliaryRowGroupVector.reset(); + StandardMinMaxLinearEquationSolver<ValueType>::clearCache(); } - - // Explicitly instantiate the solver. - template class TopologicalMinMaxLinearEquationSolver<double>; - template class TopologicalMinMaxLinearEquationSolverFactory<double>; - } // namespace solver -} // namespace storm + // Explicitly instantiate the min max linear equation solver. + template class TopologicalMinMaxLinearEquationSolver<double>; + +#ifdef STORM_HAVE_CARL + template class TopologicalMinMaxLinearEquationSolver<storm::RationalNumber>; +#endif + } +} diff --git a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h index 7bf35c2d2..617f9e1b2 100644 --- a/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h +++ b/src/storm/solver/TopologicalMinMaxLinearEquationSolver.h @@ -1,154 +1,53 @@ -#ifndef STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ -#define STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ +#pragma once -#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/solver/StandardMinMaxLinearEquationSolver.h" + +#include "storm/solver/SolverSelectionOptions.h" #include "storm/storage/StronglyConnectedComponentDecomposition.h" -#include "storm/storage/SparseMatrix.h" -#include "storm/exceptions/NotImplementedException.h" -#include "storm/exceptions/NotSupportedException.h" -#include <utility> -#include <vector> +namespace storm { -#include "storm-config.h" -#ifdef STORM_HAVE_CUDA -#include "cudaForStorm.h" -#endif + class Environment; -namespace storm { namespace solver { - - /*! - * A class that uses SCC Decompositions to solve a min/max linear equation system. - */ - template<class ValueType> - class TopologicalMinMaxLinearEquationSolver : public MinMaxLinearEquationSolver<ValueType> { + + template<typename ValueType> + class TopologicalMinMaxLinearEquationSolver : public StandardMinMaxLinearEquationSolver<ValueType> { public: TopologicalMinMaxLinearEquationSolver(); - - /*! - * Constructs a min-max linear equation solver with parameters being set according to the settings - * object. - * - * @param A The matrix defining the coefficients of the linear equation system. - */ TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A); - - virtual void setMatrix(storm::storage::SparseMatrix<ValueType> const& matrix) override; - virtual void setMatrix(storm::storage::SparseMatrix<ValueType>&& matrix) override; - - virtual bool internalSolveEquations(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; - - virtual void repeatedMultiply(Environment const& env, OptimizationDirection dir, std::vector<ValueType>& x, std::vector<ValueType> const* b, uint_fast64_t n) const override; - - private: - storm::storage::SparseMatrix<ValueType> const* A; - std::unique_ptr<storm::storage::SparseMatrix<ValueType>> localA; - - bool enableCuda; - /*! - * Given a topological sort of a SCC Decomposition, this will calculate the optimal grouping of SCCs with respect to the size of the GPU memory. - */ - std::vector<std::pair<bool, storm::storage::StateBlock>> getOptimalGroupingFromTopologicalSccDecomposition(storm::storage::StronglyConnectedComponentDecomposition<ValueType> const& sccDecomposition, std::vector<uint_fast64_t> const& topologicalSort, storm::storage::SparseMatrix<ValueType> const& matrix) const; - }; - - template <typename IndexType, typename ValueType> - bool __basicValueIteration_mvReduce_minimize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>& x, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { - // - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); - } - template <> - inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; + TopologicalMinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType>&& A); -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_double_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - template <> - inline bool __basicValueIteration_mvReduce_minimize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + virtual ~TopologicalMinMaxLinearEquationSolver() { + } - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; + virtual void clearCache() const override; -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_float_minimize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - - template <typename IndexType, typename ValueType> - bool __basicValueIteration_mvReduce_maximize(uint_fast64_t const, double const, bool const, std::vector<uint_fast64_t> const&, std::vector<storm::storage::MatrixEntry<IndexType, ValueType>> const&, std::vector<ValueType>&, std::vector<ValueType> const&, std::vector<uint_fast64_t> const&, size_t&) { - STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Unsupported template arguments."); - } - template <> - inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, double>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, double>> const& columnIndicesAndValues, std::vector<double>& x, std::vector<double> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { + virtual MinMaxLinearEquationSolverRequirements getRequirements(Environment const& env, boost::optional<storm::solver::OptimizationDirection> const& direction = boost::none, bool const& hasInitialScheduler = false) const override ; - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_double_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - template <> - inline bool __basicValueIteration_mvReduce_maximize<uint_fast64_t, float>(uint_fast64_t const maxIterationCount, double const precision, bool const relativePrecisionCheck, std::vector<uint_fast64_t> const& matrixRowIndices, std::vector<storm::storage::MatrixEntry<uint_fast64_t, float>> const& columnIndicesAndValues, std::vector<float>& x, std::vector<float> const& b, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, size_t& iterationCount) { - - (void)maxIterationCount; - (void)precision; - (void)relativePrecisionCheck; - (void)matrixRowIndices; - (void)columnIndicesAndValues; - (void)x; - (void)b; - (void)nondeterministicChoiceIndices; - (void)iterationCount; - -#ifdef STORM_HAVE_CUDA - return basicValueIteration_mvReduce_uint64_float_maximize(maxIterationCount, precision, relativePrecisionCheck, matrixRowIndices, columnIndicesAndValues, x, b, nondeterministicChoiceIndices, iterationCount); -#else - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm is compiled without CUDA support."); -#endif - } - - template<typename ValueType> - class TopologicalMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> { - public: - TopologicalMinMaxLinearEquationSolverFactory(bool trackScheduler = false); - protected: - virtual std::unique_ptr<MinMaxLinearEquationSolver<ValueType>> create(Environment const& env) const override; - }; - } // namespace solver -} // namespace storm + virtual bool internalSolveEquations(storm::Environment const& env, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const& b) const override; -#endif /* STORM_SOLVER_TOPOLOGICALVALUEITERATIONMINMAXLINEAREQUATIONSOLVER_H_ */ + private: + storm::Environment getEnvironmentForUnderlyingSolver(storm::Environment const& env, bool adaptPrecision = false) const; + + // Creates an SCC decomposition and sorts the SCCs according to a topological sort. + void createSortedSccDecomposition(bool needLongestChainSize) const; + + // Solves the SCC with the given index + // ... for the case that the SCC is trivial + bool solveTrivialScc(uint64_t const& sccState, OptimizationDirection d, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + // ... for the case that there is just one large SCC + bool solveFullyConnectedEquationSystem(storm::Environment const& sccSolverEnvironment, OptimizationDirection d, std::vector<ValueType>& x, std::vector<ValueType> const& b) const; + // ... for the remaining cases (1 < scc.size() < x.size()) + bool solveScc(storm::Environment const& sccSolverEnvironment, OptimizationDirection d, storm::storage::BitVector const& sccRowGroups, storm::storage::BitVector const& sccRows, std::vector<ValueType>& globalX, std::vector<ValueType> const& globalB) const; + + // cached auxiliary data + mutable std::unique_ptr<storm::storage::StronglyConnectedComponentDecomposition<ValueType>> sortedSccDecomposition; + mutable boost::optional<uint64_t> longestSccChainSize; + mutable std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> sccSolver; + mutable std::unique_ptr<std::vector<ValueType>> auxiliaryRowGroupVector; // A.rowGroupCount() entries + }; + } +} diff --git a/src/storm/solver/Z3LpSolver.cpp b/src/storm/solver/Z3LpSolver.cpp index 1dcc1a7f0..bd37e1baa 100644 --- a/src/storm/solver/Z3LpSolver.cpp +++ b/src/storm/solver/Z3LpSolver.cpp @@ -26,7 +26,6 @@ namespace storm { template<typename ValueType> Z3LpSolver<ValueType>::Z3LpSolver(std::string const& name, OptimizationDirection const& optDir) : LpSolver<ValueType>(optDir) { - STORM_LOG_WARN_COND(name == "", "Z3 does not support names for solvers"); z3::config config; config.set("model", true); context = std::unique_ptr<z3::context>(new z3::context(config)); @@ -128,7 +127,7 @@ namespace storm { template<typename ValueType> storm::expressions::Variable Z3LpSolver<ValueType>::addBinaryVariable(std::string const& name, ValueType objectiveFunctionCoefficient) { storm::expressions::Variable newVariable = this->manager->declareVariable(name, this->manager->getIntegerType()); - solver->add(expressionAdapter->translateExpression((newVariable.getExpression() >= this->manager->rational(storm::utility::one<storm::RationalNumber>())) && (newVariable.getExpression() <= this->manager->rational(storm::utility::one<storm::RationalNumber>())))); + solver->add(expressionAdapter->translateExpression((newVariable.getExpression() >= this->manager->rational(storm::utility::zero<storm::RationalNumber>())) && (newVariable.getExpression() <= this->manager->rational(storm::utility::one<storm::RationalNumber>())))); optimizationFunction = optimizationFunction + this->manager->rational(objectiveFunctionCoefficient) * newVariable; return newVariable; } @@ -137,7 +136,6 @@ namespace storm { void Z3LpSolver<ValueType>::addConstraint(std::string const& name, storm::expressions::Expression const& constraint) { STORM_LOG_THROW(constraint.isRelationalExpression(), storm::exceptions::InvalidArgumentException, "Illegal constraint is not a relational expression."); STORM_LOG_THROW(constraint.getOperator() != storm::expressions::OperatorType::NotEqual, storm::exceptions::InvalidArgumentException, "Illegal constraint uses inequality operator."); - STORM_LOG_WARN_COND(name == "", "Z3 does not support names for constraints"); solver->add(expressionAdapter->translateExpression(constraint)); } diff --git a/src/storm/solver/helper/SoundValueIterationHelper.cpp b/src/storm/solver/helper/SoundValueIterationHelper.cpp new file mode 100644 index 000000000..6e47bfe3e --- /dev/null +++ b/src/storm/solver/helper/SoundValueIterationHelper.cpp @@ -0,0 +1,450 @@ +#include "storm/solver/helper/SoundValueIterationHelper.h" + +#include "storm/storage/SparseMatrix.h" +#include "storm/storage/BitVector.h" +#include "storm/utility/vector.h" +#include "storm/utility/macros.h" +#include "storm/utility/NumberTraits.h" + +#include "storm/exceptions/NotSupportedException.h" + + +namespace storm { + namespace solver { + namespace helper { + + template<typename ValueType> + SoundValueIterationHelper<ValueType>::SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), hasLowerBound(false), hasUpperBound(false), hasDecisionValue(false), convergencePhase1(true), decisionValueBlocks(false), firstIndexViolatingConvergence(0), minIndex(0), maxIndex(0), relative(relative), precision(precision), rowGroupIndices(nullptr) { + STORM_LOG_THROW(matrix.getEntryCount() < std::numeric_limits<IndexType>::max(), storm::exceptions::NotSupportedException, "The number of matrix entries is too large for the selected index type."); + if (!matrix.hasTrivialRowGrouping()) { + rowGroupIndices = &matrix.getRowGroupIndices(); + uint64_t sizeOfLargestRowGroup = matrix.getSizeOfLargestRowGroup(); + xTmp.resize(sizeOfLargestRowGroup); + yTmp.resize(sizeOfLargestRowGroup); + } + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + + numRows = matrix.getRowCount(); + matrixValues.clear(); + matrixColumns.clear(); + rowIndications.clear(); + matrixValues.reserve(matrix.getNonzeroEntryCount()); + matrixColumns.reserve(matrix.getColumnCount()); + rowIndications.reserve(numRows + 1); + rowIndications.push_back(0); + for (IndexType r = 0; r < numRows; ++r) { + for (auto const& entry : matrix.getRow(r)) { + matrixValues.push_back(entry.getValue()); + matrixColumns.push_back(entry.getColumn()); + } + rowIndications.push_back(matrixValues.size()); + } + } + + template<typename ValueType> + SoundValueIterationHelper<ValueType>::SoundValueIterationHelper(SoundValueIterationHelper<ValueType>&& oldHelper, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision) : x(x), y(y), xTmp(std::move(oldHelper.xTmp)), yTmp(std::move(oldHelper.yTmp)), hasLowerBound(false), hasUpperBound(false), hasDecisionValue(false), convergencePhase1(true), decisionValueBlocks(false), firstIndexViolatingConvergence(0), minIndex(0), maxIndex(0), relative(relative), precision(precision), numRows(std::move(oldHelper.numRows)), matrixValues(std::move(oldHelper.matrixValues)), matrixColumns(std::move(oldHelper.matrixColumns)), rowIndications(std::move(oldHelper.rowIndications)), rowGroupIndices(oldHelper.rowGroupIndices) { + + x.assign(x.size(), storm::utility::zero<ValueType>()); + y.assign(x.size(), storm::utility::one<ValueType>()); + } + + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setLowerBound(ValueType const& value) { + hasLowerBound = true; + lowerBound = value; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setUpperBound(ValueType const& value) { + hasUpperBound = true; + upperBound = value; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi) { + assert(rowIndex < numRows); + ValueType xRes = bi; + ValueType yRes = storm::utility::zero<ValueType>(); + + auto entryIt = matrixValues.begin() + rowIndications[rowIndex]; + auto entryItE = matrixValues.begin() + rowIndications[rowIndex + 1]; + auto colIt = matrixColumns.begin() + rowIndications[rowIndex]; + for (; entryIt != entryItE; ++entryIt, ++colIt) { + xRes += *entryIt * x[*colIt]; + yRes += *entryIt * y[*colIt]; + } + xi = std::move(xRes); + yi = std::move(yRes); + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::performIterationStep(OptimizationDirection const& dir, std::vector<ValueType> const& b) { + if (rowGroupIndices) { + if (minimize(dir)) { + performIterationStep<InternalOptimizationDirection::Minimize>(b); + } else { + performIterationStep<InternalOptimizationDirection::Maximize>(b); + } + } else { + performIterationStep(b); + } + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::performIterationStep(std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + IndexType row = numRows; + while (row > 0) { + --row; + multiplyRow(row, b[row], *xIt, *yIt); + ++xIt; + ++yIt; + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::performIterationStep(std::vector<ValueType> const& b) { + if (!decisionValueBlocks) { + performIterationStepUpdateDecisionValue<dir>(b); + } else { + assert(decisionValue == getPrimaryBound<dir>()); + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = rowGroupIndices->rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = rowGroupIndices->rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + IndexType row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (currentValue == bestValue && yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + xBest = std::move(xi); + yBest = std::move(yi); + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b) { + auto xIt = x.rbegin(); + auto yIt = y.rbegin(); + auto groupStartIt = rowGroupIndices->rbegin(); + uint64_t groupEnd = *groupStartIt; + ++groupStartIt; + for (auto groupStartIte = rowGroupIndices->rend(); groupStartIt != groupStartIte; groupEnd = *(groupStartIt++), ++xIt, ++yIt) { + // Perform the iteration for the first row in the group + uint64_t row = *groupStartIt; + ValueType xBest, yBest; + multiplyRow(row, b[row], xBest, yBest); + ++row; + // Only do more work if there are still rows in this row group + if (row != groupEnd) { + ValueType xi, yi; + uint64_t xyTmpIndex = 0; + if (hasPrimaryBound<dir>()) { + ValueType bestValue = xBest + yBest * getPrimaryBound<dir>(); + for (;row < groupEnd; ++row) { + // Get the multiplication results + multiplyRow(row, b[row], xi, yi); + ValueType currentValue = xi + yi * getPrimaryBound<dir>(); + // Check if the current row is better then the previously found one + if (better<dir>(currentValue, bestValue)) { + if (yBest < yi) { + // We need to store the 'old' best value as it might be relevant for the decision value + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + } + xBest = std::move(xi); + yBest = std::move(yi); + bestValue = std::move(currentValue); + } else if (yBest > yi) { + // If the value for this row is not strictly better, it might still be equal and have a better y value + if (currentValue == bestValue) { + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + } else { + for (;row < groupEnd; ++row) { + multiplyRow(row, b[row], xi, yi); + // Update the best choice + if (yi > yBest || (yi == yBest && better<dir>(xi, xBest))) { + xTmp[xyTmpIndex] = std::move(xBest); + yTmp[xyTmpIndex] = std::move(yBest); + ++xyTmpIndex; + xBest = std::move(xi); + yBest = std::move(yi); + } else { + xTmp[xyTmpIndex] = std::move(xi); + yTmp[xyTmpIndex] = std::move(yi); + ++xyTmpIndex; + } + } + } + + // Update the decision value + for (uint64_t i = 0; i < xyTmpIndex; ++i) { + ValueType deltaY = yBest - yTmp[i]; + if (deltaY > storm::utility::zero<ValueType>()) { + ValueType newDecisionValue = (xTmp[i] - xBest) / deltaY; + if (!hasDecisionValue || better<dir>(newDecisionValue, decisionValue)) { + decisionValue = std::move(newDecisionValue); + hasDecisionValue = true; + } + } + } + } + *xIt = std::move(xBest); + *yIt = std::move(yBest); + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(OptimizationDirection const& dir, storm::storage::BitVector const* relevantValues) { + if (rowGroupIndices) { + if (minimize(dir)) { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::Minimize>(relevantValues); + } else { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::Maximize>(relevantValues); + } + } else { + return checkConvergenceUpdateBounds(relevantValues); + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues) { + return checkConvergenceUpdateBounds<InternalOptimizationDirection::None>(relevantValues); + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + bool SoundValueIterationHelper<ValueType>::checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues) { + + if (convergencePhase1) { + if (checkConvergencePhase1()) { + firstIndexViolatingConvergence = 0; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); + } + } else { + return false; + } + } + STORM_LOG_ASSERT(!std::any_of(y.begin(), y.end(), [](ValueType value){return storm::utility::isOne(value);}), "Did not expect staying-probability 1 at this point."); + + // Reaching this point means that we are in Phase 2: + // The difference between lower and upper bound has to be < precision at every (relevant) value + + // For efficiency reasons we first check whether it is worth to compute the actual bounds. We do so by considering possibly too tight bounds + ValueType lowerBoundCandidate, upperBoundCandidate; + if (preliminaryConvergenceCheck<dir>(lowerBoundCandidate, upperBoundCandidate)) { + updateLowerUpperBound<dir>(lowerBoundCandidate, upperBoundCandidate); + if (dir != InternalOptimizationDirection::None) { + checkIfDecisionValueBlocks<dir>(); + } + return checkConvergencePhase2(relevantValues); + } + return false; + } + + template<typename ValueType> + void SoundValueIterationHelper<ValueType>::setSolutionVector() { + // Due to a custom termination criterion it might be the case that one of the bounds was not yet established. + ValueType meanBound; + if (!hasLowerBound) { + STORM_LOG_WARN("No lower result bound was computed during sound value iteration."); + if (hasUpperBound) { + meanBound = upperBound; + } else { + STORM_LOG_WARN("No upper result bound was computed during sound value iteration."); + meanBound = storm::utility::zero<ValueType>(); + } + } else if (!hasUpperBound) { + STORM_LOG_WARN("No upper result bound was computed during sound value iteration."); + meanBound = lowerBound; + } else { + meanBound = (upperBound + lowerBound) / storm::utility::convertNumber<ValueType>(2.0); + } + + storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) -> ValueType { return xi + yi * meanBound; }); + + STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound " + << (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)") + << " and upper value bound " + << (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)") + << ". Decision value is " + << (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)") + << "."); + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkCustomTerminationCondition(storm::solver::TerminationCondition<ValueType> const& condition) { + if (condition.requiresGuarantee(storm::solver::SolverGuarantee::GreaterOrEqual)) { + if (hasUpperBound && condition.terminateNow( + [&](uint64_t const& i) { + return x[i] + y[i] * upperBound; + }, storm::solver::SolverGuarantee::GreaterOrEqual)) { + return true; + } + } else if (condition.requiresGuarantee(storm::solver::SolverGuarantee::LessOrEqual)) { + if (hasLowerBound && condition.terminateNow( + [&](uint64_t const& i) { + return x[i] + y[i] * lowerBound; + }, storm::solver::SolverGuarantee::LessOrEqual)) { + return true; + } + } + return false; + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergencePhase1() { + // Return true if y ('the probability to stay within the matrix') is < 1 at every entry + for (; firstIndexViolatingConvergence != y.size(); ++firstIndexViolatingConvergence) { + static_assert(NumberTraits<ValueType>::IsExact || std::is_same<ValueType, double>::value, "Considered ValueType not handled."); + if (NumberTraits<ValueType>::IsExact) { + if (storm::utility::isOne(y[firstIndexViolatingConvergence])) { + return false; + } + } else { + if (storm::utility::isAlmostOne(storm::utility::convertNumber<double>(y[firstIndexViolatingConvergence]))) { + return false; + } + } + } + convergencePhase1 = false; + return true; + } + + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub) { + return yi * (ub - lb) <= storm::utility::abs<ValueType>((relative ? (precision * xi) : (precision * storm::utility::convertNumber<ValueType>(2.0)))); + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + bool SoundValueIterationHelper<ValueType>::preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + lowerBoundCandidate = x[minIndex] / (storm::utility::one<ValueType>() - y[minIndex]); + upperBoundCandidate = x[maxIndex] / (storm::utility::one<ValueType>() - y[maxIndex]); + // Make sure that these candidates are at least as tight as the already known bounds + if (hasLowerBound && lowerBoundCandidate < lowerBound) { + lowerBoundCandidate = lowerBound; + } + if (hasUpperBound && upperBoundCandidate > upperBound) { + upperBoundCandidate = upperBound; + } + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBoundCandidate, upperBoundCandidate)) { + return true; + } + if (dir != InternalOptimizationDirection::None && !decisionValueBlocks) { + return hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>()); + } + return false; + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate) { + auto xIt = x.begin(); + auto xIte = x.end(); + auto yIt = y.begin(); + for (uint64_t index = 0; xIt != xIte; ++xIt, ++yIt, ++index) { + ValueType currentBound = *xIt / (storm::utility::one<ValueType>() - *yIt); + if (dir != InternalOptimizationDirection::None && decisionValueBlocks) { + if (better<dir>(getSecondaryBound<dir>(), currentBound)) { + getSecondaryIndex<dir>() = index; + getSecondaryBound<dir>() = std::move(currentBound); + } + } else { + if (currentBound < lowerBoundCandidate) { + minIndex = index; + lowerBoundCandidate = std::move(currentBound); + } else if (currentBound > upperBoundCandidate) { + maxIndex = index; + upperBoundCandidate = std::move(currentBound); + } + } + } + if ((dir != InternalOptimizationDirection::Minimize || !decisionValueBlocks) && (!hasLowerBound || lowerBoundCandidate > lowerBound)) { + setLowerBound(lowerBoundCandidate); + } + if ((dir != InternalOptimizationDirection::Maximize || !decisionValueBlocks) && (!hasUpperBound || upperBoundCandidate < upperBound)) { + setUpperBound(upperBoundCandidate); + } + } + + template<typename ValueType> + template<typename SoundValueIterationHelper<ValueType>::InternalOptimizationDirection dir> + void SoundValueIterationHelper<ValueType>::checkIfDecisionValueBlocks() { + // Check whether the decision value blocks now (i.e. further improvement of the primary bound would lead to a non-optimal scheduler). + if (!decisionValueBlocks && hasDecisionValue && better<dir>(decisionValue, getPrimaryBound<dir>())) { + getPrimaryBound<dir>() = decisionValue; + decisionValueBlocks = true; + } + } + + template<typename ValueType> + bool SoundValueIterationHelper<ValueType>::checkConvergencePhase2(storm::storage::BitVector const* relevantValues) { + // Check whether the desired precision is reached + if (isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // The current index satisfies the desired bound. We now move to the next index that violates it + while (true) { + ++firstIndexViolatingConvergence; + if (relevantValues != nullptr) { + firstIndexViolatingConvergence = relevantValues->getNextSetIndex(firstIndexViolatingConvergence); + } + if (firstIndexViolatingConvergence == x.size()) { + // Converged! + return true; + } else { + if (!isPreciseEnough(x[firstIndexViolatingConvergence], y[firstIndexViolatingConvergence], lowerBound, upperBound)) { + // not converged yet + return false; + } + } + } + } + return false; + } + + template class SoundValueIterationHelper<double>; + template class SoundValueIterationHelper<storm::RationalNumber>; + } + + } +} + diff --git a/src/storm/solver/helper/SoundValueIterationHelper.h b/src/storm/solver/helper/SoundValueIterationHelper.h new file mode 100644 index 000000000..54cdc1fb1 --- /dev/null +++ b/src/storm/solver/helper/SoundValueIterationHelper.h @@ -0,0 +1,151 @@ +#pragma once + +#include <vector> + +#include "storm/solver/OptimizationDirection.h" +#include "storm/solver/TerminationCondition.h" + +namespace storm { + + namespace storage { + template<typename ValueType> + class SparseMatrix; + + class BitVector; + } + + namespace solver { + namespace helper { + + + template<typename ValueType> + class SoundValueIterationHelper { + public: + + typedef uint32_t IndexType; + + /*! + * Creates a new helper from the given data + */ + SoundValueIterationHelper(storm::storage::SparseMatrix<ValueType> const& matrix, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision); + + /*! + * Creates a helper from the given data, considering the same matrix as the given old helper + */ + SoundValueIterationHelper(SoundValueIterationHelper<ValueType>&& oldHelper, std::vector<ValueType>& x, std::vector<ValueType>& y, bool relative, ValueType const& precision); + + /*! + * Sets the currently known lower / upper bound + */ + void setLowerBound(ValueType const& value); + void setUpperBound(ValueType const& value); + + void setSolutionVector(); + + /*! + * Performs one iteration step with respect to the given optimization direction. + */ + void performIterationStep(OptimizationDirection const& dir, std::vector<ValueType> const& b); + + /*! + * Performs one iteration step, assuming that the row grouping of the initial matrix is trivial. + */ + void performIterationStep(std::vector<ValueType> const& b); + + /*! + * Checks for convergence and updates the known lower/upper bounds. + */ + bool checkConvergenceUpdateBounds(OptimizationDirection const& dir, storm::storage::BitVector const* relevantValues = nullptr); + + /*! + * Checks for convergence and updates the known lower/upper bounds, assuming that the row grouping of the initial matrix is trivial. + */ + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr); + + /*! + * Checks whether the provided termination condition triggers termination + */ + bool checkCustomTerminationCondition(storm::solver::TerminationCondition<ValueType> const& condition); + + private: + + enum class InternalOptimizationDirection { + None, Minimize, Maximize + }; + + template<InternalOptimizationDirection dir> + void performIterationStep(std::vector<ValueType> const& b); + + template<InternalOptimizationDirection dir> + void performIterationStepUpdateDecisionValue(std::vector<ValueType> const& b); + + void multiplyRow(IndexType const& rowIndex, ValueType const& bi, ValueType& xi, ValueType& yi); + + template<InternalOptimizationDirection dir> + bool checkConvergenceUpdateBounds(storm::storage::BitVector const* relevantValues = nullptr); + + bool checkConvergencePhase1(); + bool checkConvergencePhase2(storm::storage::BitVector const* relevantValues = nullptr); + + bool isPreciseEnough(ValueType const& xi, ValueType const& yi, ValueType const& lb, ValueType const& ub); + + template<InternalOptimizationDirection dir> + bool preliminaryConvergenceCheck(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate); + + template<InternalOptimizationDirection dir> + void updateLowerUpperBound(ValueType& lowerBoundCandidate, ValueType& upperBoundCandidate); + + template<InternalOptimizationDirection dir> + void checkIfDecisionValueBlocks(); + + // Auxiliary helper functions to avoid case distinctions due to different optimization directions + template<InternalOptimizationDirection dir> + inline bool better(ValueType const& val1, ValueType const& val2) { + return (dir == InternalOptimizationDirection::Maximize) ? val1 > val2 : val1 < val2; + } + template<InternalOptimizationDirection dir> + inline ValueType& getPrimaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? upperBound : lowerBound; + } + template<InternalOptimizationDirection dir> + inline bool& hasPrimaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? hasUpperBound : hasLowerBound; + } + template<InternalOptimizationDirection dir> + inline ValueType& getSecondaryBound() { + return (dir == InternalOptimizationDirection::Maximize) ? lowerBound : upperBound; + } + template<InternalOptimizationDirection dir> + inline uint64_t& getPrimaryIndex() { + return (dir == InternalOptimizationDirection::Maximize) ? maxIndex : minIndex; + } + template<InternalOptimizationDirection dir> + inline uint64_t& getSecondaryIndex() { + return (dir == InternalOptimizationDirection::Maximize) ? minIndex : maxIndex; + } + + std::vector<ValueType>& x; + std::vector<ValueType>& y; + std::vector<ValueType> xTmp, yTmp; + + ValueType lowerBound, upperBound, decisionValue; + bool hasLowerBound, hasUpperBound, hasDecisionValue; + bool convergencePhase1; + bool decisionValueBlocks; + uint64_t firstIndexViolatingConvergence; + uint64_t minIndex, maxIndex; + + bool relative; + ValueType precision; + + IndexType numRows; + std::vector<ValueType> matrixValues; + std::vector<IndexType> matrixColumns; + std::vector<IndexType> rowIndications; + std::vector<uint_fast64_t> const* rowGroupIndices; + }; + + } + } +} + diff --git a/src/storm/storage/BitVectorHashMap.cpp b/src/storm/storage/BitVectorHashMap.cpp index 7bfe1595e..67c151bde 100644 --- a/src/storm/storage/BitVectorHashMap.cpp +++ b/src/storm/storage/BitVectorHashMap.cpp @@ -96,10 +96,12 @@ namespace storm { std::swap(oldValues, values); // Now iterate through the elements and reinsert them in the new storage. + uint64_t oldSize = numberOfElements; numberOfElements = 0; for (auto bucketIndex : oldOccupied) { findOrAddAndGetBucket(oldBuckets.get(bucketIndex * bucketSize, bucketSize), oldValues[bucketIndex]); } + STORM_LOG_ASSERT(oldSize == numberOfElements, "Size mismatch in rehashing. Size before was " << oldSize << " and new size is " << numberOfElements << "."); } template<class ValueType, class Hash> diff --git a/src/storm/storage/Distribution.h b/src/storm/storage/Distribution.h index 328e87f98..1d0fbbd5f 100644 --- a/src/storm/storage/Distribution.h +++ b/src/storm/storage/Distribution.h @@ -132,7 +132,6 @@ namespace storm { bool less(Distribution<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const; - /*! * Returns the probability of the given state * @param state The state for which the probability is returned. diff --git a/src/storm/storage/DistributionWithReward.cpp b/src/storm/storage/DistributionWithReward.cpp new file mode 100644 index 000000000..f2fd46d45 --- /dev/null +++ b/src/storm/storage/DistributionWithReward.cpp @@ -0,0 +1,53 @@ +#include "storm/storage/DistributionWithReward.h" + +#include "storm/adapters/RationalFunctionAdapter.h" + +#include "storm/utility/ConstantsComparator.h" + +namespace storm { + namespace storage { + + template<typename ValueType, typename StateType> + DistributionWithReward<ValueType, StateType>::DistributionWithReward(ValueType const& reward) : Distribution<ValueType, StateType>(), reward(reward) { + // Intentionally left empty. + } + + template<typename ValueType, typename StateType> + bool DistributionWithReward<ValueType, StateType>::equals(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const { + if (this->reward != other.reward) { + return false; + } + return Distribution<ValueType, StateType>::equals(other, comparator); + } + + template<typename ValueType, typename StateType> + bool DistributionWithReward<ValueType, StateType>::less(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const { + if (comparator.isLess(this->reward, other.reward)) { + return true; + } else if (comparator.isLess(other.reward, this->reward)) { + return false; + } else { + return Distribution<ValueType, StateType>::less(other, comparator); + } + } + + template<typename ValueType, typename StateType> + void DistributionWithReward<ValueType, StateType>::setReward(ValueType const& reward) { + this->reward = reward; + } + + template<typename ValueType, typename StateType> + ValueType const& DistributionWithReward<ValueType, StateType>::getReward() const { + return reward; + } + + template class DistributionWithReward<double>; + +#ifdef STORM_HAVE_CARL + template class DistributionWithReward<storm::RationalNumber>; + template class DistributionWithReward<storm::RationalFunction>; +#endif + + + } +} diff --git a/src/storm/storage/DistributionWithReward.h b/src/storm/storage/DistributionWithReward.h new file mode 100644 index 000000000..d830b89e2 --- /dev/null +++ b/src/storm/storage/DistributionWithReward.h @@ -0,0 +1,53 @@ +#pragma once + +#include "storm/storage/Distribution.h" + +#include "storm/utility/constants.h" + +namespace storm { + namespace utility { + template <typename ValueType> + class ConstantsComparator; + } + + namespace storage { + + template<typename ValueType, typename StateType = uint32_t> + class DistributionWithReward : public Distribution<ValueType, StateType> { + public: + /*! + * Creates an empty distribution. + */ + DistributionWithReward(ValueType const& reward = storm::utility::zero<ValueType>()); + + DistributionWithReward(DistributionWithReward const& other) = default; + DistributionWithReward& operator=(DistributionWithReward const& other) = default; + DistributionWithReward(DistributionWithReward&& other) = default; + DistributionWithReward& operator=(DistributionWithReward&& other) = default; + + /*! + * Checks whether the two distributions specify the same probabilities to go to the same states. + * + * @param other The distribution with which the current distribution is to be compared. + * @return True iff the two distributions are equal. + */ + bool equals(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator = storm::utility::ConstantsComparator<ValueType>()) const; + + bool less(DistributionWithReward<ValueType, StateType> const& other, storm::utility::ConstantsComparator<ValueType> const& comparator) const; + + /*! + * Sets the reward of this distribution. + */ + void setReward(ValueType const& reward); + + /*! + * Retrieves the reward of this distribution. + */ + ValueType const& getReward() const; + + private: + ValueType reward; + }; + + } +} diff --git a/src/storm/storage/MaximalEndComponentDecomposition.cpp b/src/storm/storage/MaximalEndComponentDecomposition.cpp index cd8b637e3..7cbf36fd7 100644 --- a/src/storm/storage/MaximalEndComponentDecomposition.cpp +++ b/src/storm/storage/MaximalEndComponentDecomposition.cpp @@ -80,7 +80,20 @@ namespace storm { endComponentStateSets.emplace_back(states.begin(), states.end(), true); } storm::storage::BitVector statesToCheck(numberOfStates); - + storm::storage::BitVector includedChoices; + if (choices) { + includedChoices = *choices; + } else if (states) { + includedChoices = storm::storage::BitVector(transitionMatrix.getRowCount()); + for (auto state : *states) { + for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { + includedChoices.set(choice, true); + } + } + } else { + includedChoices = storm::storage::BitVector(transitionMatrix.getRowCount(), true); + } + for (std::list<StateBlock>::const_iterator mecIterator = endComponentStateSets.begin(); mecIterator != endComponentStateSets.end();) { StateBlock const& mec = *mecIterator; @@ -88,7 +101,7 @@ namespace storm { bool mecChanged = false; // Get an SCC decomposition of the current MEC candidate. - StronglyConnectedComponentDecomposition<ValueType> sccs(transitionMatrix, mec, true); + StronglyConnectedComponentDecomposition<ValueType> sccs(transitionMatrix, mec, includedChoices, true); // We need to do another iteration in case we have either more than once SCC or the SCC is smaller than // the MEC canditate itself. @@ -105,10 +118,16 @@ namespace storm { bool keepStateInMEC = false; for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { + // If the choice is not part of our subsystem, skip it. if (choices && !choices->get(choice)) { continue; } + + // If the choice is not included any more, skip it. + if (!includedChoices.get(choice)) { + continue; + } bool choiceContainedInMEC = true; for (auto const& entry : transitionMatrix.getRow(choice)) { @@ -117,6 +136,7 @@ namespace storm { } if (!scc.containsState(entry.getColumn())) { + includedChoices.set(choice, false); choiceContainedInMEC = false; break; } @@ -125,7 +145,6 @@ namespace storm { // If there is at least one choice whose successor states are fully contained in the MEC, we can leave the state in the MEC. if (choiceContainedInMEC) { keepStateInMEC = true; - break; } } @@ -185,15 +204,7 @@ namespace storm { continue; } - bool choiceContained = true; - for (auto const& entry : transitionMatrix.getRow(choice)) { - if (!mecStateSet.containsState(entry.getColumn())) { - choiceContained = false; - break; - } - } - - if (choiceContained) { + if (includedChoices.get(choice)) { containedChoices.insert(choice); } } diff --git a/src/storm/storage/Scheduler.h b/src/storm/storage/Scheduler.h index b51e308b9..f3777cf55 100644 --- a/src/storm/storage/Scheduler.h +++ b/src/storm/storage/Scheduler.h @@ -44,10 +44,10 @@ namespace storm { void clearChoice(uint_fast64_t modelState, uint_fast64_t memoryState = 0); /*! - * Sets the choice defined by the scheduler for the given model and memory state. + * Gets the choice defined by the scheduler for the given model and memory state. * - * @param state The state for which to set the choice. - * @param choice The choice to set for the given state. + * @param state The state for which to get the choice. + * @param memoryState the memory state which we consider. */ SchedulerChoice<ValueType> const& getChoice(uint_fast64_t modelState, uint_fast64_t memoryState = 0) const; diff --git a/src/storm/storage/SparseMatrix.cpp b/src/storm/storage/SparseMatrix.cpp index 36dd5724e..729b85b46 100644 --- a/src/storm/storage/SparseMatrix.cpp +++ b/src/storm/storage/SparseMatrix.cpp @@ -579,6 +579,20 @@ namespace storm { return this->getRowGroupIndices()[group + 1] - this->getRowGroupIndices()[group]; } + template<typename ValueType> + typename SparseMatrix<ValueType>::index_type SparseMatrix<ValueType>::getSizeOfLargestRowGroup() const { + if (this->hasTrivialRowGrouping()) { + return 1; + } + index_type res = 0; + index_type previousGroupStart = 0; + for (auto const& i : rowGroupIndices.get()) { + res = std::max(res, i - previousGroupStart); + previousGroupStart = i; + } + return res; + } + template<typename ValueType> std::vector<typename SparseMatrix<ValueType>::index_type> const& SparseMatrix<ValueType>::getRowGroupIndices() const { // If there is no current row grouping, we need to create it. diff --git a/src/storm/storage/SparseMatrix.h b/src/storm/storage/SparseMatrix.h index e07389e5a..4013a7cbf 100644 --- a/src/storm/storage/SparseMatrix.h +++ b/src/storm/storage/SparseMatrix.h @@ -27,7 +27,7 @@ namespace storm { } namespace solver { template<typename T> - class TopologicalValueIterationMinMaxLinearEquationSolver; + class TopologicalCudaValueIterationMinMaxLinearEquationSolver; } } @@ -327,7 +327,7 @@ namespace storm { friend class storm::adapters::GmmxxAdapter<ValueType>; friend class storm::adapters::EigenAdapter; friend class storm::adapters::StormAdapter; - friend class storm::solver::TopologicalValueIterationMinMaxLinearEquationSolver<ValueType>; + friend class storm::solver::TopologicalCudaValueIterationMinMaxLinearEquationSolver<ValueType>; friend class SparseMatrixBuilder<ValueType>; typedef SparseMatrixIndexType index_type; @@ -567,6 +567,11 @@ namespace storm { */ index_type getRowGroupSize(index_type group) const; + /*! + * Returns the size of the largest row group of the matrix + */ + index_type getSizeOfLargestRowGroup() const; + /*! * Returns the grouping of rows of this matrix. * @@ -574,6 +579,7 @@ namespace storm { */ std::vector<index_type> const& getRowGroupIndices() const; + /*! * Sets the row grouping to the given one. * @note It is assumed that the new row grouping is non-trivial. diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp index af98331a7..6ab3e31f6 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.cpp +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.cpp @@ -2,6 +2,9 @@ #include "storm/models/sparse/Model.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/utility/macros.h" + +#include "storm/exceptions/UnexpectedException.h" namespace storm { namespace storage { @@ -20,30 +23,40 @@ namespace storm { template <typename RewardModelType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) { storm::storage::BitVector subsystem(model.getNumberOfStates(), block.begin(), block.end()); - performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> template <typename RewardModelType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(model.getTransitionMatrix(), subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, bool dropNaiveSccs, bool onlyBottomSccs) { storm::storage::BitVector subsystem(transitionMatrix.getRowGroupCount(), block.begin(), block.end()); - performSccDecomposition(transitionMatrix, subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); } + template <typename ValueType> + StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, storm::storage::BitVector const& choices, bool dropNaiveSccs, bool onlyBottomSccs) { + storm::storage::BitVector subsystem(transitionMatrix.getRowGroupCount(), block.begin(), block.end()); + performSccDecomposition(transitionMatrix, &subsystem, &choices, dropNaiveSccs, onlyBottomSccs); + } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true), dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, nullptr, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { - performSccDecomposition(transitionMatrix, subsystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(transitionMatrix, &subsystem, nullptr, dropNaiveSccs, onlyBottomSccs); + } + + template <typename ValueType> + StronglyConnectedComponentDecomposition<ValueType>::StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices, bool dropNaiveSccs, bool onlyBottomSccs) { + performSccDecomposition(transitionMatrix, &subsystem, &choices, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> @@ -69,7 +82,10 @@ namespace storm { } template <typename ValueType> - void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs) { + void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, bool dropNaiveSccs, bool onlyBottomSccs) { + + STORM_LOG_ASSERT(!choices || subsystem, "Expecting subsystem if choices are given."); + uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount(); // Set up the environment of the algorithm. @@ -91,16 +107,30 @@ namespace storm { // Start the search for SCCs from every state in the block. uint_fast64_t currentIndex = 0; - for (auto state : subsystem) { - if (!hasPreorderNumber.get(state)) { - performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + if (subsystem) { + for (auto state : *subsystem) { + if (!hasPreorderNumber.get(state)) { + performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, choices, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + } + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + if (!hasPreorderNumber.get(state)) { + performSccDecompositionGCM(transitionMatrix, state, statesWithSelfLoop, subsystem, choices, currentIndex, hasPreorderNumber, preorderNumbers, s, p, stateHasScc, stateToSccMapping, sccCount); + } } } // After we obtained the state-to-SCC mapping, we build the actual blocks. this->blocks.resize(sccCount); - for (auto state : subsystem) { - this->blocks[stateToSccMapping[state]].insert(state); + if (subsystem) { + for (auto state : *subsystem) { + this->blocks[stateToSccMapping[state]].insert(state); + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + this->blocks[stateToSccMapping[state]].insert(state); + } } // Now flag all trivial SCCs as such. @@ -129,13 +159,34 @@ namespace storm { // If requested, we need to drop all non-bottom SCCs. if (onlyBottomSccs) { - for (uint_fast64_t state = 0; state < numberOfStates; ++state) { - // If the block of the state is already known to be dropped, we don't need to check the transitions. - if (!blocksToDrop.get(stateToSccMapping[state])) { - for (typename storm::storage::SparseMatrix<ValueType>::const_iterator successorIt = transitionMatrix.getRowGroup(state).begin(), successorIte = transitionMatrix.getRowGroup(state).end(); successorIt != successorIte; ++successorIt) { - if (subsystem.get(successorIt->getColumn()) && stateToSccMapping[state] != stateToSccMapping[successorIt->getColumn()]) { - blocksToDrop.set(stateToSccMapping[state]); - break; + if (subsystem) { + for (uint64_t state : *subsystem) { + // If the block of the state is already known to be dropped, we don't need to check the transitions. + if (!blocksToDrop.get(stateToSccMapping[state])) { + for (uint64_t row = transitionMatrix.getRowGroupIndices()[state], endRow = transitionMatrix.getRowGroupIndices()[state + 1]; row != endRow; ++row) { + if (choices && !choices->get(row)) { + continue; + } + for (auto const& entry : transitionMatrix.getRow(row)) { + if (subsystem->get(entry.getColumn()) && stateToSccMapping[state] != stateToSccMapping[entry.getColumn()]) { + blocksToDrop.set(stateToSccMapping[state]); + break; + } + } + } + } + } + } else { + for (uint64_t state = 0; state < transitionMatrix.getRowGroupCount(); ++state) { + // If the block of the state is already known to be dropped, we don't need to check the transitions. + if (!blocksToDrop.get(stateToSccMapping[state])) { + for (uint64_t row = transitionMatrix.getRowGroupIndices()[state], endRow = transitionMatrix.getRowGroupIndices()[state + 1]; row != endRow; ++row) { + for (auto const& entry : transitionMatrix.getRow(row)) { + if (stateToSccMapping[state] != stateToSccMapping[entry.getColumn()]) { + blocksToDrop.set(stateToSccMapping[state]); + break; + } + } } } } @@ -160,15 +211,11 @@ namespace storm { template <typename ValueType> template <typename RewardModelType> void StronglyConnectedComponentDecomposition<ValueType>::performSccDecomposition(storm::models::sparse::Model<ValueType, RewardModelType> const& model, bool dropNaiveSccs, bool onlyBottomSccs) { - // Prepare a block that contains all states for a call to the other overload of this function. - storm::storage::BitVector fullSystem(model.getNumberOfStates(), true); - - // Call the overloaded function. - performSccDecomposition(model.getTransitionMatrix(), fullSystem, dropNaiveSccs, onlyBottomSccs); + performSccDecomposition(model.getTransitionMatrix(), nullptr, nullptr, dropNaiveSccs, onlyBottomSccs); } template <typename ValueType> - void StronglyConnectedComponentDecomposition<ValueType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) { + void StronglyConnectedComponentDecomposition<ValueType>::performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount) { // Prepare the stack used for turning the recursive procedure into an iterative one. std::vector<uint_fast64_t> recursionStateStack; @@ -187,20 +234,26 @@ namespace storm { s.push_back(currentState); p.push_back(currentState); - for (auto const& successor : transitionMatrix.getRowGroup(currentState)) { - if (subsystem.get(successor.getColumn()) && successor.getValue() != storm::utility::zero<ValueType>()) { - if (currentState == successor.getColumn()) { - statesWithSelfLoop.set(currentState); - } - - if (!hasPreorderNumber.get(successor.getColumn())) { - // In this case, we must recursively visit the successor. We therefore push the state - // onto the recursion stack. - recursionStateStack.push_back(successor.getColumn()); - } else { - if (!stateHasScc.get(successor.getColumn())) { - while (preorderNumbers[p.back()] > preorderNumbers[successor.getColumn()]) { - p.pop_back(); + for (uint64_t row = transitionMatrix.getRowGroupIndices()[currentState], rowEnd = transitionMatrix.getRowGroupIndices()[currentState + 1]; row != rowEnd; ++row) { + if (choices && !choices->get(row)) { + continue; + } + + for (auto const& successor : transitionMatrix.getRow(row)) { + if ((!subsystem || subsystem->get(successor.getColumn())) && successor.getValue() != storm::utility::zero<ValueType>()) { + if (currentState == successor.getColumn()) { + statesWithSelfLoop.set(currentState); + } + + if (!hasPreorderNumber.get(successor.getColumn())) { + // In this case, we must recursively visit the successor. We therefore push the state + // onto the recursion stack. + recursionStateStack.push_back(successor.getColumn()); + } else { + if (!stateHasScc.get(successor.getColumn())) { + while (preorderNumbers[p.back()] > preorderNumbers[successor.getColumn()]) { + p.pop_back(); + } } } } @@ -226,6 +279,91 @@ namespace storm { } } + template <typename ValueType> + void StronglyConnectedComponentDecomposition<ValueType>::sortTopologically(storm::storage::SparseMatrix<ValueType> const& transitions, uint64_t* longestChainSize) { + + // Get a mapping from state to the corresponding scc + STORM_LOG_THROW(this->size() < std::numeric_limits<uint32_t>::max(), storm::exceptions::UnexpectedException, "The number of SCCs is too large."); + std::vector<uint32_t> sccIndices(transitions.getRowGroupCount(), std::numeric_limits<uint32_t>::max()); + uint32_t sccIndex = 0; + for (auto const& scc : *this) { + for (auto const& state : scc) { + sccIndices[state] = sccIndex; + } + ++sccIndex; + } + + // Prepare the resulting set of sorted sccs + std::vector<storm::storage::StronglyConnectedComponent> sortedSCCs; + sortedSCCs.reserve(this->size()); + + // Find a topological sort via DFS. + storm::storage::BitVector unsortedSCCs(this->size(), true); + std::vector<uint32_t> sccStack, chainSizes; + if (longestChainSize != nullptr) { + chainSizes.resize(this->size(), 1u); + *longestChainSize = 0; + } + uint32_t const token = std::numeric_limits<uint32_t>::max(); + std::set<uint64_t> successorSCCs; + + for (uint32_t firstUnsortedScc = 0; firstUnsortedScc < unsortedSCCs.size(); firstUnsortedScc = unsortedSCCs.getNextSetIndex(firstUnsortedScc + 1)) { + + sccStack.push_back(firstUnsortedScc); + while (!sccStack.empty()) { + uint32_t currentSccIndex = sccStack.back(); + if (currentSccIndex != token) { + // Check whether the SCC is still unprocessed + if (unsortedSCCs.get(currentSccIndex)) { + // Explore the successors of the scc. + storm::storage::StronglyConnectedComponent const& currentScc = this->getBlock(currentSccIndex); + // We first push a token on the stack in order to recognize later when all successors of this SCC have been explored already. + sccStack.push_back(token); + // Now add all successors that are not already sorted. + // Successors should only be added once, so we first prepare a set of them and add them afterwards. + successorSCCs.clear(); + for (auto const& state : currentScc) { + for (auto const& entry : transitions.getRowGroup(state)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex && unsortedSCCs.get(successorSCC)) { + successorSCCs.insert(successorSCC); + } + } + } + sccStack.insert(sccStack.end(), successorSCCs.begin(), successorSCCs.end()); + + } + } else { + // all successors of the current scc have already been explored. + sccStack.pop_back(); // pop the token + + currentSccIndex = sccStack.back(); + storm::storage::StronglyConnectedComponent& scc = this->getBlock(currentSccIndex); + + // Compute the longest chain size for this scc + if (longestChainSize != nullptr) { + uint32_t& currentChainSize = chainSizes[currentSccIndex]; + for (auto const& state : scc) { + for (auto const& entry : transitions.getRowGroup(state)) { + auto const& successorSCC = sccIndices[entry.getColumn()]; + if (successorSCC != currentSccIndex) { + currentChainSize = std::max(currentChainSize, chainSizes[successorSCC] + 1); + } + } + } + *longestChainSize = std::max<uint64_t>(*longestChainSize, currentChainSize); + } + + unsortedSCCs.set(currentSccIndex, false); + sccStack.pop_back(); // pop the current scc index + sortedSCCs.push_back(std::move(scc)); + } + } + } + this->blocks = std::move(sortedSCCs); + } + + // Explicitly instantiate the SCC decomposition. template class StronglyConnectedComponentDecomposition<double>; template StronglyConnectedComponentDecomposition<double>::StronglyConnectedComponentDecomposition(storm::models::sparse::Model<double> const& model, bool dropNaiveSccs, bool onlyBottomSccs); diff --git a/src/storm/storage/StronglyConnectedComponentDecomposition.h b/src/storm/storage/StronglyConnectedComponentDecomposition.h index 20552a87b..7d244b914 100644 --- a/src/storm/storage/StronglyConnectedComponentDecomposition.h +++ b/src/storm/storage/StronglyConnectedComponentDecomposition.h @@ -78,7 +78,21 @@ namespace storm { * leaving the SCC), are kept. */ StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, bool dropNaiveSccs = false, bool onlyBottomSccs = false); - + + /* + * Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is + * given by a sparse matrix). + * + * @param transitionMatrix The transition matrix of the system to decompose. + * @param block The block to decompose into SCCs. + * @param choices A bit vector indicating which choices of the states are contained in the subsystem. + * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state + * without a self-loop) are to be kept in the decomposition. + * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of + * leaving the SCC), are kept. + */ + StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, StateBlock const& block, storm::storage::BitVector const& choices, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /* * Creates an SCC decomposition of the given system (whose transition relation is given by a sparse matrix). * @@ -103,6 +117,20 @@ namespace storm { */ StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /* + * Creates an SCC decomposition of the given subsystem in the given system (whose transition relation is + * given by a sparse matrix). + * + * @param transitionMatrix The transition matrix of the system to decompose. + * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. + * @param choices A bit vector indicating which choices of the states are contained in the subsystem. + * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state + * without a self-loop) are to be kept in the decomposition. + * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of + * leaving the SCC), are kept. + */ + StronglyConnectedComponentDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, storm::storage::BitVector const& choices, bool dropNaiveSccs = false, bool onlyBottomSccs = false); + /*! * Creates an SCC decomposition by copying the given SCC decomposition. * @@ -131,6 +159,14 @@ namespace storm { */ StronglyConnectedComponentDecomposition& operator=(StronglyConnectedComponentDecomposition&& other); + + /*! + * Sorts the SCCs topologically: The ith block can only reach states in block j<i + * @param longestChainSize if not nullptr, this value is set to the length m of the longest + * chain of SCCs B_1 B_2 ... B_m such that B_i can reach B_(i-1). + */ + void sortTopologically(storm::storage::SparseMatrix<ValueType> const& transitions, uint64_t* longestChainSize = nullptr); + private: /*! * Performs the SCC decomposition of the given model. As a side-effect this fills the vector of @@ -150,13 +186,14 @@ namespace storm { * the vector of blocks of the decomposition. * * @param transitionMatrix The transition matrix of the system to decompose. - * @param subsystem A bit vector indicating which subsystem to consider for the decomposition into SCCs. + * @param subsystem An optional bit vector indicating which subsystem to consider. + * @param choices An optional bit vector indicating which choices belong to the subsystem. * @param dropNaiveSccs A flag that indicates whether trivial SCCs (i.e. SCCs consisting of just one state * without a self-loop) are to be kept in the decomposition. * @param onlyBottomSccs If set to true, only bottom SCCs, i.e. SCCs in which all states have no way of * leaving the SCC), are kept. */ - void performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& subsystem, bool dropNaiveSccs, bool onlyBottomSccs); + void performSccDecomposition(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, bool dropNaiveSccs, bool onlyBottomSccs); /*! * Uses the algorithm by Gabow/Cheriyan/Mehlhorn ("Path-based strongly connected component algorithm") to @@ -167,7 +204,8 @@ namespace storm { * @param startState The starting state for the search of Tarjan's algorithm. * @param statesWithSelfLoop A bit vector that is to be filled with all states that have a self-loop. This * is later needed for identification of the naive SCCs. - * @param subsystem The subsystem to search. + * @param subsystem An optional bit vector indicating which subsystem to consider. + * @param choices An optional bit vector indicating which choices belong to the subsystem. * @param currentIndex The next free index that can be assigned to states. * @param hasPreorderNumber A bit that is used to keep track of the states that already have a preorder number. * @param preorderNumbers A vector storing the preorder number for each state. @@ -179,7 +217,7 @@ namespace storm { * @param sccCount The number of SCCs that have been computed. As a side effect of this function, this count * is increased. */ - void performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const& subsystem, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount); + void performSccDecompositionGCM(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, uint_fast64_t startState, storm::storage::BitVector& statesWithSelfLoop, storm::storage::BitVector const* subsystem, storm::storage::BitVector const* choices, uint_fast64_t& currentIndex, storm::storage::BitVector& hasPreorderNumber, std::vector<uint_fast64_t>& preorderNumbers, std::vector<uint_fast64_t>& s, std::vector<uint_fast64_t>& p, storm::storage::BitVector& stateHasScc, std::vector<uint_fast64_t>& stateToSccMapping, uint_fast64_t& sccCount); }; } } diff --git a/src/storm/storage/SymbolicModelDescription.cpp b/src/storm/storage/SymbolicModelDescription.cpp index e602e9300..b08166125 100644 --- a/src/storm/storage/SymbolicModelDescription.cpp +++ b/src/storm/storage/SymbolicModelDescription.cpp @@ -178,5 +178,16 @@ namespace storm { storm::utility::prism::requireNoUndefinedConstants(this->asPrismProgram()); } } + + std::ostream& operator<<(std::ostream& out, SymbolicModelDescription const& model) { + if (model.isPrismProgram()) { + out << model.asPrismProgram(); + } else if (model.isJaniModel()) { + out << model.asJaniModel(); + } else { + out << "unkown symbolic model description"; + } + return out; + } } } diff --git a/src/storm/storage/SymbolicModelDescription.h b/src/storm/storage/SymbolicModelDescription.h index 05daa5ec2..137f1a7d4 100644 --- a/src/storm/storage/SymbolicModelDescription.h +++ b/src/storm/storage/SymbolicModelDescription.h @@ -52,5 +52,7 @@ namespace storm { boost::optional<boost::variant<storm::jani::Model, storm::prism::Program>> modelDescription; }; + std::ostream& operator<<(std::ostream& out, SymbolicModelDescription const& model); + } } diff --git a/src/storm/storage/bisimulation/BisimulationDecomposition.cpp b/src/storm/storage/bisimulation/BisimulationDecomposition.cpp index fbeb10648..0b2578626 100644 --- a/src/storm/storage/bisimulation/BisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/BisimulationDecomposition.cpp @@ -168,7 +168,7 @@ namespace storm { template<typename ModelType, typename BlockDataType> BisimulationDecomposition<ModelType, BlockDataType>::BisimulationDecomposition(ModelType const& model, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, Options const& options) : model(model), backwardTransitions(backwardTransitions), options(options), partition(), comparator(), quotient(nullptr) { STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Bisimulation currently only supports models with at most one reward model."); - STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || model.getUniqueRewardModel().hasOnlyStateRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state rewards only. Consider converting the transition rewards to state rewards (via suitable function calls)."); + STORM_LOG_THROW(!options.getKeepRewards() || !model.hasRewardModel() || !model.getUniqueRewardModel().hasTransitionRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state or action rewards rewards only. Consider converting the transition rewards to state rewards (via suitable function calls)."); STORM_LOG_THROW(options.getType() != BisimulationType::Weak || !options.getBounded(), storm::exceptions::IllegalFunctionCallException, "Weak bisimulation cannot preserve bounded properties."); // Fix the respected atomic propositions if they were not explicitly given. @@ -259,9 +259,19 @@ namespace storm { } template<typename ModelType, typename BlockDataType> - void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnStateRewards() { - std::vector<ValueType> const& stateRewardVector = model.getUniqueRewardModel().getStateRewardVector(); - partition.split([&stateRewardVector] (storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { return stateRewardVector[a] < stateRewardVector[b]; }); + void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnRewards() { + auto const& rewardModel = model.getUniqueRewardModel(); + if (rewardModel.hasStateRewards()) { + this->splitInitialPartitionBasedOnRewards(rewardModel.getStateRewardVector()); + } + if (rewardModel.hasStateActionRewards() && (model.isOfType(storm::models::ModelType::Dtmc) || model.isOfType(storm::models::ModelType::Ctmc))) { + this->splitInitialPartitionBasedOnRewards(rewardModel.getStateActionRewardVector()); + } + } + + template<typename ModelType, typename BlockDataType> + void BisimulationDecomposition<ModelType, BlockDataType>::splitInitialPartitionBasedOnRewards(std::vector<ValueType> const& rewardVector) { + partition.split([&rewardVector] (storm::storage::sparse::state_type const& a, storm::storage::sparse::state_type const& b) { return rewardVector[a] < rewardVector[b]; }); } template<typename ModelType, typename BlockDataType> @@ -278,7 +288,7 @@ namespace storm { // If the model has state rewards, we need to consider them, because otherwise reward properties are not // preserved. if (options.getKeepRewards() && model.hasRewardModel()) { - this->splitInitialPartitionBasedOnStateRewards(); + this->splitInitialPartitionBasedOnRewards(); } } @@ -296,7 +306,7 @@ namespace storm { // If the model has state rewards, we need to consider them, because otherwise reward properties are not // preserved. if (options.getKeepRewards() && model.hasRewardModel()) { - this->splitInitialPartitionBasedOnStateRewards(); + this->splitInitialPartitionBasedOnRewards(); } } diff --git a/src/storm/storage/bisimulation/BisimulationDecomposition.h b/src/storm/storage/bisimulation/BisimulationDecomposition.h index 51383da56..dabdaf549 100644 --- a/src/storm/storage/bisimulation/BisimulationDecomposition.h +++ b/src/storm/storage/bisimulation/BisimulationDecomposition.h @@ -250,11 +250,16 @@ namespace storm { * @return The states with probability 0 and 1. */ virtual std::pair<storm::storage::BitVector, storm::storage::BitVector> getStatesWithProbability01() = 0; - + + /*! + * Splits the initial partition based on the (unique) reward model of the current model. + */ + virtual void splitInitialPartitionBasedOnRewards(); + /*! - * Splits the initial partition based on the (unique) state reward vector of the model. + * Splits the initial partition based on the given reward vector. */ - virtual void splitInitialPartitionBasedOnStateRewards(); + virtual void splitInitialPartitionBasedOnRewards(std::vector<ValueType> const& rewardVector); /*! * Constructs the blocks of the decomposition object based on the current partition. diff --git a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp index a90de5bb6..a084de9ba 100644 --- a/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp @@ -118,7 +118,6 @@ namespace storm { this->initializeSilentProbabilities(); } - template<typename ModelType> void DeterministicModelBisimulationDecomposition<ModelType>::postProcessInitialPartition() { if (this->options.getType() == BisimulationType::Weak && this->model.getType() == storm::models::ModelType::Dtmc) { @@ -127,14 +126,15 @@ namespace storm { if (this->options.getKeepRewards() && this->model.hasRewardModel() && this->options.getType() == BisimulationType::Weak) { // For a weak bisimulation that is to preserve reward properties, we have to flag all blocks of states - // with non-zero reward as reward blocks to they can be refined wrt. strong bisimulation. + // with non-zero reward as reward blocks so they can be refined wrt. strong bisimulation. - // Here, we assume that the initial partition already respects state rewards. Therefore, it suffices to + // Here, we assume that the initial partition already respects state (and action) rewards. Therefore, it suffices to // check the first state of each block for a non-zero reward. - std::vector<ValueType> const& stateRewardVector = this->model.getUniqueRewardModel().getStateRewardVector(); + boost::optional<std::vector<ValueType>> const& optionalStateRewardVector = this->model.getUniqueRewardModel().getOptionalStateRewardVector(); + boost::optional<std::vector<ValueType>> const& optionalStateActionRewardVector = this->model.getUniqueRewardModel().getOptionalStateActionRewardVector(); for (auto& block : this->partition.getBlocks()) { auto state = *this->partition.begin(*block); - block->data().setHasRewards(!storm::utility::isZero(stateRewardVector[state])); + block->data().setHasRewards((optionalStateRewardVector && !storm::utility::isZero(optionalStateRewardVector.get()[state])) || (optionalStateActionRewardVector && !storm::utility::isZero(optionalStateActionRewardVector.get()[state]))); } } } @@ -419,7 +419,7 @@ namespace storm { // the sorting is over. Otherwise, this interferes with the data used in the sorting process. storm::storage::sparse::state_type originalBlockIndex = block.getBeginIndex(); auto split = this->partition.splitBlock(block, - [&weakStateLabels,&block,originalBlockIndex,this] (storm::storage::sparse::state_type state1, storm::storage::sparse::state_type state2) { + [&weakStateLabels, originalBlockIndex,this] (storm::storage::sparse::state_type state1, storm::storage::sparse::state_type state2) { return weakStateLabels[this->partition.getPosition(state1) - originalBlockIndex] < weakStateLabels[this->partition.getPosition(state2) - originalBlockIndex]; }, [this, &splitterQueue, &block] (bisimulation::Block<BlockDataType>& newBlock) { @@ -661,7 +661,13 @@ namespace storm { // If the model has state rewards, we simply copy the state reward of the representative state, because // all states in a block are guaranteed to have the same state reward. if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards.get()[blockIndex] = this->model.getUniqueRewardModel().getStateRewardVector()[representativeState]; + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateRewards()) { + stateRewards.get()[blockIndex] = rewardModel.getStateRewardVector()[representativeState]; + } + if (rewardModel.hasStateActionRewards()) { + stateRewards.get()[blockIndex] += rewardModel.getStateActionRewardVector()[representativeState]; + } } } diff --git a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp index 1b1d3d0f1..019ec40c2 100644 --- a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp +++ b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.cpp @@ -63,6 +63,12 @@ namespace storm { // Otherwise, we compute the probabilities from the transition matrix. for (auto stateIt = this->partition.begin(*block), stateIte = this->partition.end(*block); stateIt != stateIte; ++stateIt) { for (uint_fast64_t choice = nondeterministicChoiceIndices[*stateIt]; choice < nondeterministicChoiceIndices[*stateIt + 1]; ++choice) { + if (this->options.getKeepRewards() && this->model.hasRewardModel()) { + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateActionRewards()) { + this->quotientDistributions[choice].setReward(rewardModel.getStateActionReward(choice)); + } + } for (auto entry : this->model.getTransitionMatrix().getRow(choice)) { if (!this->comparator.isZero(entry.getValue())) { this->quotientDistributions[choice].addProbability(this->partition.getBlock(entry.getColumn()).getId(), entry.getValue()); @@ -107,10 +113,18 @@ namespace storm { newLabeling.addLabel(ap); } - // If the model had state rewards, we need to build the state rewards for the quotient as well. + // If the model had state (action) rewards, we need to build the state rewards for the quotient as well. boost::optional<std::vector<ValueType>> stateRewards; + boost::optional<std::vector<ValueType>> stateActionRewards; + boost::optional<storm::models::sparse::StandardRewardModel<ValueType> const&> rewardModel; if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards = std::vector<ValueType>(this->blocks.size()); + rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.get().hasStateRewards()) { + stateRewards = std::vector<ValueType>(this->blocks.size()); + } + if (rewardModel.get().hasStateActionRewards()) { + stateActionRewards = std::vector<ValueType>(); + } } // Now build (a) and (b) by traversing all blocks. @@ -137,6 +151,11 @@ namespace storm { representativeState = oldBlock.data().representativeState(); } + // Give the choice a reward of zero as we artificially introduced that the block is absorbing. + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateActionRewards()) { + stateActionRewards.get().push_back(storm::utility::zero<ValueType>()); + } + // Add all of the selected atomic propositions that hold in the representative state to the state // representing the block. for (auto const& ap : atomicPropositions) { @@ -155,6 +174,9 @@ namespace storm { for (auto entry : quotientDistributions[choice]) { builder.addNextValue(currentRow, entry.first, entry.second); } + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateActionRewards()) { + stateActionRewards.get().push_back(quotientDistributions[choice].getReward()); + } ++currentRow; } @@ -169,8 +191,8 @@ namespace storm { // If the model has state rewards, we simply copy the state reward of the representative state, because // all states in a block are guaranteed to have the same state reward. - if (this->options.getKeepRewards() && this->model.hasRewardModel()) { - stateRewards.get()[blockIndex] = this->model.getUniqueRewardModel().getStateRewardVector()[representativeState]; + if (this->options.getKeepRewards() && rewardModel && rewardModel.get().hasStateRewards()) { + stateRewards.get()[blockIndex] = rewardModel.get().getStateRewardVector()[representativeState]; } } @@ -185,7 +207,7 @@ namespace storm { if (this->options.getKeepRewards() && this->model.hasRewardModel()) { STORM_LOG_THROW(this->model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Cannot preserve more than one reward model."); typename std::unordered_map<std::string, typename ModelType::RewardModelType>::const_iterator nameRewardModelPair = this->model.getRewardModels().begin(); - rewardModels.insert(std::make_pair(nameRewardModelPair->first, typename ModelType::RewardModelType(stateRewards))); + rewardModels.insert(std::make_pair(nameRewardModelPair->first, typename ModelType::RewardModelType(stateRewards, stateActionRewards))); } // Finally construct the quotient model. @@ -217,7 +239,7 @@ namespace storm { continue; } - // If the predecessor block is not marked as to-refined, we do so now. + // If the predecessor block is not marked as to-be-refined, we do so now. if (!predecessorBlock.data().splitter()) { predecessorBlock.data().setSplitter(); splitterQueue.push_back(&predecessorBlock); @@ -250,7 +272,13 @@ namespace storm { std::vector<uint_fast64_t> nondeterministicChoiceIndices = this->model.getTransitionMatrix().getRowGroupIndices(); for (decltype(this->model.getNumberOfStates()) state = 0; state < this->model.getNumberOfStates(); ++state) { for (auto choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) { - storm::storage::Distribution<ValueType> distribution; + storm::storage::DistributionWithReward<ValueType> distribution; + if (this->options.getKeepRewards() && this->model.hasRewardModel()) { + auto const& rewardModel = this->model.getUniqueRewardModel(); + if (rewardModel.hasStateActionRewards()) { + distribution.setReward(rewardModel.getStateActionReward(choice)); + } + } for (auto const& element : this->model.getTransitionMatrix().getRow(choice)) { distribution.addProbability(this->partition.getBlock(element.getColumn()).getId(), element.getValue()); } @@ -339,7 +367,7 @@ namespace storm { bool result = quotientDistributionsLess(state1, state2); return result; }, - [this, &block, &splitterQueue, &newBlocks] (Block<BlockDataType>& newBlock) { + [&newBlocks] (Block<BlockDataType>& newBlock) { newBlocks.push_back(&newBlock); }); @@ -348,7 +376,7 @@ namespace storm { for (auto el : newBlocks) { this->updateQuotientDistributionsOfPredecessors(*el, block, splitterQueue); } - + return split; } diff --git a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h index 811bce213..f42415c49 100644 --- a/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h +++ b/src/storm/storage/bisimulation/NondeterministicModelBisimulationDecomposition.h @@ -4,7 +4,7 @@ #include "storm/storage/bisimulation/BisimulationDecomposition.h" #include "storm/storage/bisimulation/DeterministicBlockData.h" -#include "storm/storage/Distribution.h" +#include "storm/storage/DistributionWithReward.h" namespace storm { namespace utility { @@ -73,10 +73,10 @@ namespace storm { std::vector<storm::storage::sparse::state_type> choiceToStateMapping; // A vector that holds the quotient distributions for all nondeterministic choices of all states. - std::vector<storm::storage::Distribution<ValueType>> quotientDistributions; + std::vector<storm::storage::DistributionWithReward<ValueType>> quotientDistributions; // A vector that stores for each state the ordered list of quotient distributions. - std::vector<storm::storage::Distribution<ValueType> const*> orderedQuotientDistributions; + std::vector<storm::storage::DistributionWithReward<ValueType> const*> orderedQuotientDistributions; }; } } diff --git a/src/storm/storage/dd/Add.cpp b/src/storm/storage/dd/Add.cpp index 635d16aed..9e91b2123 100644 --- a/src/storm/storage/dd/Add.cpp +++ b/src/storm/storage/dd/Add.cpp @@ -231,6 +231,46 @@ namespace storm { return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); } + template<DdType LibraryType, typename ValueType> + Add<LibraryType, ValueType> Add<LibraryType, ValueType>::renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + STORM_LOG_ASSERT(fromBdds.size() >= toBdds.size(), "Unable to perform rename-abstract with mismatching sizes."); + + if (fromBdds.size() == toBdds.size()) { + return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.permuteVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = toBdds.size(); index < fromBdds.size(); ++index) { + cube &= fromBdds[index]; + } + fromBdds.resize(toBdds.size()); + + return Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.sumAbstract(cube).permuteVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + template<DdType LibraryType, typename ValueType> Add<LibraryType, ValueType> Add<LibraryType, ValueType>::swapVariables(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& metaVariablePairs) const { std::set<storm::expressions::Variable> newContainedMetaVariables; diff --git a/src/storm/storage/dd/Add.h b/src/storm/storage/dd/Add.h index c25b5a8c4..1a4a811d5 100644 --- a/src/storm/storage/dd/Add.h +++ b/src/storm/storage/dd/Add.h @@ -331,6 +331,20 @@ namespace storm { */ Add<LibraryType, ValueType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! + * Renames the given meta variables in the ADD. The number of the underlying DD variables of the from meta + * variable set needs to be at least as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first abstracts from the superfluous variables + * and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Add<LibraryType, ValueType> renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + + /*! * Swaps the given pairs of meta variables in the ADD. The pairs of meta variables must be guaranteed to have * the same number of underlying ADD variables. diff --git a/src/storm/storage/dd/Bdd.cpp b/src/storm/storage/dd/Bdd.cpp index 66c6d69a7..c2452ed3b 100644 --- a/src/storm/storage/dd/Bdd.cpp +++ b/src/storm/storage/dd/Bdd.cpp @@ -319,6 +319,86 @@ namespace storm { return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); } + template<DdType LibraryType> + Bdd<LibraryType> Bdd<LibraryType>::renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + STORM_LOG_ASSERT(fromBdds.size() >= toBdds.size(), "Unable to perform rename-abstract with mismatching sizes."); + + if (fromBdds.size() == toBdds.size()) { + return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> cube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = toBdds.size(); index < fromBdds.size(); ++index) { + cube &= fromBdds[index]; + } + fromBdds.resize(toBdds.size()); + + return Bdd<LibraryType>(this->getDdManager(), internalBdd.existsAbstract(cube).swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + + template<DdType LibraryType> + Bdd<LibraryType> Bdd<LibraryType>::renameVariablesConcretize(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const { + std::vector<InternalBdd<LibraryType>> fromBdds; + std::vector<InternalBdd<LibraryType>> toBdds; + + for (auto const& metaVariable : from) { + STORM_LOG_THROW(this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename variable '" << metaVariable.getName() << "' that is not present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + fromBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(fromBdds.begin(), fromBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + for (auto const& metaVariable : to) { + STORM_LOG_THROW(!this->containsMetaVariable(metaVariable), storm::exceptions::InvalidOperationException, "Cannot rename to variable '" << metaVariable.getName() << "' that is already present."); + DdMetaVariable<LibraryType> const& ddMetaVariable = this->getDdManager().getMetaVariable(metaVariable); + for (auto const& ddVariable : ddMetaVariable.getDdVariables()) { + toBdds.push_back(ddVariable.getInternalBdd()); + } + } + std::sort(toBdds.begin(), toBdds.end(), [] (InternalBdd<LibraryType> const& a, InternalBdd<LibraryType> const& b) { return a.getLevel() < b.getLevel(); } ); + + std::set<storm::expressions::Variable> newContainedMetaVariables = to; + std::set_difference(this->getContainedMetaVariables().begin(), this->getContainedMetaVariables().end(), from.begin(), from.end(), std::inserter(newContainedMetaVariables, newContainedMetaVariables.begin())); + + STORM_LOG_ASSERT(toBdds.size() >= fromBdds.size(), "Unable to perform rename-concretize with mismatching sizes."); + + if (fromBdds.size() == toBdds.size()) { + return Bdd<LibraryType>(this->getDdManager(), internalBdd.swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } else { + InternalBdd<LibraryType> negatedCube = this->getDdManager().getBddOne().getInternalBdd(); + for (uint64_t index = fromBdds.size(); index < toBdds.size(); ++index) { + negatedCube &= !toBdds[index]; + } + toBdds.resize(fromBdds.size()); + + return Bdd<LibraryType>(this->getDdManager(), (internalBdd && negatedCube).swapVariables(fromBdds, toBdds), newContainedMetaVariables); + } + } + template<DdType LibraryType> template<typename ValueType> Add<LibraryType, ValueType> Bdd<LibraryType>::toAdd() const { diff --git a/src/storm/storage/dd/Bdd.h b/src/storm/storage/dd/Bdd.h index 41d6b2b86..bfb845c70 100644 --- a/src/storm/storage/dd/Bdd.h +++ b/src/storm/storage/dd/Bdd.h @@ -285,6 +285,32 @@ namespace storm { */ Bdd<LibraryType> renameVariables(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! + * Renames the given meta variables in the BDD. The number of the underlying DD variables of the from meta + * variable set needs to be at least as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first abstracts from the superfluous variables + * and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Bdd<LibraryType> renameVariablesAbstract(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + + /*! + * Renames the given meta variables in the BDD. The number of the underlying DD variables of the from meta + * variable set needs to be at most as large as the to meta variable set. If the amount of variables coincide, + * this operation coincides with renameVariables. Otherwise, it first adds a unique encoding in terms of the + * superfluous variables and then performs the renaming. + * + * @param from The meta variables to be renamed. The current ADD needs to contain all these meta variables. + * @param to The meta variables that are the target of the renaming process. The current ADD must not contain + * any of these meta variables. + * @return The resulting ADD. + */ + Bdd<LibraryType> renameVariablesConcretize(std::set<storm::expressions::Variable> const& from, std::set<storm::expressions::Variable> const& to) const; + /*! * Retrieves whether this DD represents the constant one function. * diff --git a/src/storm/storage/dd/BisimulationDecomposition.cpp b/src/storm/storage/dd/BisimulationDecomposition.cpp index 6d649aede..d43dd9c65 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.cpp +++ b/src/storm/storage/dd/BisimulationDecomposition.cpp @@ -2,7 +2,7 @@ #include "storm/storage/dd/bisimulation/Partition.h" #include "storm/storage/dd/bisimulation/PartitionRefiner.h" -#include "storm/storage/dd/bisimulation/MdpPartitionRefiner.h" +#include "storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h" #include "storm/storage/dd/bisimulation/QuotientExtractor.h" #include "storm/storage/dd/bisimulation/PartialQuotientExtractor.h" @@ -24,51 +24,53 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> std::unique_ptr<PartitionRefiner<DdType, ValueType>> createRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition) { - if (model.isOfType(storm::models::ModelType::Mdp)) { - return std::make_unique<MdpPartitionRefiner<DdType, ValueType>>(*model.template as<storm::models::symbolic::Mdp<DdType, ValueType>>(), initialPartition); + if (model.isOfType(storm::models::ModelType::Mdp) || model.isOfType(storm::models::ModelType::MarkovAutomaton)) { + return std::make_unique<NondeterministicModelPartitionRefiner<DdType, ValueType>>(*model.template as<storm::models::symbolic::NondeterministicModel<DdType, ValueType>>(), initialPartition); } else { return std::make_unique<PartitionRefiner<DdType, ValueType>>(model, initialPartition); } } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, preservationInformation))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, storm::storage::BisimulationType const& bisimulationType) : model(model), preservationInformation(model, formulas), refiner(createRefiner(model, Partition<DdType, ValueType>::create(model, bisimulationType, formulas))) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialPartition, bisimulation::PreservationInformation<DdType, ValueType> const& preservationInformation) : model(model), preservationInformation(preservationInformation), refiner(createRefiner(model, initialPartition)) { this->initialize(); } - template <storm::dd::DdType DdType, typename ValueType> - BisimulationDecomposition<DdType, ValueType>::~BisimulationDecomposition() = default; + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + BisimulationDecomposition<DdType, ValueType, ExportValueType>::~BisimulationDecomposition() = default; - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::initialize() { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::initialize() { auto const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>(); - showProgress = generalSettings.isVerboseSet(); + verboseProgress = generalSettings.isVerboseSet(); showProgressDelay = generalSettings.getShowProgressDelay(); + + auto start = std::chrono::high_resolution_clock::now(); this->refineWrtRewardModels(); + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Refining with respect to reward models took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); - STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); -#ifndef NDEBUG + STORM_LOG_INFO("Initial partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); STORM_LOG_TRACE("Initial partition has " << refiner->getStatePartition().getNodeCount() << " nodes."); -#endif } - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::compute(bisimulation::SignatureMode const& mode) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::compute(bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); @@ -80,25 +82,22 @@ namespace storm { refined = refiner->refine(mode); ++iterations; - STORM_LOG_TRACE("After iteration " << iterations << " partition has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - if (showProgress) { - auto now = std::chrono::high_resolution_clock::now(); - auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); - if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay) { - auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); - STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "s) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - timeOfLastMessage = std::chrono::high_resolution_clock::now(); - } + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::milliseconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay * 1000 || verboseProgress) { + auto durationSinceStart = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count(); + STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_DEBUG("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations)."); + STORM_LOG_INFO("Partition refinement completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms (" << iterations << " iterations, signature: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalSignatureTime()).count() << "ms, refinement: " << std::chrono::duration_cast<std::chrono::milliseconds>(refiner->getTotalRefinementTime()).count() << "ms)."); } - template <storm::dd::DdType DdType, typename ValueType> - bool BisimulationDecomposition<DdType, ValueType>::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + bool BisimulationDecomposition<DdType, ValueType, ExportValueType>::compute(uint64_t steps, bisimulation::SignatureMode const& mode) { STORM_LOG_ASSERT(refiner, "No suitable refiner."); STORM_LOG_ASSERT(this->refiner->getStatus() != Status::FixedPoint, "Can only proceed if no fixpoint has been reached yet."); STORM_LOG_ASSERT(steps > 0, "Can only perform positive number of steps."); @@ -112,49 +111,47 @@ namespace storm { ++iterations; - if (showProgress) { - auto now = std::chrono::high_resolution_clock::now(); - auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); - if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay) { - auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); - STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); - timeOfLastMessage = std::chrono::high_resolution_clock::now(); - } + auto now = std::chrono::high_resolution_clock::now(); + auto durationSinceLastMessage = std::chrono::duration_cast<std::chrono::seconds>(now - timeOfLastMessage).count(); + if (static_cast<uint64_t>(durationSinceLastMessage) >= showProgressDelay || verboseProgress) { + auto durationSinceStart = std::chrono::duration_cast<std::chrono::seconds>(now - start).count(); + STORM_LOG_INFO("State partition after " << iterations << " iterations (" << durationSinceStart << "ms) has " << refiner->getStatePartition().getNumberOfBlocks() << " blocks."); + timeOfLastMessage = std::chrono::high_resolution_clock::now(); } } return !refined; } - template <storm::dd::DdType DdType, typename ValueType> - bool BisimulationDecomposition<DdType, ValueType>::getReachedFixedPoint() const { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + bool BisimulationDecomposition<DdType, ValueType, ExportValueType>::getReachedFixedPoint() const { return this->refiner->getStatus() == Status::FixedPoint; } - template <storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> BisimulationDecomposition<DdType, ValueType>::getQuotient() const { - std::shared_ptr<storm::models::Model<ValueType>> quotient; + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> BisimulationDecomposition<DdType, ValueType, ExportValueType>::getQuotient() const { + std::shared_ptr<storm::models::Model<ExportValueType>> quotient; if (this->refiner->getStatus() == Status::FixedPoint) { - STORM_LOG_TRACE("Starting full quotient extraction."); - QuotientExtractor<DdType, ValueType> extractor; + STORM_LOG_INFO("Starting full quotient extraction."); + QuotientExtractor<DdType, ValueType, ExportValueType> extractor; quotient = extractor.extract(model, refiner->getStatePartition(), preservationInformation); } else { STORM_LOG_THROW(model.getType() == storm::models::ModelType::Dtmc || model.getType() == storm::models::ModelType::Mdp, storm::exceptions::InvalidOperationException, "Can only extract partial quotient for discrete-time models."); - STORM_LOG_TRACE("Starting partial quotient extraction."); + STORM_LOG_INFO("Starting partial quotient extraction."); if (!partialQuotientExtractor) { - partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType>>(model); + partialQuotientExtractor = std::make_unique<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>>(model); } quotient = partialQuotientExtractor->extract(refiner->getStatePartition(), preservationInformation); } - STORM_LOG_TRACE("Quotient extraction done."); + STORM_LOG_INFO("Quotient extraction done."); return quotient; } - template <storm::dd::DdType DdType, typename ValueType> - void BisimulationDecomposition<DdType, ValueType>::refineWrtRewardModels() { + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + void BisimulationDecomposition<DdType, ValueType, ExportValueType>::refineWrtRewardModels() { for (auto const& rewardModelName : this->preservationInformation.getRewardModelNames()) { auto const& rewardModel = this->model.getRewardModel(rewardModelName); refiner->refineWrtRewardModel(rewardModel); @@ -165,6 +162,7 @@ namespace storm { template class BisimulationDecomposition<storm::dd::DdType::Sylvan, double>; template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class BisimulationDecomposition<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/storage/dd/BisimulationDecomposition.h b/src/storm/storage/dd/BisimulationDecomposition.h index 21ff7de2a..1a552c497 100644 --- a/src/storm/storage/dd/BisimulationDecomposition.h +++ b/src/storm/storage/dd/BisimulationDecomposition.h @@ -29,11 +29,11 @@ namespace storm { template <storm::dd::DdType DdType, typename ValueType> class PartitionRefiner; - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType> class PartialQuotientExtractor; } - template <storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class BisimulationDecomposition { public: BisimulationDecomposition(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::storage::BisimulationType const& bisimulationType); @@ -64,7 +64,7 @@ namespace storm { /*! * Retrieves the quotient model after the bisimulation decomposition was computed. */ - std::shared_ptr<storm::models::Model<ValueType>> getQuotient() const; + std::shared_ptr<storm::models::Model<ExportValueType>> getQuotient() const; private: void initialize(); @@ -80,10 +80,10 @@ namespace storm { std::unique_ptr<bisimulation::PartitionRefiner<DdType, ValueType>> refiner; // A quotient extractor that is used when the fixpoint has not been reached yet. - mutable std::unique_ptr<bisimulation::PartialQuotientExtractor<DdType, ValueType>> partialQuotientExtractor; + mutable std::unique_ptr<bisimulation::PartialQuotientExtractor<DdType, ValueType, ExportValueType>> partialQuotientExtractor; // A flag indicating whether progress is reported. - bool showProgress; + bool verboseProgress; // The delay between progress reports. uint64_t showProgressDelay; diff --git a/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp index 08a1585e7..cb281f719 100644 --- a/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/InternalCuddSignatureRefiner.cpp @@ -117,10 +117,11 @@ namespace storm { DdNode* partitionThen; DdNode* partitionElse; short offset; - bool isNondeterminismVariable = false; + bool isNondeterminismVariable; while (skipped && !Cudd_IsConstant(nonBlockVariablesNode)) { // Remember an offset that indicates whether the top variable is a nondeterminism variable or not. offset = options.shiftStateVariables ? 1 : 0; + isNondeterminismVariable = false; if (!Cudd_IsConstant(nondeterminismVariablesNode) && Cudd_NodeReadIndex(nondeterminismVariablesNode) == Cudd_NodeReadIndex(nonBlockVariablesNode)) { offset = 0; isNondeterminismVariable = true; @@ -260,10 +261,11 @@ namespace storm { DdNode* signatureThen; DdNode* signatureElse; short offset; - bool isNondeterminismVariable = false; + bool isNondeterminismVariable; while (skippedBoth && !Cudd_IsConstant(nonBlockVariablesNode)) { // Remember an offset that indicates whether the top variable is a nondeterminism variable or not. offset = options.shiftStateVariables ? 1 : 0; + isNondeterminismVariable = false; if (!Cudd_IsConstant(nondeterminismVariablesNode) && Cudd_NodeReadIndex(nondeterminismVariablesNode) == Cudd_NodeReadIndex(nonBlockVariablesNode)) { offset = 0; isNondeterminismVariable = true; diff --git a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp index 07c46fc3c..ce14cd837 100644 --- a/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/InternalSylvanSignatureRefiner.cpp @@ -11,13 +11,15 @@ namespace storm { namespace dd { namespace bisimulation { + static const uint64_t NO_ELEMENT_MARKER = -1ull; + InternalSylvanSignatureRefinerBase::InternalSylvanSignatureRefinerBase(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& manager, storm::expressions::Variable const& blockVariable, std::set<storm::expressions::Variable> const& stateVariables, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nondeterminismVariables, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& nonBlockVariables, InternalSignatureRefinerOptions const& options) : manager(manager), blockVariable(blockVariable), stateVariables(stateVariables), nondeterminismVariables(nondeterminismVariables), nonBlockVariables(nonBlockVariables), options(options), numberOfBlockVariables(manager.getMetaVariable(blockVariable).getNumberOfDdVariables()), blockCube(manager.getMetaVariable(blockVariable).getCube()), nextFreeBlockIndex(0), numberOfRefinements(0), currentCapacity(1ull << 20), resizeFlag(0) { // Perform garbage collection to clean up stuff not needed anymore. LACE_ME; sylvan_gc(); - table.resize(3 * currentCapacity); + table.resize(3 * currentCapacity, NO_ELEMENT_MARKER); } template<typename ValueType> @@ -30,13 +32,14 @@ namespace storm { Partition<storm::dd::DdType::Sylvan, ValueType> InternalSignatureRefiner<storm::dd::DdType::Sylvan, ValueType>::refine(Partition<storm::dd::DdType::Sylvan, ValueType> const& oldPartition, Signature<storm::dd::DdType::Sylvan, ValueType> const& signature) { std::pair<storm::dd::Bdd<storm::dd::DdType::Sylvan>, boost::optional<storm::dd::Bdd<storm::dd::DdType::Sylvan>>> newPartitionDds = refine(oldPartition, signature.getSignatureAdd()); ++numberOfRefinements; + return oldPartition.replacePartition(newPartitionDds.first, nextFreeBlockIndex, nextFreeBlockIndex, newPartitionDds.second); } template<typename ValueType> void InternalSignatureRefiner<storm::dd::DdType::Sylvan, ValueType>::clearCaches() { for (auto& e : this->table) { - e = 0ull; + e = NO_ELEMENT_MARKER; } for (auto& e : this->signatures) { e = 0ull; @@ -142,7 +145,7 @@ namespace storm { uint64_t oldCapacity = refiner->currentCapacity; refiner->currentCapacity <<= 1; - refiner->table = std::vector<uint64_t>(3 * refiner->currentCapacity); + refiner->table = std::vector<uint64_t>(3 * refiner->currentCapacity, NO_ELEMENT_MARKER); CALL(sylvan_rehash, 0, oldCapacity, refiner); @@ -173,13 +176,13 @@ namespace storm { ptr = refiner->table.data() + pos*3; a = *ptr; if (a == sig) { - while ((b=ptr[1]) == 0) continue; + while ((b=ptr[1]) == NO_ELEMENT_MARKER) continue; if (b == previous_block) { - while ((c=ptr[2]) == 0) continue; + while ((c=ptr[2]) == NO_ELEMENT_MARKER) continue; return c; } - } else if (a == 0) { - if (cas(ptr, 0, sig)) { + } else if (a == NO_ELEMENT_MARKER) { + if (cas(ptr, NO_ELEMENT_MARKER, sig)) { c = ptr[2] = __sync_fetch_and_add(&refiner->nextFreeBlockIndex, 1); ptr[1] = previous_block; return c; @@ -189,7 +192,7 @@ namespace storm { } pos++; if (pos >= refiner->currentCapacity) pos = 0; - if (++count >= 128) return 0; + if (++count >= 128) return NO_ELEMENT_MARKER; } } @@ -219,11 +222,11 @@ namespace storm { } return sylvan_cube(vars, e.data()); } - + TASK_3(BDD, sylvan_assign_block, BDD, sig, BDD, previous_block, InternalSylvanSignatureRefinerBase*, refiner) { assert(previous_block != mtbdd_false); // if so, incorrect call! - + // maybe do garbage collection sylvan_gc_test(); @@ -232,21 +235,25 @@ namespace storm { sig = (uint64_t)-1; } - // try to claim previous block number - assert(previous_block != sylvan_false); - const uint64_t p_b = CALL(sylvan_decode_block, previous_block); - assert(p_b < refiner->signatures.size()); - - for (;;) { - BDD cur = *(volatile BDD*)&refiner->signatures[p_b]; - if (cur == sig) return previous_block; - if (cur != 0) break; - if (cas(&refiner->signatures[p_b], 0, sig)) return previous_block; + if (refiner->options.reuseBlockNumbers) { + // try to claim previous block number + assert(previous_block != sylvan_false); + const uint64_t p_b = CALL(sylvan_decode_block, previous_block); + assert(p_b < refiner->signatures.size()); + + for (;;) { + BDD cur = *(volatile BDD*)&refiner->signatures[p_b]; + if (cur == sig) return previous_block; + if (cur != 0) break; + if (cas(&refiner->signatures[p_b], 0, sig)) return previous_block; + } } // no previous block number, search or insert uint64_t c; - while ((c = sylvan_search_or_insert(sig, previous_block, refiner)) == 0) CALL(sylvan_grow, refiner); + while ((c = sylvan_search_or_insert(sig, previous_block, refiner)) == NO_ELEMENT_MARKER) { + CALL(sylvan_grow, refiner); + } return CALL(sylvan_encode_block, refiner->blockCube.getInternalBdd().getSylvanBdd().GetBDD(), refiner->numberOfBlockVariables, c); } diff --git a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp deleted file mode 100644 index bd585fa83..000000000 --- a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "storm/storage/dd/bisimulation/MdpPartitionRefiner.h" - -#include "storm/models/symbolic/Mdp.h" -#include "storm/models/symbolic/StandardRewardModel.h" - -namespace storm { - namespace dd { - namespace bisimulation { - - template<storm::dd::DdType DdType, typename ValueType> - MdpPartitionRefiner<DdType, ValueType>::MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(mdp, initialStatePartition), mdp(mdp), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(mdp, initialStatePartition.getBlockVariables())), stateSignatureRefiner(mdp.getManager(), this->statePartition.getBlockVariable(), mdp.getRowVariables(), mdp.getColumnVariables(), true) { - // Intentionally left empty. - } - - template<storm::dd::DdType DdType, typename ValueType> - bool MdpPartitionRefiner<DdType, ValueType>::refine(bisimulation::SignatureMode const& mode) { - // In this procedure, we will - // (1) refine the partition of nondeterministic choices based on the state partition. For this, we use - // the signature computer/refiner of the superclass. These objects use the full transition matrix. - // (2) if the choice partition was in fact split, the state partition also needs to be refined. - // For this, we use the signature computer/refiner of this class. - - STORM_LOG_TRACE("Refining choice partition."); - Partition<DdType, ValueType> newChoicePartition = this->internalRefine(this->signatureComputer, this->signatureRefiner, this->choicePartition, this->statePartition, mode); - - if (newChoicePartition.getNumberOfBlocks() == choicePartition.getNumberOfBlocks()) { - this->status = Status::FixedPoint; - return false; - } else { - this->choicePartition = newChoicePartition; - - // Compute state signatures. - storm::dd::Bdd<DdType> choicePartitionAsBdd; - if (this->choicePartition.storedAsBdd()) { - choicePartitionAsBdd = this->choicePartition.asBdd(); - } else { - choicePartitionAsBdd = this->choicePartition.asAdd().notZero(); - } - Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(mdp.getNondeterminismVariables()).template toAdd<ValueType>()); - - // If the choice partition changed, refine the state partition. - STORM_LOG_TRACE("Refining state partition."); - Partition<DdType, ValueType> newStatePartition = this->internalRefine(stateSignature, this->stateSignatureRefiner, this->statePartition); - - if (newStatePartition == this->statePartition) { - this->status = Status::FixedPoint; - return false; - } else { - this->statePartition = newStatePartition; - return true; - } - } - } - - template<storm::dd::DdType DdType, typename ValueType> - Partition<DdType, ValueType> const& MdpPartitionRefiner<DdType, ValueType>::getChoicePartition() const { - return choicePartition; - } - - template<storm::dd::DdType DdType, typename ValueType> - bool MdpPartitionRefiner<DdType, ValueType>::refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) { - STORM_LOG_TRACE("Refining with respect to state-action rewards."); - Partition<DdType, ValueType> newChoicePartition = this->signatureRefiner.refine(this->choicePartition, Signature<DdType, ValueType>(stateActionRewards)); - if (newChoicePartition == this->choicePartition) { - return false; - } else { - this->choicePartition = newChoicePartition; - return true; - } - } - - template class MdpPartitionRefiner<storm::dd::DdType::CUDD, double>; - - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, double>; - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalNumber>; - template class MdpPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalFunction>; - - } - } -} diff --git a/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp new file mode 100644 index 000000000..d047acfde --- /dev/null +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.cpp @@ -0,0 +1,108 @@ +#include "storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h" + +#include "storm/models/symbolic/MarkovAutomaton.h" +#include "storm/models/symbolic/StandardRewardModel.h" + +namespace storm { + namespace dd { + namespace bisimulation { + + template<storm::dd::DdType DdType, typename ValueType> + NondeterministicModelPartitionRefiner<DdType, ValueType>::NondeterministicModelPartitionRefiner(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(model, initialStatePartition), model(model), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(model, initialStatePartition.getBlockVariables())), stateSignatureRefiner(model.getManager(), this->statePartition.getBlockVariable(), model.getRowVariables(), model.getColumnVariables(), true) { + + // For Markov automata, we refine the state partition wrt. to their exit rates. + if (model.isOfType(storm::models::ModelType::MarkovAutomaton)) { + STORM_LOG_TRACE("Refining with respect to exit rates."); + auto exitRateVector = this->model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getExitRateVector(); + this->statePartition = stateSignatureRefiner.refine(this->statePartition, Signature<DdType, ValueType>(exitRateVector)); + } + } + + template<storm::dd::DdType DdType, typename ValueType> + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refine(bisimulation::SignatureMode const& mode) { + // In this procedure, we will + // (1) refine the partition of nondeterministic choices based on the state partition. For this, we use + // the signature computer/refiner of the superclass. These objects use the full transition matrix. + // (2) if the choice partition was in fact split, the state partition also needs to be refined. + // For this, we use the signature computer/refiner of this class. + + STORM_LOG_TRACE("Refining choice partition."); + Partition<DdType, ValueType> newChoicePartition = this->internalRefine(this->signatureComputer, this->signatureRefiner, this->choicePartition, this->statePartition, mode); + + if (newChoicePartition.getNumberOfBlocks() == choicePartition.getNumberOfBlocks()) { + this->status = Status::FixedPoint; + return false; + } else { + this->choicePartition = newChoicePartition; + + // Compute state signatures. + storm::dd::Bdd<DdType> choicePartitionAsBdd; + if (this->choicePartition.storedAsBdd()) { + choicePartitionAsBdd = this->choicePartition.asBdd(); + } else { + choicePartitionAsBdd = this->choicePartition.asAdd().notZero(); + } + + auto signatureStart = std::chrono::high_resolution_clock::now(); + Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(model.getNondeterminismVariables()).template toAdd<ValueType>()); + auto signatureEnd = std::chrono::high_resolution_clock::now(); + this->totalSignatureTime += (signatureEnd - signatureStart); + + // If the choice partition changed, refine the state partition. + STORM_LOG_TRACE("Refining state partition."); + auto refinementStart = std::chrono::high_resolution_clock::now(); + Partition<DdType, ValueType> newStatePartition = this->internalRefine(stateSignature, this->stateSignatureRefiner, this->statePartition); + auto refinementEnd = std::chrono::high_resolution_clock::now(); + + auto signatureTime = std::chrono::duration_cast<std::chrono::milliseconds>(signatureEnd - signatureStart).count(); + auto refinementTime = std::chrono::duration_cast<std::chrono::milliseconds>(refinementEnd - refinementStart).count(); + STORM_LOG_INFO("Refinement " << (this->refinements-1) << " produced " << newStatePartition.getNumberOfBlocks() << " blocks and was completed in " << (signatureTime + refinementTime) << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); + + if (newStatePartition == this->statePartition) { + this->status = Status::FixedPoint; + return false; + } else { + this->statePartition = newStatePartition; + return true; + } + } + } + + template<storm::dd::DdType DdType, typename ValueType> + Partition<DdType, ValueType> const& NondeterministicModelPartitionRefiner<DdType, ValueType>::getChoicePartition() const { + return choicePartition; + } + + template <storm::dd::DdType DdType, typename ValueType> + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refineWrtStateRewards(storm::dd::Add<DdType, ValueType> const& stateRewards) { + STORM_LOG_TRACE("Refining with respect to state rewards."); + Partition<DdType, ValueType> newStatePartition = this->stateSignatureRefiner.refine(this->statePartition, Signature<DdType, ValueType>(stateRewards)); + if (newStatePartition == this->statePartition) { + return false; + } else { + this->statePartition = newStatePartition; + return true; + } + } + + template<storm::dd::DdType DdType, typename ValueType> + bool NondeterministicModelPartitionRefiner<DdType, ValueType>::refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) { + STORM_LOG_TRACE("Refining with respect to state-action rewards."); + Partition<DdType, ValueType> newChoicePartition = this->signatureRefiner.refine(this->choicePartition, Signature<DdType, ValueType>(stateActionRewards)); + if (newChoicePartition == this->choicePartition) { + return false; + } else { + this->choicePartition = newChoicePartition; + return true; + } + } + + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::CUDD, double>; + + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, double>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class NondeterministicModelPartitionRefiner<storm::dd::DdType::Sylvan, storm::RationalFunction>; + + } + } +} diff --git a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h similarity index 75% rename from src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h rename to src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h index 77766dd95..0dae7f90e 100644 --- a/src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h +++ b/src/storm/storage/dd/bisimulation/NondeterministicModelPartitionRefiner.h @@ -14,9 +14,9 @@ namespace storm { namespace bisimulation { template <storm::dd::DdType DdType, typename ValueType> - class MdpPartitionRefiner : public PartitionRefiner<DdType, ValueType> { + class NondeterministicModelPartitionRefiner : public PartitionRefiner<DdType, ValueType> { public: - MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition); + NondeterministicModelPartitionRefiner(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition); /*! * Refines the partition. @@ -34,8 +34,10 @@ namespace storm { private: virtual bool refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) override; + virtual bool refineWrtStateRewards(storm::dd::Add<DdType, ValueType> const& stateRewards) override; + // The model to refine. - storm::models::symbolic::Mdp<DdType, ValueType> const& mdp; + storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model; // The choice partition in the refinement process. Partition<DdType, ValueType> choicePartition; diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp index 9e5e34b54..fea92c755 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.cpp @@ -15,18 +15,18 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> - PartialQuotientExtractor<DdType, ValueType>::PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model) : model(model) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + PartialQuotientExtractor<DdType, ValueType, ExportValueType>::PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model) : model(model) { auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); this->quotientFormat = settings.getQuotientFormat(); STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> PartialQuotientExtractor<DdType, ValueType>::extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> PartialQuotientExtractor<DdType, ValueType, ExportValueType>::extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr<storm::models::Model<ValueType>> result; + std::shared_ptr<storm::models::Model<ExportValueType>> result; STORM_LOG_THROW(this->quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Dd, storm::exceptions::NotSupportedException, "Only DD-based partial quotient extraction is currently supported."); result = extractDdQuotient(partition, preservationInformation); @@ -38,8 +38,8 @@ namespace storm { return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> PartialQuotientExtractor<DdType, ValueType>::extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> PartialQuotientExtractor<DdType, ValueType, ExportValueType>::extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Mdp) { @@ -122,16 +122,19 @@ namespace storm { end = std::chrono::high_resolution_clock::now(); STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::make_shared<storm::models::symbolic::Mdp<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); + result = std::make_shared<storm::models::symbolic::Mdp<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), preservedLabelBdds, quotientRewardModels); } else if (modelType == storm::models::ModelType::Mdp) { std::set<storm::expressions::Variable> allNondeterminismVariables; std::set_union(model.getRowVariables().begin(), model.getRowVariables().end(), model.getNondeterminismVariables().begin(), model.getNondeterminismVariables().end(), std::inserter(allNondeterminismVariables, allNondeterminismVariables.begin())); - return std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); + result = std::make_shared<storm::models::symbolic::StochasticTwoPlayerGame<DdType, ValueType>>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getRowVariables(), model.getNondeterminismVariables(), allNondeterminismVariables, preservedLabelBdds, quotientRewardModels); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported quotient type."); } + + return result->template toValueType<ExportValueType>(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract partial quotient for this model type."); } @@ -142,6 +145,7 @@ namespace storm { #ifdef STORM_HAVE_CARL template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class PartialQuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>; #endif diff --git a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h index 26ae033e6..d5c638c2a 100644 --- a/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/PartialQuotientExtractor.h @@ -16,15 +16,15 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class PartialQuotientExtractor { public: PartialQuotientExtractor(storm::models::symbolic::Model<DdType, ValueType> const& model); - std::shared_ptr<storm::models::Model<ValueType>> extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::Model<ExportValueType>> extract(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); private: - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractDdQuotient(Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); // The model for which to compute the partial quotient. storm::models::symbolic::Model<DdType, ValueType> const& model; diff --git a/src/storm/storage/dd/bisimulation/Partition.cpp b/src/storm/storage/dd/bisimulation/Partition.cpp index d3708c6a5..6ada72f6b 100644 --- a/src/storm/storage/dd/bisimulation/Partition.cpp +++ b/src/storm/storage/dd/bisimulation/Partition.cpp @@ -130,6 +130,8 @@ namespace storm { std::pair<storm::expressions::Variable, storm::expressions::Variable> blockVariables = createBlockVariables(model); + auto start = std::chrono::high_resolution_clock::now(); + // Set up the construction. storm::dd::DdManager<DdType>& manager = model.getManager(); storm::dd::Bdd<DdType> partitionBdd = manager.getBddZero(); @@ -153,6 +155,9 @@ namespace storm { // Move the partition over to the primed variables. partitionBdd = partitionBdd.swapVariables(model.getRowColumnMetaVariablePairs()); + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Created distance and label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + // Store the partition as an ADD only in the case of CUDD. if (DdType == storm::dd::DdType::CUDD) { return Partition<DdType, ValueType>(partitionBdd.template toAdd<ValueType>(), blockVariables, blockCount, blockCount); @@ -191,8 +196,11 @@ namespace storm { for (auto const& expression : expressions) { stateSets.emplace_back(model.getStates(expression)); } + auto start = std::chrono::high_resolution_clock::now(); std::pair<storm::dd::Bdd<DdType>, uint64_t> partitionBddAndBlockCount = createPartitionBdd(model.getManager(), model, stateSets, blockVariables.first); - + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Created label-based initial partition in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + // Store the partition as an ADD only in the case of CUDD. if (DdType == storm::dd::DdType::CUDD) { return Partition<DdType, ValueType>(partitionBddAndBlockCount.first.template toAdd<ValueType>(), blockVariables, partitionBddAndBlockCount.second, partitionBddAndBlockCount.second); diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp index 4fe427ffa..87af0987b 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.cpp @@ -2,6 +2,8 @@ #include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/storage/dd/DdManager.h" + #include "storm/utility/macros.h" #include "storm/exceptions/NotSupportedException.h" @@ -10,7 +12,7 @@ namespace storm { namespace bisimulation { template <storm::dd::DdType DdType, typename ValueType> - PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isOfType(storm::models::ModelType::Mdp), model.getNondeterminismVariables()) { + PartitionRefiner<DdType, ValueType>::PartitionRefiner(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& initialStatePartition) : status(Status::Initialized), refinements(0), statePartition(initialStatePartition), signatureComputer(model), signatureRefiner(model.getManager(), statePartition.getBlockVariable(), model.getRowAndNondeterminismVariables(), model.getColumnVariables(), !model.isNondeterministicModel(), model.getNondeterminismVariables()), totalSignatureTime(0), totalRefinementTime(0) { // Intentionally left empty. } @@ -48,7 +50,7 @@ namespace storm { auto signatureEnd = std::chrono::high_resolution_clock::now(); totalSignatureTime += (signatureEnd - signatureStart); STORM_LOG_TRACE("Signature " << refinements << "[" << index << "] DD has " << signature.getSignatureAdd().getNodeCount() << " nodes."); - + auto refinementStart = std::chrono::high_resolution_clock::now(); newPartition = signatureRefiner.refine(oldPartition, signature); auto refinementEnd = std::chrono::high_resolution_clock::now(); @@ -64,7 +66,7 @@ namespace storm { } auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count(); - STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); + STORM_LOG_INFO("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms)."); ++refinements; return newPartition; } else { @@ -76,11 +78,11 @@ namespace storm { Partition<DdType, ValueType> PartitionRefiner<DdType, ValueType>::internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition) { STORM_LOG_TRACE("Signature " << refinements << " DD has " << signature.getSignatureAdd().getNodeCount() << " nodes."); - auto start = std::chrono::high_resolution_clock::now(); + auto refinementStart = std::chrono::high_resolution_clock::now(); auto newPartition = signatureRefiner.refine(oldPartition, signature); - auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count(); - STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms."); - + auto refinementEnd = std::chrono::high_resolution_clock::now(); + totalRefinementTime += (refinementEnd - refinementStart); + ++refinements; return newPartition; } @@ -133,6 +135,16 @@ namespace storm { return status; } + template <storm::dd::DdType DdType, typename ValueType> + std::chrono::high_resolution_clock::duration PartitionRefiner<DdType, ValueType>::getTotalSignatureTime() const { + return totalSignatureTime; + } + + template <storm::dd::DdType DdType, typename ValueType> + std::chrono::high_resolution_clock::duration PartitionRefiner<DdType, ValueType>::getTotalRefinementTime() const { + return totalRefinementTime; + } + template class PartitionRefiner<storm::dd::DdType::CUDD, double>; template class PartitionRefiner<storm::dd::DdType::Sylvan, double>; diff --git a/src/storm/storage/dd/bisimulation/PartitionRefiner.h b/src/storm/storage/dd/bisimulation/PartitionRefiner.h index d4e59a207..4716a811a 100644 --- a/src/storm/storage/dd/bisimulation/PartitionRefiner.h +++ b/src/storm/storage/dd/bisimulation/PartitionRefiner.h @@ -53,6 +53,9 @@ namespace storm { */ Status getStatus() const; + std::chrono::high_resolution_clock::duration getTotalSignatureTime() const; + std::chrono::high_resolution_clock::duration getTotalRefinementTime() const; + protected: Partition<DdType, ValueType> internalRefine(SignatureComputer<DdType, ValueType>& stateSignatureComputer, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition, Partition<DdType, ValueType> const& targetPartition, SignatureMode const& mode = SignatureMode::Eager); Partition<DdType, ValueType> internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition); diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp index 2e059fbef..1ba224331 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.cpp @@ -7,11 +7,13 @@ #include "storm/models/symbolic/Dtmc.h" #include "storm/models/symbolic/Ctmc.h" #include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/MarkovAutomaton.h" #include "storm/models/symbolic/StandardRewardModel.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/Ctmc.h" #include "storm/models/sparse/Mdp.h" +#include "storm/models/sparse/MarkovAutomaton.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/storage/dd/bisimulation/PreservationInformation.h" @@ -220,10 +222,10 @@ namespace storm { spp::sparse_hash_map<BDD, bool> visitedNodes; }; - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class InternalSparseQuotientExtractor; - template<storm::dd::DdType DdType, typename ValueType> + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class InternalSparseQuotientExtractorBase { public: InternalSparseQuotientExtractorBase(storm::models::symbolic::Model<DdType, ValueType> const& model, storm::dd::Bdd<DdType> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<DdType> const& representatives) : model(model), manager(model.getManager()), isNondeterministic(false), partitionBdd(partitionBdd), numberOfBlocks(numberOfBlocks), blockVariable(blockVariable), representatives(representatives), matrixEntriesCreated(false) { @@ -257,23 +259,23 @@ namespace storm { virtual ~InternalSparseQuotientExtractorBase() = default; - storm::storage::SparseMatrix<ValueType> extractTransitionMatrix(storm::dd::Add<DdType, ValueType> const& transitionMatrix) { + storm::storage::SparseMatrix<ExportValueType> extractTransitionMatrix(storm::dd::Add<DdType, ValueType> const& transitionMatrix) { return extractMatrixInternal(transitionMatrix); } - std::vector<ValueType> extractStateVector(storm::dd::Add<DdType, ValueType> const& vector) { + std::vector<ExportValueType> extractStateVector(storm::dd::Add<DdType, ValueType> const& vector) { return extractVectorInternal(vector, this->rowVariablesCube, this->odd); } - std::vector<ValueType> extractStateActionVector(storm::dd::Add<DdType, ValueType> const& vector) { + std::vector<ExportValueType> extractStateActionVector(storm::dd::Add<DdType, ValueType> const& vector) { if (!this->isNondeterministic) { return extractStateVector(vector); } else { STORM_LOG_ASSERT(!this->rowPermutation.empty(), "Expected proper row permutation."); - std::vector<ValueType> valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); + std::vector<ExportValueType> valueVector = extractVectorInternal(vector, this->allSourceVariablesCube, this->nondeterminismOdd); // Reorder the values according to the known row permutation. - std::vector<ValueType> reorderedValues(valueVector.size()); + std::vector<ExportValueType> reorderedValues(valueVector.size()); for (uint64_t pos = 0; pos < valueVector.size(); ++pos) { reorderedValues[pos] = valueVector[rowPermutation[pos]]; } @@ -290,14 +292,14 @@ namespace storm { } protected: - virtual storm::storage::SparseMatrix<ValueType> extractMatrixInternal(storm::dd::Add<DdType, ValueType> const& matrix) = 0; + virtual storm::storage::SparseMatrix<ExportValueType> extractMatrixInternal(storm::dd::Add<DdType, ValueType> const& matrix) = 0; - virtual std::vector<ValueType> extractVectorInternal(storm::dd::Add<DdType, ValueType> const& vector, storm::dd::Bdd<DdType> const& variablesCube, storm::dd::Odd const& odd) = 0; + virtual std::vector<ExportValueType> extractVectorInternal(storm::dd::Add<DdType, ValueType> const& vector, storm::dd::Bdd<DdType> const& variablesCube, storm::dd::Odd const& odd) = 0; - storm::storage::SparseMatrix<ValueType> createMatrixFromEntries() { + storm::storage::SparseMatrix<ExportValueType> createMatrixFromEntries() { for (auto& row : matrixEntries) { std::sort(row.begin(), row.end(), - [] (storm::storage::MatrixEntry<uint_fast64_t, ValueType> const& a, storm::storage::MatrixEntry<uint_fast64_t, ValueType> const& b) { + [] (storm::storage::MatrixEntry<uint_fast64_t, ExportValueType> const& a, storm::storage::MatrixEntry<uint_fast64_t, ExportValueType> const& b) { return a.getColumn() < b.getColumn(); }); } @@ -305,12 +307,12 @@ namespace storm { rowPermutation = std::vector<uint64_t>(matrixEntries.size()); std::iota(rowPermutation.begin(), rowPermutation.end(), 0ull); if (this->isNondeterministic) { - std::sort(rowPermutation.begin(), rowPermutation.end(), [this] (uint64_t first, uint64_t second) { return this->rowToState[first] < this->rowToState[second]; } ); + std::stable_sort(rowPermutation.begin(), rowPermutation.end(), [this] (uint64_t first, uint64_t second) { return this->rowToState[first] < this->rowToState[second]; } ); } uint64_t rowCounter = 0; uint64_t lastState = this->isNondeterministic ? rowToState[rowPermutation.front()] : 0; - storm::storage::SparseMatrixBuilder<ValueType> builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); + storm::storage::SparseMatrixBuilder<ExportValueType> builder(matrixEntries.size(), this->numberOfBlocks, 0, true, this->isNondeterministic); if (this->isNondeterministic) { builder.newRowGroup(0); } @@ -341,7 +343,7 @@ namespace storm { return builder.build(); } - void addMatrixEntry(uint64_t row, uint64_t column, ValueType const& value) { + void addMatrixEntry(uint64_t row, uint64_t column, ExportValueType const& value) { this->matrixEntries[row].emplace_back(column, value); } @@ -388,7 +390,7 @@ namespace storm { bool matrixEntriesCreated; // The entries of the quotient matrix that is built. - std::vector<std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>>> matrixEntries; + std::vector<std::vector<storm::storage::MatrixEntry<uint_fast64_t, ExportValueType>>> matrixEntries; // A vector storing for each row which state it belongs to. std::vector<uint64_t> rowToState; @@ -619,33 +621,33 @@ namespace storm { spp::sparse_hash_map<DdNode const*, uint64_t> blockToOffset; }; - template<typename ValueType> - class InternalSparseQuotientExtractor<storm::dd::DdType::Sylvan, ValueType> : public InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType> { + template<typename ValueType, typename ExportValueType> + class InternalSparseQuotientExtractor<storm::dd::DdType::Sylvan, ValueType, ExportValueType> : public InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType, ExportValueType> { public: - InternalSparseQuotientExtractor(storm::models::symbolic::Model<storm::dd::DdType::Sylvan, ValueType> const& model, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& representatives) : InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType>(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { + InternalSparseQuotientExtractor(storm::models::symbolic::Model<storm::dd::DdType::Sylvan, ValueType> const& model, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& partitionBdd, storm::expressions::Variable const& blockVariable, uint64_t numberOfBlocks, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& representatives) : InternalSparseQuotientExtractorBase<storm::dd::DdType::Sylvan, ValueType, ExportValueType>(model, partitionBdd, blockVariable, numberOfBlocks, representatives) { this->createBlockToOffsetMapping(); } private: - virtual storm::storage::SparseMatrix<ValueType> extractMatrixInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& matrix) override { + virtual storm::storage::SparseMatrix<ExportValueType> extractMatrixInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& matrix) override { this->createMatrixEntryStorage(); extractTransitionMatrixRec(matrix.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->isNondeterministic ? this->nondeterminismOdd : this->odd, 0, this->partitionBdd.getInternalBdd().getSylvanBdd().GetBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), this->allSourceVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->nondeterminismVariablesCube.getInternalBdd().getSylvanBdd().GetBDD(), this->isNondeterministic ? &this->odd : nullptr, 0); return this->createMatrixFromEntries(); } - virtual std::vector<ValueType> extractVectorInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& vector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& variablesCube, storm::dd::Odd const& odd) override { - std::vector<ValueType> result(odd.getTotalOffset()); + virtual std::vector<ExportValueType> extractVectorInternal(storm::dd::Add<storm::dd::DdType::Sylvan, ValueType> const& vector, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& variablesCube, storm::dd::Odd const& odd) override { + std::vector<ExportValueType> result(odd.getTotalOffset()); extractVectorRec(vector.getInternalAdd().getSylvanMtbdd().GetMTBDD(), this->representatives.getInternalBdd().getSylvanBdd().GetBDD(), variablesCube.getInternalBdd().getSylvanBdd().GetBDD(), odd, 0, result); return result; } - void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ValueType>& result) { + void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ExportValueType>& result) { if (representativesNode == sylvan_false || mtbdd_iszero(vector)) { return; } if (sylvan_isconst(variables)) { - result[offset] = storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(vector); + result[offset] = storm::utility::convertNumber<ExportValueType>(storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(vector)); } else { MTBDD vectorT; MTBDD vectorE; @@ -721,7 +723,7 @@ namespace storm { // If we have moved through all source variables, we must have arrived at a target block encoding. if (sylvan_isconst(variables)) { STORM_LOG_ASSERT(mtbdd_isleaf(transitionMatrixNode), "Expected constant node."); - this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(transitionMatrixNode)); + this->addMatrixEntry(sourceOffset, blockToOffset.at(targetPartitionNode), storm::utility::convertNumber<ExportValueType>(storm::dd::InternalAdd<storm::dd::DdType::Sylvan, ValueType>::getValue(transitionMatrixNode))); if (stateOdd) { this->assignRowToState(sourceOffset, stateOffset); } @@ -815,32 +817,33 @@ namespace storm { spp::sparse_hash_map<BDD, uint64_t> blockToOffset; }; - template<storm::dd::DdType DdType, typename ValueType> - QuotientExtractor<DdType, ValueType>::QuotientExtractor() : useRepresentatives(false) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + QuotientExtractor<DdType, ValueType, ExportValueType>::QuotientExtractor() : useRepresentatives(false) { auto const& settings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>(); this->useRepresentatives = settings.isUseRepresentativesSet(); + this->useOriginalVariables = settings.isUseOriginalVariablesSet(); this->quotientFormat = settings.getQuotientFormat(); } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::Model<ValueType>> QuotientExtractor<DdType, ValueType>::extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::Model<ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto start = std::chrono::high_resolution_clock::now(); - std::shared_ptr<storm::models::Model<ValueType>> result; + std::shared_ptr<storm::models::Model<ExportValueType>> result; if (quotientFormat == storm::settings::modules::BisimulationSettings::QuotientFormat::Sparse) { result = extractSparseQuotient(model, partition, preservationInformation); } else { result = extractDdQuotient(model, partition, preservationInformation); } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient extraction completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "Quotient could not be extracted."); return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::sparse::Model<ValueType>> QuotientExtractor<DdType, ValueType>::extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto states = partition.getStates().swapVariables(model.getRowColumnMetaVariablePairs()); storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsAdd() ? partition.asAdd().toBdd() : partition.asBdd(); @@ -850,10 +853,10 @@ namespace storm { auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); STORM_LOG_ASSERT(representatives.getNonZeroCount() == partition.getNumberOfBlocks(), "Representatives size does not match that of the partition: " << representatives.getNonZeroCount() << " vs. " << partition.getNumberOfBlocks() << "."); STORM_LOG_ASSERT((representatives && partitionAsBdd).existsAbstract(model.getRowVariables()) == partitionAsBdd.existsAbstract(model.getRowVariables()), "Representatives do not cover all blocks."); - InternalSparseQuotientExtractor<DdType, ValueType> sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); - storm::storage::SparseMatrix<ValueType> quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); + InternalSparseQuotientExtractor<DdType, ValueType, ExportValueType> sparseExtractor(model, partitionAsBdd, partition.getBlockVariable(), partition.getNumberOfBlocks(), representatives); + storm::storage::SparseMatrix<ExportValueType> quotientTransitionMatrix = sparseExtractor.extractTransitionMatrix(model.getTransitionMatrix()); auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); storm::models::sparse::StateLabeling quotientStateLabeling(partition.getNumberOfBlocks()); @@ -875,55 +878,64 @@ namespace storm { } } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); - std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> quotientRewardModels; + std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ExportValueType>> quotientRewardModels; for (auto const& rewardModelName : preservationInformation.getRewardModelNames()) { auto const& rewardModel = model.getRewardModel(rewardModelName); - boost::optional<std::vector<ValueType>> quotientStateRewards; + boost::optional<std::vector<ExportValueType>> quotientStateRewards; if (rewardModel.hasStateRewards()) { quotientStateRewards = sparseExtractor.extractStateVector(rewardModel.getStateRewardVector()); } - boost::optional<std::vector<ValueType>> quotientStateActionRewards; + boost::optional<std::vector<ExportValueType>> quotientStateActionRewards; if (rewardModel.hasStateActionRewards()) { quotientStateActionRewards = sparseExtractor.extractStateActionVector(rewardModel.getStateActionRewardVector()); } - quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ValueType>(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); + quotientRewardModels.emplace(rewardModelName, storm::models::sparse::StandardRewardModel<ExportValueType>(std::move(quotientStateRewards), std::move(quotientStateActionRewards), boost::none)); } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); - std::shared_ptr<storm::models::sparse::Model<ValueType>> result; + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> result; if (model.getType() == storm::models::ModelType::Dtmc) { - result = std::make_shared<storm::models::sparse::Dtmc<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Dtmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Ctmc) { - result = std::make_shared<storm::models::sparse::Ctmc<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Ctmc<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); } else if (model.getType() == storm::models::ModelType::Mdp) { - result = std::make_shared<storm::models::sparse::Mdp<ValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + result = std::make_shared<storm::models::sparse::Mdp<ExportValueType>>(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels)); + } else if (model.getType() == storm::models::ModelType::MarkovAutomaton) { + storm::models::symbolic::MarkovAutomaton<DdType, ValueType> const& markovAutomaton = *model.template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(); + + boost::optional<storm::storage::BitVector> markovianStates = sparseExtractor.extractSetExists(markovAutomaton.getMarkovianStates()); + storm::storage::sparse::ModelComponents<ExportValueType> modelComponents(std::move(quotientTransitionMatrix), std::move(quotientStateLabeling), std::move(quotientRewardModels), false, std::move(markovianStates)); + modelComponents.exitRates = sparseExtractor.extractStateVector(markovAutomaton.getExitRateVector()); + + result = std::make_shared<storm::models::sparse::MarkovAutomaton<ExportValueType>>(std::move(modelComponents)); } return result; } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { - return extractQuotientUsingBlockVariables(model, partition, preservationInformation); + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + + if (this->useOriginalVariables) { + return extractQuotientUsingOriginalVariables(model, partition, preservationInformation); + } else { + return extractQuotientUsingBlockVariables(model, partition, preservationInformation); + } } - template<storm::dd::DdType DdType, typename ValueType> - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> QuotientExtractor<DdType, ValueType>::extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { auto modelType = model.getType(); bool useRepresentativesForThisExtraction = this->useRepresentatives; - if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp) { - if (modelType == storm::models::ModelType::Mdp) { - STORM_LOG_WARN_COND(!useRepresentativesForThisExtraction, "Using representatives is unsupported for MDPs, falling back to regular extraction."); - useRepresentativesForThisExtraction = false; - } + if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { // Sanity checks. STORM_LOG_ASSERT(partition.getNumberOfStates() == model.getNumberOfStates(), "Mismatching partition size."); @@ -932,16 +944,20 @@ namespace storm { std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()}; std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()}; std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())}; + + auto start = std::chrono::high_resolution_clock::now(); + // Compute representatives. storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); + partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); + auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); + if (useRepresentativesForThisExtraction) { - storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariable = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); - storm::dd::Bdd<DdType> representativePartition = partitionAsBddOverPrimedBlockVariable.existsAbstractRepresentative(model.getColumnVariables()).renameVariables(model.getColumnVariables(), blockVariableSet); - partitionAsBdd = (representativePartition && partitionAsBddOverPrimedBlockVariable).existsAbstract(blockPrimeVariableSet); + storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); + storm::dd::Bdd<DdType> tmp = (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.getRowVariables(), blockVariableSet); + partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet); } - auto start = std::chrono::high_resolution_clock::now(); - partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getRowVariables()); storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables()); @@ -962,7 +978,7 @@ namespace storm { } } auto end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); start = std::chrono::high_resolution_clock::now(); std::set<storm::expressions::Variable> blockAndRowVariables; @@ -973,13 +989,12 @@ namespace storm { storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(blockAndRowVariables, blockPrimeAndColumnVariables), model.getColumnVariables()); // Pick a representative from each block. - auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); partitionAsBdd &= representatives; partitionAsAdd *= partitionAsBdd.template toAdd<ValueType>(); quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()); end = std::chrono::high_resolution_clock::now(); - + // Check quotient matrix for sanity. if (std::is_same<ValueType, storm::RationalNumber>::value) { STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>()).isZero(), "Illegal entries in quotient matrix."); @@ -988,10 +1003,13 @@ namespace storm { } STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(blockPrimeVariableSet).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(blockPrimeVariableSet).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal non-probabilistic matrix."); - STORM_LOG_TRACE("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); - storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeVariableSet) && reachableStates; + + std::set<storm::expressions::Variable> blockPrimeAndNondeterminismVariables = model.getNondeterminismVariables(); + blockPrimeAndNondeterminismVariables.insert(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end()); + storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(blockPrimeAndNondeterminismVariables) && reachableStates; start = std::chrono::high_resolution_clock::now(); std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels; @@ -1011,17 +1029,144 @@ namespace storm { quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(quotientStateRewards, quotientStateActionRewards, boost::none)); } end = std::chrono::high_resolution_clock::now(); - STORM_LOG_TRACE("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; + if (modelType == storm::models::ModelType::Dtmc) { + result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + } else if (modelType == storm::models::ModelType::Ctmc) { + result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + } else if (modelType == storm::models::ModelType::Mdp) { + result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + } else { + result = std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + } + + return result->template toValueType<ExportValueType>(); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); + } + } + + template<storm::dd::DdType DdType, typename ValueType, typename ExportValueType> + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> QuotientExtractor<DdType, ValueType, ExportValueType>::extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation) { + auto modelType = model.getType(); + + bool useRepresentativesForThisExtraction = this->useRepresentatives; + if (modelType == storm::models::ModelType::Dtmc || modelType == storm::models::ModelType::Ctmc || modelType == storm::models::ModelType::Mdp || modelType == storm::models::ModelType::MarkovAutomaton) { + STORM_LOG_WARN_COND(!this->useRepresentatives, "Using representatives is unsupported for this extraction, falling back to regular extraction."); + + // Sanity checks. + STORM_LOG_ASSERT(partition.getNumberOfStates() == model.getNumberOfStates(), "Mismatching partition size."); + STORM_LOG_ASSERT(partition.getStates().renameVariables(model.getColumnVariables(), model.getRowVariables()) == model.getReachableStates(), "Mismatching partition."); + + std::set<storm::expressions::Variable> blockVariableSet = {partition.getBlockVariable()}; + std::set<storm::expressions::Variable> blockPrimeVariableSet = {partition.getPrimedBlockVariable()}; + std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> blockMetaVariablePairs = {std::make_pair(partition.getBlockVariable(), partition.getPrimedBlockVariable())}; + + auto start = std::chrono::high_resolution_clock::now(); + + // Compute representatives. + storm::dd::Bdd<DdType> partitionAsBdd = partition.storedAsBdd() ? partition.asBdd() : partition.asAdd().notZero(); + partitionAsBdd = partitionAsBdd.renameVariables(model.getColumnVariables(), model.getRowVariables()); + auto representatives = InternalRepresentativeComputer<DdType>(partitionAsBdd, model.getRowVariables()).getRepresentatives(); + + if (useRepresentativesForThisExtraction) { + storm::dd::Bdd<DdType> partitionAsBddOverPrimedBlockVariables = partitionAsBdd.renameVariables(blockVariableSet, blockPrimeVariableSet); + storm::dd::Bdd<DdType> tmp = (representatives && partitionAsBddOverPrimedBlockVariables).renameVariablesConcretize(model.getRowVariables(), blockVariableSet); + partitionAsBdd = (tmp && partitionAsBddOverPrimedBlockVariables).existsAbstract(blockPrimeVariableSet); + } + + storm::dd::Bdd<DdType> reachableStates = partitionAsBdd.existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + storm::dd::Bdd<DdType> initialStates = (model.getInitialStates() && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + + std::map<std::string, storm::dd::Bdd<DdType>> preservedLabelBdds; + for (auto const& label : preservationInformation.getLabels()) { + preservedLabelBdds.emplace(label, (model.getStates(label) && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables())); + } + for (auto const& expression : preservationInformation.getExpressions()) { + std::stringstream stream; + stream << expression; + std::string expressionAsString = stream.str(); + + auto it = preservedLabelBdds.find(expressionAsString); + if (it != preservedLabelBdds.end()) { + STORM_LOG_WARN("Duplicate label '" << expressionAsString << "', dropping second label definition."); + } else { + preservedLabelBdds.emplace(stream.str(), (model.getStates(expression) && partitionAsBdd).existsAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables())); + } + } + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Quotient labels extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + start = std::chrono::high_resolution_clock::now(); + std::set<storm::expressions::Variable> blockAndRowVariables; + std::set_union(blockVariableSet.begin(), blockVariableSet.end(), model.getRowVariables().begin(), model.getRowVariables().end(), std::inserter(blockAndRowVariables, blockAndRowVariables.end())); + std::set<storm::expressions::Variable> blockPrimeAndColumnVariables; + std::set_union(blockPrimeVariableSet.begin(), blockPrimeVariableSet.end(), model.getColumnVariables().begin(), model.getColumnVariables().end(), std::inserter(blockPrimeAndColumnVariables, blockPrimeAndColumnVariables.end())); + storm::dd::Add<DdType, ValueType> partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); + storm::dd::Add<DdType, ValueType> quotientTransitionMatrix = model.getTransitionMatrix().multiplyMatrix(partitionAsAdd.renameVariables(model.getRowVariables(), model.getColumnVariables()), model.getColumnVariables()).renameVariablesAbstract(blockVariableSet, model.getColumnVariables()); + + // Pick a representative from each block. + partitionAsBdd &= representatives; + partitionAsAdd = partitionAsBdd.template toAdd<ValueType>(); + // Workaround for problem with CUDD. Matrix-Matrix multiplication yields other result than multiplication+sum-abstract... + if (DdType == storm::dd::DdType::CUDD) { + quotientTransitionMatrix = (quotientTransitionMatrix * partitionAsAdd).sumAbstract(model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } else { + quotientTransitionMatrix = quotientTransitionMatrix.multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } + end = std::chrono::high_resolution_clock::now(); + + // Check quotient matrix for sanity. + if (std::is_same<ValueType, storm::RationalNumber>::value) { + STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>()).isZero(), "Illegal entries in quotient matrix."); + } else { + STORM_LOG_ASSERT(quotientTransitionMatrix.greater(storm::utility::one<ValueType>() + storm::utility::convertNumber<ValueType>(1e-6)).isZero(), "Illegal entries in quotient matrix."); + } + STORM_LOG_ASSERT(quotientTransitionMatrix.sumAbstract(model.getColumnVariables()).equalModuloPrecision(quotientTransitionMatrix.notZero().existsAbstract(model.getColumnVariables()).template toAdd<ValueType>(), storm::utility::convertNumber<ValueType>(1e-6)), "Illegal probabilistic matrix."); + + STORM_LOG_INFO("Quotient transition matrix extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + storm::dd::Bdd<DdType> quotientTransitionMatrixBdd = quotientTransitionMatrix.notZero(); + + std::set<storm::expressions::Variable> columnAndNondeterminismVariables = model.getColumnVariables(); + columnAndNondeterminismVariables.insert(model.getNondeterminismVariables().begin(), model.getNondeterminismVariables().end()); + storm::dd::Bdd<DdType> deadlockStates = !quotientTransitionMatrixBdd.existsAbstract(columnAndNondeterminismVariables) && reachableStates; + + start = std::chrono::high_resolution_clock::now(); + std::unordered_map<std::string, storm::models::symbolic::StandardRewardModel<DdType, ValueType>> quotientRewardModels; + for (auto const& rewardModelName : preservationInformation.getRewardModelNames()) { + auto const& rewardModel = model.getRewardModel(rewardModelName); + + boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateRewards; + if (rewardModel.hasStateRewards()) { + quotientStateRewards = rewardModel.getStateRewardVector().multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } + + boost::optional<storm::dd::Add<DdType, ValueType>> quotientStateActionRewards; + if (rewardModel.hasStateActionRewards()) { + quotientStateActionRewards = rewardModel.getStateActionRewardVector().multiplyMatrix(partitionAsAdd, model.getRowVariables()).renameVariablesAbstract(blockVariableSet, model.getRowVariables()); + } + + quotientRewardModels.emplace(rewardModelName, storm::models::symbolic::StandardRewardModel<DdType, ValueType>(quotientStateRewards, quotientStateActionRewards, boost::none)); + } + end = std::chrono::high_resolution_clock::now(); + STORM_LOG_INFO("Reward models extracted in " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms."); + + std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> result; if (modelType == storm::models::ModelType::Dtmc) { - return std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Dtmc<DdType, ValueType>>(new storm::models::symbolic::Dtmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Ctmc) { - return std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Ctmc<DdType, ValueType>>(new storm::models::symbolic::Ctmc<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), preservedLabelBdds, quotientRewardModels)); } else if (modelType == storm::models::ModelType::Mdp) { - return std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, blockVariableSet, blockPrimeVariableSet, blockMetaVariablePairs, model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); + result = std::shared_ptr<storm::models::symbolic::Mdp<DdType, ValueType>>(new storm::models::symbolic::Mdp<DdType, ValueType>(model.getManager().asSharedPointer(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } else { - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported quotient type."); + result = std::shared_ptr<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>(new storm::models::symbolic::MarkovAutomaton<DdType, ValueType>(model.getManager().asSharedPointer(), model. template as<storm::models::symbolic::MarkovAutomaton<DdType, ValueType>>()->getMarkovianMarker(), reachableStates, initialStates, deadlockStates, quotientTransitionMatrix, model.getRowVariables(), model.getColumnVariables(), model.getRowColumnMetaVariablePairs(), model.getNondeterminismVariables(), preservedLabelBdds, quotientRewardModels)); } + + return result->template toValueType<ExportValueType>(); } else { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Cannot extract quotient for this model type."); } @@ -1031,6 +1176,7 @@ namespace storm { template class QuotientExtractor<storm::dd::DdType::Sylvan, double>; template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber>; + template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalNumber, double>; template class QuotientExtractor<storm::dd::DdType::Sylvan, storm::RationalFunction>; } diff --git a/src/storm/storage/dd/bisimulation/QuotientExtractor.h b/src/storm/storage/dd/bisimulation/QuotientExtractor.h index dcce31659..422453bf7 100644 --- a/src/storm/storage/dd/bisimulation/QuotientExtractor.h +++ b/src/storm/storage/dd/bisimulation/QuotientExtractor.h @@ -16,20 +16,22 @@ namespace storm { namespace dd { namespace bisimulation { - template<storm::dd::DdType DdType, typename ValueType> + template <storm::dd::DdType DdType, typename ValueType, typename ExportValueType = ValueType> class QuotientExtractor { public: QuotientExtractor(); - std::shared_ptr<storm::models::Model<ValueType>> extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::Model<ExportValueType>> extract(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); private: - std::shared_ptr<storm::models::sparse::Model<ValueType>> extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); - std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::sparse::Model<ExportValueType>> extractSparseQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractDdQuotient(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractQuotientUsingBlockVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + std::shared_ptr<storm::models::symbolic::Model<DdType, ExportValueType>> extractQuotientUsingOriginalVariables(storm::models::symbolic::Model<DdType, ValueType> const& model, Partition<DdType, ValueType> const& partition, PreservationInformation<DdType, ValueType> const& preservationInformation); + bool useRepresentatives; + bool useOriginalVariables; storm::settings::modules::BisimulationSettings::QuotientFormat quotientFormat; }; diff --git a/src/storm/storage/dd/bisimulation/SignatureComputer.cpp b/src/storm/storage/dd/bisimulation/SignatureComputer.cpp index 1d31137a7..89345ee9d 100644 --- a/src/storm/storage/dd/bisimulation/SignatureComputer.cpp +++ b/src/storm/storage/dd/bisimulation/SignatureComputer.cpp @@ -97,7 +97,7 @@ namespace storm { SignatureMode const& SignatureComputer<DdType, ValueType>::getSignatureMode() const { return mode; } - + template<storm::dd::DdType DdType, typename ValueType> Signature<DdType, ValueType> SignatureComputer<DdType, ValueType>::getFullSignature(Partition<DdType, ValueType> const& partition) const { if (partition.storedAsBdd()) { diff --git a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp index 9645ebdf3..11c6b12ca 100644 --- a/src/storm/storage/dd/cudd/InternalCuddAdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddAdd.cpp @@ -231,7 +231,7 @@ namespace storm { for (auto const& ddVariable : summationDdVariables) { summationAdds.push_back(ddVariable.toAdd<ValueType>().getCuddAdd()); } - + // return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().TimesPlus(otherMatrix.getCuddAdd(), summationAdds)); // return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Triangle(otherMatrix.getCuddAdd(), summationAdds)); return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationAdds)); diff --git a/src/storm/storage/dd/cudd/InternalCuddBdd.cpp b/src/storm/storage/dd/cudd/InternalCuddBdd.cpp index 5fc12e567..b69040372 100644 --- a/src/storm/storage/dd/cudd/InternalCuddBdd.cpp +++ b/src/storm/storage/dd/cudd/InternalCuddBdd.cpp @@ -294,7 +294,7 @@ namespace storm { } else if (dd == Cudd_ReadOne(manager.getManager()) && complement) { return; } - + // If we are at the maximal level, the value to be set is stored as a constant in the DD. if (currentRowLevel == maxLevel) { result.set(currentRowOffset, true); diff --git a/src/storm/storage/dd/sylvan/InternalSylvanAdd.h b/src/storm/storage/dd/sylvan/InternalSylvanAdd.h index dc65e240a..5137caf15 100644 --- a/src/storm/storage/dd/sylvan/InternalSylvanAdd.h +++ b/src/storm/storage/dd/sylvan/InternalSylvanAdd.h @@ -319,7 +319,7 @@ namespace storm { * @return The resulting ADD. */ InternalAdd<DdType::Sylvan, ValueType> swapVariables(std::vector<InternalBdd<DdType::Sylvan>> const& from, std::vector<InternalBdd<DdType::Sylvan>> const& to) const; - + /*! * Permutes the given pairs of DD variables in the ADD. The pairs of meta variables have to be represented by * ADDs must have equal length. diff --git a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp index a2ded9452..eaab6e2c2 100644 --- a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp +++ b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp @@ -64,25 +64,39 @@ namespace storm { } lace_startup(0, 0, 0); - // Each node takes 24 bytes and the maximal memory is specified in megabytes. - uint_fast64_t totalNodesToStore = storm::settings::getModule<storm::settings::modules::SylvanSettings>().getMaximalMemory() * 1024 * 1024 / 24; + // Table/cache size computation taken from newer version of sylvan. + uint64_t memorycap = storm::settings::getModule<storm::settings::modules::SylvanSettings>().getMaximalMemory() * 1024 * 1024; - // Compute the power of two that still fits within the total numbers to store. - uint_fast64_t powerOfTwo = findLargestPowerOfTwoFitting(totalNodesToStore); + uint64_t table_ratio = 0; + uint64_t initial_ratio = 0; - STORM_LOG_THROW(powerOfTwo >= 16, storm::exceptions::InvalidSettingsException, "Too little memory assigned to sylvan."); + uint64_t max_t = 1; + uint64_t max_c = 1; + if (table_ratio > 0) { + max_t <<= table_ratio; + } else { + max_c <<= -table_ratio; + } - uint64_t maxTableSize = 1ull << powerOfTwo; - uint64_t maxCacheSize = 1ull << (powerOfTwo - 1); - if (maxTableSize + maxCacheSize > totalNodesToStore) { - maxTableSize >>= 1; + uint64_t cur = max_t * 24 + max_c * 36; + STORM_LOG_THROW(cur <= memorycap, storm::exceptions::InvalidSettingsException, "Memory cap incompatible with default table ratio."); + + while (2*cur < memorycap && max_t < 0x0000040000000000) { + max_t *= 2; + max_c *= 2; + cur *= 2; } - uint64_t initialTableSize = 1ull << std::max(powerOfTwo - 4, static_cast<uint_fast64_t>(16)); - uint64_t initialCacheSize = initialTableSize; + uint64_t min_t = max_t, min_c = max_c; + while (initial_ratio > 0 && min_t > 0x1000 && min_c > 0x1000) { + min_t >>= 1; + min_c >>= 1; + initial_ratio--; + } + // End of copied code. - STORM_LOG_DEBUG("Initializing sylvan. Initial/max table size: " << initialTableSize << "/" << maxTableSize << ", initial/max cache size: " << initialCacheSize << "/" << maxCacheSize << "."); - sylvan::Sylvan::initPackage(initialTableSize, maxTableSize, initialCacheSize, maxCacheSize); + STORM_LOG_DEBUG("Initializing sylvan library. Initial/max table size: " << min_t << "/" << max_t << ", initial/max cache size: " << min_c << "/" << max_c << "."); + sylvan::Sylvan::initPackage(min_t, max_t, min_c, max_c); sylvan::Sylvan::initBdd(); sylvan::Sylvan::initMtbdd(); diff --git a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp index 2cd3c2f61..92ed03c5c 100644 --- a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp +++ b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp @@ -6,11 +6,13 @@ #include "storm/storage/expressions/IntegerLiteralExpression.h" #include "storm/storage/expressions/RationalLiteralExpression.h" #include "storm/storage/expressions/ExpressionVisitor.h" + #include "storm/utility/macros.h" +#include "storm/utility/constants.h" +#include "storm/utility/NumberTraits.h" #include "storm/exceptions/InvalidTypeException.h" #include "storm/exceptions/InvalidStateException.h" - namespace storm { namespace expressions { BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ExpressionManager const& manager, Type const& type, std::shared_ptr<BaseExpression const> const& firstOperand, std::shared_ptr<BaseExpression const> const& secondOperand, OperatorType operatorType) : BinaryExpression(manager, type, firstOperand, secondOperand), operatorType(operatorType) { @@ -31,6 +33,7 @@ namespace storm { case OperatorType::Min: result = storm::expressions::OperatorType::Min; break; case OperatorType::Max: result = storm::expressions::OperatorType::Max; break; case OperatorType::Power: result = storm::expressions::OperatorType::Power; break; + case OperatorType::Modulo: result = storm::expressions::OperatorType::Modulo; break; } return result; } @@ -49,6 +52,7 @@ namespace storm { case OperatorType::Min: result = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: result = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: result = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break; + case OperatorType::Modulo: result = firstOperandEvaluation % secondOperandEvaluation; break; } return result; } @@ -67,6 +71,7 @@ namespace storm { case OperatorType::Min: result = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: result = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: result = std::pow(firstOperandEvaluation, secondOperandEvaluation); break; + case OperatorType::Modulo: result = std::fmod(firstOperandEvaluation, secondOperandEvaluation); break; } return result; } @@ -79,7 +84,7 @@ namespace storm { if (this->hasIntegerType()) { int_fast64_t firstOperandEvaluation = firstOperandSimplified->evaluateAsInt(); int_fast64_t secondOperandEvaluation = secondOperandSimplified->evaluateAsInt(); - int_fast64_t newValue = 0; + boost::optional<int_fast64_t> newValue; switch (this->getOperatorType()) { case OperatorType::Plus: newValue = firstOperandEvaluation + secondOperandEvaluation; break; case OperatorType::Minus: newValue = firstOperandEvaluation - secondOperandEvaluation; break; @@ -87,28 +92,40 @@ namespace storm { case OperatorType::Min: newValue = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: newValue = std::max(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Power: newValue = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break; - case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break; + case OperatorType::Modulo: newValue = firstOperandEvaluation % secondOperandEvaluation; break; + case OperatorType::Divide: break; // do not simplify division. + } + if (newValue) { + return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), newValue.get())); } - return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), newValue)); } else if (this->hasRationalType()) { storm::RationalNumber firstOperandEvaluation = firstOperandSimplified->evaluateAsRational(); storm::RationalNumber secondOperandEvaluation = secondOperandSimplified->evaluateAsRational(); - storm::RationalNumber newValue = 0; + boost::optional<storm::RationalNumber> newValue; switch (this->getOperatorType()) { case OperatorType::Plus: newValue = firstOperandEvaluation + secondOperandEvaluation; break; case OperatorType::Minus: newValue = firstOperandEvaluation - secondOperandEvaluation; break; case OperatorType::Times: newValue = firstOperandEvaluation * secondOperandEvaluation; break; case OperatorType::Min: newValue = std::min(firstOperandEvaluation, secondOperandEvaluation); break; case OperatorType::Max: newValue = std::max(firstOperandEvaluation, secondOperandEvaluation); break; + case OperatorType::Divide: newValue = firstOperandEvaluation / secondOperandEvaluation; break; case OperatorType::Power: { - STORM_LOG_THROW(carl::isInteger(secondOperandEvaluation), storm::exceptions::InvalidStateException, "Can not simplify pow() with fractional exponent."); - std::size_t exponent = carl::toInt<carl::uint>(secondOperandEvaluation); - newValue = carl::pow(firstOperandEvaluation, exponent); + if (carl::isInteger(secondOperandEvaluation)) { + std::size_t exponent = carl::toInt<carl::uint>(secondOperandEvaluation); + newValue = carl::pow(firstOperandEvaluation, exponent); + } break; } - case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break; + case OperatorType::Modulo: { + if (carl::isInteger(firstOperandEvaluation) && carl::isInteger(secondOperandEvaluation)) { + newValue = storm::utility::mod(storm::utility::numerator(firstOperandEvaluation), storm::utility::numerator(secondOperandEvaluation)); + } + break; + } + } + if (newValue) { + return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue.get())); } - return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue)); } } @@ -137,6 +154,7 @@ namespace storm { case OperatorType::Min: stream << "min(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; case OperatorType::Max: stream << "max(" << *this->getFirstOperand() << ", " << *this->getSecondOperand() << ")"; break; case OperatorType::Power: stream << *this->getFirstOperand() << " ^ " << *this->getSecondOperand(); break; + case OperatorType::Modulo: stream << *this->getFirstOperand() << " % " << *this->getSecondOperand(); break; } stream << ")"; } diff --git a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h index 1e9adb028..1879b141d 100644 --- a/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h +++ b/src/storm/storage/expressions/BinaryNumericalFunctionExpression.h @@ -11,7 +11,7 @@ namespace storm { /*! * An enum type specifying the different operators applicable. */ - enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power}; + enum class OperatorType {Plus, Minus, Times, Divide, Min, Max, Power, Modulo}; /*! * Constructs a binary numerical function expression with the given return type, operands and operator. diff --git a/src/storm/storage/expressions/EquivalenceChecker.cpp b/src/storm/storage/expressions/EquivalenceChecker.cpp index b8d538656..c00d4fae6 100644 --- a/src/storm/storage/expressions/EquivalenceChecker.cpp +++ b/src/storm/storage/expressions/EquivalenceChecker.cpp @@ -13,6 +13,12 @@ namespace storm { } } + void EquivalenceChecker::addConstraints(std::vector<storm::expressions::Expression> const& constraints) { + for (auto const& constraint : constraints) { + this->smtSolver->add(constraint); + } + } + bool EquivalenceChecker::areEquivalent(storm::expressions::Expression const& first, storm::expressions::Expression const& second) { this->smtSolver->push(); this->smtSolver->add((first && !second) || (!first && second)); @@ -21,5 +27,9 @@ namespace storm { return equivalent; } + bool EquivalenceChecker::areEquivalentModuloNegation(storm::expressions::Expression const& first, storm::expressions::Expression const& second) { + return this->areEquivalent(first, second) || this->areEquivalent(first, !second); + } + } } diff --git a/src/storm/storage/expressions/EquivalenceChecker.h b/src/storm/storage/expressions/EquivalenceChecker.h index 2ec39ba8a..5d60eb50b 100644 --- a/src/storm/storage/expressions/EquivalenceChecker.h +++ b/src/storm/storage/expressions/EquivalenceChecker.h @@ -20,7 +20,10 @@ namespace storm { */ EquivalenceChecker(std::unique_ptr<storm::solver::SmtSolver>&& smtSolver, boost::optional<storm::expressions::Expression> const& constraint = boost::none); + void addConstraints(std::vector<storm::expressions::Expression> const& constraints); + bool areEquivalent(storm::expressions::Expression const& first, storm::expressions::Expression const& second); + bool areEquivalentModuloNegation(storm::expressions::Expression const& first, storm::expressions::Expression const& second); private: std::unique_ptr<storm::solver::SmtSolver> smtSolver; diff --git a/src/storm/storage/expressions/Expression.cpp b/src/storm/storage/expressions/Expression.cpp index ed00728f0..2ec1604a7 100644 --- a/src/storm/storage/expressions/Expression.cpp +++ b/src/storm/storage/expressions/Expression.cpp @@ -229,6 +229,11 @@ namespace storm { } Expression operator+(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } assertSameManager(first.getBaseExpression(), second.getBaseExpression()); return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getManager(), first.getType().plusMinusTimes(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Plus))); } @@ -272,7 +277,18 @@ namespace storm { return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getBaseExpression().getManager(), first.getType().power(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Power))); } + Expression operator%(Expression const& first, Expression const& second) { + assertSameManager(first.getBaseExpression(), second.getBaseExpression()); + return Expression(std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(first.getBaseExpression().getManager(), first.getType().power(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Modulo))); + } + Expression operator&&(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } + assertSameManager(first.getBaseExpression(), second.getBaseExpression()); if (first.isTrue()) { STORM_LOG_THROW(second.hasBooleanType(), storm::exceptions::InvalidTypeException, "Operator requires boolean operands."); @@ -287,6 +303,11 @@ namespace storm { } Expression operator||(Expression const& first, Expression const& second) { + if (!first.isInitialized()) { + return second; + } else if (!second.isInitialized()) { + return first; + } assertSameManager(first.getBaseExpression(), second.getBaseExpression()); return Expression(std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(first.getBaseExpression().getManager(), first.getType().logicalConnective(second.getType()), first.getBaseExpressionPointer(), second.getBaseExpressionPointer(), BinaryBooleanFunctionExpression::OperatorType::Or))); } diff --git a/src/storm/storage/expressions/Expression.h b/src/storm/storage/expressions/Expression.h index 98a2e6417..99d409e2e 100644 --- a/src/storm/storage/expressions/Expression.h +++ b/src/storm/storage/expressions/Expression.h @@ -33,6 +33,7 @@ namespace storm { friend Expression operator*(Expression const& first, Expression const& second); friend Expression operator/(Expression const& first, Expression const& second); friend Expression operator^(Expression const& first, Expression const& second); + friend Expression operator%(Expression const& first, Expression const& second); friend Expression operator&&(Expression const& first, Expression const& second); friend Expression operator||(Expression const& first, Expression const& second); friend Expression operator!(Expression const& first); diff --git a/src/storm/storage/expressions/LinearityCheckVisitor.cpp b/src/storm/storage/expressions/LinearityCheckVisitor.cpp index 9eeb3ea56..86650acea 100644 --- a/src/storm/storage/expressions/LinearityCheckVisitor.cpp +++ b/src/storm/storage/expressions/LinearityCheckVisitor.cpp @@ -77,6 +77,7 @@ namespace storm { case BinaryNumericalFunctionExpression::OperatorType::Min: return LinearityStatus::NonLinear; break; case BinaryNumericalFunctionExpression::OperatorType::Max: return LinearityStatus::NonLinear; break; case BinaryNumericalFunctionExpression::OperatorType::Power: return LinearityStatus::NonLinear; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: return LinearityStatus::NonLinear; break; } STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Illegal binary numerical expression operator."); } diff --git a/src/storm/storage/expressions/OperatorType.cpp b/src/storm/storage/expressions/OperatorType.cpp index 1036869bc..bba61a653 100644 --- a/src/storm/storage/expressions/OperatorType.cpp +++ b/src/storm/storage/expressions/OperatorType.cpp @@ -16,6 +16,7 @@ namespace storm { case OperatorType::Min: stream << "min"; break; case OperatorType::Max: stream << "max"; break; case OperatorType::Power: stream << "^"; break; + case OperatorType::Modulo: stream << "%"; break; case OperatorType::Equal: stream << "="; break; case OperatorType::NotEqual: stream << "!="; break; case OperatorType::Less: stream << "<"; break; diff --git a/src/storm/storage/expressions/OperatorType.h b/src/storm/storage/expressions/OperatorType.h index f056f494a..e334b8104 100644 --- a/src/storm/storage/expressions/OperatorType.h +++ b/src/storm/storage/expressions/OperatorType.h @@ -19,6 +19,7 @@ namespace storm { Min, Max, Power, + Modulo, Equal, NotEqual, Less, diff --git a/src/storm/storage/expressions/ToCppVisitor.cpp b/src/storm/storage/expressions/ToCppVisitor.cpp index b68de7132..70b76a467 100644 --- a/src/storm/storage/expressions/ToCppVisitor.cpp +++ b/src/storm/storage/expressions/ToCppVisitor.cpp @@ -142,6 +142,13 @@ namespace storm { expression.getSecondOperand()->accept(*this, data); stream << ")"; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: + stream << "("; + expression.getFirstOperand()->accept(*this, data); + stream << " % "; + expression.getSecondOperand()->accept(*this, data); + stream << ")"; + break; } return boost::none; } diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index d9098af2b..b3b0df9c3 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -100,6 +100,13 @@ namespace storm { expression.getSecondOperand()->accept(*this, data); stream << ")"; break; + case BinaryNumericalFunctionExpression::OperatorType::Modulo: + stream << "("; + expression.getFirstOperand()->accept(*this, data); + stream << "%"; + expression.getSecondOperand()->accept(*this, data); + stream << ")"; + break; case BinaryNumericalFunctionExpression::OperatorType::Max: stream << "max("; expression.getFirstOperand()->accept(*this, data); @@ -213,7 +220,7 @@ namespace storm { } boost::any ToExprtkStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { - stream << "(" << expression.getValue() << ")"; + stream << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << "(" << expression.getValueAsDouble() << ")"; return boost::any(); } } diff --git a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp index 15a8d61eb..89408f9d3 100644 --- a/src/storm/storage/expressions/ToRationalNumberVisitor.cpp +++ b/src/storm/storage/expressions/ToRationalNumberVisitor.cpp @@ -48,6 +48,7 @@ namespace storm { RationalNumberType firstOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getFirstOperand()->accept(*this, data)); RationalNumberType secondOperandAsRationalNumber = boost::any_cast<RationalNumberType>(expression.getSecondOperand()->accept(*this, data)); RationalNumberType result; + uint_fast64_t exponentAsInteger; switch(expression.getOperatorType()) { case BinaryNumericalFunctionExpression::OperatorType::Plus: result = firstOperandAsRationalNumber + secondOperandAsRationalNumber; @@ -75,10 +76,12 @@ namespace storm { break; case BinaryNumericalFunctionExpression::OperatorType::Power: STORM_LOG_THROW(storm::utility::isInteger(secondOperandAsRationalNumber), storm::exceptions::InvalidArgumentException, "Exponent of power operator must be a positive integer."); - uint_fast64_t exponentAsInteger = storm::utility::convertNumber<carl::uint>(secondOperandAsRationalNumber); + exponentAsInteger = storm::utility::convertNumber<carl::uint>(secondOperandAsRationalNumber); result = storm::utility::pow(firstOperandAsRationalNumber, exponentAsInteger); return result; break; + default: + STORM_LOG_ASSERT(false, "Illegal operator type."); } // Return a dummy. This point must, however, never be reached. diff --git a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp index 3ed20d7b6..770c7b9f1 100644 --- a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp +++ b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp @@ -74,6 +74,7 @@ namespace storm { operandEvaluation = operandSimplified->evaluateAsRational(); } + bool rationalToInteger = this->getOperatorType() == OperatorType::Floor || this->getOperatorType() == OperatorType::Ceil; if (operandSimplified->hasIntegerType()) { int_fast64_t value = 0; switch (this->getOperatorType()) { @@ -82,6 +83,15 @@ namespace storm { case OperatorType::Ceil: value = std::ceil(boost::get<int_fast64_t>(operandEvaluation)); break; } return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), value)); + } else if (rationalToInteger) { + int_fast64_t value = 0; + switch (this->getOperatorType()) { + case OperatorType::Floor: value = storm::utility::convertNumber<int_fast64_t>(storm::RationalNumber(carl::floor(boost::get<storm::RationalNumber>(operandEvaluation)))); break; + case OperatorType::Ceil: value = storm::utility::convertNumber<int_fast64_t>(storm::RationalNumber(carl::ceil(boost::get<storm::RationalNumber>(operandEvaluation)))); break; + default: + STORM_LOG_ASSERT(false, "Unexpected rational to integer conversion."); + } + return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), value)); } else { storm::RationalNumber value = storm::utility::zero<storm::RationalNumber>(); switch (this->getOperatorType()) { diff --git a/src/storm/storage/jani/Automaton.cpp b/src/storm/storage/jani/Automaton.cpp index 920854628..f4c65c759 100644 --- a/src/storm/storage/jani/Automaton.cpp +++ b/src/storm/storage/jani/Automaton.cpp @@ -12,47 +12,7 @@ namespace storm { namespace jani { - namespace detail { - Edges::Edges(iterator it, iterator ite) : it(it), ite(ite) { - // Intentionally left empty. - } - - Edges::iterator Edges::begin() const { - return it; - } - - Edges::iterator Edges::end() const { - return ite; - } - - bool Edges::empty() const { - return it == ite; - } - - std::size_t Edges::size() const { - return std::distance(it, ite); - } - - ConstEdges::ConstEdges(const_iterator it, const_iterator ite) : it(it), ite(ite) { - // Intentionally left empty. - } - - ConstEdges::const_iterator ConstEdges::begin() const { - return it; - } - - ConstEdges::const_iterator ConstEdges::end() const { - return ite; - } - bool ConstEdges::empty() const { - return it == ite; - } - - std::size_t ConstEdges::size() const { - return std::distance(it, ite); - } - } Automaton::Automaton(std::string const& name, storm::expressions::Variable const& locationExpressionVariable) : name(name), locationExpressionVariable(locationExpressionVariable) { // Add a sentinel element to the mapping from locations to starting indices. @@ -175,6 +135,10 @@ namespace storm { return locationExpressionVariable; } + Edge const& Automaton::getEdge(uint64_t index) const { + return edges.getConcreteEdges()[index]; + } + Automaton::Edges Automaton::getEdgesFromLocation(std::string const& name) { auto it = locationToIndex.find(name); STORM_LOG_THROW(it != locationToIndex.end(), storm::exceptions::InvalidArgumentException, "Cannot retrieve edges from unknown location '" << name << "."); @@ -301,46 +265,32 @@ namespace storm { return ConstEdges(it1, it2); } - - void Automaton::addEdge(Edge const& edge) { STORM_LOG_THROW(edge.getSourceLocationIndex() < locations.size(), storm::exceptions::InvalidArgumentException, "Cannot add edge with unknown source location index '" << edge.getSourceLocationIndex() << "'."); - - // Find the right position for the edge and insert it properly. - auto posIt = edges.begin(); - std::advance(posIt, locationToStartingIndex[edge.getSourceLocationIndex() + 1]); - edges.insert(posIt, edge); - + assert(validate()); + + edges.insertEdge(edge, locationToStartingIndex[edge.getSourceLocationIndex()], locationToStartingIndex[edge.getSourceLocationIndex() + 1]); + // Update the set of action indices of this automaton. + actionIndices.insert(edge.getActionIndex()); + // Now update the starting indices of all subsequent locations. for (uint64_t locationIndex = edge.getSourceLocationIndex() + 1; locationIndex < locationToStartingIndex.size(); ++locationIndex) { ++locationToStartingIndex[locationIndex]; } - // Sort all edges form the source location of the newly introduced edge by their action indices. - auto it = edges.begin(); - std::advance(it, locationToStartingIndex[edge.getSourceLocationIndex()]); - auto ite = edges.begin(); - std::advance(ite, locationToStartingIndex[edge.getSourceLocationIndex() + 1]); - std::sort(it, ite, [] (Edge const& a, Edge const& b) { return a.getActionIndex() < b.getActionIndex(); } ); - - // Update the set of action indices of this automaton. - actionIndices.insert(edge.getActionIndex()); + } std::vector<Edge>& Automaton::getEdges() { - return edges; + return edges.getConcreteEdges(); } std::vector<Edge> const& Automaton::getEdges() const { - return edges; + return edges.getConcreteEdges(); } std::set<uint64_t> Automaton::getActionIndices() const { - std::set<uint64_t> result; - for (auto const& edge : edges) { - result.insert(edge.getActionIndex()); - } - return result; + return edges.getActionIndices(); } uint64_t Automaton::getNumberOfLocations() const { @@ -424,35 +374,22 @@ namespace storm { this->setInitialStatesRestriction(this->getInitialStatesRestriction().substitute(substitution)); - for (auto& templateEdge : templateEdges) { - templateEdge->substitute(substitution); - } - for (auto& edge : this->getEdges()) { - edge.substitute(substitution); - } + edges.substitute(substitution); } void Automaton::registerTemplateEdge(std::shared_ptr<TemplateEdge> const& te) { - templateEdges.insert(te); + edges.insertTemplateEdge(te); } void Automaton::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) { for (auto& location : locations) { location.changeAssignmentVariables(remapping); } - for (auto& templateEdge : templateEdges) { - templateEdge->changeAssignmentVariables(remapping); - } + edges.changeAssignmentVariables(remapping); } void Automaton::finalize(Model const& containingModel) { //simplifyIndexedAssignments(); - templateEdges.clear(); - for (auto& edge : edges) { - templateEdges.insert(edge.getTemplateEdge()); - } - for (auto& templateEdge : templateEdges) { - templateEdge->finalize(containingModel); - } + edges.finalize(containingModel); } bool Automaton::containsVariablesOnlyInProbabilitiesOrTransientAssignments(std::set<storm::expressions::Variable> const& variables) const { @@ -479,9 +416,7 @@ namespace storm { } void Automaton::pushEdgeAssignmentsToDestinations() { - for (auto& templateEdge : templateEdges) { - templateEdge->pushAssignmentsToDestinations(); - } + edges.pushAssignmentsToDestinations(); } bool Automaton::hasTransientEdgeDestinationAssignments() const { @@ -494,25 +429,20 @@ namespace storm { } void Automaton::liftTransientEdgeDestinationAssignments() { - for (auto& templateEdge : templateEdges) { - templateEdge->liftTransientDestinationAssignments(); - } + edges.liftTransientDestinationAssignments(); } - void Automaton::simplifyIndexedAssignments() { - // TODO has to be fixed. - for (auto& edge : edges) { - edge.simplifyIndexedAssignments(variables); + bool Automaton::validate() const { + assert(locationToStartingIndex.size() == locations.size() + 1); + for(uint64_t i = 0; i < locations.size(); i++) { + assert(locationToStartingIndex[i] <= locationToStartingIndex[i+1]); } + return true; } + bool Automaton::usesAssignmentLevels() const { - for (auto const& edge : this->getEdges()) { - if (edge.usesAssignmentLevels()) { - return true; - } - } - return false; + return edges.usesAssignmentLevels(); } bool Automaton::isLinear() const { @@ -521,14 +451,26 @@ namespace storm { for (auto const& location : this->getLocations()) { result &= location.isLinear(); } - - for (auto const& templateEdge : templateEdges) { - result &= templateEdge->isLinear(); + if (result) { + return edges.isLinear(); } - - return result; + return false; } + void Automaton::restrictToEdges(boost::container::flat_set<uint_fast64_t> const& edgeIndices) { + std::vector<Edge> oldEdges = this->edges.getConcreteEdges(); + + this->edges.clearConcreteEdges(); + actionIndices.clear(); + for (auto& e : locationToStartingIndex) { + e = 0; + } + + for (auto const& index : edgeIndices) { + this->addEdge(oldEdges[index]); + } + } + void Automaton::writeDotToStream(std::ostream& outStream, std::vector<std::string> const& actionNames) const { outStream << "\tsubgraph " << name << " {" << std::endl; diff --git a/src/storm/storage/jani/Automaton.h b/src/storm/storage/jani/Automaton.h index 37b4e9755..c549ecca8 100644 --- a/src/storm/storage/jani/Automaton.h +++ b/src/storm/storage/jani/Automaton.h @@ -7,6 +7,8 @@ #include <boost/container/flat_set.hpp> #include "storm/storage/jani/VariableSet.h" +#include "storm/storage/jani/TemplateEdgeContainer.h" +#include "storm/storage/jani/EdgeContainer.h" namespace storm { @@ -16,73 +18,8 @@ namespace storm { class Edge; class TemplateEdge; class Location; - - namespace detail { - class Edges { - public: - typedef std::vector<Edge>::iterator iterator; - typedef std::vector<Edge>::const_iterator const_iterator; - - Edges(iterator it, iterator ite); - - /*! - * Retrieves an iterator to the edges. - */ - iterator begin() const; - - /*! - * Retrieves an end iterator to the edges. - */ - iterator end() const; - - /*! - * Determines whether this set of edges is empty. - */ - bool empty() const; - - /*! - * Retrieves the number of edges. - */ - std::size_t size() const; - - private: - iterator it; - iterator ite; - }; - - class ConstEdges { - public: - typedef std::vector<Edge>::iterator iterator; - typedef std::vector<Edge>::const_iterator const_iterator; - - ConstEdges(const_iterator it, const_iterator ite); - - /*! - * Retrieves an iterator to the edges. - */ - const_iterator begin() const; - - /*! - * Retrieves an end iterator to the edges. - */ - const_iterator end() const; - /*! - * Determines whether this set of edges is empty. - */ - bool empty() const; - /*! - * Retrieves the number of edges. - */ - std::size_t size() const; - - private: - const_iterator it; - const_iterator ite; - }; - } - class Model; class Automaton { @@ -218,6 +155,11 @@ namespace storm { */ storm::expressions::Variable const& getLocationExpressionVariable() const; + /*! + * Retrieves the edge with the given index in this automaton. + */ + Edge const& getEdge(uint64_t index) const; + /*! * Retrieves the edges of the location with the given name. */ @@ -257,6 +199,8 @@ namespace storm { * Adds an edge to the automaton. */ void addEdge(Edge const& edge); + + bool validate() const; /*! * Retrieves the edges of the automaton. @@ -374,6 +318,11 @@ namespace storm { void writeDotToStream(std::ostream& outStream, std::vector<std::string> const& actionNames) const; + /*! + * Restricts the automaton to the edges given by the indices. All other edges are deleted. + */ + void restrictToEdges(boost::container::flat_set<uint_fast64_t> const& edgeIndices); + private: /// The name of the automaton. std::string name; @@ -391,10 +340,7 @@ namespace storm { std::unordered_map<std::string, uint64_t> locationToIndex; /// All edges of the automaton - std::vector<Edge> edges; - - /// The templates for the contained edges. - std::unordered_set<std::shared_ptr<TemplateEdge>> templateEdges; + EdgeContainer edges; /// A mapping from location indices to the starting indices. If l is mapped to i, it means that the edges /// leaving location l start at index i of the edges vector. diff --git a/src/storm/storage/jani/Edge.cpp b/src/storm/storage/jani/Edge.cpp index 18fb35f4f..4460b2a65 100644 --- a/src/storm/storage/jani/Edge.cpp +++ b/src/storm/storage/jani/Edge.cpp @@ -116,8 +116,24 @@ namespace storm { } } + void Edge::setTemplateEdge(std::shared_ptr<TemplateEdge> const& newTe) { + templateEdge = newTe; + uint64_t i = 0; + std::vector<EdgeDestination> newdestinations; + + assert(destinations.size() == newTe->getNumberOfDestinations()); + for (auto& destination : destinations) { + newdestinations.emplace_back(destination.getLocationIndex(), destination.getProbability(), newTe->getDestination(i)); + //destination.updateTemplateEdgeDestination(newTe->getDestination(i)); + ++i; + } + destinations = newdestinations; + } + std::shared_ptr<TemplateEdge> const& Edge::getTemplateEdge() { return templateEdge; } + + } } diff --git a/src/storm/storage/jani/Edge.h b/src/storm/storage/jani/Edge.h index af98706ae..002b97d40 100644 --- a/src/storm/storage/jani/Edge.h +++ b/src/storm/storage/jani/Edge.h @@ -110,8 +110,12 @@ namespace storm { * @param localVars */ void simplifyIndexedAssignments(VariableSet const& localVars); - + std::shared_ptr<TemplateEdge> const& getTemplateEdge(); + + void setTemplateEdge(std::shared_ptr<TemplateEdge> const& newTe); + + void assertValid() const; private: /// The index of the source location. diff --git a/src/storm/storage/jani/EdgeContainer.cpp b/src/storm/storage/jani/EdgeContainer.cpp new file mode 100644 index 000000000..b7a9ca1ec --- /dev/null +++ b/src/storm/storage/jani/EdgeContainer.cpp @@ -0,0 +1,200 @@ +#include "storm/storage/jani/EdgeContainer.h" +#include "storm/storage/jani/Edge.h" +#include "storm/storage/jani/TemplateEdge.h" +#include "storm/storage/jani/Variable.h" +#include "storm/storage/jani/Model.h" + + + +namespace storm { + namespace jani { + namespace detail { + Edges::Edges(iterator it, iterator ite) : it(it), ite(ite) { + // Intentionally left empty. + } + + Edges::iterator Edges::begin() const { + return it; + } + + Edges::iterator Edges::end() const { + return ite; + } + + bool Edges::empty() const { + return it == ite; + } + + std::size_t Edges::size() const { + return std::distance(it, ite); + } + + ConstEdges::ConstEdges(const_iterator it, const_iterator ite) : it(it), ite(ite) { + // Intentionally left empty. + } + + ConstEdges::const_iterator ConstEdges::begin() const { + return it; + } + + ConstEdges::const_iterator ConstEdges::end() const { + return ite; + } + + bool ConstEdges::empty() const { + return it == ite; + } + + std::size_t ConstEdges::size() const { + return std::distance(it, ite); + } + } + + EdgeContainer::EdgeContainer(EdgeContainer const& other) { + edges = other.getConcreteEdges(); + //templates = other.templates; + std::map<std::shared_ptr<TemplateEdge>, std::shared_ptr<TemplateEdge>> map; + for (auto const& te : other.templates) { + auto newTe = std::make_shared<TemplateEdge>(*te); + this->templates.insert(newTe); + map[te] = newTe; + } + + for (auto& e : edges) { + if(map.count(e.getTemplateEdge()) == 0) { + e.setTemplateEdge(std::make_shared<TemplateEdge>(*(e.getTemplateEdge()))); + } else { + e.setTemplateEdge(map[e.getTemplateEdge()]); + } + } + + + + } + + void EdgeContainer::finalize(Model const& containingModel) { + templates.clear(); + for (auto& edge : edges) { + templates.insert(edge.getTemplateEdge()); + } + for (auto& templateEdge : templates) { + templateEdge->finalize(containingModel); + } + } + + void EdgeContainer::clearConcreteEdges() { + edges.clear(); + } + + void EdgeContainer::liftTransientDestinationAssignments() { + for (auto& templateEdge : templates) { + templateEdge->liftTransientDestinationAssignments(); + } + } + + void EdgeContainer::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) { + for (auto& templateEdge : templates) { + templateEdge->substitute(substitution); + } + for (auto& edge : edges) { + edge.substitute(substitution); + } + } + + bool EdgeContainer::isLinear() const { + for (auto const& templateEdge : templates) { + if (!templateEdge->isLinear()) { + return false; + } + } + return true; + } + + + bool EdgeContainer::usesAssignmentLevels() const { + for (auto const& edge : edges) { + if (edge.usesAssignmentLevels()) { + return true; + } + } + return false; + + } + + + + std::vector<Edge> & EdgeContainer::getConcreteEdges() { + return edges; + } + + std::vector<Edge> const& EdgeContainer::getConcreteEdges() const { + return edges; + } + + std::set<uint64_t> EdgeContainer::getActionIndices() const { + std::set<uint64_t> result; + for (auto const& edge : edges) { + result.insert(edge.getActionIndex()); + } + return result; + } + + /** + * Insert an edge, then sort the range between locstart and locend according to the action index. + * @param e + * @param locStart index where to start + * @param locEnd index where to end + */ + void EdgeContainer::insertEdge(Edge const &e, uint64_t locStart, uint64_t locEnd) { + assert(locStart <= locEnd); + // Find the right position for the edge and insert it properly. + auto posIt = edges.begin(); + std::advance(posIt, locEnd); + edges.insert(posIt, e); + + // Sort all edges form the source location of the newly introduced edge by their action indices. + auto it = edges.begin(); + std::advance(it, locStart); + auto ite = edges.begin(); + std::advance(ite, locEnd + 1); + std::sort(it, ite, [] (Edge const& a, Edge const& b) { return a.getActionIndex() < b.getActionIndex(); } ); + + } + + void EdgeContainer::insertTemplateEdge(std::shared_ptr <TemplateEdge> const &te) { + templates.insert(te); + } + + void EdgeContainer::pushAssignmentsToDestinations() { + for (auto& templateEdge : templates) { + templateEdge->pushAssignmentsToDestinations(); + } + } + + void EdgeContainer::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) { + for (auto& templateEdge : templates) { + templateEdge->changeAssignmentVariables(remapping); + } + } + + size_t EdgeContainer::size() const { + return edges.size(); + } + + EdgeContainer::iterator EdgeContainer::begin() { + return edges.begin(); + } + EdgeContainer::iterator EdgeContainer::end() { + return edges.end(); + } + EdgeContainer::const_iterator EdgeContainer::begin() const { + return edges.begin(); + } + EdgeContainer::const_iterator EdgeContainer::end() const { + return edges.end(); + } + + + + } +} \ No newline at end of file diff --git a/src/storm/storage/jani/EdgeContainer.h b/src/storm/storage/jani/EdgeContainer.h new file mode 100644 index 000000000..f4738e1e0 --- /dev/null +++ b/src/storm/storage/jani/EdgeContainer.h @@ -0,0 +1,125 @@ +#pragma once + +#include <vector> +#include <set> +#include <map> +#include "storm/storage/expressions/Expression.h" +#include "storm/storage/jani/TemplateEdgeContainer.h" + +namespace storm { + namespace jani { + + class Edge; + class TemplateEdge; + class Variable; + class Model; + + namespace detail { + class Edges { + public: + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + Edges(iterator it, iterator ite); + + /*! + * Retrieves an iterator to the edges. + */ + iterator begin() const; + + /*! + * Retrieves an end iterator to the edges. + */ + iterator end() const; + + /*! + * Determines whether this set of edges is empty. + */ + bool empty() const; + + /*! + * Retrieves the number of edges. + */ + std::size_t size() const; + + private: + iterator it; + iterator ite; + }; + + + class ConstEdges { + public: + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + ConstEdges(const_iterator it, const_iterator ite); + + /*! + * Retrieves an iterator to the edges. + */ + const_iterator begin() const; + + /*! + * Retrieves an end iterator to the edges. + */ + const_iterator end() const; + + /*! + * Determines whether this set of edges is empty. + */ + bool empty() const; + + /*! + * Retrieves the number of edges. + */ + std::size_t size() const; + + private: + const_iterator it; + const_iterator ite; + }; + } + + + class EdgeContainer { + public: + + typedef std::vector<Edge>::iterator iterator; + typedef std::vector<Edge>::const_iterator const_iterator; + + + EdgeContainer() = default; + EdgeContainer(EdgeContainer const& other); + + void clearConcreteEdges(); + std::vector<Edge> const& getConcreteEdges() const; + std::vector<Edge> & getConcreteEdges(); + size_t size() const; + + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + std::set<uint64_t> getActionIndices() const; + + void substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution); + void liftTransientDestinationAssignments(); + void pushAssignmentsToDestinations(); + void insertEdge(Edge const& e, uint64_t locStart, uint64_t locEnd); + void insertTemplateEdge(std::shared_ptr<TemplateEdge> const& te); + bool isLinear() const; + bool usesAssignmentLevels() const; + void finalize(Model const& containingModel); + + void changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping); + + + private: + std::vector<Edge> edges; + TemplateEdgeContainer templates; + }; + } +} + diff --git a/src/storm/storage/jani/EdgeDestination.cpp b/src/storm/storage/jani/EdgeDestination.cpp index 81efbfff5..62b92c1f0 100644 --- a/src/storm/storage/jani/EdgeDestination.cpp +++ b/src/storm/storage/jani/EdgeDestination.cpp @@ -58,5 +58,9 @@ namespace storm { TemplateEdgeDestination const& EdgeDestination::getTemplateEdgeDestination() const { return templateEdgeDestination.get(); } + + void EdgeDestination::updateTemplateEdgeDestination(TemplateEdgeDestination const& newTed) { + templateEdgeDestination = newTed; + } } } diff --git a/src/storm/storage/jani/EdgeDestination.h b/src/storm/storage/jani/EdgeDestination.h index 7cefe9c7a..62dd6114e 100644 --- a/src/storm/storage/jani/EdgeDestination.h +++ b/src/storm/storage/jani/EdgeDestination.h @@ -66,6 +66,8 @@ namespace storm { * Retrieves the template destination for this destination. */ TemplateEdgeDestination const& getTemplateEdgeDestination() const; + + void updateTemplateEdgeDestination(TemplateEdgeDestination const& newTed); private: // The index of the destination location. diff --git a/src/storm/storage/jani/JSONExporter.cpp b/src/storm/storage/jani/JSONExporter.cpp index 5fde8267a..0c0c212a0 100644 --- a/src/storm/storage/jani/JSONExporter.cpp +++ b/src/storm/storage/jani/JSONExporter.cpp @@ -455,6 +455,8 @@ namespace storm { return "max"; case OpType::Power: return "pow"; + case OpType::Modulo: + return "mod"; case OpType::Equal: return "="; case OpType::NotEqual: diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index 27232786b..47533126c 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -15,6 +15,7 @@ #include "storm/storage/jani/ParallelComposition.h" #include "storm/storage/jani/CompositionInformationVisitor.h" #include "storm/storage/jani/Compositions.h" +#include "storm/storage/jani/JSONExporter.h" #include "storm/storage/expressions/LinearityCheckVisitor.h" @@ -211,11 +212,14 @@ namespace storm { if (!SynchronizationVector::isNoActionInput(actionName)) { components.push_back(i); uint64_t actionIndex = oldModel.getActionIndex(actionName); + // store that automaton occurs in the sync vector. participatingAutomataAndActions.push_back(std::make_pair(composedAutomata[i], actionIndex)); + // Store for later that this action is one of the possible actions that synchronise synchronizingActionIndices[i].insert(actionIndex); } } - + + // What is the action label that should be attached to the composed actions uint64_t resultingActionIndex = Model::SILENT_ACTION_INDEX; if (vector.getOutput() != Model::SILENT_ACTION_NAME) { if (newModel.hasAction(vector.getOutput())) { @@ -688,14 +692,10 @@ namespace storm { return false; } - storm::expressions::ExpressionManager& Model::getExpressionManager() { - return *expressionManager; - } - - storm::expressions::ExpressionManager const& Model::getExpressionManager() const { + storm::expressions::ExpressionManager& Model::getExpressionManager() const { return *expressionManager; } - + uint64_t Model::addAutomaton(Automaton const& automaton) { auto it = automatonToIndex.find(automaton.getName()); STORM_LOG_THROW(it == automatonToIndex.end(), storm::exceptions::WrongFormatException, "Automaton with name '" << automaton.getName() << "' already exists."); @@ -1154,7 +1154,36 @@ namespace storm { } return false; } + + uint64_t Model::encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex) { + return automatonIndex << 32 | edgeIndex; + } + + std::pair<uint64_t, uint64_t> Model::decodeAutomatonAndEdgeIndices(uint64_t index) { + return std::make_pair(index >> 32, index & ((1ull << 32) - 1)); + } + + Model Model::restrictEdges(boost::container::flat_set<uint_fast64_t> const& automataAndEdgeIndices) const { + Model result(*this); + // Restrict all automata. + for (uint64_t automatonIndex = 0; automatonIndex < result.automata.size(); ++automatonIndex) { + + // Compute the set of edges that is to be kept for this automaton. + boost::container::flat_set<uint_fast64_t> automatonEdgeIndices; + for (auto const& e : automataAndEdgeIndices) { + auto automatonAndEdgeIndex = decodeAutomatonAndEdgeIndices(e); + if (automatonAndEdgeIndex.first == automatonIndex) { + automatonEdgeIndices.insert(automatonAndEdgeIndex.second); + } + } + + result.automata[automatonIndex].restrictToEdges(automatonEdgeIndices); + } + + return result; + } + Model Model::createModelFromAutomaton(Automaton const& automaton) const { // Copy the full model Model newModel(*this); @@ -1194,5 +1223,10 @@ namespace storm { outStream << "}"; } + + std::ostream& operator<<(std::ostream& out, Model const& model) { + JsonExporter::toStream(model, std::vector<storm::jani::Property>(), out); + return out; + } } } diff --git a/src/storm/storage/jani/Model.h b/src/storm/storage/jani/Model.h index bb0b48f26..2dc69d147 100644 --- a/src/storm/storage/jani/Model.h +++ b/src/storm/storage/jani/Model.h @@ -228,13 +228,8 @@ namespace storm { /*! * Retrieves the manager responsible for the expressions in the JANI model. */ - storm::expressions::ExpressionManager& getExpressionManager(); + storm::expressions::ExpressionManager& getExpressionManager() const; - /*! - * Retrieves the manager responsible for the expressions in the JANI model. - */ - storm::expressions::ExpressionManager const& getExpressionManager() const; - /*! * Adds the given automaton to the automata of this model. */ @@ -449,6 +444,18 @@ namespace storm { */ bool reusesActionsInComposition() const; + /*! + * Encode and decode a tuple of automaton and edge index in one 64-bit index. + */ + static uint64_t encodeAutomatonAndEdgeIndices(uint64_t automatonIndex, uint64_t edgeIndex); + static std::pair<uint64_t, uint64_t> decodeAutomatonAndEdgeIndices(uint64_t index); + + /*! + * Creates a new model that only contains the selected edges. The edge indices encode the automata and + * (local) indices of the edges within the automata. + */ + Model restrictEdges(boost::container::flat_set<uint_fast64_t> const& automataAndEdgeIndices) const; + void writeDotToStream(std::ostream& outStream = std::cout) const; /// The name of the silent action. @@ -505,6 +512,8 @@ namespace storm { // The expression restricting the legal initial values of the global variables. storm::expressions::Expression initialStatesRestriction; }; + + std::ostream& operator<<(std::ostream& out, Model const& model); } } diff --git a/src/storm/storage/jani/ParallelComposition.cpp b/src/storm/storage/jani/ParallelComposition.cpp index d81db1d91..0d439e0ce 100644 --- a/src/storm/storage/jani/ParallelComposition.cpp +++ b/src/storm/storage/jani/ParallelComposition.cpp @@ -116,7 +116,7 @@ namespace storm { return !(vector1 == vector2); } - bool SynchronizationVectorLexicographicalLess::operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) { + bool SynchronizationVectorLexicographicalLess::operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) const { STORM_LOG_THROW(vector1.size() == vector2.size(), storm::exceptions::WrongFormatException, "Cannot compare synchronization vectors of different size."); for (uint64_t i = 0; i < vector1.size(); ++i) { if (vector1.getInput(i) < vector2.getInput(i)) { diff --git a/src/storm/storage/jani/ParallelComposition.h b/src/storm/storage/jani/ParallelComposition.h index c3d41717c..381ace5f8 100644 --- a/src/storm/storage/jani/ParallelComposition.h +++ b/src/storm/storage/jani/ParallelComposition.h @@ -62,7 +62,7 @@ namespace storm { bool operator!=(SynchronizationVector const& vector1, SynchronizationVector const& vector2); struct SynchronizationVectorLexicographicalLess { - bool operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2); + bool operator()(SynchronizationVector const& vector1, SynchronizationVector const& vector2) const; }; std::ostream& operator<<(std::ostream& stream, SynchronizationVector const& synchronizationVector); diff --git a/src/storm/storage/jani/TemplateEdgeContainer.cpp b/src/storm/storage/jani/TemplateEdgeContainer.cpp new file mode 100644 index 000000000..81ce8f874 --- /dev/null +++ b/src/storm/storage/jani/TemplateEdgeContainer.cpp @@ -0,0 +1,12 @@ +#include "storm/storage/jani/TemplateEdgeContainer.h" +#include "storm/storage/jani/TemplateEdge.h" + +namespace storm { + namespace jani { + TemplateEdgeContainer::TemplateEdgeContainer(TemplateEdgeContainer const &other) { + for (auto const& te : other) { + this->insert(std::make_shared<TemplateEdge>(*te)); + } + } + } +} \ No newline at end of file diff --git a/src/storm/storage/jani/TemplateEdgeContainer.h b/src/storm/storage/jani/TemplateEdgeContainer.h new file mode 100644 index 000000000..293302594 --- /dev/null +++ b/src/storm/storage/jani/TemplateEdgeContainer.h @@ -0,0 +1,16 @@ +#pragma once + +#include <memory> +#include <unordered_set> + +namespace storm { + namespace jani { + + class TemplateEdge; + + struct TemplateEdgeContainer : public std::unordered_set<std::shared_ptr<TemplateEdge>> { + TemplateEdgeContainer() = default; + TemplateEdgeContainer(TemplateEdgeContainer const& other); + }; + } +} \ No newline at end of file diff --git a/src/storm/storage/prism/Program.cpp b/src/storm/storage/prism/Program.cpp index aea47fd09..228df8541 100644 --- a/src/storm/storage/prism/Program.cpp +++ b/src/storm/storage/prism/Program.cpp @@ -1124,7 +1124,7 @@ namespace storm { if (this->getModelType() == Program::ModelType::DTMC || this->getModelType() == Program::ModelType::MDP) { STORM_LOG_THROW(!hasMarkovianCommand, storm::exceptions::WrongFormatException, "Discrete-time model must not have Markovian commands."); } else if (this->getModelType() == Program::ModelType::CTMC) { - STORM_LOG_THROW(!hasProbabilisticCommand, storm::exceptions::WrongFormatException, "The input model is a CTMC, but uses probabilistic commands like they are used in PRISM. Please use Markovian commands instead or turn on the PRISM compatibility mode using the appropriate flag."); + STORM_LOG_THROW(!hasProbabilisticCommand, storm::exceptions::WrongFormatException, "The input model is a CTMC, but uses probabilistic commands like they are used in PRISM. Please use Markovian commands instead or turn on the PRISM compatibility mode using the flag '-pc'."); } // Now check the reward models. @@ -1711,16 +1711,16 @@ namespace storm { return Command(newCommandIndex, false, actionIndex, actionName, newGuard, newUpdates, this->getFilename(), 0); } - storm::jani::Model Program::toJani(bool allVariablesGlobal) const { + storm::jani::Model Program::toJani(bool allVariablesGlobal, std::string suffix) const { ToJaniConverter converter; - storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal); + storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal, suffix); STORM_LOG_WARN_COND(!converter.labelsWereRenamed(), "Labels were renamed in PRISM-to-JANI conversion, but the mapping is not stored."); return resultingModel; } - std::pair<storm::jani::Model, std::map<std::string, std::string>> Program::toJaniWithLabelRenaming(bool allVariablesGlobal) const { + std::pair<storm::jani::Model, std::map<std::string, std::string>> Program::toJaniWithLabelRenaming(bool allVariablesGlobal, std::string suffix) const { ToJaniConverter converter; - storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal); + storm::jani::Model resultingModel = converter.convert(*this, allVariablesGlobal, suffix); return std::make_pair(resultingModel, converter.getLabelRenaming()); } diff --git a/src/storm/storage/prism/Program.h b/src/storm/storage/prism/Program.h index 7dedc6667..4d6d303fc 100644 --- a/src/storm/storage/prism/Program.h +++ b/src/storm/storage/prism/Program.h @@ -603,13 +603,13 @@ namespace storm { /*! * Converts the PRISM model into an equivalent JANI model. */ - storm::jani::Model toJani(bool allVariablesGlobal = false) const; + storm::jani::Model toJani(bool allVariablesGlobal = false, std::string suffix = "") const; /*! * Converts the PRISM model into an equivalent JANI model and retrieves possible label renamings that had * to be performed in the process. */ - std::pair<storm::jani::Model, std::map<std::string, std::string>> toJaniWithLabelRenaming(bool allVariablesGlobal = false) const; + std::pair<storm::jani::Model, std::map<std::string, std::string>> toJaniWithLabelRenaming(bool allVariablesGlobal = false, std::string suffix = "") const; private: /*! diff --git a/src/storm/storage/prism/ToJaniConverter.cpp b/src/storm/storage/prism/ToJaniConverter.cpp index 7719b08e5..9712a52a7 100644 --- a/src/storm/storage/prism/ToJaniConverter.cpp +++ b/src/storm/storage/prism/ToJaniConverter.cpp @@ -13,7 +13,7 @@ namespace storm { namespace prism { - storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program, bool allVariablesGlobal) { + storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program, bool allVariablesGlobal, std::string suffix) { std::shared_ptr<storm::expressions::ExpressionManager> manager = program.getManager().getSharedPointer(); // Start by creating an empty JANI model. @@ -95,11 +95,11 @@ namespace storm { } } - // Go through the labels and construct assignments to transient variables that are added to the loctions. + // Go through the labels and construct assignments to transient variables that are added to the locations. std::vector<storm::jani::Assignment> transientLocationAssignments; for (auto const& label : program.getLabels()) { bool renameLabel = manager->hasVariable(label.getName()) || program.hasRewardModel(label.getName()); - std::string finalLabelName = renameLabel ? "label_" + label.getName() : label.getName(); + std::string finalLabelName = renameLabel ? "label_" + label.getName() + suffix : label.getName(); if (renameLabel) { STORM_LOG_WARN_COND(!renameLabel, "Label '" << label.getName() << "' was renamed to '" << finalLabelName << "' in PRISM-to-JANI conversion, as another variable with that name already exists."); labelRenaming[label.getName()] = finalLabelName; @@ -161,7 +161,7 @@ namespace storm { // Keep track of the action indices contained in this module. std::set<uint_fast64_t> actionIndicesOfModule; - storm::jani::Automaton automaton(module.getName(), manager->declareIntegerVariable("_loc_prism2jani_" + module.getName())); + storm::jani::Automaton automaton(module.getName(), manager->declareIntegerVariable("_loc_prism2jani_" + module.getName() + "_" + suffix)); for (auto const& variable : module.getIntegerVariables()) { storm::jani::BoundedIntegerVariable newIntegerVariable = *storm::jani::makeBoundedIntegerVariable(variable.getName(), variable.getExpressionVariable(), variable.hasInitialValue() ? boost::make_optional(variable.getInitialValueExpression()) : boost::none, false, variable.getLowerBoundExpression(), variable.getUpperBoundExpression()); std::set<uint_fast64_t> const& accessingModuleIndices = variablesToAccessingModuleIndices[variable.getExpressionVariable()]; diff --git a/src/storm/storage/prism/ToJaniConverter.h b/src/storm/storage/prism/ToJaniConverter.h index 2ab5c0509..e68c9612e 100644 --- a/src/storm/storage/prism/ToJaniConverter.h +++ b/src/storm/storage/prism/ToJaniConverter.h @@ -14,7 +14,7 @@ namespace storm { class ToJaniConverter { public: - storm::jani::Model convert(storm::prism::Program const& program, bool allVariablesGlobal = false); + storm::jani::Model convert(storm::prism::Program const& program, bool allVariablesGlobal = false, std::string suffix = ""); bool labelsWereRenamed() const; std::map<std::string, std::string> const& getLabelRenaming() const; diff --git a/src/storm/storage/sparse/JaniChoiceOrigins.cpp b/src/storm/storage/sparse/JaniChoiceOrigins.cpp index 4fce08388..d012c4418 100644 --- a/src/storm/storage/sparse/JaniChoiceOrigins.cpp +++ b/src/storm/storage/sparse/JaniChoiceOrigins.cpp @@ -1,14 +1,16 @@ #include "storm/storage/sparse/JaniChoiceOrigins.h" +#include "storm/storage/jani/Model.h" + #include "storm/utility/macros.h" +#include "storm/exceptions/InvalidArgumentException.h" namespace storm { namespace storage { namespace sparse { - JaniChoiceOrigins::JaniChoiceOrigins(std::vector<uint_fast64_t> const& indexToIdentifierMapping) : ChoiceOrigins(indexToIdentifierMapping) { - // Intentionally left empty - STORM_LOG_ASSERT(false, "Jani choice origins not properly implemented"); + JaniChoiceOrigins::JaniChoiceOrigins(std::shared_ptr<storm::jani::Model const> const& janiModel, std::vector<uint_fast64_t> const& indexToIdentifierMapping, std::vector<EdgeIndexSet> const& identifierToEdgeIndexSetMapping) : ChoiceOrigins(indexToIdentifierMapping), model(janiModel), identifierToEdgeIndexSet(identifierToEdgeIndexSetMapping) { + STORM_LOG_THROW(identifierToEdgeIndexSet[this->getIdentifierForChoicesWithNoOrigin()].empty(), storm::exceptions::InvalidArgumentException, "The given edge set for the choices without origin is non-empty"); } bool JaniChoiceOrigins::isJaniChoiceOrigins() const { @@ -16,17 +18,27 @@ namespace storm { } uint_fast64_t JaniChoiceOrigins::getNumberOfIdentifiers() const { - return 0; + return identifierToEdgeIndexSet.size(); + } + + storm::jani::Model const& JaniChoiceOrigins::getModel() const { + return *model; } - + + JaniChoiceOrigins::EdgeIndexSet const& JaniChoiceOrigins::getEdgeIndexSet(uint_fast64_t choiceIndex) const { + return identifierToEdgeIndexSet[this->getIdentifier(choiceIndex)]; + } + std::shared_ptr<ChoiceOrigins> JaniChoiceOrigins::cloneWithNewIndexToIdentifierMapping(std::vector<uint_fast64_t>&& indexToIdentifierMapping) const { - return std::make_shared<JaniChoiceOrigins>(std::move(indexToIdentifierMapping)); + auto result = std::make_shared<JaniChoiceOrigins>(this->model, std::move(indexToIdentifierMapping), std::move(identifierToEdgeIndexSet)); + result->identifierToInfo = this->identifierToInfo; + return result; } void JaniChoiceOrigins::computeIdentifierInfos() const { - + STORM_LOG_ASSERT(false, "Jani choice origins not properly implemented"); } } } -} \ No newline at end of file +} diff --git a/src/storm/storage/sparse/JaniChoiceOrigins.h b/src/storm/storage/sparse/JaniChoiceOrigins.h index 3f0d09207..9e4de090b 100644 --- a/src/storm/storage/sparse/JaniChoiceOrigins.h +++ b/src/storm/storage/sparse/JaniChoiceOrigins.h @@ -3,25 +3,30 @@ #include <memory> #include <string> -#include "storm/storage/sparse/ChoiceOrigins.h" +#include <boost/container/flat_set.hpp> +#include "storm/storage/sparse/ChoiceOrigins.h" namespace storm { + namespace jani { + class Model; + } + namespace storage { namespace sparse { - /*! * This class represents for each choice the origin in the jani specification * // TODO complete this */ class JaniChoiceOrigins : public ChoiceOrigins { public: - + typedef boost::container::flat_set<uint_fast64_t> EdgeIndexSet; + /*! * Creates a new representation of the choice indices to their origin in the Jani specification */ - JaniChoiceOrigins(std::vector<uint_fast64_t> const& indexToIdentifierMapping); + JaniChoiceOrigins(std::shared_ptr<storm::jani::Model const> const& janiModel, std::vector<uint_fast64_t> const& indexToIdentifierMapping, std::vector<EdgeIndexSet> const& identifierToEdgeIndexSetMapping); virtual ~JaniChoiceOrigins() = default; @@ -33,6 +38,18 @@ namespace storm { */ virtual uint_fast64_t getNumberOfIdentifiers() const override; + /*! + * Retrieves the associated JANI model. + */ + storm::jani::Model const& getModel() const; + + /* + * Returns the set of edges that induced the choice with the given index. + * The edges set is represented by a set of indices that encode an automaton index and its local edge index. + */ + EdgeIndexSet const& getEdgeIndexSet(uint_fast64_t choiceIndex) const; + + private: /* * Returns a copy of this object where the mapping of choice indices to origin identifiers is replaced by the given one. */ @@ -43,9 +60,9 @@ namespace storm { */ virtual void computeIdentifierInfos() const override; - private: - + std::shared_ptr<storm::jani::Model const> model; + std::vector<EdgeIndexSet> identifierToEdgeIndexSet; }; } } -} \ No newline at end of file +} diff --git a/src/storm/storage/sparse/PrismChoiceOrigins.cpp b/src/storm/storage/sparse/PrismChoiceOrigins.cpp index 366b9524b..69084f8cd 100644 --- a/src/storm/storage/sparse/PrismChoiceOrigins.cpp +++ b/src/storm/storage/sparse/PrismChoiceOrigins.cpp @@ -35,8 +35,7 @@ namespace storm { } std::shared_ptr<ChoiceOrigins> PrismChoiceOrigins::cloneWithNewIndexToIdentifierMapping(std::vector<uint_fast64_t>&& indexToIdentifierMapping) const { - std::vector<CommandSet> identifierToCommandSetMapping = this->identifierToCommandSet; - auto result = std::make_shared<PrismChoiceOrigins>(this->program, std::move(indexToIdentifierMapping), std::move(identifierToCommandSetMapping)); + auto result = std::make_shared<PrismChoiceOrigins>(this->program, std::move(indexToIdentifierMapping), std::move(this->identifierToCommandSet)); result->identifierToInfo = this->identifierToInfo; return result; } diff --git a/src/storm/storage/sparse/PrismChoiceOrigins.h b/src/storm/storage/sparse/PrismChoiceOrigins.h index 2a004d633..f2a6af716 100644 --- a/src/storm/storage/sparse/PrismChoiceOrigins.h +++ b/src/storm/storage/sparse/PrismChoiceOrigins.h @@ -32,7 +32,7 @@ namespace storm { virtual ~PrismChoiceOrigins() = default; - virtual bool isPrismChoiceOrigins() const override ; + virtual bool isPrismChoiceOrigins() const override; /* * Returns the number of identifier that are used by this object. diff --git a/src/storm/utility/DirectEncodingExporter.cpp b/src/storm/utility/DirectEncodingExporter.cpp index e0913a0f2..ec29cbe1e 100644 --- a/src/storm/utility/DirectEncodingExporter.cpp +++ b/src/storm/utility/DirectEncodingExporter.cpp @@ -21,20 +21,17 @@ namespace storm { // Notice that for CTMCs we write the rate matrix instead of probabilities // Initialize - storm::models::ModelType type = sparseModel->getType(); std::vector<ValueType> exitRates; // Only for CTMCs and MAs. - if(sparseModel->getType() == storm::models::ModelType::Ctmc) { + if (sparseModel->getType() == storm::models::ModelType::Ctmc) { exitRates = sparseModel->template as<storm::models::sparse::Ctmc<ValueType>>()->getExitRateVector(); - } else if(sparseModel->getType() == storm::models::ModelType::MarkovAutomaton) { - type = storm::models::ModelType::Mdp; - STORM_LOG_WARN("Markov automaton is exported as MDP (indication of Markovian choices is not supported in DRN format)."); + } else if (sparseModel->getType() == storm::models::ModelType::MarkovAutomaton) { exitRates = sparseModel->template as<storm::models::sparse::MarkovAutomaton<ValueType>>()->getExitRates(); } // Write header os << "// Exported by storm" << std::endl; os << "// Original model type: " << sparseModel->getType() << std::endl; - os << "@type: " << type << std::endl; + os << "@type: " << sparseModel->getType() << std::endl; os << "@parameters" << std::endl; if (parameters.empty()) { for (std::string const& parameter : getParameters(sparseModel)) { @@ -55,10 +52,16 @@ namespace storm { os << "@model" << std::endl; storm::storage::SparseMatrix<ValueType> const& matrix = sparseModel->getTransitionMatrix(); - + + // Iterate over states and export state information and outgoing transitions for (typename storm::storage::SparseMatrix<ValueType>::index_type group = 0; group < matrix.getRowGroupCount(); ++group) { os << "state " << group; + // Write exit rates for CTMCs and MAs + if (!exitRates.empty()) { + os << " !" << exitRates.at(group); + } + // Write state rewards bool first = true; for (auto const& rewardModelEntry : sparseModel->getRewardModels()) { @@ -70,7 +73,7 @@ namespace storm { } if(rewardModelEntry.second.hasStateRewards()) { - os << rewardModelEntry.second.getStateRewardVector().at(group); + os << storm::utility::to_string(rewardModelEntry.second.getStateRewardVector().at(group)); } else { os << "0"; } @@ -92,22 +95,23 @@ namespace storm { // Iterate over all actions for (typename storm::storage::SparseMatrix<ValueType>::index_type row = start; row < end; ++row) { - // Print the actual row. + // Write choice if (sparseModel->hasChoiceLabeling()) { os << "\taction "; bool lfirst = true; for (auto const& label : sparseModel->getChoiceLabeling().getLabelsOfChoice(row)) { if (!lfirst) { os << "_"; + lfirst = false; } os << label; - lfirst = false; } } else { os << "\taction " << row - start; } + + // Write action rewards bool first = true; - // Write transition rewards for (auto const& rewardModelEntry : sparseModel->getRewardModels()) { if (first) { os << " ["; @@ -116,7 +120,7 @@ namespace storm { os << ", "; } - if(rewardModelEntry.second.hasStateActionRewards()) { + if (rewardModelEntry.second.hasStateActionRewards()) { os << storm::utility::to_string(rewardModelEntry.second.getStateActionRewardVector().at(row)); } else { os << "0"; @@ -126,19 +130,18 @@ namespace storm { if (!first) { os << "]"; } - os << std::endl; - - // Write probabilities - for(auto it = matrix.begin(row); it != matrix.end(row); ++it) { + + // Write transitions + for (auto it = matrix.begin(row); it != matrix.end(row); ++it) { ValueType prob = it->getValue(); os << "\t\t" << it->getColumn() << " : "; os << storm::utility::to_string(prob) << std::endl; } - + } - } // end matrix iteration - + } // end state iteration + } template<typename ValueType> @@ -146,9 +149,6 @@ namespace storm { return {}; } - template void explicitExportSparseModel<double>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<double>> sparseModel, std::vector<std::string> const& parameters); - -#ifdef STORM_HAVE_CARL template<> std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel) { std::vector<std::string> parameters; @@ -167,8 +167,9 @@ namespace storm { return parameters; } + // Template instantiations + template void explicitExportSparseModel<double>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<double>> sparseModel, std::vector<std::string> const& parameters); template void explicitExportSparseModel<storm::RationalNumber>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<storm::RationalNumber>> sparseModel, std::vector<std::string> const& parameters); template void explicitExportSparseModel<storm::RationalFunction>(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<storm::RationalFunction>> sparseModel, std::vector<std::string> const& parameters); -#endif } } diff --git a/src/storm/utility/DirectEncodingExporter.h b/src/storm/utility/DirectEncodingExporter.h index 9728599a6..5ffe4d10d 100644 --- a/src/storm/utility/DirectEncodingExporter.h +++ b/src/storm/utility/DirectEncodingExporter.h @@ -18,13 +18,13 @@ namespace storm { void explicitExportSparseModel(std::ostream& os, std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel, std::vector<std::string> const& parameters); /*! - * Accumalate parameters in the model. + * Accumulate parameters in the model. * * @param sparseModel Model. * @return List of parameters in the model. */ template<typename ValueType> std::vector<std::string> getParameters(std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel); - + } } diff --git a/src/storm/utility/ExpressionHelper.cpp b/src/storm/utility/ExpressionHelper.cpp new file mode 100644 index 000000000..219d6e39c --- /dev/null +++ b/src/storm/utility/ExpressionHelper.cpp @@ -0,0 +1,29 @@ +#include "storm/utility/ExpressionHelper.h" +#include "storm/utility/constants.h" + +namespace storm { + namespace utility { + + ExpressionHelper::ExpressionHelper(std::shared_ptr<storm::expressions::ExpressionManager> const& expressionManager) : manager(expressionManager) { + // Intentionally left empty + } + + storm::expressions::Expression ExpressionHelper::sum(std::vector<storm::expressions::Expression>&& summands) const { + if (summands.empty()) { + return manager->rational(storm::utility::zero<storm::RationalNumber>()); + } + // As the sum can potentially have many summands, we want to make sure that the formula tree is (roughly balanced) + auto it = summands.begin(); + while (summands.size() > 1) { + if (it == summands.end() || it == summands.end() - 1) { + it = summands.begin(); + } + *it = *it + summands.back(); + summands.pop_back(); + ++it; + } + return summands.front(); + } + + } +} \ No newline at end of file diff --git a/src/storm/utility/ExpressionHelper.h b/src/storm/utility/ExpressionHelper.h new file mode 100644 index 000000000..6c171a286 --- /dev/null +++ b/src/storm/utility/ExpressionHelper.h @@ -0,0 +1,28 @@ +#pragma once + +#include <vector> +#include <memory> +#include "storm/storage/expressions/Expression.h" +#include "storm/storage/expressions/ExpressionManager.h" + +namespace storm { + namespace utility { + + class ExpressionHelper { + + public: + ExpressionHelper(std::shared_ptr<storm::expressions::ExpressionManager> const& expressionManager); + + /*! + * Creates an expression that is the sum over all the given summands. + */ + storm::expressions::Expression sum(std::vector<storm::expressions::Expression>&& summands) const; + + private: + + std::shared_ptr<storm::expressions::ExpressionManager> manager; + }; + + + } +} \ No newline at end of file diff --git a/src/storm/utility/ProgressMeasurement.cpp b/src/storm/utility/ProgressMeasurement.cpp index db471035f..4a0715323 100644 --- a/src/storm/utility/ProgressMeasurement.cpp +++ b/src/storm/utility/ProgressMeasurement.cpp @@ -1,6 +1,7 @@ #include "storm/utility/ProgressMeasurement.h" #include <sstream> +#include <limits> #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GeneralSettings.h" @@ -9,7 +10,7 @@ namespace storm { namespace utility { - ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName) { + ProgressMeasurement::ProgressMeasurement(std::string const& itemName) : itemName(itemName), maxCount(std::numeric_limits<uint64_t>::max()) { delay = storm::settings::getModule<storm::settings::modules::GeneralSettings>().getShowProgressDelay(); } @@ -48,7 +49,7 @@ namespace storm { } bool ProgressMeasurement::isMaxCountSet() const { - return this->maxCount > 0; + return this->maxCount < std::numeric_limits<uint64_t>::max(); } uint64_t ProgressMeasurement::getMaxCount() const { @@ -61,7 +62,7 @@ namespace storm { } void ProgressMeasurement::unsetMaxCount() { - this->maxCount = 0; + this->maxCount = std::numeric_limits<uint64_t>::max(); } uint64_t ProgressMeasurement::getShowProgressDelay() const { diff --git a/src/storm/utility/ProgressMeasurement.h b/src/storm/utility/ProgressMeasurement.h index 904294ef5..089758583 100644 --- a/src/storm/utility/ProgressMeasurement.h +++ b/src/storm/utility/ProgressMeasurement.h @@ -92,7 +92,7 @@ namespace storm { // A name for what this is measuring (iterations, states, ...) std::string itemName; - // The maximal count that can be achieved. Zero means unspecified. + // The maximal count that can be achieved. numeric_limits<uint64_t>::max() means unspecified. uint64_t maxCount; // The last displayed count diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index cd6556fed..6c0d1c814 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -48,7 +48,11 @@ namespace storm { bool isAlmostZero(double const& a) { return a < 1e-12 && a > -1e-12; } - + + bool isAlmostOne(double const& a) { + return a < (1.0 + 1e-12) && a > (1.0 - 1e-12); + } + template<typename ValueType> bool isConstant(ValueType const&) { return true; @@ -159,13 +163,26 @@ namespace storm { template<typename ValueType> ValueType minimum(std::vector<ValueType> const& values) { - return minmax(values).first; + assert(!values.empty()); + ValueType min = values.front(); + for (auto const& vt : values) { + if (vt < min) { + min = vt; + } + } + return min; } - template<typename ValueType> ValueType maximum(std::vector<ValueType> const& values) { - return minmax(values).second; + assert(!values.empty()); + ValueType max = values.front(); + for (auto const& vt : values) { + if (vt > max) { + max = vt; + } + } + return max; } template<typename K, typename ValueType> @@ -307,7 +324,12 @@ namespace storm { uint_fast64_t convertNumber(ClnRationalNumber const& number) { return carl::toInt<carl::uint>(number); } - + + template<> + int_fast64_t convertNumber(ClnRationalNumber const& number) { + return carl::toInt<carl::sint>(number); + } + template<> ClnRationalNumber convertNumber(double const& number) { return carl::rationalize<ClnRationalNumber>(number); @@ -499,7 +521,12 @@ namespace storm { uint_fast64_t convertNumber(GmpRationalNumber const& number){ return carl::toInt<carl::uint>(number); } - + + template<> + int_fast64_t convertNumber(GmpRationalNumber const& number){ + return carl::toInt<carl::sint>(number); + } + template<> GmpRationalNumber convertNumber(double const& number){ return carl::rationalize<GmpRationalNumber>(number); @@ -892,7 +919,7 @@ namespace storm { template bool isZero(int const& value); template bool isConstant(int const& value); template bool isInfinity(int const& value); - + // uint32_t template uint32_t one(); template uint32_t zero(); @@ -901,7 +928,7 @@ namespace storm { template bool isZero(uint32_t const& value); template bool isConstant(uint32_t const& value); template bool isInfinity(uint32_t const& value); - + // storm::storage::sparse::state_type template storm::storage::sparse::state_type one(); template storm::storage::sparse::state_type zero(); @@ -910,11 +937,11 @@ namespace storm { template bool isZero(storm::storage::sparse::state_type const& value); template bool isConstant(storm::storage::sparse::state_type const& value); template bool isInfinity(storm::storage::sparse::state_type const& value); - + // other instantiations template unsigned long convertNumber(long const&); template double convertNumber(long const&); - + #if defined(STORM_HAVE_CLN) // Instantiations for (CLN) rational number. template storm::ClnRationalNumber one(); @@ -938,7 +965,7 @@ namespace storm { template storm::ClnRationalNumber min(storm::ClnRationalNumber const& first, storm::ClnRationalNumber const& second); template std::string to_string(storm::ClnRationalNumber const& value); #endif - + #if defined(STORM_HAVE_GMP) // Instantiations for (GMP) rational number. template storm::GmpRationalNumber one(); @@ -961,10 +988,10 @@ namespace storm { template storm::GmpRationalNumber min(storm::GmpRationalNumber const& first, storm::GmpRationalNumber const& second); template std::string to_string(storm::GmpRationalNumber const& value); #endif - + #if defined(STORM_HAVE_CARL) && defined(STORM_HAVE_GMP) && defined(STORM_HAVE_CLN) #endif - + #ifdef STORM_HAVE_CARL // Instantiations for rational function. template RationalFunction one(); diff --git a/src/storm/utility/constants.h b/src/storm/utility/constants.h index 5eb1d1fc5..360128f00 100644 --- a/src/storm/utility/constants.h +++ b/src/storm/utility/constants.h @@ -44,6 +44,8 @@ namespace storm { bool isZero(ValueType const& a); bool isAlmostZero(double const& a); + + bool isAlmostOne(double const& a); template<typename ValueType> bool isConstant(ValueType const& a); diff --git a/src/storm/utility/dd.cpp b/src/storm/utility/dd.cpp index 47d15347e..3ecbef7d6 100644 --- a/src/storm/utility/dd.cpp +++ b/src/storm/utility/dd.cpp @@ -45,14 +45,49 @@ namespace storm { return reachableStates; } + template <storm::dd::DdType Type> + storm::dd::Bdd<Type> computeBackwardsReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& constraintStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables) { + STORM_LOG_TRACE("Computing backwards reachable states: transition matrix BDD has " << transitions.getNodeCount() << " node(s) and " << transitions.getNonZeroCount() << " non-zero(s), " << initialStates.getNonZeroCount() << " initial states)."); + + auto start = std::chrono::high_resolution_clock::now(); + storm::dd::Bdd<Type> reachableStates = initialStates; + + // Perform the BFS to discover all reachable states. + bool changed = true; + uint_fast64_t iteration = 0; + do { + changed = false; + storm::dd::Bdd<Type> tmp = reachableStates.inverseRelationalProduct(transitions, rowMetaVariables, columnMetaVariables); + storm::dd::Bdd<Type> newReachableStates = tmp && (!reachableStates) && constraintStates; + + // Check whether new states were indeed discovered. + if (!newReachableStates.isZero()) { + changed = true; + } + + reachableStates |= newReachableStates; + + ++iteration; + STORM_LOG_TRACE("Iteration " << iteration << " of (backward) reachability computation completed: " << reachableStates.getNonZeroCount() << " reachable states found."); + } while (changed); + + auto end = std::chrono::high_resolution_clock::now(); + STORM_LOG_TRACE("Backward reachability computation completed in " << iteration << " iterations (" << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms)."); + + return reachableStates; + } + template <storm::dd::DdType Type> storm::dd::Bdd<Type> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) { - return ddManager.getIdentity(rowColumnMetaVariablePairs); + return ddManager.getIdentity(rowColumnMetaVariablePairs, false); } template storm::dd::Bdd<storm::dd::DdType::CUDD> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); template storm::dd::Bdd<storm::dd::DdType::Sylvan> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::Sylvan> const& initialStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::CUDD> computeBackwardsReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& constraintStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::Sylvan> computeBackwardsReachableStates(storm::dd::Bdd<storm::dd::DdType::Sylvan> const& initialStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& constraintStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template storm::dd::Bdd<storm::dd::DdType::CUDD> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::CUDD> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); template storm::dd::Bdd<storm::dd::DdType::Sylvan> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); diff --git a/src/storm/utility/dd.h b/src/storm/utility/dd.h index 65e079bf3..679e1bd50 100644 --- a/src/storm/utility/dd.h +++ b/src/storm/utility/dd.h @@ -25,7 +25,10 @@ namespace storm { template <storm::dd::DdType Type> storm::dd::Bdd<Type> computeReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); - + + template <storm::dd::DdType Type> + storm::dd::Bdd<Type> computeBackwardsReachableStates(storm::dd::Bdd<Type> const& initialStates, storm::dd::Bdd<Type> const& constraintStates, storm::dd::Bdd<Type> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables); + template <storm::dd::DdType Type, typename ValueType> storm::dd::Add<Type, ValueType> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs); diff --git a/src/storm/utility/graph.cpp b/src/storm/utility/graph.cpp index a2716ba8d..5bb8cc758 100644 --- a/src/storm/utility/graph.cpp +++ b/src/storm/utility/graph.cpp @@ -479,9 +479,9 @@ namespace storm { } template <typename T> - void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler) { + void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter) { - // set an arbitrary choice for the psi states. + // set an arbitrary (valid) choice for the psi states. for (auto const& psiState : psiStates) { for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { scheduler.setChoice(0, psiState, memState); @@ -504,27 +504,29 @@ namespace storm { // Check whether the predecessor has only successors in the prob1E state set for one of the // nondeterminstic choices. for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) { - bool allSuccessorsInProb1EStates = true; - bool hasSuccessorInCurrentStates = false; - for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { - if (!prob1EStates.get(successorEntryIt->getColumn())) { - allSuccessorsInProb1EStates = false; + if (!rowFilter || rowFilter.get().get(row)) { + bool allSuccessorsInProb1EStates = true; + bool hasSuccessorInCurrentStates = false; + for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { + if (!prob1EStates.get(successorEntryIt->getColumn())) { + allSuccessorsInProb1EStates = false; + break; + } else if (currentStates.get(successorEntryIt->getColumn())) { + hasSuccessorInCurrentStates = true; + } + } + + // If all successors for a given nondeterministic choice are in the prob1E state set, we + // perform a backward search from that state. + if (allSuccessorsInProb1EStates && hasSuccessorInCurrentStates) { + for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { + scheduler.setChoice(row - nondeterministicChoiceIndices[predecessorEntryIt->getColumn()], predecessorEntryIt->getColumn(), memState); + } + currentStates.set(predecessorEntryIt->getColumn(), true); + stack.push_back(predecessorEntryIt->getColumn()); break; - } else if (currentStates.get(successorEntryIt->getColumn())) { - hasSuccessorInCurrentStates = true; } } - - // If all successors for a given nondeterministic choice are in the prob1E state set, we - // perform a backward search from that state. - if (allSuccessorsInProb1EStates && hasSuccessorInCurrentStates) { - for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) { - scheduler.setChoice(row - nondeterministicChoiceIndices[predecessorEntryIt->getColumn()], predecessorEntryIt->getColumn(), memState); - } - currentStates.set(predecessorEntryIt->getColumn(), true); - stack.push_back(predecessorEntryIt->getColumn()); - break; - } } } } @@ -595,7 +597,7 @@ namespace storm { } template <typename T> - storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) { + storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint) { size_t numberOfStates = phiStates.size(); // Initialize the environment for the iterative algorithm. @@ -620,25 +622,27 @@ namespace storm { // Check whether the predecessor has only successors in the current state set for one of the // nondeterminstic choices. for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) { - bool allSuccessorsInCurrentStates = true; - bool hasNextStateSuccessor = false; - for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { - if (!currentStates.get(successorEntryIt->getColumn())) { - allSuccessorsInCurrentStates = false; + if (!choiceConstraint || choiceConstraint.get().get(row)) { + bool allSuccessorsInCurrentStates = true; + bool hasNextStateSuccessor = false; + for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) { + if (!currentStates.get(successorEntryIt->getColumn())) { + allSuccessorsInCurrentStates = false; + break; + } else if (nextStates.get(successorEntryIt->getColumn())) { + hasNextStateSuccessor = true; + } + } + + // If all successors for a given nondeterministic choice are in the current state set, we + // add it to the set of states for the next iteration and perform a backward search from + // that state. + if (allSuccessorsInCurrentStates && hasNextStateSuccessor) { + nextStates.set(predecessorEntryIt->getColumn(), true); + stack.push_back(predecessorEntryIt->getColumn()); break; - } else if (nextStates.get(successorEntryIt->getColumn())) { - hasNextStateSuccessor = true; } } - - // If all successors for a given nondeterministic choice are in the current state set, we - // add it to the set of states for the next iteration and perform a backward search from - // that state. - if (allSuccessorsInCurrentStates && hasNextStateSuccessor) { - nextStates.set(predecessorEntryIt->getColumn(), true); - stack.push_back(predecessorEntryIt->getColumn()); - break; - } } } } @@ -1381,13 +1385,13 @@ namespace storm { template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::Scheduler<double>& scheduler); - template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler); + template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ; template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<double, storm::models::sparse::StandardRewardModel<double>> const& model, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); @@ -1446,13 +1450,13 @@ namespace storm { template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::Scheduler<storm::RationalNumber>& scheduler); - template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler); + template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ; template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<storm::RationalNumber> const& model, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); @@ -1503,7 +1507,7 @@ namespace storm { template storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); - template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + template storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); template storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<storm::RationalFunction> const& model, storm::storage::SparseMatrix<storm::RationalFunction> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); diff --git a/src/storm/utility/graph.h b/src/storm/utility/graph.h index 0f9b3c66e..79103700b 100644 --- a/src/storm/utility/graph.h +++ b/src/storm/utility/graph.h @@ -297,9 +297,10 @@ namespace storm { * @param phiStates The set of states satisfying phi. * @param psiStates The set of states satisfying psi. * @param scheduler The resulting scheduler for the prob1EStates. The scheduler is not set at the remaining states. + * @param rowFilter If given, only scheduler choices within this filter are taken. This filter is ignored for the psiStates. */ template <typename T> - void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler); + void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none); /*! * Computes the sets of states that have probability greater 0 of satisfying phi until psi under at least @@ -330,10 +331,11 @@ namespace storm { * @param backwardTransitions The reversed transition relation of the model. * @param phiStates The set of all states satisfying phi. * @param psiStates The set of all states satisfying psi. + * @param choiceConstraint If given, only the selected choices are considered. * @return A bit vector that represents all states with probability 1. */ template <typename T> - storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates); + storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::optional<storm::storage::BitVector> const& choiceConstraint = boost::none); /*! * Computes the sets of states that have probability 1 of satisfying phi until psi under at least diff --git a/src/storm/utility/numerical.cpp b/src/storm/utility/numerical.cpp index 38b793fa5..9c17928ab 100644 --- a/src/storm/utility/numerical.cpp +++ b/src/storm/utility/numerical.cpp @@ -258,8 +258,8 @@ namespace storm { } result.totalWeight += result.weights[j]; - STORM_LOG_TRACE("Fox-Glynn(lambda=" << lambda << ", eps=" << epsilon << "): ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << "."); - + STORM_LOG_TRACE("Fox-Glynn: ltp = " << result.left << ", rtp = " << result.right << ", w = " << result.totalWeight << ", " << result.weights.size() << " weights."); + return result; } diff --git a/src/storm/utility/storm-version.h b/src/storm/utility/storm-version.h index e4d372cc7..b6b1d3d2e 100644 --- a/src/storm/utility/storm-version.h +++ b/src/storm/utility/storm-version.h @@ -7,35 +7,45 @@ namespace storm { namespace utility { - + struct StormVersion { /// The major version of Storm. const static unsigned versionMajor; - + /// The minor version of Storm. const static unsigned versionMinor; - + /// The patch version of Storm. const static unsigned versionPatch; - + + /// The label version of Storm (might be empty). + const static std::string versionLabel; + /// Flag indicating if the version of Storm is a development version. const static bool versionDev; + + enum class VersionSource { + Git, Static + }; + + /// The source of the versioning information. + const static VersionSource versionSource; /// The short hash of the git commit this build is based on const static std::string gitRevisionHash; - + /// How many commits passed since the tag was last set. - const static unsigned commitsAhead; - + const static boost::optional<unsigned> commitsAhead; + /// 0 iff there no files were modified in the checkout, 1 otherwise. If none, no information about dirtyness is given. const static boost::optional<bool> dirty; - + /// The system which has compiled Storm. const static std::string systemName; - + /// The system version which has compiled Storm. const static std::string systemVersion; - + /// The compiler version that was used to build Storm. const static std::string cxxCompiler; @@ -45,20 +55,23 @@ namespace storm { static std::string shortVersionString() { std::stringstream sstream; sstream << versionMajor << "." << versionMinor << "." << versionPatch; + if (!versionLabel.empty()) { + sstream << "-" << versionLabel; + } if (versionDev) { sstream << " (dev)"; } return sstream.str(); } - + static std::string longVersionString() { std::stringstream sstream; - sstream << "Version " << versionMajor << "." << versionMinor << "." << versionPatch; - if (versionDev) { - sstream << " (dev)"; + sstream << "Version " << shortVersionString(); + if (versionSource == VersionSource::Static) { + sstream << " (derived statically)"; } if (commitsAhead) { - sstream << " (+ " << commitsAhead << " commits)"; + sstream << " (+ " << commitsAhead.get() << " commits)"; } if (!gitRevisionHash.empty()) { sstream << " build from revision " << gitRevisionHash; @@ -76,7 +89,7 @@ namespace storm { } return sstream.str(); } - + static std::string buildInfo() { std::stringstream sstream; sstream << "Compiled on " << systemName << " " << systemVersion << " using " << cxxCompiler << " with flags '" << cxxFlags << "'"; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index d870d2b21..a693be0a0 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(storm) -add_subdirectory(storm-pars) \ No newline at end of file +add_subdirectory(storm-pars) +add_subdirectory(storm-dft) diff --git a/src/test/storage/SymbolicBisimulationDecompositionTest.cpp b/src/test/storage/SymbolicBisimulationDecompositionTest.cpp deleted file mode 100644 index 4948f7906..000000000 --- a/src/test/storage/SymbolicBisimulationDecompositionTest.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "gtest/gtest.h" -#include "storm-config.h" -#include "storm/parser/PrismParser.h" -#include "storm/storage/SymbolicModelDescription.h" -#include "storm/builder/DdPrismModelBuilder.h" -#include "storm/models/symbolic/Dtmc.h" -#include "storm/storage/dd/BisimulationDecomposition.h" - -TEST(SymbolicBisimulationDecompositionTest_Cudd, Die) { - storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm"); - storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); - - std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD, double>().build(program); - - storm::dd::BisimulationDecomposition<storm::dd::DdType::CUDD, double> decomposition(*model, storm::dd::bisimulation::Partition<storm::dd::DdType::CUDD, double>::create(*model, {"one"})); - decomposition.compute(); -} - -TEST(SymbolicBisimulationDecompositionTest_Cudd, Crowds) { - storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.pm"); - storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); - - std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>> model = storm::builder::DdPrismModelBuilder<storm::dd::DdType::CUDD, double>().build(program); - - storm::dd::BisimulationDecomposition<storm::dd::DdType::CUDD, double> decomposition(*model, storm::dd::bisimulation::Partition<storm::dd::DdType::CUDD, double>::create(*model, {"observe0Greater1"})); - decomposition.compute(); -} diff --git a/src/test/storm-dft/CMakeLists.txt b/src/test/storm-dft/CMakeLists.txt new file mode 100644 index 000000000..d461c2f9d --- /dev/null +++ b/src/test/storm-dft/CMakeLists.txt @@ -0,0 +1,23 @@ +# Base path for test files +set(STORM_TESTS_BASE_PATH "${PROJECT_SOURCE_DIR}/src/test/storm-dft") + +# Test Sources +file(GLOB_RECURSE ALL_FILES ${STORM_TESTS_BASE_PATH}/*.h ${STORM_TESTS_BASE_PATH}/*.cpp) + +register_source_groups_from_filestructure("${ALL_FILES}" test) + +# Note that the tests also need the source files, except for the main file +include_directories(${GTEST_INCLUDE_DIR}) + +foreach (testsuite api) + + file(GLOB_RECURSE TEST_${testsuite}_FILES ${STORM_TESTS_BASE_PATH}/${testsuite}/*.h ${STORM_TESTS_BASE_PATH}/${testsuite}/*.cpp) + add_executable (test-dft-${testsuite} ${TEST_${testsuite}_FILES} ${STORM_TESTS_BASE_PATH}/storm-test.cpp) + target_link_libraries(test-dft-${testsuite} storm-dft) + target_link_libraries(test-dft-${testsuite} ${STORM_TEST_LINK_LIBRARIES}) + + add_dependencies(test-dft-${testsuite} test-resources) + add_test(NAME run-test-dft-${testsuite} COMMAND $<TARGET_FILE:test-dft-${testsuite}>) + add_dependencies(tests test-dft-${testsuite}) + +endforeach () diff --git a/src/test/storm-dft/api/DftModelCheckerTest.cpp b/src/test/storm-dft/api/DftModelCheckerTest.cpp new file mode 100644 index 000000000..5db58d60d --- /dev/null +++ b/src/test/storm-dft/api/DftModelCheckerTest.cpp @@ -0,0 +1,185 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "storm-dft/api/storm-dft.h" + +namespace { + + // Configurations for DFT analysis + struct DftAnalysisConfig { + bool useSR; + bool useMod; + bool useDC; + }; + + class NoOptimizationsConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, false, false}; + } + }; + class DontCareConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, false, true}; + } + }; + class ModularisationConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {false, true, false}; + } + }; + class SymmetryReductionConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {true, false, false}; + } + }; + class AllOptimizationsConfig { + public: + typedef double ValueType; + static DftAnalysisConfig createConfig() { + return DftAnalysisConfig {true, true, true}; + } + }; + + // General base class for testing of DFT model checking + template<typename TestType> + class DftModelCheckerTest : public ::testing::Test { + public: + typedef typename TestType::ValueType ValueType; + + DftModelCheckerTest() : config(TestType::createConfig()) { + } + + DftAnalysisConfig const& getConfig() const { + return config; + } + + double analyzeMTTF(std::string const& file) { + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); + std::string property = "Tmin=? [F \"failed\"]"; + std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property)); + typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod, config.useDC, false); + return boost::get<double>(results[0]); + } + + private: + DftAnalysisConfig config; + }; + + typedef ::testing::Types< + NoOptimizationsConfig, + DontCareConfig, + ModularisationConfig, + SymmetryReductionConfig, + AllOptimizationsConfig + > TestingTypes; + + TYPED_TEST_CASE(DftModelCheckerTest, TestingTypes); + + TYPED_TEST(DftModelCheckerTest, AndMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/and.dft"); + EXPECT_FLOAT_EQ(result, 3); + } + + TYPED_TEST(DftModelCheckerTest, OrMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/or.dft"); + EXPECT_FLOAT_EQ(result, 1); + } + + TYPED_TEST(DftModelCheckerTest, VotingMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting.dft"); + EXPECT_FLOAT_EQ(result, 5/3.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting2.dft"); + EXPECT_FLOAT_EQ(result, 10/17.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting3.dft"); + EXPECT_FLOAT_EQ(result, 1.7356173); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting4.dft"); + EXPECT_FLOAT_EQ(result, 5/6.0); + } + + TYPED_TEST(DftModelCheckerTest, PandMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pand.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + + TYPED_TEST(DftModelCheckerTest, PorMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/por.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + + TYPED_TEST(DftModelCheckerTest, FdepMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep2.dft"); + EXPECT_FLOAT_EQ(result, 2); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep3.dft"); + EXPECT_FLOAT_EQ(result, 2.5); + if (this->getConfig().useMod) { + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"), storm::exceptions::NotSupportedException); + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"), storm::exceptions::NotSupportedException); + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"); + EXPECT_FLOAT_EQ(result, 2/3.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"); + EXPECT_FLOAT_EQ(result, 1); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"); + EXPECT_FLOAT_EQ(result, 3); + } + } + + TYPED_TEST(DftModelCheckerTest, PdepMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep.dft"); + EXPECT_FLOAT_EQ(result, 8/3.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep3.dft"); + EXPECT_FLOAT_EQ(result, 67/24.0); + if (this->getConfig().useMod) { + if (!this->getConfig().useDC) { + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep2.dft"); + EXPECT_FLOAT_EQ(result, 38/15.0); + } + EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"), storm::exceptions::NotSupportedException); + } else { + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + } + TYPED_TEST(DftModelCheckerTest, SpareMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare.dft"); + EXPECT_FLOAT_EQ(result, 46/13.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare2.dft"); + EXPECT_FLOAT_EQ(result, 43/23.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare3.dft"); + EXPECT_FLOAT_EQ(result, 14/11.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare4.dft"); + EXPECT_FLOAT_EQ(result, 4.8458967); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare5.dft"); + EXPECT_FLOAT_EQ(result, 8/3.0); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare6.dft"); + EXPECT_FLOAT_EQ(result, 1.4); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare7.dft"); + EXPECT_FLOAT_EQ(result, 3.6733334); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare8.dft"); + EXPECT_FLOAT_EQ(result, 4.78846); // DFTCalc has result of 4.33779 due to different semantics of nested spares + } + TYPED_TEST(DftModelCheckerTest, SeqMTTF) { + double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq.dft"); + EXPECT_FLOAT_EQ(result, 4); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq2.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq3.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq4.dft"); + EXPECT_FLOAT_EQ(result, 6); + result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq5.dft"); + EXPECT_EQ(result, storm::utility::infinity<double>()); + } + +} diff --git a/src/test/storm-dft/api/DftParserTest.cpp b/src/test/storm-dft/api/DftParserTest.cpp new file mode 100644 index 000000000..48a621ac1 --- /dev/null +++ b/src/test/storm-dft/api/DftParserTest.cpp @@ -0,0 +1,13 @@ +#include "gtest/gtest.h" +#include "storm-config.h" + +#include "storm-dft/api/storm-dft.h" + +namespace { + + TEST(DftParserTest, LoadFromGalileo) { + std::string file = STORM_TEST_RESOURCES_DIR "/dft/and.dft"; + std::shared_ptr<storm::storage::DFT<double>> dft = storm::api::loadDFTGalileo<double>(file); + } + +} diff --git a/src/test/storm-dft/storm-test.cpp b/src/test/storm-dft/storm-test.cpp new file mode 100644 index 000000000..cf9106876 --- /dev/null +++ b/src/test/storm-dft/storm-test.cpp @@ -0,0 +1,8 @@ +#include "gtest/gtest.h" +#include "storm-dft/settings/DftSettings.h" + +int main(int argc, char **argv) { + storm::settings::initializeDftSettings("Storm-dft (Functional) Testing Suite", "test-dft"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp b/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp index b00b44c0d..dd6d59cf8 100644 --- a/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp +++ b/src/test/storm-pars/modelchecker/SparseDtmcParameterLiftingTest.cpp @@ -21,6 +21,18 @@ namespace { return env; } }; + + class DoubleSVIEnvironment { + public: + typedef double ValueType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + class RationalPiEnvironment { public: typedef storm::RationalNumber ValueType; @@ -44,6 +56,7 @@ namespace { typedef ::testing::Types< DoubleViEnvironment, + DoubleSVIEnvironment, RationalPiEnvironment > TestingTypes; diff --git a/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp b/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp index 31c5d7436..de5e6f849 100644 --- a/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm-pars/modelchecker/SymbolicParametricDtmcPrctlModelCheckerTest.cpp @@ -40,7 +40,7 @@ TEST(SymbolicDtmcPrctlModelCheckerTest, Die_RationalFunction_Sylvan) { std::shared_ptr<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> dtmc = model->as<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>>(); - storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> checker(*dtmc, std::unique_ptr<storm::solver::SymbolicLinearEquationSolverFactory<storm::dd::DdType::Sylvan, storm::RationalFunction>>(new storm::solver::SymbolicEliminationLinearEquationSolverFactory<storm::dd::DdType::Sylvan, storm::RationalFunction>())); + storm::modelchecker::SymbolicDtmcPrctlModelChecker<storm::models::symbolic::Dtmc<storm::dd::DdType::Sylvan, storm::RationalFunction>> checker(*dtmc); std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("P=? [F \"one\"]"); diff --git a/src/test/storm-pars/storm-test.cpp b/src/test/storm-pars/storm-test.cpp index 203c56b40..14855a65a 100644 --- a/src/test/storm-pars/storm-test.cpp +++ b/src/test/storm-pars/storm-test.cpp @@ -1,8 +1,8 @@ #include "gtest/gtest.h" -#include "storm/settings/SettingsManager.h" +#include "storm-pars/settings/ParsSettings.h" int main(int argc, char **argv) { - storm::settings::initializeAll("Storm-pars (Functional) Testing Suite", "test-pars"); + storm::settings::initializeParsSettings("Storm-pars (Functional) Testing Suite", "test-pars"); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp index 8e02b7b46..ad6654ff4 100644 --- a/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/DtmcPrctlModelCheckerTest.cpp @@ -25,6 +25,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" namespace { @@ -205,7 +206,7 @@ namespace { } }; - class SparseNativeSoundPowerEnvironment { + class SparseNativeSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; @@ -216,7 +217,25 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration); + env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + + class SparseNativeIntervalIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Dtmc<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::IntervalIteration); + env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; } @@ -237,6 +256,22 @@ namespace { } }; + class SparseTopologicalEigenLUEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = true; + typedef storm::RationalNumber ValueType; + typedef storm::models::sparse::Dtmc<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); + env.solver().topological().setUnderlyingEquationSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); + return env; + } + }; + class HybridSylvanGmmxxGmresEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; @@ -269,7 +304,7 @@ namespace { } }; - class HybridCuddNativeSoundPowerEnvironment { + class HybridCuddNativeSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::CUDD; static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Hybrid; @@ -446,11 +481,13 @@ namespace { SparseNativeWalkerChaeEnvironment, SparseNativeSorEnvironment, SparseNativePowerEnvironment, - SparseNativeSoundPowerEnvironment, + SparseNativeSoundValueIterationEnvironment, + SparseNativeIntervalIterationEnvironment, SparseNativeRationalSearchEnvironment, + SparseTopologicalEigenLUEnvironment, HybridSylvanGmmxxGmresEnvironment, HybridCuddNativeJacobiEnvironment, - HybridCuddNativeSoundPowerEnvironment, + HybridCuddNativeSoundValueIterationEnvironment, HybridSylvanNativeRationalSearchEnvironment, DdSylvanNativePowerEnvironment, DdCuddNativeJacobiEnvironment, diff --git a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp index 5c37d24d0..e0741fa30 100644 --- a/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/MdpPrctlModelCheckerTest.cpp @@ -19,6 +19,7 @@ #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/QualitativeCheckResult.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/logic/Formulas.h" #include "storm/storage/jani/Property.h" @@ -39,6 +40,22 @@ namespace { return env; } }; + class SparseDoubleIntervalIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::IntervalIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; class SparseDoubleSoundValueIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models @@ -49,12 +66,48 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setForceSoundness(true); - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; } }; + + class SparseDoubleTopologicalValueIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; + + class SparseDoubleTopologicalSoundValueIterationEnvironment { + public: + static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models + static const storm::settings::modules::CoreSettings::Engine engine = storm::settings::modules::CoreSettings::Engine::Sparse; + static const bool isExact = false; + typedef double ValueType; + typedef storm::models::sparse::Mdp<ValueType> ModelType; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + env.solver().minMax().setRelativeTerminationCriterion(false); + return env; + } + }; + class SparseRationalPolicyIterationEnvironment { public: static const storm::dd::DdType ddType = storm::dd::DdType::Sylvan; // Unused for sparse models @@ -119,7 +172,7 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().setForceSoundness(true); - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); env.solver().minMax().setRelativeTerminationCriterion(false); return env; @@ -282,7 +335,10 @@ namespace { typedef ::testing::Types< SparseDoubleValueIterationEnvironment, + SparseDoubleIntervalIterationEnvironment, SparseDoubleSoundValueIterationEnvironment, + SparseDoubleTopologicalValueIterationEnvironment, + SparseDoubleTopologicalSoundValueIterationEnvironment, SparseRationalPolicyIterationEnvironment, SparseRationalRationalSearchEnvironment, HybridCuddDoubleValueIterationEnvironment, @@ -382,6 +438,8 @@ namespace { TYPED_TEST(MdpPrctlModelCheckerTest, consensus) { std::string formulasString = "Pmax=? [F \"finished\"]"; formulasString += "; Pmax=? [F \"all_coins_equal_1\"]"; + formulasString += "; P<0.8 [F \"all_coins_equal_1\"]"; + formulasString += "; P<0.9 [F \"all_coins_equal_1\"]"; formulasString += "; Rmax=? [F \"all_coins_equal_1\"]"; formulasString += "; Rmin=? [F \"all_coins_equal_1\"]"; formulasString += "; Rmax=? [F \"finished\"]"; @@ -403,15 +461,21 @@ namespace { EXPECT_NEAR(this->parseNumber("57/64"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); result = checker->check(this->env(), tasks[2]); - EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + EXPECT_FALSE(this->getQualitativeResultAtInitialState(model, result)); result = checker->check(this->env(), tasks[3]); - EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + EXPECT_TRUE(this->getQualitativeResultAtInitialState(model, result)); result = checker->check(this->env(), tasks[4]); + EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + + result = checker->check(this->env(), tasks[5]); + EXPECT_TRUE(storm::utility::isInfinity(this->getQuantitativeResultAtInitialState(model, result))); + + result = checker->check(this->env(), tasks[6]); EXPECT_NEAR(this->parseNumber("75"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); - result = checker->check(this->env(), tasks[5]); + result = checker->check(this->env(), tasks[7]); EXPECT_NEAR(this->parseNumber("48"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); } diff --git a/src/test/storm/parser/DirectEncodingParserTest.cpp b/src/test/storm/parser/DirectEncodingParserTest.cpp index 07d63b017..93bd34e04 100644 --- a/src/test/storm/parser/DirectEncodingParserTest.cpp +++ b/src/test/storm/parser/DirectEncodingParserTest.cpp @@ -1,23 +1,24 @@ #include "gtest/gtest.h" #include "storm-config.h" +#include "storm/parser/DirectEncodingParser.h" #include "storm/models/sparse/StandardRewardModel.h" #include "storm/models/sparse/Mdp.h" -#include "storm/parser/DirectEncodingParser.h" +#include "storm/models/sparse/MarkovAutomaton.h" -TEST(DirectEncodingParserTest, CtmcParsing) { - std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ctmc/cluster2.drn"); +TEST(DirectEncodingParserTest, DtmcParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.drn"); // Test if parsed correctly. - ASSERT_EQ(storm::models::ModelType::Ctmc, modelPtr->getType()); - ASSERT_EQ(276ul, modelPtr->getNumberOfStates()); - ASSERT_EQ(1120ul, modelPtr->getNumberOfTransitions()); + ASSERT_EQ(storm::models::ModelType::Dtmc, modelPtr->getType()); + ASSERT_EQ(8607ul, modelPtr->getNumberOfStates()); + ASSERT_EQ(15113ul, modelPtr->getNumberOfTransitions()); ASSERT_TRUE(modelPtr->hasLabel("init")); ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); - ASSERT_TRUE(modelPtr->hasLabel("premium")); - ASSERT_EQ(64ul, modelPtr->getStates("premium").getNumberOfSetBits()); - ASSERT_TRUE(modelPtr->hasLabel("minimum")); - ASSERT_EQ(132ul, modelPtr->getStates("minimum").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("observeIGreater1")); + ASSERT_EQ(4650ul, modelPtr->getStates("observeIGreater1").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("observe0Greater1")); + ASSERT_EQ(1260ul, modelPtr->getStates("observe0Greater1").getNumberOfSetBits()); } TEST(DirectEncodingParserTest, MdpParsing) { @@ -36,3 +37,36 @@ TEST(DirectEncodingParserTest, MdpParsing) { ASSERT_EQ(2ul, modelPtr->getStates("eleven").getNumberOfSetBits()); } +TEST(DirectEncodingParserTest, CtmcParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ctmc/cluster2.drn"); + + // Test if parsed correctly. + ASSERT_EQ(storm::models::ModelType::Ctmc, modelPtr->getType()); + ASSERT_EQ(276ul, modelPtr->getNumberOfStates()); + ASSERT_EQ(1120ul, modelPtr->getNumberOfTransitions()); + ASSERT_TRUE(modelPtr->hasLabel("init")); + ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("premium")); + ASSERT_EQ(64ul, modelPtr->getStates("premium").getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("minimum")); + ASSERT_EQ(132ul, modelPtr->getStates("minimum").getNumberOfSetBits()); +} + +TEST(DirectEncodingParserTest, MarkovAutomatonParsing) { + std::shared_ptr<storm::models::sparse::Model<double>> modelPtr = storm::parser::DirectEncodingParser<double>::parseModel(STORM_TEST_RESOURCES_DIR "/ma/jobscheduler.drn"); + std::shared_ptr<storm::models::sparse::MarkovAutomaton<double>> ma = modelPtr->as<storm::models::sparse::MarkovAutomaton<double>>(); + + // Test if parsed correctly. + ASSERT_EQ(storm::models::ModelType::MarkovAutomaton, modelPtr->getType()); + ASSERT_EQ(17ul, ma->getNumberOfStates()); + ASSERT_EQ(25ul, ma->getNumberOfTransitions()); + ASSERT_EQ(19ul, ma->getNumberOfChoices()); + ASSERT_EQ(10ul, ma->getMarkovianStates().getNumberOfSetBits()); + ASSERT_EQ(5, ma->getMaximalExitRate()); + ASSERT_TRUE(ma->hasRewardModel("avg_waiting_time")); + ASSERT_TRUE(modelPtr->hasLabel("init")); + ASSERT_EQ(1ul, modelPtr->getInitialStates().getNumberOfSetBits()); + ASSERT_TRUE(modelPtr->hasLabel("one_job_finished")); + ASSERT_EQ(6ul, modelPtr->getStates("one_job_finished").getNumberOfSetBits()); +} + diff --git a/src/test/storm/solver/LinearEquationSolverTest.cpp b/src/test/storm/solver/LinearEquationSolverTest.cpp index 696654658..114452ba8 100644 --- a/src/test/storm/solver/LinearEquationSolverTest.cpp +++ b/src/test/storm/solver/LinearEquationSolverTest.cpp @@ -6,6 +6,7 @@ #include "storm/environment/solver/NativeSolverEnvironment.h" #include "storm/environment/solver/GmmxxSolverEnvironment.h" #include "storm/environment/solver/EigenSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/utility/vector.h" namespace { @@ -23,7 +24,7 @@ namespace { } }; - class NativeDoubleSoundPowerEnvironment { + class NativeDoubleSoundValueIterationEnvironment { public: typedef double ValueType; static const bool isExact = false; @@ -31,7 +32,22 @@ namespace { storm::Environment env; env.solver().setForceSoundness(true); env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); - env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::Power); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::SoundValueIteration); + env.solver().native().setRelativeTerminationCriterion(false); + env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); + return env; + } + }; + + class NativeDoubleIntervalIterationEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setForceSoundness(true); + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Native); + env.solver().native().setMethod(storm::solver::NativeLinearEquationSolverMethod::IntervalIteration); env.solver().native().setRelativeTerminationCriterion(false); env.solver().native().setPrecision(storm::utility::convertNumber<storm::RationalNumber, std::string>("1e-6")); return env; @@ -250,6 +266,19 @@ namespace { } }; + class TopologicalEigenRationalLUEnvironment { + public: + typedef storm::RationalNumber ValueType; + static const bool isExact = true; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().setLinearEquationSolverType(storm::solver::EquationSolverType::Topological); + env.solver().topological().setUnderlyingEquationSolverType(storm::solver::EquationSolverType::Eigen); + env.solver().eigen().setMethod(storm::solver::EigenLinearEquationSolverMethod::SparseLU); + return env; + } + }; + template<typename TestType> class LinearEquationSolverTest : public ::testing::Test { public: @@ -264,7 +293,8 @@ namespace { typedef ::testing::Types< NativeDoublePowerEnvironment, - NativeDoubleSoundPowerEnvironment, + NativeDoubleSoundValueIterationEnvironment, + NativeDoubleIntervalIterationEnvironment, NativeDoubleJacobiEnvironment, NativeDoubleGaussSeidelEnvironment, NativeDoubleSorEnvironment, @@ -280,7 +310,8 @@ namespace { EigenGmresIluEnvironment, EigenBicgstabNoneEnvironment, EigenDoubleLUEnvironment, - EigenRationalLUEnvironment + EigenRationalLUEnvironment, + TopologicalEigenRationalLUEnvironment > TestingTypes; TYPED_TEST_CASE(LinearEquationSolverTest, TestingTypes); @@ -314,7 +345,7 @@ namespace { auto requirements = factory.getRequirements(this->env()); requirements.clearUpperBounds(); requirements.clearLowerBounds(); - ASSERT_TRUE(requirements.empty()); + ASSERT_FALSE(requirements.hasEnabledRequirement()); auto solver = factory.create(this->env(), A); solver->setBounds(this->parseNumber("-100"), this->parseNumber("100")); ASSERT_NO_THROW(solver->solveEquations(this->env(), x, b)); @@ -322,29 +353,4 @@ namespace { EXPECT_NEAR(x[1], this->parseNumber("457/9"), this->precision()); EXPECT_NEAR(x[2], this->parseNumber("875/18"), this->precision()); } - - TYPED_TEST(LinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder<ValueType> builder); - storm::storage::SparseMatrixBuilder<ValueType> builder; - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); - - storm::storage::SparseMatrix<ValueType> A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector<ValueType> x(5); - x[4] = this->parseNumber("1"); - - auto factory = storm::solver::GeneralLinearEquationSolverFactory<ValueType>(); - auto solver = factory.create(this->env(), A); - ASSERT_NO_THROW(solver->repeatedMultiply(x, nullptr, 4)); - EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); - } } \ No newline at end of file diff --git a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp index 5da2067e5..725590bc8 100644 --- a/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp +++ b/src/test/storm/solver/MinMaxLinearEquationSolverTest.cpp @@ -6,6 +6,7 @@ #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/environment/solver/MinMaxSolverEnvironment.h" #include "storm/environment/solver/NativeSolverEnvironment.h" +#include "storm/environment/solver/TopologicalSolverEnvironment.h" #include "storm/solver/SolverSelectionOptions.h" #include "storm/storage/SparseMatrix.h" @@ -28,12 +29,26 @@ namespace { static const bool isExact = false; static storm::Environment createEnvironment() { storm::Environment env; - env.solver().minMax().setMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::SoundValueIteration); + env.solver().setForceSoundness(true); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); + return env; + } + }; + + class DoubleIntervalIterationEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::IntervalIteration); env.solver().setForceSoundness(true); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-6)); return env; } }; + class DoubleTopologicalViEnvironment { public: typedef double ValueType; @@ -41,6 +56,19 @@ namespace { static storm::Environment createEnvironment() { storm::Environment env; env.solver().minMax().setMethod(storm::solver::MinMaxMethod::Topological); + env.solver().topological().setUnderlyingMinMaxMethod(storm::solver::MinMaxMethod::ValueIteration); + env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); + return env; + } + }; + + class DoubleTopologicalCudaViEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().minMax().setMethod(storm::solver::MinMaxMethod::TopologicalCuda); env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-8)); return env; } @@ -95,7 +123,9 @@ namespace { typedef ::testing::Types< DoubleViEnvironment, DoubleSoundViEnvironment, + DoubleIntervalIterationEnvironment, DoubleTopologicalViEnvironment, + DoubleTopologicalCudaViEnvironment, DoublePIEnvironment, RationalPIEnvironment, RationalRationalSearchEnvironment @@ -122,59 +152,13 @@ namespace { solver->setBounds(this->parseNumber("0"), this->parseNumber("2")); storm::solver::MinMaxLinearEquationSolverRequirements req = solver->getRequirements(this->env()); req.clearBounds(); - ASSERT_TRUE(req.empty()); + ASSERT_FALSE(req.hasEnabledRequirement()); ASSERT_NO_THROW(solver->solveEquations(this->env(), storm::OptimizationDirection::Minimize, x, b)); EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); ASSERT_NO_THROW(solver->solveEquations(this->env(), storm::OptimizationDirection::Maximize, x, b)); EXPECT_NEAR(x[0], this->parseNumber("0.99"), this->precision()); } - - TYPED_TEST(MinMaxLinearEquationSolverTest, MatrixVectorMultiplication) { - typedef typename TestFixture::ValueType ValueType; - - storm::storage::SparseMatrixBuilder<ValueType> builder(0, 0, 0, false, true); - ASSERT_NO_THROW(builder.newRowGroup(0)); - ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); - ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); - ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); - ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); - ASSERT_NO_THROW(builder.newRowGroup(2)); - ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); - ASSERT_NO_THROW(builder.newRowGroup(3)); - ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); - - storm::storage::SparseMatrix<ValueType> A; - ASSERT_NO_THROW(A = builder.build()); - - std::vector<ValueType> initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; - std::vector<ValueType> x; - - auto factory = storm::solver::GeneralMinMaxLinearEquationSolverFactory<ValueType>(); - auto solver = factory.create(this->env(), A); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); - EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); - EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); - - x = initialX; - ASSERT_NO_THROW(solver->repeatedMultiply(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); - EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); - } - } diff --git a/src/test/storm/solver/MultiplierTest.cpp b/src/test/storm/solver/MultiplierTest.cpp new file mode 100644 index 000000000..62a1a7c0c --- /dev/null +++ b/src/test/storm/solver/MultiplierTest.cpp @@ -0,0 +1,123 @@ +#include "gtest/gtest.h" +#include "storm-config.h" +#include "test/storm_gtest.h" + +#include "storm/storage/SparseMatrix.h" +#include "storm/solver/Multiplier.h" +#include "storm/environment/solver/MultiplierEnvironment.h" + +#include "storm/utility/vector.h" +namespace { + + class NativeEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Native); + return env; + } + }; + + class GmmxxEnvironment { + public: + typedef double ValueType; + static const bool isExact = false; + static storm::Environment createEnvironment() { + storm::Environment env; + env.solver().multiplier().setType(storm::solver::MultiplierType::Gmmxx); + return env; + } + }; + + template<typename TestType> + class MultiplierTest : public ::testing::Test { + public: + typedef typename TestType::ValueType ValueType; + MultiplierTest() : _environment(TestType::createEnvironment()) {} + storm::Environment const& env() const { return _environment; } + ValueType precision() const { return TestType::isExact ? parseNumber("0") : parseNumber("1e-15");} + ValueType parseNumber(std::string const& input) const { return storm::utility::convertNumber<ValueType>(input);} + private: + storm::Environment _environment; + }; + + typedef ::testing::Types< + NativeEnvironment, + GmmxxEnvironment + > TestingTypes; + + TYPED_TEST_CASE(MultiplierTest, TestingTypes); + + TYPED_TEST(MultiplierTest, repeatedMultiplyTest) { + typedef typename TestFixture::ValueType ValueType; + ASSERT_NO_THROW(storm::storage::SparseMatrixBuilder<ValueType> builder); + storm::storage::SparseMatrixBuilder<ValueType> builder; + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(0, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 3, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(2, 4, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(3, 4, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.addNextValue(4, 4, this->parseNumber("1"))); + + storm::storage::SparseMatrix<ValueType> A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector<ValueType> x(5); + x[4] = this->parseNumber("1"); + + auto factory = storm::solver::MultiplierFactory<ValueType>(); + auto multiplier = factory.create(this->env(), A); + ASSERT_NO_THROW(multiplier->repeatedMultiply(this->env(), x, nullptr, 4)); + EXPECT_NEAR(x[0], this->parseNumber("1"), this->precision()); + } + + TYPED_TEST(MultiplierTest, repeatedMultiplyAndReduceTest) { + typedef typename TestFixture::ValueType ValueType; + + storm::storage::SparseMatrixBuilder<ValueType> builder(0, 0, 0, false, true); + ASSERT_NO_THROW(builder.newRowGroup(0)); + ASSERT_NO_THROW(builder.addNextValue(0, 0, this->parseNumber("0.9"))); + ASSERT_NO_THROW(builder.addNextValue(0, 1, this->parseNumber("0.099"))); + ASSERT_NO_THROW(builder.addNextValue(0, 2, this->parseNumber("0.001"))); + ASSERT_NO_THROW(builder.addNextValue(1, 1, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.addNextValue(1, 2, this->parseNumber("0.5"))); + ASSERT_NO_THROW(builder.newRowGroup(2)); + ASSERT_NO_THROW(builder.addNextValue(2, 1, this->parseNumber("1"))); + ASSERT_NO_THROW(builder.newRowGroup(3)); + ASSERT_NO_THROW(builder.addNextValue(3, 2, this->parseNumber("1"))); + + storm::storage::SparseMatrix<ValueType> A; + ASSERT_NO_THROW(A = builder.build()); + + std::vector<ValueType> initialX = {this->parseNumber("0"), this->parseNumber("1"), this->parseNumber("0")}; + std::vector<ValueType> x; + + auto factory = storm::solver::MultiplierFactory<ValueType>(); + auto multiplier = factory.create(this->env(), A); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.099"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 2)); + EXPECT_NEAR(x[0], this->parseNumber("0.1881"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Minimize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 1)); + EXPECT_NEAR(x[0], this->parseNumber("0.5"), this->precision()); + + x = initialX; + ASSERT_NO_THROW(multiplier->repeatedMultiplyAndReduce(this->env(), storm::OptimizationDirection::Maximize, x, nullptr, 20)); + EXPECT_NEAR(x[0], this->parseNumber("0.923808265834023387639"), this->precision()); + } + +} \ No newline at end of file diff --git a/src/test/storm/storage/CuddDdTest.cpp b/src/test/storm/storage/CuddDdTest.cpp index 499be2a12..c1ae09561 100644 --- a/src/test/storm/storage/CuddDdTest.cpp +++ b/src/test/storm/storage/CuddDdTest.cpp @@ -589,6 +589,29 @@ TEST(CuddDd, MultiplyMatrixTest) { EXPECT_TRUE(dd3 == dd2 * manager->template getConstant<double>(2)); } +TEST(CuddDd, MultiplyMatrixTest2) { + std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>()); + std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 0, 2); + std::pair<storm::expressions::Variable, storm::expressions::Variable> b = manager->addMetaVariable("b", 0, 2); + + storm::dd::Add<storm::dd::DdType::CUDD, double> p = manager->getAddZero<double>(); + p += (manager->getEncoding(x.first, 2, true) && manager->getEncoding(b.first, 0, true)).template toAdd<double>(); + p += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(b.first, 2, true)).template toAdd<double>(); + + storm::dd::Add<storm::dd::DdType::CUDD, double> q = manager->getAddZero<double>(); + q += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(0.3); + q += (manager->getEncoding(x.first, 1, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(0.3); + q += (manager->getEncoding(x.first, 0, true) && manager->getEncoding(x.second, 2, true)).template toAdd<double>() * manager->template getConstant<double>(0.7); + q += (manager->getEncoding(x.first, 1, true) && manager->getEncoding(x.second, 2, true)).template toAdd<double>() * manager->template getConstant<double>(0.7); + q += (manager->getEncoding(x.first, 2, true) && manager->getEncoding(x.second, 0, true)).template toAdd<double>() * manager->template getConstant<double>(1); + + storm::dd::Add<storm::dd::DdType::CUDD, double> r = q.multiplyMatrix(p, {x.first}); + + ASSERT_EQ(12ull, r.getNodeCount()); + ASSERT_EQ(4ull, r.getLeafCount()); + ASSERT_EQ(3ull, r.getNonZeroCount()); +} + TEST(CuddDd, GetSetValueTest) { std::shared_ptr<storm::dd::DdManager<storm::dd::DdType::CUDD>> manager(new storm::dd::DdManager<storm::dd::DdType::CUDD>()); std::pair<storm::expressions::Variable, storm::expressions::Variable> x = manager->addMetaVariable("x", 1, 9); diff --git a/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp b/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp index a7c23edf3..6e9718e6b 100644 --- a/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp +++ b/src/test/storm/storage/MaximalEndComponentDecompositionTest.cpp @@ -3,7 +3,11 @@ #include "storm/parser/AutoParser.h" #include "storm/storage/MaximalEndComponentDecomposition.h" #include "storm/models/sparse/MarkovAutomaton.h" +#include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/StandardRewardModel.h" +#include "storm/builder/ExplicitModelBuilder.h" +#include "storm/storage/SymbolicModelDescription.h" +#include "storm/parser/PrismParser.h" TEST(MaximalEndComponentDecomposition, FullSystem1) { std::shared_ptr<storm::models::sparse::Model<double>> abstractModel = storm::parser::AutoParser<>::parseModel(STORM_TEST_RESOURCES_DIR "/tra/tiny1.tra", STORM_TEST_RESOURCES_DIR "/lab/tiny1.lab", "", ""); @@ -133,3 +137,42 @@ TEST(MaximalEndComponentDecomposition, Subsystem) { ASSERT_TRUE(false); } } + +TEST(MaximalEndComponentDecomposition, Example1) { + std::string prismModelPath = STORM_TEST_RESOURCES_DIR "/mdp/prism-mec-example1.nm"; + storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(prismModelPath); + storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); + + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program).build(); + std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = model->as<storm::models::sparse::Mdp<double>>(); + + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(*mdp); + + EXPECT_EQ(mecDecomposition.size(), 2); + + ASSERT_TRUE(mecDecomposition[0].getStateSet() == storm::storage::MaximalEndComponent::set_type{2}); + EXPECT_TRUE(mecDecomposition[0].getChoicesForState(2) == storm::storage::MaximalEndComponent::set_type{3}); + + ASSERT_TRUE(mecDecomposition[1].getStateSet() == storm::storage::MaximalEndComponent::set_type{0}); + EXPECT_TRUE(mecDecomposition[1].getChoicesForState(0) == storm::storage::MaximalEndComponent::set_type{0}); +} + +TEST(MaximalEndComponentDecomposition, Example2) { + std::string prismModelPath = STORM_TEST_RESOURCES_DIR "/mdp/prism-mec-example2.nm"; + storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(prismModelPath); + storm::prism::Program program = modelDescription.preprocess().asPrismProgram(); + + std::shared_ptr<storm::models::sparse::Model<double>> model = storm::builder::ExplicitModelBuilder<double>(program).build(); + std::shared_ptr<storm::models::sparse::Mdp<double>> mdp = model->as<storm::models::sparse::Mdp<double>>(); + + storm::storage::MaximalEndComponentDecomposition<double> mecDecomposition(*mdp); + + EXPECT_EQ(mecDecomposition.size(), 2); + + ASSERT_TRUE(mecDecomposition[0].getStateSet() == storm::storage::MaximalEndComponent::set_type{2}); + EXPECT_TRUE(mecDecomposition[0].getChoicesForState(2) == storm::storage::MaximalEndComponent::set_type{4}); + + ASSERT_TRUE((mecDecomposition[1].getStateSet() == storm::storage::MaximalEndComponent::set_type{0, 1})); + EXPECT_TRUE((mecDecomposition[1].getChoicesForState(0) == storm::storage::MaximalEndComponent::set_type{0, 1})); + EXPECT_TRUE((mecDecomposition[1].getChoicesForState(1) == storm::storage::MaximalEndComponent::set_type{3})); +} diff --git a/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp b/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp index fbaaf5df4..d339bd027 100644 --- a/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp +++ b/src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp @@ -71,7 +71,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker(*quotientMdp); storm::parser::FormulaParser formulaParser; std::shared_ptr<storm::logic::Formula const> minFormula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"one\"]"); @@ -97,7 +97,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker2(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker2(*quotientMdp); result = checker2.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -117,7 +117,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Cudd) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker3(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::CUDD, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>> checker3(*quotientMdp); result = checker3.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::CUDD>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -191,7 +191,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker(*quotientMdp); storm::parser::FormulaParser formulaParser; std::shared_ptr<storm::logic::Formula const> minFormula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"one\"]"); @@ -217,7 +217,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker2(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker2(*quotientMdp); result = checker2.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); @@ -237,7 +237,7 @@ TEST(SymbolicModelBisimulationDecomposition, DiePartialQuotient_Sylvan) { ASSERT_TRUE(quotient->isSymbolicModel()); quotientMdp = quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>>(); - storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker3(*quotientMdp, std::make_unique<storm::solver::GeneralSymbolicMinMaxLinearEquationSolverFactory<storm::dd::DdType::Sylvan, double>>()); + storm::modelchecker::SymbolicMdpPrctlModelChecker<storm::models::symbolic::Mdp<storm::dd::DdType::Sylvan, double>> checker3(*quotientMdp); result = checker3.check(*minFormula); result->filter(storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>(quotientMdp->getReachableStates(), quotientMdp->getInitialStates())); diff --git a/src/test/storm/utility/KSPTest.cpp b/src/test/storm/utility/KSPTest.cpp index df8b4f212..5ac954314 100644 --- a/src/test/storm/utility/KSPTest.cpp +++ b/src/test/storm/utility/KSPTest.cpp @@ -39,7 +39,7 @@ TEST(KSPTest, singleTarget) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); double dist = spg.getDistance(100); - EXPECT_DOUBLE_EQ(1.5231305000339649e-06, dist); + EXPECT_NEAR(1.5231305000339662e-06, dist, 1e-12); } TEST(KSPTest, reentry) { @@ -47,11 +47,11 @@ TEST(KSPTest, reentry) { storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); double dist = spg.getDistance(100); - EXPECT_DOUBLE_EQ(1.5231305000339649e-06, dist); + EXPECT_NEAR(1.5231305000339662e-06, dist, 1e-12); // get another distance to ensure re-entry is no problem double dist2 = spg.getDistance(500); - EXPECT_DOUBLE_EQ(3.0462610000679282e-08, dist2); + EXPECT_NEAR(3.0462610000679315e-08, dist2, 1e-12); } TEST(KSPTest, groupTarget) { @@ -60,13 +60,13 @@ TEST(KSPTest, groupTarget) { auto spg = storm::utility::ksp::ShortestPathsGenerator<double>(*model, groupTarget); double dist1 = spg.getDistance(8); - EXPECT_DOUBLE_EQ(0.00018449245583999996, dist1); + EXPECT_NEAR(0.00018449245583999996, dist1, 1e-12); double dist2 = spg.getDistance(9); - EXPECT_DOUBLE_EQ(0.00018449245583999996, dist2); + EXPECT_NEAR(0.00018449245583999996, dist2, 1e-12); double dist3 = spg.getDistance(12); - EXPECT_DOUBLE_EQ(7.5303043199999984e-06, dist3); + EXPECT_NEAR(7.5303043199999984e-06, dist3, 1e-12); } TEST(KSPTest, kTooLargeException) { @@ -80,23 +80,26 @@ TEST(KSPTest, kspStateSet) { auto model = buildExampleModel(); storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); - storm::storage::BitVector referenceBV(model->getNumberOfStates(), false); - for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 3, 5, 7, 10, 14, 19, 25, 29, 33, 36, 40, 44, 50, 56, 62, 70, 77, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { - referenceBV.set(s, true); - } - auto bv = spg.getStates(7); - - EXPECT_EQ(referenceBV, bv); + EXPECT_EQ(50, bv.getNumberOfSetBits()); + + // The result may sadly depend on the compiler/system, so checking a particular outcome is not feasible. +// storm::storage::BitVector referenceBV(model->getNumberOfStates(), false); +// for (auto s : std::vector<storm::utility::ksp::state_t>{0, 1, 2, 4, 6, 9, 12, 17, 22, 30, 37, 45, 52, 58, 65, 70, 74, 77, 81, 85, 92, 98, 104, 112, 119, 127, 134, 140, 146, 154, 161, 169, 176, 182, 188, 196, 203, 211, 218, 224, 230, 238, 245, 253, 260, 266, 272, 281, 288, 296}) { +// referenceBV.set(s, true); +// } +// +// EXPECT_EQ(referenceBV, bv); } TEST(KSPTest, kspPathAsList) { auto model = buildExampleModel(); storm::utility::ksp::ShortestPathsGenerator<double> spg(*model, testState); - // TODO: use path that actually has a loop or something to make this more interesting - auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 62, 56, 50, 44, 36, 29, 40, 33, 25, 19, 14, 10, 7, 5, 3, 1, 0}; auto list = spg.getPathAsList(7); - - EXPECT_EQ(reference, list); + EXPECT_EQ(50, list.size()); + + // TODO: use path that actually has a loop or something to make this more interesting +// auto reference = storm::utility::ksp::OrderedStateList{296, 288, 281, 272, 266, 260, 253, 245, 238, 230, 224, 218, 211, 203, 196, 188, 182, 176, 169, 161, 154, 146, 140, 134, 127, 119, 112, 104, 98, 92, 85, 77, 70, 81, 74, 65, 58, 52, 45, 37, 30, 22, 17, 12, 9, 6, 4, 2, 1, 0}; +// EXPECT_EQ(reference, list); } diff --git a/storm-version.cpp.in b/storm-version.cpp.in index c6c1acf71..6e3706bae 100644 --- a/storm-version.cpp.in +++ b/storm-version.cpp.in @@ -1,5 +1,4 @@ -//AUTO GENERATED -- DO NOT CHANGE -// TODO resolve issues when placing this in the build order directly. +// AUTO GENERATED -- DO NOT CHANGE #include "storm/utility/storm-version.h" namespace storm { @@ -8,9 +7,11 @@ namespace storm { const unsigned StormVersion::versionMajor = @STORM_VERSION_MAJOR@; const unsigned StormVersion::versionMinor = @STORM_VERSION_MINOR@; const unsigned StormVersion::versionPatch = @STORM_VERSION_DEV_PATCH@; + const std::string StormVersion::versionLabel = "@STORM_VERSION_LABEL@"; const bool StormVersion::versionDev = @STORM_VERSION_DEV@; + const StormVersion::VersionSource StormVersion::versionSource = @STORM_VERSION_SOURCE@; const std::string StormVersion::gitRevisionHash = "@STORM_VERSION_GIT_HASH@"; - const unsigned StormVersion::commitsAhead = @STORM_VERSION_COMMITS_AHEAD@; + const boost::optional<unsigned> StormVersion::commitsAhead = @STORM_VERSION_COMMITS_AHEAD@; const boost::optional<bool> StormVersion::dirty = @STORM_VERSION_DIRTY@; const std::string StormVersion::systemName = "@CMAKE_SYSTEM_NAME@"; const std::string StormVersion::systemVersion = "@CMAKE_SYSTEM_VERSION@"; @@ -20,5 +21,6 @@ namespace storm { #else const std::string StormVersion::cxxFlags = "@CMAKE_CXX_FLAGS@" " " "@CMAKE_CXX_FLAGS_DEBUG@"; #endif + } } diff --git a/travis/build.sh b/travis/build.sh index 668e4f18e..2873a6ec7 100755 --- a/travis/build.sh +++ b/travis/build.sh @@ -1,5 +1,4 @@ #!/bin/bash -x -# Inspired by https://github.com/google/fruit N_JOBS=2 TIMEOUT_MAC=1600 @@ -27,21 +26,31 @@ linux) docker rm -f storm &>/dev/null # Run container set -e - docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX + case "$CONFIG" in + *DebugTravis) + docker run -d -it --name storm --privileged movesrwth/carl:travis-debug + ;; + *ReleaseTravis) + docker run -d -it --name storm --privileged movesrwth/carl:travis + ;; + *) + docker run -d -it --name storm --privileged movesrwth/storm-basesystem:$LINUX + ;; + esac # Copy local content into container - docker exec storm mkdir storm - docker cp . storm:/storm + docker exec storm mkdir /opt/storm + docker cp . storm:/opt/storm set +e # Execute main process - timeout $TIMEOUT_LINUX docker exec storm bash -c " + docker exec storm bash -c " export CONFIG=$CONFIG; export COMPILER=$COMPILER; export N_JOBS=$N_JOBS; export STLARG=; export OS=$OS; - cd storm; - travis/build-helper.sh $1" + cd /opt/storm; + timeout $TIMEOUT_LINUX ./travis/build_helper.sh $1" EXITCODE=$? ;; @@ -53,7 +62,7 @@ osx) export N_JOBS export STLARG export OS - gtimeout $TIMEOUT_MAC travis/build-helper.sh "$1" + gtimeout $TIMEOUT_MAC travis/build_helper.sh "$1" EXITCODE=$? ;; diff --git a/travis/build_carl.sh b/travis/build_carl.sh new file mode 100755 index 000000000..37be2a986 --- /dev/null +++ b/travis/build_carl.sh @@ -0,0 +1,41 @@ +#!/bin/bash -x + +N_JOBS=2 +TIMEOUT_LINUX=2300 + +OS=$TRAVIS_OS_NAME + +case $OS in +linux) + # Execute docker image on Linux + # Stop previous session + docker rm -f carl &>/dev/null + # Run container + set -e + docker run -d -it --name carl --privileged movesrwth/storm-basesystem:$LINUX + # Copy local content into container + docker cp travis/build_carl_helper.sh carl:/opt/ + set +e + + # Execute main process + docker exec carl bash -c " + export CONFIG=$CONFIG; + export COMPILER=$COMPILER; + export N_JOBS=$N_JOBS; + export STLARG=; + export OS=$OS; + cd /opt/; + timeout $TIMEOUT_LINUX ./build_carl_helper.sh" + ;; + +osx) + echo "Building carl on Mac OSX not used." + exit 1 + ;; + +*) + # Unknown OS + echo "Unsupported OS: $OS" + exit 1 +esac + diff --git a/travis/build_carl_helper.sh b/travis/build_carl_helper.sh new file mode 100755 index 000000000..cfb1a31a6 --- /dev/null +++ b/travis/build_carl_helper.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +set -e + +# Helper for travis folding +travis_fold() { + local action=$1 + local name=$2 + echo -en "travis_fold:${action}:${name}\r" +} + +# Helper for building and testing +run() { + travis_fold start install_dependencies + apt-get update + apt-get install -qq -y openjdk-8-jdk maven uuid-dev pkg-config + travis_fold end install_dependencies + + travis_fold start install_carl + git clone https://github.com/smtrat/carl.git + cd carl + mkdir build + cd build + cmake .. "${CMAKE_ARGS[@]}" + make lib_carl addons -j$N_JOBS + travis_fold end install_carl +} + + +# This only exists in OS X, but it doesn't cause issues in Linux (the dir doesn't exist, so it's +# ignored). +export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" + +case $COMPILER in +gcc-6) + export CC=gcc-6 + export CXX=g++-6 + ;; + +gcc) + export CC=gcc + export CXX=g++ + ;; + +clang-4) + case "$OS" in + linux) + export CC=clang-4.0 + export CXX=clang++-4.0 + ;; + osx) + export CC=/usr/local/opt/llvm/bin/clang-4.0 + export CXX=/usr/local/opt/llvm/bin/clang++ + ;; + *) echo "Error: unexpected OS: $OS"; exit 1 ;; + esac + ;; + +clang) + export CC=clang + export CXX=clang++ + ;; + +*) + echo "Unrecognized value of COMPILER: $COMPILER" + exit 1 +esac + +# Build +echo CXX version: $($CXX --version) +echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1) +echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)) + +case "$CONFIG" in +DefaultDebug*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +DefaultRelease*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG" -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DTHREAD_SAFE=ON -DBUILD_ADDONS=ON -DBUILD_ADDON_PARSER=ON) + ;; +*) + echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 + ;; +esac + +run diff --git a/travis/build-helper.sh b/travis/build_helper.sh similarity index 81% rename from travis/build-helper.sh rename to travis/build_helper.sh index 7d722dc99..15a6dafeb 100755 --- a/travis/build-helper.sh +++ b/travis/build_helper.sh @@ -1,5 +1,4 @@ #!/bin/bash -# Inspired by https://github.com/google/fruit set -e @@ -10,6 +9,14 @@ travis_fold() { echo -en "travis_fold:${action}:${name}\r" } +# Helper to write output every minute +function bell() { + while true; do + echo "travis_wait for it..." + sleep 60 + done +} + # Helper for distinguishing between different runs run() { case "$1" in @@ -106,9 +113,15 @@ echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)) case "$CONFIG" in -DefaultDebug) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG") ;; -DefaultRelease) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG") ;; -*) echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 ;; +DefaultDebug*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DSTORM_DEVELOPER=ON -DSTORM_PORTABLE=ON -DCMAKE_CXX_FLAGS="$STLARG") + ;; +DefaultRelease*) + CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DSTORM_DEVELOPER=OFF -DSTORM_PORTABLE=ON -DCMAKE_CXX_FLAGS="$STLARG") + ;; +*) + echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 + ;; esac # Restore timestamps of files @@ -121,4 +134,9 @@ fi ruby travis/mtime_cache/mtime_cache.rb -g travis/mtime_cache/globs.txt -c travis/mtime_cache/cache.json travis_fold end mtime +# Run and print output to avoid travis timeout +bell & +bellPID=$! +trap 'rc=$?; kill $bellPID; exit $rc' EXIT run "$1" + diff --git a/travis/generate_travis.py b/travis/generate_travis.py index 87f622c57..ac4e89417 100644 --- a/travis/generate_travis.py +++ b/travis/generate_travis.py @@ -1,21 +1,21 @@ +# Generate .travis.yml automatically # Configuration for Linux configs_linux = [ - # OS, compiler - ("ubuntu-16.10", "gcc", ""), - #("debian-9", "gcc", ""), + # OS, compiler, build type + ("debian-9", "gcc", "DefaultDebug"), + ("debian-9", "gcc", "DefaultRelease"), + ("ubuntu-17.10", "gcc", "DefaultDebugTravis"), + ("ubuntu-17.10", "gcc", "DefaultReleaseTravis"), + ("ubuntu-18.04", "gcc", "DefaultDebug"), + ("ubuntu-18.04", "gcc", "DefaultRelease"), ] # Configurations for Mac configs_mac = [ - # OS, compiler -# ("osx", "clang", ""), -] - -# Build types -build_types = [ - "DefaultDebug", - "DefaultRelease", + # OS, compiler, build type +# ("osx", "clang", "DefaultDebug"), +# ("osx", "clang", "DefaultRelease"), ] # Stages in travis @@ -29,10 +29,10 @@ stages = [ if __name__ == "__main__": + allow_failures = [] + s = "" # Initial config - s += "# This file was inspired from https://github.com/google/fruit\n" - s += "\n" s += "#\n" s += "# General config\n" s += "#\n" @@ -61,7 +61,7 @@ if __name__ == "__main__": s += " on_failure: always\n" s += " on_success: change\n" s += " recipients:\n" - s += ' secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w="\n' + s += ' secure: "BoMQTBWnkh4ZLIHEaKu0tAKDohhVmOQ2pz/fjc+ScKG8mtvXqtpx0TiyePOUV1MuYNZiAP7x4mwABcoid55SwZ4+LPjd8uxXNfOji9B9GW5YqbqRvAeh7Es7dx48MyLYPIezjoryHH9R3Q2zZ9gmxgtw5eirjURcLNTXpKAwq/oOsKvh+vhOx4Qierw98wEXjMV7ipBzE4cfkgUbbX7oxGh1nsAsCew+rRmNLijfmE9tctYdH5W0wE+zC9ik+12Xyk3FwsDIABirPHfeCcEl+b9I0h1a2vZSZIA+sCDkIGKTiv9pCnsthn5LJc9pMLX7B/Wf6xLGMzpSiw3P1ZzjXpOE026WuyhTMVXqZYvbl7cJoNZiLCfTYg3MQVq5NHkq0h0jInIH7QlZYd0hZPOGONwdy17O1QmnX2Weq6G+Ps9siLVKFba37+y5PfRYkiUatJvDf2f7Jdxye6TWrUmlxQkAvs65ioyr8doad7IT1/yaGr/rBpXeQqZp6zNoMYr/cCRAYX6nOrnSszgiIWEc8QMMx+G31v77Uvd++9VG4MG9gbdpexpfYRNzKAxDarSaYEOuaWm2Z6R87bpNcjA+tW0hnBHBzRx0NFYYqXyW0tpVO9+035A9CHrLDLz77r4jJttcRvrP2rTbTBiwuhpmiufRyk3BuWlgzU3yaSuQV3M="\n' s += "\n" s += "#\n" s += "# Configurations\n" @@ -69,6 +69,40 @@ if __name__ == "__main__": s += "jobs:\n" s += " include:\n" + # Start with prebuilding carl for docker + s += "\n" + s += " ###\n" + s += " # Stage: Build Carl\n" + s += " ###\n" + s += "\n" + for config in configs_linux: + linux = config[0] + compiler = config[1] + build_type = config[2] + if "Travis" in build_type: + s += " # {} - {}\n".format(linux, build_type) + buildConfig = "" + buildConfig += " - stage: Build Carl\n" + buildConfig += " os: linux\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + buildConfig += " install:\n" + buildConfig += " - travis/install_linux.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build_carl.sh\n" + # Upload to DockerHub + buildConfig += " after_success:\n" + buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' + if "Debug" in build_type: + buildConfig += " - docker commit carl movesrwth/carl:travis-debug;\n" + buildConfig += " - docker push movesrwth/carl:travis-debug;\n" + elif "Release" in build_type: + buildConfig += " - docker commit carl movesrwth/carl:travis;\n" + buildConfig += " - docker push movesrwth/carl:travis;\n" + else: + assert False + s += buildConfig + # Generate all configurations for stage in stages: s += "\n" @@ -79,58 +113,68 @@ if __name__ == "__main__": # Mac OS X for config in configs_mac: osx = config[0] - compiler = "{}{}".format(config[1], config[2]) - s += " # {}\n".format(osx) + compiler = config[1] + build_type = config[2] + s += " # {} - {}\n".format(osx, build_type) buildConfig = "" - for build in build_types: - buildConfig += " - stage: {}\n".format(stage[0]) - buildConfig += " os: osx\n" - buildConfig += " osx_image: xcode9.1\n" - buildConfig += " compiler: {}\n".format(config[1]) - buildConfig += " env: CONFIG={} COMPILER={} STL=libc++\n".format(build, compiler) - buildConfig += " install:\n" - if stage[1] == "Build1": - buildConfig += " - rm -rf build\n" - buildConfig += " - travis/install_osx.sh\n" - buildConfig += " script:\n" - buildConfig += " - travis_wait 60 travis/build.sh {}\n".format(stage[1]) - buildConfig += " after_failure:\n" - buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" + buildConfig += " - stage: {}\n".format(stage[0]) + buildConfig += " os: osx\n" + buildConfig += " osx_image: xcode9.1\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} COMPILER={} STL=libc++\n".format(build_type, compiler) + buildConfig += " install:\n" + if stage[1] == "Build1": + buildConfig += " - rm -rf build\n" + buildConfig += " - travis/install_osx.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build.sh {}\n".format(stage[1]) + buildConfig += " after_failure:\n" + buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" s += buildConfig # Linux via Docker for config in configs_linux: + allow_fail = "" linux = config[0] - compiler = "{}{}".format(config[1], config[2]) - s += " # {}\n".format(linux) + compiler = config[1] + build_type = config[2] + s += " # {} - {}\n".format(linux, build_type) buildConfig = "" - for build in build_types: - buildConfig += " - stage: {}\n".format(stage[0]) - buildConfig += " os: linux\n" - buildConfig += " compiler: {}\n".format(config[1]) - buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build, linux, compiler) - buildConfig += " install:\n" - if stage[1] == "Build1": - buildConfig += " - rm -rf build\n" - buildConfig += " - travis/install_linux.sh\n" - buildConfig += " script:\n" - buildConfig += " - travis_wait 60 travis/build.sh {}\n".format(stage[1]) - buildConfig += " before_cache:\n" - buildConfig += " - docker cp storm:/storm/. .\n" - buildConfig += " after_failure:\n" - buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" - # Upload to dockerhub - if stage[1] == "TestAll": - buildConfig += " after_success:\n" - buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' - if "Debug" in build: - buildConfig += " - docker commit storm mvolk/storm-debug:travis;\n" - buildConfig += " - docker push mvolk/storm-debug:travis;\n" - elif "Release" in build: - buildConfig += " - docker commit storm mvolk/storm:travis;\n" - buildConfig += " - docker push mvolk/storm:travis;\n" - else: - assert False + buildConfig += " - stage: {}\n".format(stage[0]) + allow_fail += " - stage: {}\n".format(stage[0]) + buildConfig += " os: linux\n" + allow_fail += " os: linux\n" + buildConfig += " compiler: {}\n".format(compiler) + buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + allow_fail += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build_type, linux, compiler) + buildConfig += " install:\n" + if stage[1] == "Build1": + buildConfig += " - rm -rf build\n" + buildConfig += " - travis/install_linux.sh\n" + buildConfig += " script:\n" + buildConfig += " - travis/build.sh {}\n".format(stage[1]) + buildConfig += " before_cache:\n" + buildConfig += " - docker cp storm:/opt/storm/. .\n" + buildConfig += " after_failure:\n" + buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n" + # Upload to DockerHub + if stage[1] == "TestAll" and "Travis" in build_type: + buildConfig += " after_success:\n" + buildConfig += ' - docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";\n' + if "Debug" in build_type: + buildConfig += " - docker commit storm movesrwth/storm:travis-debug;\n" + buildConfig += " - docker push movesrwth/storm:travis-debug;\n" + elif "Release" in build_type: + buildConfig += " - docker commit storm movesrwth/storm:travis;\n" + buildConfig += " - docker push movesrwth/storm:travis;\n" + else: + assert False s += buildConfig + if "Travis" in build_type and "Release" in build_type: + allow_failures.append(allow_fail) + if len(allow_failures) > 0: + s += " allow_failures:\n" + for fail in allow_failures: + s += fail print(s) diff --git a/version.cmake b/version.cmake index d76de7858..9a0907e74 100644 --- a/version.cmake +++ b/version.cmake @@ -1,4 +1,4 @@ set(STORM_VERSION_MAJOR 1) set(STORM_VERSION_MINOR 2) -set(STORM_VERSION_PATCH 0) +set(STORM_VERSION_PATCH 1)