Browse Source

Merge from master

main
Matthias Volk 7 years ago
parent
commit
a7ffafb7d7
  1. 63
      .travis.yml
  2. 28
      CHANGELOG.md
  3. 74
      CMakeLists.txt
  4. 2
      doc/checklist_new_release.md
  5. 23
      resources/3rdparty/CMakeLists.txt
  6. 6
      resources/3rdparty/carl/CMakeLists.txt
  7. 20
      resources/cmake/macros/export.cmake
  8. 11
      resources/cmake/stormConfigVersion.cmake.in
  9. 28
      resources/examples/testfiles/ctmc/simple2.sm
  10. 71
      resources/examples/testfiles/dft/and.json
  11. 42
      resources/examples/testfiles/ma/simple2.ma
  12. 12
      resources/examples/testfiles/mdp/prism-mec-example1.nm
  13. 13
      resources/examples/testfiles/mdp/prism-mec-example2.nm
  14. 5
      src/CMakeLists.txt
  15. 4
      src/storm-cli-utilities/CMakeLists.txt
  16. 29
      src/storm-cli-utilities/cli.cpp
  17. 7
      src/storm-cli-utilities/cli.h
  18. 56
      src/storm-cli-utilities/model-handling.h
  19. 9
      src/storm-conv-cli/CMakeLists.txt
  20. 207
      src/storm-conv-cli/storm-conv.cpp
  21. 40
      src/storm-conv/CMakeLists.txt
  22. 71
      src/storm-conv/api/storm-conv.cpp
  23. 28
      src/storm-conv/api/storm-conv.h
  24. 15
      src/storm-conv/converter/options/JaniConversionOptions.cpp
  25. 32
      src/storm-conv/converter/options/JaniConversionOptions.h
  26. 12
      src/storm-conv/converter/options/PrismToJaniConverterOptions.cpp
  27. 21
      src/storm-conv/converter/options/PrismToJaniConverterOptions.h
  28. 24
      src/storm-conv/settings/ConvSettings.cpp
  29. 11
      src/storm-conv/settings/ConvSettings.h
  30. 77
      src/storm-conv/settings/modules/ConversionGeneralSettings.cpp
  31. 88
      src/storm-conv/settings/modules/ConversionGeneralSettings.h
  32. 80
      src/storm-conv/settings/modules/ConversionInputSettings.cpp
  33. 86
      src/storm-conv/settings/modules/ConversionInputSettings.h
  34. 57
      src/storm-conv/settings/modules/ConversionOutputSettings.cpp
  35. 49
      src/storm-conv/settings/modules/ConversionOutputSettings.h
  36. 78
      src/storm-conv/settings/modules/JaniExportSettings.cpp
  37. 14
      src/storm-conv/settings/modules/JaniExportSettings.h
  38. 40
      src/storm-counterexamples/CMakeLists.txt
  39. 2
      src/storm-counterexamples/api/counterexamples.cpp
  40. 4
      src/storm-counterexamples/api/counterexamples.h
  41. 2
      src/storm-counterexamples/counterexamples/Counterexample.cpp
  42. 0
      src/storm-counterexamples/counterexamples/Counterexample.h
  43. 2
      src/storm-counterexamples/counterexamples/HighLevelCounterexample.cpp
  44. 2
      src/storm-counterexamples/counterexamples/HighLevelCounterexample.h
  45. 4
      src/storm-counterexamples/counterexamples/MILPMinimalLabelSetGenerator.h
  46. 754
      src/storm-counterexamples/counterexamples/SMTMinimalLabelSetGenerator.h
  47. 4
      src/storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.cpp
  48. 0
      src/storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h
  49. 2
      src/storm-dft-cli/CMakeLists.txt
  50. 9
      src/storm-dft-cli/storm-dft.cpp
  51. 4
      src/storm-dft/CMakeLists.txt
  52. 16
      src/storm-dft/api/storm-dft.cpp
  53. 33
      src/storm-dft/api/storm-dft.h
  54. 3
      src/storm-dft/modelchecker/dft/DFTModelChecker.cpp
  55. 4
      src/storm-dft/parser/DFTGalileoParser.h
  56. 126
      src/storm-dft/parser/DFTJsonParser.cpp
  57. 12
      src/storm-dft/parser/DFTJsonParser.h
  58. 2
      src/storm-dft/settings/DftSettings.cpp
  59. 50
      src/storm-dft/storage/dft/DftJsonExporter.cpp
  60. 6
      src/storm-dft/storage/dft/DftJsonExporter.h
  61. 3
      src/storm-gspn-cli/CMakeLists.txt
  62. 66
      src/storm-gspn-cli/storm-gspn.cpp
  63. 26
      src/storm-gspn/CMakeLists.txt
  64. 56
      src/storm-gspn/api/storm-gspn.cpp
  65. 8
      src/storm-gspn/api/storm-gspn.h
  66. 2
      src/storm-gspn/builder/ExplicitGspnModelBuilder.cpp
  67. 157
      src/storm-gspn/builder/JaniGSPNBuilder.cpp
  68. 11
      src/storm-gspn/builder/JaniGSPNBuilder.h
  69. 153
      src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp
  70. 13
      src/storm-gspn/parser/GreatSpnEditorProjectParser.h
  71. 5
      src/storm-gspn/parser/GspnParser.cpp
  72. 2
      src/storm-gspn/parser/GspnParser.h
  73. 17
      src/storm-gspn/settings/modules/GSPNExportSettings.cpp
  74. 17
      src/storm-gspn/settings/modules/GSPNExportSettings.h
  75. 37
      src/storm-gspn/settings/modules/GSPNSettings.cpp
  76. 31
      src/storm-gspn/settings/modules/GSPNSettings.h
  77. 20
      src/storm-gspn/storage/gspn/GSPN.cpp
  78. 11
      src/storm-gspn/storage/gspn/GSPN.h
  79. 24
      src/storm-gspn/storage/gspn/GspnBuilder.cpp
  80. 15
      src/storm-gspn/storage/gspn/GspnBuilder.h
  81. 11
      src/storm-gspn/storage/gspn/GspnJsonExporter.cpp
  82. 47
      src/storm-gspn/storage/gspn/TimedTransition.h
  83. 2
      src/storm-pars-cli/CMakeLists.txt
  84. 256
      src/storm-pars-cli/storm-pars.cpp
  85. 2
      src/storm-pars/CMakeLists.txt
  86. 27
      src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp
  87. 28
      src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h
  88. 6
      src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp
  89. 6
      src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp
  90. 2
      src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp
  91. 4
      src/storm-pars/settings/ParsSettings.cpp
  92. 23
      src/storm-pars/settings/modules/ParametricSettings.cpp
  93. 20
      src/storm-pars/settings/modules/ParametricSettings.h
  94. 42
      src/storm-parsers/CMakeLists.txt
  95. 6
      src/storm-parsers/api/model_descriptions.cpp
  96. 0
      src/storm-parsers/api/model_descriptions.h
  97. 71
      src/storm-parsers/api/properties.cpp
  98. 43
      src/storm-parsers/api/properties.h
  99. 4
      src/storm-parsers/api/storm-parsers.h
  100. 4
      src/storm-parsers/parser/AtomicPropositionLabelingParser.cpp

63
.travis.yml

@ -9,6 +9,9 @@ sudo: required
dist: trusty
language: cpp
git:
depth: false
# Enable caching
cache:
timeout: 1000
@ -25,7 +28,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: "VWnsiQkt1xjgRo1hfNiNQqvLSr0fshFmLV7jJlUixhCr094mgD0U2bNKdUfebm28Byg9UyDYPbOFDC0sx7KydKiL1q7FKKXkyZH0k04wUu8XiNw+fYkDpmPnQs7G2n8oJ/GFJnr1Wp/1KI3qX5LX3xot4cJfx1I5iFC2O+p+ng6v/oSX+pewlMv4i7KL16ftHHHMo80N694v3g4B2NByn4GU2/bjVQcqlBp/TiVaUa5Nqu9DxZi/n9CJqGEaRHOblWyMO3EyTZsn45BNSWeQ3DtnMwZ73rlIr9CaEgCeuArc6RGghUAVqRI5ao+N5apekIaILwTgL6AJn+Lw/+NRPa8xclgd0rKqUQJMJCDZKjKz2lmIs3bxfELOizxJ3FJQ5R95FAxeAZ6rb/j40YqVVTw2IMBDnEE0J5ZmpUYNUtPti/Adf6GD9Fb2y8sLo0XDJzkI8OxYhfgjSy5KYmRj8O5MXcP2MAE8LQauNO3MaFnL9VMVOTZePJrPozQUgM021uyahf960+QNI06Uqlmg+PwWkSdllQlxHHplOgW7zClFhtSUpnJxcsUBzgg4kVg80gXUwAQkaDi7A9Wh2bs+TvMlmHzBwg+2SaAfWDgjeJIeOaipDkF1uSGzC+EHAiiKYMLd4Aahoi8SuelJUucoyJyLAq00WdUFQIh/izVhM4Y="
#
# Configurations
@ -37,11 +40,11 @@ jobs:
# Stage: Build Carl
###
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Build Carl
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -50,11 +53,11 @@ jobs:
- 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
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Build Carl
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -96,11 +99,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Build (1st run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- rm -rf build
- travis/install_linux.sh
@ -110,11 +113,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultReleaseTravis
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Build (1st run)
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- rm -rf build
- travis/install_linux.sh
@ -183,11 +186,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Build (2nd run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -196,11 +199,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultReleaseTravis
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Build (2nd run)
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -266,11 +269,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Build (3rd run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -279,11 +282,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultReleaseTravis
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Build (3rd run)
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -349,11 +352,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Build (4th run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -362,11 +365,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultReleaseTravis
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Build (4th run)
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -432,11 +435,11 @@ jobs:
- docker cp storm:/opt/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-17.10 - DefaultDebugTravis
# ubuntu-18.04 - DefaultDebugTravis
- stage: Test all
os: linux
compiler: gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultDebugTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -449,11 +452,11 @@ jobs:
- docker login -u "$DOCKER_USERNAME" -p "$DOCKER_PASSWORD";
- docker commit storm movesrwth/storm:travis-debug;
- docker push movesrwth/storm:travis-debug;
# ubuntu-17.10 - DefaultReleaseTravis
# ubuntu-18.04 - DefaultReleaseTravis
- stage: Test all
os: linux
compiler: gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
install:
- travis/install_linux.sh
script:
@ -495,17 +498,17 @@ jobs:
allow_failures:
- stage: Build (1st run)
os: linux
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
- stage: Build (2nd run)
os: linux
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
- stage: Build (3rd run)
os: linux
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
- stage: Build (4th run)
os: linux
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc
- stage: Test all
os: linux
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-17.10 COMPILER=gcc
env: CONFIG=DefaultReleaseTravis LINUX=ubuntu-18.04 COMPILER=gcc

28
CHANGELOG.md

@ -7,12 +7,32 @@ The releases of major and minor versions contain an overview of changes since th
Version 1.2.x
-------------
### Version 1.2.2 (to be released)
### Version 1.2.4 (2018/08)
- New binary `storm-conv` that handles conversions between model files (currently: prism to jani)
- Added support for expected time properties for discrete time models
- Several bug fixes related to jani
- `storm-gspn`: Improved .pnpro parser
- `storm-gspn`: Added support for single/infinite/k-server semantics for GSPNs given in the .pnpro format
- `storm-gspn`: Added option to set a global capacity for all places
- `storm-gspn`: Added option to include a set of standard properties when converting GSPNs to jani
### Version 1.2.3 (2018/07)
- Fix in version parsing
### Version 1.2.2 (2018/07)
- Sound value iteration (SVI) for DTMCs and MDPs
- Topological solver for linear equation systems and MinMax equation systems (enabled by default)
- Added support for expected total rewards in the sparse engine
- By default, iteration-based solvers are no longer aborted after a given number of steps.
- Improved export for jani models
- A fix in parsing jani properties
- Several extensions to high-level counterexamples
- `storm-parsers` extracted to reduce linking time
- `storm-counterexamples` extracted to reduce linking time
- `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.
- Improved Storm installation
- Several bug fixes
### Version 1.2.1 (2018/02)
- Multi-dimensional reward bounded reachability properties for DTMCs.

74
CMakeLists.txt

@ -78,7 +78,15 @@ 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")
message("CMAKE_INSTALL_DIR: ${CMAKE_INSTALL_DIR}")
# 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(STATUS "Storm - 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.
set(CMAKE_BUILD_TYPE "DEBUG")
@ -135,15 +143,15 @@ elseif (WIN32)
set(STATIC_EXT ".lib")
set(LIB_PREFIX "")
endif()
message(STATUS "Assuming extension for shared libraries: ${DYNAMIC_EXT}")
message(STATUS "Assuming extension for static libraries: ${STATIC_EXT}")
message(STATUS "Storm - Assuming extension for shared libraries: ${DYNAMIC_EXT}")
message(STATUS "Storm - Assuming extension for static libraries: ${STATIC_EXT}")
if(BUILD_SHARED_LIBS)
set(LIB_EXT ${DYNAMIC_EXT})
message(STATUS "Build dynamic libraries.")
message(STATUS "Storm - Build dynamic libraries.")
else()
set(LIB_EXT ${STATIC_EXT})
message(STATUS "Build static libraries.")
message(STATUS "Storm - Build static libraries.")
endif()
#############################################################
@ -169,7 +177,7 @@ 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
@ -213,16 +221,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")
@ -232,20 +240,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,16 +410,22 @@ 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
# 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_TAG_HASH "${CMAKE_MATCH_4}") # is not used
set(STORM_VERSION_APPENDIX "${CMAKE_MATCH_5}") # might be empty
set(STORM_VERSION_DIRTY boost::none)
if (NOT "${STORM_GIT_VERSION_STRING}" STREQUAL "")
# check whether the git version lookup failed
if (STORM_GIT_VERSION_STRING MATCHES "NOTFOUND")
set(STORM_VERSION_SOURCE "VersionSource::Static")
set(STORM_VERSION_COMMITS_AHEAD 0)
set(STORM_VERSION_DIRTY 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}.")
else()
set(STORM_VERSION_SOURCE "VersionSource::Git")
if ("${STORM_VERSION_APPENDIX}" MATCHES "^.*dirty.*$")
set(STORM_VERSION_DIRTY "true")
else()
@ -419,15 +433,6 @@ if (NOT "${STORM_GIT_VERSION_STRING}" STREQUAL "")
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 "")
@ -436,18 +441,19 @@ else()
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)
set(STORM_VERSION_DEV "true")
set(STORM_VERSION_DEV_STRING " (dev)")
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_COMMITS_AHEAD 0)
set(STORM_VERSION_DEV "false")
set(STORM_VERSION_DEV_STRING "")
set(STORM_VERSION_DEV_PATCH ${STORM_VERSION_PATCH})
endif()
@ -455,7 +461,7 @@ endif()
set(STORM_VERSION "${STORM_VERSION_MAJOR}.${STORM_VERSION_MINOR}.${STORM_VERSION_DEV_PATCH}")
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_LABEL_STRING} + ${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
@ -490,4 +496,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)

2
doc/checklist_new_release.md

@ -1,5 +1,5 @@
The following steps should be performed before releasing a new storm version.
Note that in most case a simultaneous release of [carl](https://github.com/smtrat/carl), [storm](https://github.com/moves-rwth/storm), [pycarl](https://github.com/moves-rwth/pycarl/) and [stormpy](https://github.com/moves-rwth/stormpy/) is preferred.
Note that in most cases a simultaneous release of [carl](https://github.com/smtrat/carl), [storm](https://github.com/moves-rwth/storm), [pycarl](https://github.com/moves-rwth/pycarl/) and [stormpy](https://github.com/moves-rwth/stormpy/) is preferred.
1. Update `CHANGELOG.md`
To get all the commits from an author since the last tag execute:

23
resources/3rdparty/CMakeLists.txt

@ -168,6 +168,15 @@ else()
message (WARNING "Storm - Z3 not found. Building of Prism/JANI models will not be supported.")
endif(Z3_FOUND)
# split Z3 version into its components
string(REPLACE "." ";" Z3_VERSION_LIST ${Z3_VERSION})
list(GET Z3_VERSION_LIST 0 STORM_Z3_VERSION_MAJOR)
list(GET Z3_VERSION_LIST 1 STORM_Z3_VERSION_MINOR)
list(GET Z3_VERSION_LIST 2 STORM_Z3_VERSION_PATCH)
if (NOT "${Z3_VERSION}" VERSION_LESS "4.7.1")
set(STORM_Z3_API_USES_STANDARD_INTEGERS ON)
endif()
#############################################################
##
## glpk
@ -239,16 +248,16 @@ if(carl_FOUND AND NOT STORM_FORCE_SHIPPED_CARL)
else()
set(STORM_SHIPPED_CARL ON)
# The first external project will be built at *configure stage*
message("START CARL CONFIG PROCESS")
file(MAKE_DIRECTORY ${STORM_3RDPARTY_BINARY_DIR}/carl_download)
message(STATUS "Carl - Start of config process")
file(MAKE_DIRECTORY ${STORM_3RDPARTY_BINARY_DIR}/carl_download)
execute_process(
COMMAND ${CMAKE_COMMAND} ${STORM_3RDPARTY_SOURCE_DIR}/carl "-DSTORM_3RDPARTY_BINARY_DIR=${STORM_3RDPARTY_BINARY_DIR}" "-DBoost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}" "-DBoost_INCLUDE_DIRS=${Boost_INCLUDE_DIRS}"
WORKING_DIRECTORY ${STORM_3RDPARTY_BINARY_DIR}/carl_download
OUTPUT_VARIABLE carlconfig_out
RESULT_VARIABLE carlconfig_result)
if(NOT carlconfig_result)
message("${carlconfig_out}")
message(STATUS "${carlconfig_out}")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} --build . --target carl-config
@ -257,10 +266,10 @@ else()
RESULT_VARIABLE carlconfig_result
)
if(NOT carlconfig_result)
message("${carlconfig_out}")
message(STATUS "${carlconfig_out}")
endif()
message("END CARL CONFIG PROCESS")
message(STATUS "Carl - End of config process")
message(STATUS "Storm - Using shipped version of carl.")
ExternalProject_Add(
carl

6
resources/3rdparty/carl/CMakeLists.txt

@ -4,11 +4,11 @@ include(ExternalProject)
option(STORM_3RDPARTY_BINARY_DIR "3rd party bin dir")
message(STORM_3RDPARTY_BINARY_DIR: ${STORM_3RDPARTY_BINARY_DIR})
message(STATUS "Carl - Storm 3rdparty binary dir: ${STORM_3RDPARTY_BINARY_DIR}")
ExternalProject_Add(carl-config
GIT_REPOSITORY https://github.com/smtrat/carl
GIT_TAG 17.12
GIT_TAG 18.06
PREFIX here
SOURCE_DIR source_dir
BINARY_DIR ${STORM_3RDPARTY_BINARY_DIR}/carl
@ -22,4 +22,4 @@ ExternalProject_Add(carl-config
add_custom_target(build-carl)
add_dependencies(build-carl carl-config)
message("done")
message(STATUS "Carl - Finished configuration.")

20
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
)

11
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()

28
resources/examples/testfiles/ctmc/simple2.sm

@ -0,0 +1,28 @@
ctmc
module main
s : [0..4]; // current state:
<> s=0 -> 4 : (s'=1) + 4 : (s'=2);
<> s=1 -> 0.3 : (s'=2) + 0.7 : (s'=1);
<> s=2 -> 0.5 : (s'=2) + 0.5 : (s'=3);
<> s=3 -> 1 : (s'=4);
<> s=4 -> 1 : (s'=3);
endmodule
rewards "rew1"
s=0 : 7;
[] s=2 : 1;
endrewards
rewards "rew2"
s=0 : 7;
[] s=2 : 1;
[] s=4 : 100;
endrewards

71
resources/examples/testfiles/dft/and.json

@ -0,0 +1,71 @@
{
"toplevel": "2",
"parameters": {},
"nodes": [
{
"data": {
"id": "0",
"name": "A",
"type": "be",
"rate": "1",
"dorm": "1",
"label": "A (1)"
},
"position": {
"x": 440,
"y": 260
},
"group": "nodes",
"removed": false,
"selected": false,
"selectable": true,
"locked": false,
"grabbable": true,
"classes": "be"
},
{
"data": {
"id": "1",
"name": "B",
"type": "be",
"rate": "1",
"dorm": "1",
"label": "B (1)"
},
"position": {
"x": 548,
"y": 265
},
"group": "nodes",
"removed": false,
"selected": false,
"selectable": true,
"locked": false,
"grabbable": true,
"classes": "be"
},
{
"data": {
"id": "2",
"name": "Z",
"type": "and",
"children": [
"0",
"1"
],
"label": "Z"
},
"position": {
"x": 505,
"y": 119
},
"group": "nodes",
"removed": false,
"selected": false,
"selectable": true,
"locked": false,
"grabbable": true,
"classes": "and"
}
]
}

42
resources/examples/testfiles/ma/simple2.ma

@ -0,0 +1,42 @@
ma
module main
s : [0..5]; // current state:
<> s=0 -> 4 : (s'=1) + 4 : (s'=2);
[alpha] s=1 -> 1 : (s'=0);
[beta] s=1 -> 0.3 : (s'=5) + 0.7 : (s'=1);
<> s=5 -> 1 : (s'=2);
[gamma] s=2 -> 1 : (s'=1);
[delta] s=2 -> 0.5 : (s'=2) + 0.5 : (s'=3);
<> s=3 -> 1 : (s'=4);
[lambda] s=4 -> 1 : (s'=3);
endmodule
rewards "rew0"
[delta] s=2 : 1;
endrewards
rewards "rew1"
s=0 : 7;
[delta] s=2 : 1;
endrewards
rewards "rew2"
s=0 : 7;
[delta] s=2 : 1;
[lambda] s=4 : 100;
endrewards
rewards "rew3"
s=0 : 7;
[delta] s=2 : 1;
[gamma] s=2 : 100;
[lambda] s=4 : 27;
endrewards

12
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

13
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

5
src/CMakeLists.txt

@ -5,6 +5,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_custom_target(binaries)
add_subdirectory(storm)
add_subdirectory(storm-counterexamples)
add_subdirectory(storm-parsers)
add_subdirectory(storm-cli-utilities)
add_subdirectory(storm-pgcl)
add_subdirectory(storm-pgcl-cli)
@ -14,7 +16,8 @@ add_subdirectory(storm-dft)
add_subdirectory(storm-dft-cli)
add_subdirectory(storm-pars)
add_subdirectory(storm-pars-cli)
add_subdirectory(storm-conv)
add_subdirectory(storm-conv-cli)
add_subdirectory(test)

4
src/storm-cli-utilities/CMakeLists.txt

@ -17,7 +17,7 @@ set_target_properties(storm-cli-utilities PROPERTIES DEFINE_SYMBOL "")
list(APPEND STORM_TARGETS storm-cli-utilities)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-cli-utilities PUBLIC storm)
target_link_libraries(storm-cli-utilities PUBLIC storm storm-counterexamples storm-parsers)
# Install storm headers to include directory.
foreach(HEADER ${STORM_CLI_UTIL_HEADERS})
@ -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)

29
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"
@ -48,6 +49,8 @@ namespace storm {
storm::cli::printHeader("Storm", argc, argv);
storm::settings::initializeAll("Storm", "storm");
storm::settings::addModule<storm::settings::modules::CounterexampleGeneratorSettings>();
storm::utility::Stopwatch totalTimer(true);
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
@ -63,7 +66,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 +94,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 +102,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);
}
}

7
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);

56
src/storm-cli-utilities/model-handling.h

@ -2,6 +2,9 @@
#include "storm/api/storm.h"
#include "storm-counterexamples/api/counterexamples.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm/utility/resources.h"
#include "storm/utility/file.h"
#include "storm/utility/storm-version.h"
@ -14,6 +17,7 @@
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/storage/jani/Property.h"
#include "storm/models/ModelBase.h"
@ -34,7 +38,6 @@
#include "storm/settings/modules/CoreSettings.h"
#include "storm/settings/modules/AbstractionSettings.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include "storm/utility/Stopwatch.h"
@ -63,10 +66,16 @@ namespace storm {
auto const& janiPropertyInput = janiInput.second;
if (ioSettings.isJaniPropertiesSet()) {
for (auto const& propName : ioSettings.getJaniProperties()) {
auto propertyIt = janiPropertyInput.find(propName);
STORM_LOG_THROW(propertyIt != janiPropertyInput.end(), storm::exceptions::InvalidArgumentException, "No JANI property with name '" << propName << "' is known.");
input.properties.emplace_back(propertyIt->second);
if (ioSettings.areJaniPropertiesSelected()) {
for (auto const& propName : ioSettings.getSelectedJaniProperties()) {
auto propertyIt = janiPropertyInput.find(propName);
STORM_LOG_THROW(propertyIt != janiPropertyInput.end(), storm::exceptions::InvalidArgumentException, "No JANI property with name '" << propName << "' is known.");
input.properties.emplace_back(propertyIt->second);
}
} else {
for (auto const& property : janiPropertyInput) {
input.properties.emplace_back(property.second);
}
}
}
}
@ -126,7 +135,7 @@ namespace storm {
if (transformToJani) {
storm::prism::Program const& model = output.model.get().asPrismProgram();
auto modelAndRenaming = model.toJaniWithLabelRenaming(true);
auto modelAndRenaming = model.toJaniWithLabelRenaming(true, "", false);
output.model = modelAndRenaming.first;
if (!modelAndRenaming.second.empty()) {
@ -150,10 +159,6 @@ namespace storm {
if (ioSettings.isExportJaniDotSet()) {
storm::api::exportJaniModelAsDot(model.asJaniModel(), ioSettings.getExportJaniDotFilename());
}
if (model.isJaniModel() && storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) {
storm::api::exportJaniModel(model.asJaniModel(), input.properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename());
}
}
}
@ -183,11 +188,15 @@ namespace storm {
template <typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::settings::modules::BuildSettings const& buildSettings) {
auto counterexampleGeneratorSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
storm::builder::BuilderOptions options(createFormulasToRespect(input.properties));
options.setBuildChoiceLabels(buildSettings.isBuildChoiceLabelsSet());
options.setBuildStateValuations(buildSettings.isBuildStateValuationsSet());
options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
if (storm::settings::manager().hasModule(storm::settings::modules::CounterexampleGeneratorSettings::moduleName)) {
auto counterexampleGeneratorSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
} else {
options.setBuildChoiceOrigins(false);
}
options.setBuildAllLabels(buildSettings.isBuildFullModelSet());
options.setBuildAllRewardModels(buildSettings.isBuildFullModelSet());
options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet());
@ -356,18 +365,12 @@ namespace storm {
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.");
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
for (auto const& property : input.properties) {
formulas.emplace_back(property.getRawFormula());
}
result->first = storm::api::transformSymbolicToSparseModel(symbolicModel, formulas);
STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "The translation to a sparse model is not supported for the given model type.");
}
return *result;
@ -419,7 +422,10 @@ namespace storm {
STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::NotSupportedException, "Counterexample generation is currently only supported for sparse models.");
auto sparseModel = model->as<storm::models::sparse::Model<ValueType>>();
for (auto& rewModel : sparseModel->getRewardModels()) {
rewModel.second.reduceToStateBasedRewards(sparseModel->getTransitionMatrix(), true);
}
STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Dtmc) || sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample is currently only supported for discrete-time models.");
auto counterexampleSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
@ -505,7 +511,7 @@ namespace storm {
}
void printModelCheckingProperty(storm::jani::Property const& property) {
STORM_PRINT(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl);
STORM_PRINT(std::endl << "Model checking property \"" << property.getName() << "\": " << *property.getRawFormula() << " ..." << std::endl);
}
template<typename ValueType>

9
src/storm-conv-cli/CMakeLists.txt

@ -0,0 +1,9 @@
# Create storm-conv.
add_executable(storm-conv-cli ${PROJECT_SOURCE_DIR}/src/storm-conv-cli/storm-conv.cpp)
target_link_libraries(storm-conv-cli storm-conv storm-cli-utilities) # Adding headers for xcode
set_target_properties(storm-conv-cli PROPERTIES OUTPUT_NAME "storm-conv")
add_dependencies(binaries storm-conv-cli)
# installation
install(TARGETS storm-conv-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

207
src/storm-conv-cli/storm-conv.cpp

@ -0,0 +1,207 @@
#include "storm-conv/api/storm-conv.h"
#include "storm/settings/SettingsManager.h"
#include "storm-conv/settings/ConvSettings.h"
#include "storm-conv/settings/modules/ConversionGeneralSettings.h"
#include "storm-conv/settings/modules/ConversionInputSettings.h"
#include "storm-conv/settings/modules/ConversionOutputSettings.h"
#include "storm/api/storm.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm/utility/initialize.h"
#include "storm/utility/macros.h"
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Property.h"
#include "storm-cli-utilities/cli.h"
#include "storm/exceptions/OptionParserException.h"
namespace storm {
namespace conv {
void setUrgentOptions() {
// Set the correct log level
if (storm::settings::getModule<storm::settings::modules::ConversionOutputSettings>().isStdOutOutputEnabled()) {
storm::utility::setLogLevel(l3pp::LogLevel::OFF);
} else {
auto const& general = storm::settings::getModule<storm::settings::modules::ConversionGeneralSettings>();
if (general.isVerboseSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::INFO);
}
if (general.isDebugOutputSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::DEBUG);
}
if (general.isTraceOutputSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::TRACE);
}
}
}
void processPrismInputJaniOutput(storm::prism::Program const& prismProg, std::vector<storm::jani::Property> const& properties) {
auto const& output = storm::settings::getModule<storm::settings::modules::ConversionOutputSettings>();
auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>();
auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
storm::converter::PrismToJaniConverterOptions options;
options.allVariablesGlobal = jani.isGlobalVarsSet();
options.suffix = "";
options.janiOptions = storm::converter::JaniConversionOptions(jani);
std::string outputFilename = "";
if (output.isJaniOutputFilenameSet()) {
outputFilename = output.getJaniOutputFilename();
} else if (input.isPrismInputSet() && !output.isStdOutOutputEnabled()) {
outputFilename = input.getPrismInputFilename();
// Remove extension if present
auto dotPos = outputFilename.rfind('.');
if (dotPos != std::string::npos) {
outputFilename.erase(dotPos);
}
std::string suffix = "";
if (input.isConstantsSet()) {
suffix = input.getConstantDefinitionString();
std::replace(suffix.begin(), suffix.end(), ',', '_');
std::replace(suffix.begin(), suffix.end(), '=', '-');
}
suffix = suffix + ".jani";
outputFilename += suffix;
}
auto startOfFilename = outputFilename.rfind("/");
if (startOfFilename == std::string::npos) {
startOfFilename = 0;
} else {
++startOfFilename;
}
auto endOfFilename = outputFilename.rfind(".");
if (endOfFilename == std::string::npos) {
endOfFilename = outputFilename.size();
}
options.janiOptions.modelName = outputFilename.substr(startOfFilename, endOfFilename - startOfFilename);
auto janiModelProperties = storm::api::convertPrismToJani(prismProg, properties, options);
if (outputFilename != "") {
storm::api::exportJaniToFile(janiModelProperties.first, janiModelProperties.second, outputFilename, jani.isCompactJsonSet());
}
if (output.isStdOutOutputEnabled()) {
storm::api::printJaniToStream(janiModelProperties.first, janiModelProperties.second, std::cout, jani.isCompactJsonSet());
}
}
void processPrismInput() {
auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>();
// Parse the prism program
storm::storage::SymbolicModelDescription prismProg = storm::api::parseProgram(input.getPrismInputFilename(), input.isPrismCompatibilityEnabled());
// Parse properties (if available)
std::vector<storm::jani::Property> properties;
if (input.isPropertyInputSet()) {
boost::optional<std::set<std::string>> propertyFilter = storm::api::parsePropertyFilter(input.getPropertyInputFilter());
properties = storm::api::parsePropertiesForSymbolicModelDescription(input.getPropertyInput(), prismProg, propertyFilter);
}
// Substitute constant definitions in program and properties.
std::string constantDefinitionString = input.getConstantDefinitionString();
auto constantDefinitions = prismProg.parseConstantDefinitions(constantDefinitionString);
prismProg = prismProg.preprocess(constantDefinitions);
if (!properties.empty()) {
properties = storm::api::substituteConstantsInProperties(properties, constantDefinitions);
}
// Branch on the type of output
auto const& output = storm::settings::getModule<storm::settings::modules::ConversionOutputSettings>();
if (output.isJaniOutputSet()) {
processPrismInputJaniOutput(prismProg.asPrismProgram(), properties);
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "There is either no outputformat specified or the provided combination of input and output format is not compatible.");
}
}
void processOptions() {
// Start by setting some urgent options (log levels, etc.)
setUrgentOptions();
// Branch on the type of input
auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>();
if (input.isPrismInputSet()) {
processPrismInput();
}
}
}
}
bool parseOptions(const int argc, const char* argv[]) {
try {
storm::settings::mutableManager().setFromCommandLine(argc, argv);
} catch (storm::exceptions::OptionParserException& e) {
storm::settings::manager().printHelp();
throw e;
return false;
}
auto const& general = storm::settings::getModule<storm::settings::modules::ConversionGeneralSettings>();
// Set options from config file (if given)
if (general.isConfigSet()) {
storm::settings::mutableManager().setFromConfigurationFile(general.getConfigFilename());
}
bool result = true;
if (general.isHelpSet()) {
storm::settings::manager().printHelp(general.getHelpModuleName());
result = false;
}
if (general.isVersionSet()) {
storm::cli::printVersion("storm-conv");
result = false;;
}
return result;
}
/*!
* Main entry point of the executable storm-conv.
*/
int main(const int argc, const char** argv) {
try {
storm::utility::setUp();
// Print header info only if output to sdtout is disabled
bool outputToStdOut = false;
for (int i = 1; i < argc; ++i) {
if (std::string(argv[i]) == "--" + storm::settings::modules::ConversionOutputSettings::stdoutOptionName) {
outputToStdOut = true;
}
}
if (outputToStdOut) {
storm::utility::setLogLevel(l3pp::LogLevel::OFF);
} else {
storm::cli::printHeader("Storm-conv", argc, argv);
}
storm::settings::initializeConvSettings("Storm-conv", "storm-conv");
if (!parseOptions(argc, argv)) {
return -1;
}
storm::conv::processOptions();
storm::utility::cleanUp();
return 0;
} catch (storm::exceptions::BaseException const& exception) {
STORM_LOG_ERROR("An exception caused Storm-conv 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-conv to terminate. The message of this exception is: " << exception.what());
return 2;
}
}

40
src/storm-conv/CMakeLists.txt

@ -0,0 +1,40 @@
file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-conv/*.h ${PROJECT_SOURCE_DIR}/src/storm-conv/*.cpp)
register_source_groups_from_filestructure("${ALL_FILES}" storm-conv)
file(GLOB_RECURSE STORM_CONV_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-conv/*/*.cpp)
file(GLOB_RECURSE STORM_CONV_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-conv/*/*.h)
# Create storm-conv.
add_library(storm-conv SHARED ${STORM_CONV_SOURCES} ${STORM_CONV_HEADERS})
# Remove define symbol for shared libstorm.
set_target_properties(storm-conv PROPERTIES DEFINE_SYMBOL "")
#add_dependencies(storm resources)
list(APPEND STORM_TARGETS storm-conv)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-conv PUBLIC storm ${STORM_CONV_LINK_LIBRARIES})
# Install storm headers to include directory.
foreach(HEADER ${STORM_CONV_HEADERS})
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/src/?" "" RELATIVE_HEADER_PATH ${HEADER})
string(REGEX MATCH "(.*)[/\\]" RELATIVE_DIRECTORY ${RELATIVE_HEADER_PATH})
string(REGEX REPLACE "${RELATIVE_DIRECTORY}/?" "" HEADER_FILENAME ${RELATIVE_HEADER_PATH})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy ${HEADER} ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
DEPENDS ${HEADER}
)
list(APPEND STORM_CONV_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}")
endforeach()
add_custom_target(copy_storm_conv_headers DEPENDS ${STORM_CONV_OUTPUT_HEADERS} ${STORM_CONV_HEADERS})
add_dependencies(storm-conv copy_storm_conv_headers)
# installation
install(TARGETS storm-conv EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

71
src/storm-conv/api/storm-conv.cpp

@ -0,0 +1,71 @@
#include "storm-conv/api/storm-conv.h"
#include "storm/storage/prism/Program.h"
#include "storm/storage/jani/Property.h"
#include "storm/storage/jani/JaniLocationExpander.h"
#include "storm/storage/jani/JSONExporter.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/CoreSettings.h"
namespace storm {
namespace api {
void postprocessJani(storm::jani::Model& janiModel, storm::converter::JaniConversionOptions options) {
if (!options.locationVariables.empty()) {
for (auto const& pair : options.locationVariables) {
storm::jani::JaniLocationExpander expander(janiModel);
expander.transform(pair.first, pair.second);
janiModel = expander.getResult();
}
}
if (options.exportFlattened) {
std::shared_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
if (storm::settings::hasModule<storm::settings::modules::CoreSettings>()) {
smtSolverFactory = std::make_shared<storm::utility::solver::SmtSolverFactory>();
} else {
smtSolverFactory = std::make_shared<storm::utility::solver::Z3SmtSolverFactory>();
}
janiModel = janiModel.flattenComposition(smtSolverFactory);
}
if (options.standardCompliant) {
janiModel.makeStandardJaniCompliant();
}
if (options.modelName) {
janiModel.setName(options.modelName.get());
}
}
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> convertPrismToJani(storm::prism::Program const& program, std::vector<storm::jani::Property> const& properties, storm::converter::PrismToJaniConverterOptions options) {
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> res;
// Perform conversion
auto modelAndRenaming = program.toJaniWithLabelRenaming(options.allVariablesGlobal, options.suffix, options.janiOptions.standardCompliant);
res.first = std::move(modelAndRenaming.first);
// Amend properties to potentially changed labels
for (auto const& property : properties) {
res.second.emplace_back(property.substituteLabels(modelAndRenaming.second));
}
// Postprocess Jani model based on the options
postprocessJani(res.first, options.janiOptions);
return res;
}
void exportJaniToFile(storm::jani::Model const& model, std::vector<storm::jani::Property> const& properties, std::string const& filename, bool compact) {
storm::jani::JsonExporter::toFile(model, properties, filename, true, compact);
}
void printJaniToStream(storm::jani::Model const& model, std::vector<storm::jani::Property> const& properties, std::ostream& ostream, bool compact) {
storm::jani::JsonExporter::toStream(model, properties, ostream, true, compact);
}
}
}

28
src/storm-conv/api/storm-conv.h

@ -0,0 +1,28 @@
#pragma once
#include "storm-conv/converter/options/PrismToJaniConverterOptions.h"
#include "storm-conv/converter/options/JaniConversionOptions.h"
namespace storm {
namespace prism {
class Program;
}
namespace jani {
class Model;
class Property;
}
namespace api {
void postprocessJani(storm::jani::Model& janiModel, storm::converter::JaniConversionOptions options);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> convertPrismToJani(storm::prism::Program const& program, std::vector<storm::jani::Property> const& properties = std::vector<storm::jani::Property>(), storm::converter::PrismToJaniConverterOptions options = storm::converter::PrismToJaniConverterOptions());
void exportJaniToFile(storm::jani::Model const& model, std::vector<storm::jani::Property> const& properties, std::string const& filename, bool compact = false);
void printJaniToStream(storm::jani::Model const& model, std::vector<storm::jani::Property> const& properties, std::ostream& ostream, bool compact = false);
}
}

15
src/storm-conv/converter/options/JaniConversionOptions.cpp

@ -0,0 +1,15 @@
#include "storm-conv/converter/options/PrismToJaniConverterOptions.h"
namespace storm {
namespace converter {
JaniConversionOptions::JaniConversionOptions() : standardCompliant(false), exportFlattened(false) {
// Intentionally left empty
};
JaniConversionOptions::JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings) : locationVariables(settings.getLocationVariables()), standardCompliant(settings.isExportAsStandardJaniSet()), exportFlattened(settings.isExportFlattenedSet()) {
// Intentionally left empty
};
}
}

32
src/storm-conv/converter/options/JaniConversionOptions.h

@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <vector>
#include <boost/optional.hpp>
#include "storm-conv/settings/modules/JaniExportSettings.h"
namespace storm {
namespace converter {
struct JaniConversionOptions {
JaniConversionOptions();
JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings);
/// (Automaton,Variable)-pairs that will be transformed to location variables of the respective automaton.
std::vector<std::pair<std::string, std::string>> locationVariables;
/// If set, the model will be made standard compliant (e.g. no state rewards for discrete time models)
bool standardCompliant;
/// If set, the model is transformed into a single automaton
bool exportFlattened;
/// If given, the model will get this name
boost::optional<std::string> modelName;
};
}
}

12
src/storm-conv/converter/options/PrismToJaniConverterOptions.cpp

@ -0,0 +1,12 @@
#include "storm-conv/converter/options/PrismToJaniConverterOptions.h"
namespace storm {
namespace converter {
PrismToJaniConverterOptions::PrismToJaniConverterOptions() : allVariablesGlobal(false), suffix("") {
// Intentionally left empty
};
}
}

21
src/storm-conv/converter/options/PrismToJaniConverterOptions.h

@ -0,0 +1,21 @@
#pragma once
#include <string>
#include "storm-conv/converter/options/JaniConversionOptions.h"
namespace storm {
namespace converter {
struct PrismToJaniConverterOptions {
PrismToJaniConverterOptions();
bool allVariablesGlobal;
std::string suffix;
JaniConversionOptions janiOptions;
};
}
}

24
src/storm-conv/settings/ConvSettings.cpp

@ -0,0 +1,24 @@
#include "storm-conv/settings/ConvSettings.h"
#include "storm-conv/settings/modules/ConversionGeneralSettings.h"
#include "storm-conv/settings/modules/ConversionInputSettings.h"
#include "storm-conv/settings/modules/ConversionOutputSettings.h"
#include "storm-conv/settings/modules/JaniExportSettings.h"
#include "storm/settings/SettingsManager.h"
namespace storm {
namespace settings {
void initializeConvSettings(std::string const& name, std::string const& executableName) {
storm::settings::mutableManager().setName(name, executableName);
// Register relevant settings modules.
storm::settings::addModule<storm::settings::modules::ConversionGeneralSettings>();
storm::settings::addModule<storm::settings::modules::ConversionInputSettings>();
storm::settings::addModule<storm::settings::modules::ConversionOutputSettings>();
storm::settings::addModule<storm::settings::modules::JaniExportSettings>();
}
}
}

11
src/storm-conv/settings/ConvSettings.h

@ -0,0 +1,11 @@
#pragma once
#include <string>
namespace storm {
namespace settings {
void initializeConvSettings(std::string const& name, std::string const& executableName);
}
}

77
src/storm-conv/settings/modules/ConversionGeneralSettings.cpp

@ -0,0 +1,77 @@
#include "storm-conv/settings/modules/ConversionGeneralSettings.h"
#include "storm/settings/SettingsManager.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 ConversionGeneralSettings::moduleName = "general";
const std::string ConversionGeneralSettings::helpOptionName = "help";
const std::string ConversionGeneralSettings::helpOptionShortName = "h";
const std::string ConversionGeneralSettings::versionOptionName = "version";
const std::string ConversionGeneralSettings::verboseOptionName = "verbose";
const std::string ConversionGeneralSettings::verboseOptionShortName = "v";
const std::string ConversionGeneralSettings::debugOptionName = "debug";
const std::string ConversionGeneralSettings::traceOptionName = "trace";
const std::string ConversionGeneralSettings::configOptionName = "config";
const std::string ConversionGeneralSettings::configOptionShortName = "c";
ConversionGeneralSettings::ConversionGeneralSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, helpOptionName, false, "Shows all available options, arguments and descriptions.").setShortName(helpOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("hint", "A regular expression to show help for all matching entities or 'all' for the complete help.").setDefaultValueString("all").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, versionOptionName, false, "Prints the version information.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, verboseOptionName, false, "Enables more verbose output.").setShortName(verboseOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, debugOptionName, false, "Enables verbose and debug output.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, traceOptionName, false, "Enables verbose and debug and trace output.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, configOptionName, false, "If given, this file will be read and parsed for additional configuration settings.").setShortName(configOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the configuration.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
}
bool ConversionGeneralSettings::isHelpSet() const {
return this->getOption(helpOptionName).getHasOptionBeenSet();
}
bool ConversionGeneralSettings::isVersionSet() const {
return this->getOption(versionOptionName).getHasOptionBeenSet();
}
std::string ConversionGeneralSettings::getHelpModuleName() const {
return this->getOption(helpOptionName).getArgumentByName("hint").getValueAsString();
}
bool ConversionGeneralSettings::isVerboseSet() const {
return this->getOption(verboseOptionName).getHasOptionBeenSet();
}
bool ConversionGeneralSettings::isDebugOutputSet() const {
return this->getOption(debugOptionName).getHasOptionBeenSet();
}
bool ConversionGeneralSettings::isTraceOutputSet() const {
return this->getOption(traceOptionName).getHasOptionBeenSet();
}
bool ConversionGeneralSettings::isConfigSet() const {
return this->getOption(configOptionName).getHasOptionBeenSet();
}
std::string ConversionGeneralSettings::getConfigFilename() const {
return this->getOption(configOptionName).getArgumentByName("filename").getValueAsString();
}
void ConversionGeneralSettings::finalize() {
// Intentionally left empty.
}
bool ConversionGeneralSettings::check() const {
return true;
}
} // namespace modules
} // namespace settings
} // namespace storm

88
src/storm-conv/settings/modules/ConversionGeneralSettings.h

@ -0,0 +1,88 @@
#pragma once
#include "storm/settings/modules/ModuleSettings.h"
namespace storm {
namespace settings {
namespace modules {
class ConversionGeneralSettings : public ModuleSettings {
public:
ConversionGeneralSettings();
/*!
* Retrieves whether the help option was set.
*
* @return True if the help option was set.
*/
bool isHelpSet() const;
/*!
* Retrieves whether the version option was set.
*
* @return True if the version option was set.
*/
bool isVersionSet() const;
/*!
* Retrieves the name of the module for which to show the help or "all" to indicate that the full help
* needs to be shown.
*
* @return The name of the module for which to show the help or "all".
*/
std::string getHelpModuleName() const;
/*!
* Retrieves whether the verbose option was set.
*
* @return True if the verbose option was set.
*/
bool isVerboseSet() const;
/*!
* Retrieves whether the debug output option was set.
*
*/
bool isDebugOutputSet() const;
/*!
* Retrieves whether the trace output option was set.
*
*/
bool isTraceOutputSet() const;
/*!
* Retrieves whether the config option was set.
*
* @return True if the config option was set.
*/
bool isConfigSet() const;
/*!
* Retrieves the name of the file that is to be scanned for settings.
*
* @return The name of the file that is to be scanned for settings.
*/
std::string getConfigFilename() const;
bool check() const override;
void finalize() 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 helpOptionName;
static const std::string helpOptionShortName;
static const std::string versionOptionName;
static const std::string verboseOptionName;
static const std::string verboseOptionShortName;
static const std::string debugOptionName;
static const std::string traceOptionName;
static const std::string configOptionName;
static const std::string configOptionShortName;
};
}
}
}

80
src/storm-conv/settings/modules/ConversionInputSettings.cpp

@ -0,0 +1,80 @@
#include "storm-conv/settings/modules/ConversionInputSettings.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/Option.h"
#include "storm/settings/OptionBuilder.h"
#include "storm/settings/ArgumentBuilder.h"
#include "storm/settings/Argument.h"
#include "storm/exceptions/InvalidSettingsException.h"
namespace storm {
namespace settings {
namespace modules {
const std::string ConversionInputSettings::moduleName = "input";
const std::string ConversionInputSettings::propertyOptionName = "prop";
const std::string ConversionInputSettings::propertyOptionShortName = "prop";
const std::string ConversionInputSettings::constantsOptionName = "constants";
const std::string ConversionInputSettings::constantsOptionShortName = "const";
const std::string ConversionInputSettings::prismInputOptionName = "prism";
const std::string ConversionInputSettings::prismCompatibilityOptionName = "prismcompat";
const std::string ConversionInputSettings::prismCompatibilityOptionShortName = "pc";
ConversionInputSettings::ConversionInputSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, propertyOptionName, false, "Specifies the properties to be checked on the model.").setShortName(propertyOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("property or filename", "The formula or the file containing the formulas.").build())
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filter", "The names of the properties to check.").setDefaultValueString("all").build())
.build());
this->addOption(storm::settings::OptionBuilder(moduleName, constantsOptionName, false, "Specifies the constant replacements to use in symbolic models. Note that this requires the model to be given as an symbolic model (i.e., via --" + prismInputOptionName + ").").setShortName(constantsOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("values", "A comma separated list of constants and their value, e.g. a=1,b=2,c=3.").setDefaultValueString("").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, prismInputOptionName, false, "Parses the model given in the PRISM format.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the PRISM input.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, prismCompatibilityOptionName, false, "Enables PRISM compatibility. This may be necessary to process some PRISM models.").setShortName(prismCompatibilityOptionShortName).build());
}
bool ConversionInputSettings::isPrismInputSet() const {
return this->getOption(prismInputOptionName).getHasOptionBeenSet();
}
std::string ConversionInputSettings::getPrismInputFilename() const {
return this->getOption(prismInputOptionName).getArgumentByName("filename").getValueAsString();
}
bool ConversionInputSettings::isPrismCompatibilityEnabled() const {
return this->getOption(prismCompatibilityOptionName).getHasOptionBeenSet();
}
bool ConversionInputSettings::isConstantsSet() const {
return this->getOption(constantsOptionName).getHasOptionBeenSet();
}
std::string ConversionInputSettings::getConstantDefinitionString() const {
return this->getOption(constantsOptionName).getArgumentByName("values").getValueAsString();
}
bool ConversionInputSettings::isPropertyInputSet() const {
return this->getOption(propertyOptionName).getHasOptionBeenSet();
}
std::string ConversionInputSettings::getPropertyInput() const {
return this->getOption(propertyOptionName).getArgumentByName("property or filename").getValueAsString();
}
std::string ConversionInputSettings::getPropertyInputFilter() const {
return this->getOption(propertyOptionName).getArgumentByName("filter").getValueAsString();
}
void ConversionInputSettings::finalize() {
// Intentionally left empty.
}
bool ConversionInputSettings::check() const {
return true;
}
} // namespace modules
} // namespace settings
} // namespace storm

86
src/storm-conv/settings/modules/ConversionInputSettings.h

@ -0,0 +1,86 @@
#pragma once
#include "storm/settings/modules/ModuleSettings.h"
namespace storm {
namespace settings {
namespace modules {
class ConversionInputSettings : public ModuleSettings {
public:
ConversionInputSettings();
/*!
* Retrieves whether the property option was set.
*
* @return True if the property option was set.
*/
bool isPropertyInputSet() const;
/*!
* Retrieves the property specified with the property option.
*
* @return The property specified with the property option.
*/
std::string getPropertyInput() const;
/*!
* Retrieves the property filter.
*
* @return The property filter.
*/
std::string getPropertyInputFilter() const;
/*!
* Retrieves whether constant definition option was set.
*
* @return True if the constant definition option was set.
*/
bool isConstantsSet() const;
/*!
* Retrieves the string that defines the constants of a symbolic model (given via the symbolic option).
*
* @return The string that defines the constants of a symbolic model.
*/
std::string getConstantDefinitionString() const;
/*!
* Retrieves whether the PRISM language option was set.
*/
bool isPrismInputSet() const;
/*!
* Retrieves the name of the file that contains the PRISM model specification if the model was given
* using the PRISM input option.
*/
std::string getPrismInputFilename() const;
/*!
* Retrieves whether the PRISM compatibility mode was enabled.
*
* @return True iff the PRISM compatibility mode was enabled.
*/
bool isPrismCompatibilityEnabled() const;
bool check() const override;
void finalize() 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 propertyOptionName;
static const std::string propertyOptionShortName;
static const std::string constantsOptionName;
static const std::string constantsOptionShortName;
static const std::string prismInputOptionName;
static const std::string prismCompatibilityOptionName;
static const std::string prismCompatibilityOptionShortName;
};
}
}
}

57
src/storm-conv/settings/modules/ConversionOutputSettings.cpp

@ -0,0 +1,57 @@
#include "storm-conv/settings/modules/ConversionOutputSettings.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/Option.h"
#include "storm/settings/OptionBuilder.h"
#include "storm/settings/ArgumentBuilder.h"
#include "storm/settings/Argument.h"
#include "storm/exceptions/InvalidSettingsException.h"
#include "storm/exceptions/InvalidOperationException.h"
namespace storm {
namespace settings {
namespace modules {
const std::string ConversionOutputSettings::moduleName = "output";
const std::string ConversionOutputSettings::stdoutOptionName = "stdout";
const std::string ConversionOutputSettings::janiOutputOptionName = "tojani";
ConversionOutputSettings::ConversionOutputSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, stdoutOptionName, false, "If set, the output will be printed to stdout.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, janiOutputOptionName, false, "converts the input model to Jani.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "the name of the output file (if not empty).").setDefaultValueString("").build()).build());
}
bool ConversionOutputSettings::isStdOutOutputEnabled() const {
return this->getOption(stdoutOptionName).getHasOptionBeenSet();
}
bool ConversionOutputSettings::isJaniOutputSet() const {
return this->getOption(janiOutputOptionName).getHasOptionBeenSet();
}
bool ConversionOutputSettings::isJaniOutputFilenameSet() const {
return isJaniOutputSet()
&& !this->getOption(janiOutputOptionName).getArgumentByName("filename").wasSetFromDefaultValue()
&& this->getOption(janiOutputOptionName).getArgumentByName("filename").getHasBeenSet()
&& this->getOption(janiOutputOptionName).getArgumentByName("filename").getValueAsString() != "";
}
std::string ConversionOutputSettings::getJaniOutputFilename() const {
STORM_LOG_THROW(isJaniOutputFilenameSet(), storm::exceptions::InvalidOperationException, "Tried to get the jani output name although none was specified.");
return this->getOption(janiOutputOptionName).getArgumentByName("filename").getValueAsString();
}
void ConversionOutputSettings::finalize() {
// Intentionally left empty.
}
bool ConversionOutputSettings::check() const {
STORM_LOG_THROW(!isJaniOutputFilenameSet() || ArgumentValidatorFactory::createWritableFileValidator()->isValid(getJaniOutputFilename()), storm::exceptions::InvalidSettingsException, "Unable to write at file " + getJaniOutputFilename());
return true;
}
} // namespace modules
} // namespace settings
} // namespace storm

49
src/storm-conv/settings/modules/ConversionOutputSettings.h

@ -0,0 +1,49 @@
#pragma once
#include "storm/settings/modules/ModuleSettings.h"
namespace storm {
namespace settings {
namespace modules {
class ConversionOutputSettings : public ModuleSettings {
public:
ConversionOutputSettings();
/*!
* Retrieves whether the output should be printed to stdout
*/
bool isStdOutOutputEnabled() const;
/*!
* Retrieves whether the output should be in the Jani format
*/
bool isJaniOutputSet() const;
/*!
* Retrieves whether an output filename for the jani file was specified
*/
bool isJaniOutputFilenameSet() const;
/*!
* Retrieves the name of the jani output (if specified)
*/
std::string getJaniOutputFilename() const;
bool check() const override;
void finalize() override;
// The name of the module.
static const std::string moduleName;
// name of the option that enables output to stdout. It needs to be public because we have to check this option very early
static const std::string stdoutOptionName;
private:
// Define the string names of the options as constants.
static const std::string janiOutputOptionName;
};
}
}
}

78
src/storm-conv/settings/modules/JaniExportSettings.cpp

@ -0,0 +1,78 @@
#include "JaniExportSettings.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 <boost/algorithm/string.hpp>
namespace storm {
namespace settings {
namespace modules {
const std::string JaniExportSettings::moduleName = "exportJani";
const std::string JaniExportSettings::standardCompliantOptionName = "standard-compliant";
const std::string JaniExportSettings::standardCompliantOptionShortName = "standard";
const std::string JaniExportSettings::exportFlattenOptionName = "flatten";
const std::string JaniExportSettings::locationVariablesOptionName = "location-variables";
const std::string JaniExportSettings::globalVariablesOptionName = "globalvars";
const std::string JaniExportSettings::compactJsonOptionName = "compactjson";
JaniExportSettings::JaniExportSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, locationVariablesOptionName, true, "Variables to export in the location").addArgument(storm::settings::ArgumentBuilder::createStringArgument("variables", "A comma separated list of automaton and local variable names seperated by a dot, e.g. A.x,B.y.").setDefaultValueString("").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, standardCompliantOptionName, false, "Export in standard compliant variant.").setShortName(standardCompliantOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, exportFlattenOptionName, false, "Flattens the composition of Automata to obtain an equivalent model that contains exactly one automaton").build());
this->addOption(storm::settings::OptionBuilder(moduleName, globalVariablesOptionName, false, "If set, variables will preferably be made global, e.g., to guarantee the same variable order as in the input file.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, compactJsonOptionName, false, "If set, the size of the resulting jani file will be reduced at the cost of (human-)readability.").build());
}
bool JaniExportSettings::isExportAsStandardJaniSet() const {
return this->getOption(standardCompliantOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isExportFlattenedSet() const {
return this->getOption(exportFlattenOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isLocationVariablesSet() const {
return this->getOption(locationVariablesOptionName).getHasOptionBeenSet();
}
std::vector<std::pair<std::string, std::string>> JaniExportSettings::getLocationVariables() const {
std::vector<std::pair<std::string, std::string>> result;
if (isLocationVariablesSet()) {
std::string argument = this->getOption(locationVariablesOptionName).getArgumentByName("variables").getValueAsString();
std::vector<std::string> arguments;
boost::split( arguments, argument, boost::is_any_of(","));
for (auto const& pair : arguments) {
std::vector<std::string> keyvaluepair;
boost::split( keyvaluepair, pair, boost::is_any_of("."));
STORM_LOG_THROW(keyvaluepair.size() == 2, storm::exceptions::IllegalArgumentException, "Expected a name of the form AUTOMATON.VARIABLE (with no further dots) but got " << pair);
result.emplace_back(keyvaluepair.at(0), keyvaluepair.at(1));
}
}
return result;
}
bool JaniExportSettings::isGlobalVarsSet() const {
return this->getOption(globalVariablesOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isCompactJsonSet() const {
return this->getOption(compactJsonOptionName).getHasOptionBeenSet();
}
void JaniExportSettings::finalize() {
}
bool JaniExportSettings::check() const {
return true;
}
}
}
}

14
src/storm/settings/modules/JaniExportSettings.h → src/storm-conv/settings/modules/JaniExportSettings.h

@ -25,7 +25,17 @@ namespace storm {
std::string getJaniFilename() const;
bool isExportAsStandardJaniSet() const;
bool isExportFlattenedSet() const;
bool isLocationVariablesSet() const;
bool isGlobalVarsSet() const;
bool isCompactJsonSet() const;
std::vector<std::pair<std::string, std::string>> getLocationVariables() const;
bool check() const override;
void finalize() override;
@ -36,6 +46,10 @@ namespace storm {
static const std::string janiFileOptionShortName;
static const std::string standardCompliantOptionName;
static const std::string standardCompliantOptionShortName;
static const std::string exportFlattenOptionName;
static const std::string locationVariablesOptionName;
static const std::string globalVariablesOptionName;
static const std::string compactJsonOptionName;
};
}

40
src/storm-counterexamples/CMakeLists.txt

@ -0,0 +1,40 @@
file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-counterexamples/*.h ${PROJECT_SOURCE_DIR}/src/storm-counterexamples/*.cpp)
register_source_groups_from_filestructure("${ALL_FILES}" storm-counterexamples)
file(GLOB_RECURSE STORM_CEX_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-counterexamples/*/*.cpp)
file(GLOB_RECURSE STORM_CEX_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-counterexamples/*/*.h)
# Create storm-dft.
add_library(storm-counterexamples SHARED ${STORM_CEX_SOURCES} ${STORM_CEX_HEADERS})
# Remove define symbol for shared libstorm.
set_target_properties(storm-counterexamples PROPERTIES DEFINE_SYMBOL "")
#add_dependencies(storm resources)
list(APPEND STORM_TARGETS storm-counterexamples)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-counterexamples PUBLIC storm)
# Install storm headers to include directory.
foreach(HEADER ${STORM_CEX_HEADERS})
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/src/?" "" RELATIVE_HEADER_PATH ${HEADER})
string(REGEX MATCH "(.*)[/\\]" RELATIVE_DIRECTORY ${RELATIVE_HEADER_PATH})
string(REGEX REPLACE "${RELATIVE_DIRECTORY}/?" "" HEADER_FILENAME ${RELATIVE_HEADER_PATH})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy ${HEADER} ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
DEPENDS ${HEADER}
)
list(APPEND STORM_CEX_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}")
endforeach()
add_custom_target(copy_storm_cex_headers DEPENDS ${STORM_CEX_OUTPUT_HEADERS} ${STORM_CEX_HEADERS})
add_dependencies(storm-counterexamples copy_storm_cex_headers)
# installation
install(TARGETS storm-counterexamples EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

2
src/storm/api/counterexamples.cpp → src/storm-counterexamples/api/counterexamples.cpp

@ -1,4 +1,4 @@
#include "storm/api/counterexamples.h"
#include "storm-counterexamples/api/counterexamples.h"
#include "storm/environment/Environment.h"

4
src/storm/api/counterexamples.h → src/storm-counterexamples/api/counterexamples.h

@ -1,7 +1,7 @@
#pragma once
#include "storm/counterexamples/MILPMinimalLabelSetGenerator.h"
#include "storm/counterexamples/SMTMinimalLabelSetGenerator.h"
#include "storm-counterexamples/counterexamples/MILPMinimalLabelSetGenerator.h"
#include "storm-counterexamples/counterexamples/SMTMinimalLabelSetGenerator.h"
namespace storm {
namespace api {

2
src/storm/counterexamples/Counterexample.cpp → src/storm-counterexamples/counterexamples/Counterexample.cpp

@ -1,4 +1,4 @@
#include "storm/counterexamples/Counterexample.h"
#include "storm-counterexamples/counterexamples/Counterexample.h"
namespace storm {
namespace counterexamples {

0
src/storm/counterexamples/Counterexample.h → src/storm-counterexamples/counterexamples/Counterexample.h

2
src/storm/counterexamples/HighLevelCounterexample.cpp → src/storm-counterexamples/counterexamples/HighLevelCounterexample.cpp

@ -1,4 +1,4 @@
#include "storm/counterexamples/HighLevelCounterexample.h"
#include "storm-counterexamples/counterexamples/HighLevelCounterexample.h"
namespace storm {
namespace counterexamples {

2
src/storm/counterexamples/HighLevelCounterexample.h → src/storm-counterexamples/counterexamples/HighLevelCounterexample.h

@ -1,6 +1,6 @@
#pragma once
#include "storm/counterexamples/Counterexample.h"
#include "Counterexample.h"
#include "storm/storage/SymbolicModelDescription.h"

4
src/storm/counterexamples/MILPMinimalLabelSetGenerator.h → src/storm-counterexamples/counterexamples/MILPMinimalLabelSetGenerator.h

@ -17,7 +17,7 @@
#include "storm/solver/MinMaxLinearEquationSolver.h"
#include "storm/counterexamples/HighLevelCounterexample.h"
#include "storm-counterexamples/counterexamples/HighLevelCounterexample.h"
#include "storm/utility/graph.h"
#include "storm/utility/counterexamples.h"
@ -29,7 +29,7 @@
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/CounterexampleGeneratorSettings.h"
#include "storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h"
namespace storm {

754
src/storm-counterexamples/counterexamples/SMTMinimalLabelSetGenerator.h
File diff suppressed because it is too large
View File

4
src/storm/settings/modules/CounterexampleGeneratorSettings.cpp → src/storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.cpp

@ -1,4 +1,4 @@
#include "storm/settings/modules/CounterexampleGeneratorSettings.h"
#include "storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h"
#include "storm/settings/SettingsManager.h"
#include "storm/exceptions/InvalidSettingsException.h"
@ -53,7 +53,7 @@ namespace storm {
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.");

0
src/storm/settings/modules/CounterexampleGeneratorSettings.h → src/storm-counterexamples/settings/modules/CounterexampleGeneratorSettings.h

2
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)

9
src/storm-dft-cli/storm-dft.cpp

@ -6,7 +6,10 @@
#include "storm-dft/settings/modules/DftGspnSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm/utility/initialize.h"
#include "storm-cli-utilities/cli.h"
@ -32,10 +35,10 @@ void processOptions() {
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());
dft = storm::api::loadDFTJsonFile<ValueType>(dftIOSettings.getDftJsonFilename());
} else {
STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename());
dft = storm::api::loadDFTGalileo<ValueType>(dftIOSettings.getDftFilename());
dft = storm::api::loadDFTGalileoFile<ValueType>(dftIOSettings.getDftFilename());
}
if (dftIOSettings.isDisplayStatsSet()) {
@ -46,7 +49,7 @@ void processOptions() {
if (dftIOSettings.isExportToJson()) {
// Export to json
storm::api::exportDFTToJson<ValueType>(*dft, dftIOSettings.getExportJsonFilename());
storm::api::exportDFTToJsonFile<ValueType>(*dft, dftIOSettings.getExportJsonFilename());
return;
}

4
src/storm-dft/CMakeLists.txt

@ -17,7 +17,7 @@ set_target_properties(storm-dft PROPERTIES DEFINE_SYMBOL "")
list(APPEND STORM_TARGETS storm-dft)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-dft PUBLIC storm storm-gspn ${STORM_DFT_LINK_LIBRARIES})
target_link_libraries(storm-dft PUBLIC storm storm-gspn storm-parsers ${STORM_DFT_LINK_LIBRARIES})
# Install storm headers to include directory.
foreach(HEADER ${STORM_DFT_HEADERS})
@ -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)

16
src/storm-dft/api/storm-dft.cpp

@ -7,12 +7,24 @@ namespace storm {
namespace api {
template<>
void exportDFTToJson(storm::storage::DFT<double> const& dft, std::string const& file) {
void exportDFTToJsonFile(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) {
void exportDFTToJsonFile(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<>
std::string exportDFTToJsonString(storm::storage::DFT<double> const& dft) {
std::stringstream stream;
storm::storage::DftJsonExporter<double>::toStream(dft, stream);
return stream.str();
}
template<>
std::string exportDFTToJsonString(storm::storage::DFT<storm::RationalFunction> const& dft) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to JSON not supported for this data type.");
}

33
src/storm-dft/api/storm-dft.h

@ -23,8 +23,21 @@ namespace storm {
* @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));
std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTGalileoFile(std::string const& file) {
return std::make_shared<storm::storage::DFT<ValueType>>(storm::parser::DFTGalileoParser<ValueType>::parseDFT(file));
}
/*!
* Load DFT from JSON string.
*
* @param jsonString String containing DFT description in JSON format.
*
* @return DFT.
*/
template<typename ValueType>
std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTJsonString(std::string const& jsonString) {
storm::parser::DFTJsonParser<ValueType> parser;
return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJsonFromString(jsonString));
}
/*!
@ -35,9 +48,9 @@ namespace storm {
* @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));
std::shared_ptr<storm::storage::DFT<ValueType>> loadDFTJsonFile(std::string const& file) {
storm::parser::DFTJsonParser<ValueType> parser;
return std::make_shared<storm::storage::DFT<ValueType>>(parser.parseJsonFromFile(file));
}
/*!
@ -99,7 +112,15 @@ namespace storm {
* @param file File.
*/
template<typename ValueType>
void exportDFTToJson(storm::storage::DFT<ValueType> const& dft, std::string const& file);
void exportDFTToJsonFile(storm::storage::DFT<ValueType> const& dft, std::string const& file);
/*!
* Export DFT to JSON string.
*
* @param dft DFT.
*/
template<typename ValueType>
std::string exportDFTToJsonString(storm::storage::DFT<ValueType> const& dft);
/*!
* Export DFT to SMT encoding.

3
src/storm-dft/modelchecker/dft/DFTModelChecker.cpp

@ -1,9 +1,12 @@
#include "DFTModelChecker.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/builder/ParallelCompositionBuilder.h"
#include "storm/utility/bitoperations.h"
#include "storm/utility/DirectEncodingExporter.h"
#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h"
#include "storm-dft/builder/ExplicitDFTModelBuilder.h"
#include "storm-dft/storage/dft/DFTIsomorphism.h"

4
src/storm-dft/parser/DFTGalileoParser.h

@ -3,12 +3,12 @@
#include <map>
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/parser/ExpressionParser.h"
#include "storm-parsers/parser/ExpressionParser.h"
#include "storm/storage/expressions/ExpressionEvaluator.h"
#include "storm-dft/storage/dft/DFT.h"
#include "storm-dft/builder/DFTBuilder.h"
#include "storm/parser/ValueParser.h"
#include "storm-parsers/parser/ValueParser.h"
namespace storm {

126
src/storm-dft/parser/DFTJsonParser.cpp

@ -15,54 +15,48 @@ namespace storm {
namespace parser {
template<typename ValueType>
storm::storage::DFT<ValueType> DFTJsonParser<ValueType>::parseJson(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;
storm::storage::DFT<ValueType> DFTJsonParser<ValueType>::parseJsonFromFile(std::string const& filename) {
STORM_LOG_DEBUG("Parsing from JSON file");
std::ifstream file;
storm::utility::openFile(filename, file);
json jsonInput;
jsonInput << file;
storm::utility::closeFile(file);
return parseJson(jsonInput);
}
template<typename ValueType>
std::string DFTJsonParser<ValueType>::generateUniqueName(std::string const& id, std::string const& name) {
std::string newId = name;
std::replace(newId.begin(), newId.end(), ' ', '_');
std::replace(newId.begin(), newId.end(), '-', '_');
return newId + "_" + id;
storm::storage::DFT<ValueType> DFTJsonParser<ValueType>::parseJsonFromString(std::string const& jsonString) {
STORM_LOG_DEBUG("Parsing from JSON string");
json jsonInput = json::parse(jsonString);
return parseJson(jsonInput);
}
template<typename ValueType>
void DFTJsonParser<ValueType>::readFile(const std::string& filename) {
STORM_LOG_DEBUG("Parsing from JSON");
std::ifstream file;
storm::utility::openFile(filename, file);
json parsedJson;
parsedJson << file;
storm::utility::closeFile(file);
json parameters = parsedJson.at("parameters");
#ifdef STORM_HAVE_CARL
for (auto it = parameters.begin(); it != parameters.end(); ++it) {
STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions.");
std::string parameter = it.key();
storm::expressions::Variable var = manager->declareRationalVariable(parameter);
identifierMapping.emplace(var.getName(), var);
parser.setIdentifierMapping(identifierMapping);
STORM_LOG_TRACE("Added parameter: " << var.getName());
storm::storage::DFT<ValueType> DFTJsonParser<ValueType>::parseJson(json const& jsonInput) {
// Try to parse parameters
if (jsonInput.find("parameters") != jsonInput.end()) {
json parameters = jsonInput.at("parameters");
STORM_LOG_THROW(parameters.empty() || (std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions.");
for (auto it = parameters.begin(); it != parameters.end(); ++it) {
std::string parameter = it.key();
storm::expressions::Variable var = manager->declareRationalVariable(parameter);
identifierMapping.emplace(var.getName(), var);
parser.setIdentifierMapping(identifierMapping);
STORM_LOG_TRACE("Added parameter: " << var.getName());
}
}
#endif
json nodes = parsedJson.at("nodes");
json nodes = jsonInput.at("nodes");
// Start by building mapping from ids to their unique names
std::map<std::string, std::string> nameMapping;
for (auto& element: nodes) {
for (auto& element : nodes) {
json data = element.at("data");
std::string id = data.at("id");
nameMapping[id] = generateUniqueName(id, data.at("name"));
}
// Parse nodes
for (auto& element : nodes) {
STORM_LOG_TRACE("Parsing: " << element);
bool success = true;
@ -82,7 +76,7 @@ namespace storm {
} else if (type == "or") {
success = builder.addOrElement(name, childNames);
} else if (type == "vot") {
std::string votThreshold = data.at("voting");
std::string votThreshold = parseJsonNumber(data.at("voting"));
success = builder.addVotElement(name, boost::lexical_cast<unsigned>(votThreshold), childNames);
} else if (type == "pand") {
success = builder.addPandElement(name, childNames);
@ -95,11 +89,11 @@ namespace storm {
} else if (type== "fdep") {
success = builder.addDepElement(name, childNames, storm::utility::one<ValueType>());
} else if (type== "pdep") {
ValueType probability = parseRationalExpression(data.at("prob"));
ValueType probability = parseRationalExpression(parseJsonNumber(data.at("prob")));
success = builder.addDepElement(name, childNames, probability);
} else if (type == "be") {
ValueType failureRate = parseRationalExpression(data.at("rate"));
ValueType dormancyFactor = parseRationalExpression(data.at("dorm"));
ValueType failureRate = parseRationalExpression(parseJsonNumber(data.at("rate")));
ValueType dormancyFactor = parseRationalExpression(parseJsonNumber(data.at("dorm")));
bool transient = false;
if (data.count("transient") > 0) {
transient = data.at("transient");
@ -110,23 +104,52 @@ namespace storm {
success = false;
}
// Do not set layout for dependencies
// This does not work because dependencies might be splitted
// TODO: do splitting later in rewriting step
if (type != "fdep" && type != "pdep") {
// Set layout positions
json position = element.at("position");
double x = position.at("x");
double y = position.at("y");
builder.addLayoutInfo(name, x / 7, y / 7);
// Try to set layout information
if (element.find("position") != element.end()) {
// Do not set layout for dependencies
// This does not work because dependencies might be splitted
// TODO: do splitting later in rewriting step
if (type != "fdep" && type != "pdep") {
// Set layout positions
json position = element.at("position");
double x = position.at("x");
double y = position.at("y");
builder.addLayoutInfo(name, x / 7, y / 7);
}
}
STORM_LOG_THROW(success, storm::exceptions::FileIoException, "Error while adding element '" << element << "'.");
}
std::string toplevelName = nameMapping[parsedJson.at("toplevel")];
std::string toplevelName = nameMapping[parseJsonNumber(jsonInput.at("toplevel"))];
if(!builder.setTopLevel(toplevelName)) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown.");
}
// Build DFT
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 DFTJsonParser<ValueType>::generateUniqueName(std::string const& id, std::string const& name) {
std::string newId = name;
std::replace(newId.begin(), newId.end(), ' ', '_');
std::replace(newId.begin(), newId.end(), '-', '_');
return newId + "_" + id;
}
template<typename ValueType>
std::string DFTJsonParser<ValueType>::parseJsonNumber(json number) {
if (number.is_string()) {
return number.get<std::string>();
} else {
std::stringstream stream;
stream << number;
return stream.str();
}
}
template<typename ValueType>
@ -140,10 +163,6 @@ namespace storm {
return boost::lexical_cast<double>(expr);
}
// Explicitly instantiate the class.
template class DFTJsonParser<double>;
#ifdef STORM_HAVE_CARL
template<>
storm::RationalFunction DFTJsonParser<storm::RationalFunction>::parseRationalExpression(std::string const& expr) {
STORM_LOG_TRACE("Translating expression: " << expr);
@ -154,8 +173,9 @@ namespace storm {
return rationalFunction;
}
// Explicitly instantiate the class.
template class DFTJsonParser<double>;
template class DFTJsonParser<RationalFunction>;
#endif
}
}

12
src/storm-dft/parser/DFTJsonParser.h

@ -3,7 +3,7 @@
#include <map>
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/parser/ExpressionParser.h"
#include "storm-parsers/parser/ExpressionParser.h"
#include "storm/storage/expressions/ExpressionEvaluator.h"
#include "storm-dft/storage/dft/DFT.h"
@ -33,14 +33,18 @@ namespace storm {
DFTJsonParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) {
}
storm::storage::DFT<ValueType> parseJson(std::string const& filename);
storm::storage::DFT<ValueType> parseJsonFromString(std::string const& jsonString);
storm::storage::DFT<ValueType> parseJsonFromFile(std::string const& filename);
private:
void readFile(std::string const& filename);
storm::storage::DFT<ValueType> parseJson(json const& jsonInput);
std::string generateUniqueName(std::string const& id, std::string const& name);
ValueType parseRationalExpression(std::string const& expr);
std::string parseJsonNumber(json number);
};
}
}

2
src/storm-dft/settings/DftSettings.cpp

@ -20,7 +20,7 @@
#include "storm/settings/modules/GameSolverSettings.h"
#include "storm/settings/modules/BisimulationSettings.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include "storm-conv/settings/modules/JaniExportSettings.h"
#include "storm-gspn/settings/modules/GSPNSettings.h"
#include "storm-gspn/settings/modules/GSPNExportSettings.h"

50
src/storm-dft/storage/dft/DftJsonExporter.cpp

@ -24,28 +24,23 @@ namespace storm {
template<typename ValueType>
modernjson::json DftJsonExporter<ValueType>::translate(storm::storage::DFT<ValueType> const& dft) {
modernjson::json jsonDft;
jsonDft["toplevel"] = dft.getTopLevelIndex();
// Parameters
modernjson::json jsonParameters;
jsonDft["parameters"] = jsonParameters;
// Nodes
modernjson::json jsonNodes;
for (size_t i = 0; i < dft.nrElements(); ++i) {
modernjson::json jsonNode = translateNode(dft.getElement(i));
jsonNodes.push_back(jsonNode);
}
jsonDft["nodes"] = jsonNodes;
modernjson::json jsonDft;
jsonDft["toplevel"] = std::to_string(dft.getTopLevelIndex());
jsonDft["nodes"] = jsonNodes;
return jsonDft;
}
template<typename ValueType>
modernjson::json DftJsonExporter<ValueType>::translateNode(DFTElementCPointer const& element) {
modernjson::json nodeData;
nodeData["id"] = element->id();
nodeData["id"] = std::to_string(element->id());
nodeData["name"] = element->name();
std::string type = storm::storage::toString(element->type());
std::transform(type.begin(), type.end(), type.begin(), ::tolower);
@ -54,36 +49,39 @@ namespace storm {
if (element->isGate()) {
// Set children for gate
std::shared_ptr<DFTGate<ValueType> const> gate = std::static_pointer_cast<DFTGate<ValueType> const>(element);
std::vector<size_t> children;
std::vector<std::string> children;
for (DFTElementPointer const& child : gate->children()) {
children.push_back(child->id());
children.push_back(std::to_string(child->id()));
}
nodeData["children"] = children;
// Set gate specific data
// Gate dependent export
switch (element->type()) {
case storm::storage::DFTElementType::VOT:
nodeData["voting"] = std::static_pointer_cast<storm::storage::DFTVot<ValueType> const>(element)->threshold();
break;
case storm::storage::DFTElementType::PDEP:
{
ValueType probability = std::static_pointer_cast<storm::storage::DFTDependency<ValueType> const>(element)->probability();
if (!storm::utility::isOne<ValueType>(probability)) {
std::stringstream stream;
stream << probability;
nodeData["prob"] = stream.str();
}
break;
}
default:
break;
}
} else if (element->isBasicElement()) {
// Set BE specific data
std::shared_ptr<DFTBE<ValueType> const> be = std::static_pointer_cast<DFTBE<ValueType> const>(element);
nodeData["rate"] = storm::utility::to_string(be->activeFailureRate());
nodeData["dorm"] = storm::utility::to_string(be->passiveFailureRate() / be->activeFailureRate());
nodeData["repair"] = 0;
nodeData["transient"] = be->isTransient();
} else if (element->isDependency()) {
std::shared_ptr<DFTDependency<ValueType> const> dependency = std::static_pointer_cast<DFTDependency<ValueType> const>(element);
std::vector<size_t> children = { dependency->triggerEvent()->id() };
for (DFTElementPointer const& child : dependency->dependentEvents()) {
children.push_back(child->id());
}
nodeData["children"] = children;
nodeData["prob"] = storm::utility::to_string(dependency->probability());
} else {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Type name: " << type << " not supported for export.");
std::stringstream stream;
stream << be->activeFailureRate();
nodeData["rate"] = stream.str();
stream.str(std::string()); // Clear stringstream
ValueType dormancy = be->passiveFailureRate() / be->activeFailureRate();
stream << dormancy;
nodeData["dorm"] = stream.str();
}
modernjson::json jsonNode;

6
src/storm-dft/storage/dft/DftJsonExporter.h

@ -29,14 +29,12 @@ namespace storm {
static void toStream(storm::storage::DFT<ValueType> const& dft, std::ostream& os);
static modernjson::json translate(storm::storage::DFT<ValueType> const& dft);
private:
static modernjson::json translate(storm::storage::DFT<ValueType> const& dft);
static modernjson::json translateNode(DFTElementCPointer const& element);
};
}
}

3
src/storm-gspn-cli/CMakeLists.txt

@ -1,3 +1,4 @@
# Create storm-gspn.
add_executable(storm-gspn-cli ${PROJECT_SOURCE_DIR}/src/storm-gspn-cli/storm-gspn.cpp)
target_link_libraries(storm-gspn-cli storm-gspn storm-cli-utilities) # Adding headers for xcode
set_target_properties(storm-gspn-cli PROPERTIES OUTPUT_NAME "storm-gspn")
@ -5,4 +6,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)
install(TARGETS storm-gspn-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

66
src/storm-gspn-cli/storm-gspn.cpp

@ -5,16 +5,15 @@
#include "storm-gspn/builder/JaniGSPNBuilder.h"
#include "storm-gspn/api/storm-gspn.h"
#include "storm/exceptions/BaseException.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/utility/macros.h"
#include "storm/utility/initialize.h"
#include "api/storm.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm-cli-utilities/cli.h"
#include "storm/parser/FormulaParser.h"
#include "storm-parsers/parser/FormulaParser.h"
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/storage/jani/Model.h"
@ -27,12 +26,13 @@
#include "storm/exceptions/FileIoException.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm-gspn/settings/modules/GSPNSettings.h"
#include "storm-gspn/settings/modules/GSPNExportSettings.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/settings/modules/DebugSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include "storm-conv/settings/modules/JaniExportSettings.h"
#include "storm/settings/modules/ResourceSettings.h"
@ -54,25 +54,6 @@ void initializeSettings() {
}
std::unordered_map<std::string, uint64_t> parseCapacitiesList(std::string const& filename) {
std::unordered_map<std::string, uint64_t> map;
std::ifstream stream;
storm::utility::openFile(filename, stream);
std::string line;
while ( std::getline(stream, line) ) {
std::vector<std::string> strs;
boost::split(strs, line, boost::is_any_of("\t "));
STORM_LOG_THROW(strs.size() == 2, storm::exceptions::WrongFormatException, "Expect key value pairs");
std::cout << std::stoll(strs[1]) << std::endl;
map[strs[0]] = std::stoll(strs[1]);
}
storm::utility::closeFile(stream);
return map;
}
int main(const int argc, const char **argv) {
try {
storm::utility::setUp();
@ -83,14 +64,22 @@ int main(const int argc, const char **argv) {
if (!optionsCorrect) {
return -1;
}
auto gspnSettings = storm::settings::getModule<storm::settings::modules::GSPNSettings>();
// parse gspn from file
if (!storm::settings::getModule<storm::settings::modules::GSPNSettings>().isGspnFileSet()) {
return -1;
if (!gspnSettings.isGspnFileSet()) {
// If no gspn file is given, nothing needs to be done.
return 0;
}
std::string constantDefinitionString = "";
if (gspnSettings.isConstantsSet()) {
constantDefinitionString = gspnSettings.getConstantDefinitionString();
}
auto parser = storm::parser::GspnParser();
auto gspn = parser.parse(storm::settings::getModule<storm::settings::modules::GSPNSettings>().getGspnFilename());
auto gspn = parser.parse(gspnSettings.getGspnFilename(), constantDefinitionString);
std::string formulaString = "";
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isPropertySet()) {
@ -99,28 +88,29 @@ int main(const int argc, const char **argv) {
boost::optional<std::set<std::string>> propertyFilter;
storm::parser::FormulaParser formulaParser(gspn->getExpressionManager());
std::vector<storm::jani::Property> properties = storm::api::parseProperties(formulaParser, formulaString, propertyFilter);
properties = storm::api::substituteConstantsInProperties(properties, gspn->getConstantsSubstitution());
if (!gspn->isValid()) {
STORM_LOG_ERROR("The gspn is not valid.");
}
if(storm::settings::getModule<storm::settings::modules::GSPNSettings>().isCapacitiesFileSet()) {
auto capacities = parseCapacitiesList(storm::settings::getModule<storm::settings::modules::GSPNSettings>().getCapacitiesFilename());
if(gspnSettings.isCapacitiesFileSet()) {
auto capacities = storm::api::parseCapacitiesList(gspnSettings.getCapacitiesFilename(), *gspn);
gspn->setCapacities(capacities);
} else if (gspnSettings.isCapacitySet()) {
uint64_t capacity = gspnSettings.getCapacity();
std::unordered_map<std::string, uint64_t> capacities;
for (auto const& place : gspn->getPlaces()) {
capacities.emplace(place.getName(), capacity);
}
gspn->setCapacities(capacities);
}
storm::api::handleGSPNExportSettings(*gspn);
storm::api::handleGSPNExportSettings(*gspn, [&](storm::builder::JaniGSPNBuilder const&) { return properties; });
if(storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) {
storm::jani::Model* model = storm::api::buildJani(*gspn);
storm::api::exportJaniModel(*model, properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename());
delete model;
}
delete gspn;
return 0;
//
// // construct ma
// auto builder = storm::builder::ExplicitGspnModelBuilder<>();
// auto ma = builder.translateGspn(gspn, formula);

26
src/storm-gspn/CMakeLists.txt

@ -8,11 +8,31 @@ file(GLOB_RECURSE STORM_GSPN_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-gspn/*/*.cp
file(GLOB_RECURSE STORM_GSPN_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-gspn/*/*.h)
# Create storm-pgcl.
# Create storm-gspn.
add_library(storm-gspn SHARED ${STORM_GSPN_SOURCES} ${STORM_GSPN_HEADERS})
# Remove define symbol for shared libstorm.
set_target_properties(storm-gspn PROPERTIES DEFINE_SYMBOL "")
#add_dependencies(storm resources)
list(APPEND STORM_TARGETS storm-gspn)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-gspn storm ${STORM_GSPN_LINK_LIBRARIES})
target_link_libraries(storm-gspn PUBLIC storm storm-conv storm-parsers ${STORM_GSPN_LINK_LIBRARIES})
# Install storm headers to include directory.
foreach(HEADER ${STORM_GSPN_HEADERS})
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/src/?" "" RELATIVE_HEADER_PATH ${HEADER})
string(REGEX MATCH "(.*)[/\\]" RELATIVE_DIRECTORY ${RELATIVE_HEADER_PATH})
string(REGEX REPLACE "${RELATIVE_DIRECTORY}/?" "" HEADER_FILENAME ${RELATIVE_HEADER_PATH})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy ${HEADER} ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
DEPENDS ${HEADER}
)
list(APPEND STORM_GSPN_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}")
endforeach()
add_custom_target(copy_storm_gspn_headers DEPENDS ${STORM_GSPN_OUTPUT_HEADERS} ${STORM_GSPN_HEADERS})
add_dependencies(storm-gspn copy_storm_gspn_headers)
# 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)

56
src/storm-gspn/api/storm-gspn.cpp

@ -3,7 +3,10 @@
#include "storm/settings/SettingsManager.h"
#include "storm/utility/file.h"
#include "storm-gspn/settings/modules/GSPNExportSettings.h"
#include "storm-conv/settings/modules/JaniExportSettings.h"
#include "storm-conv/api/storm-conv.h"
#include "storm-parsers/parser/ExpressionParser.h"
#include "storm/exceptions/WrongFormatException.h"
namespace storm {
namespace api {
@ -13,7 +16,7 @@ namespace storm {
return builder.build();
}
void handleGSPNExportSettings(storm::gspn::GSPN const& gspn) {
void handleGSPNExportSettings(storm::gspn::GSPN const& gspn, std::function<std::vector<storm::jani::Property>(storm::builder::JaniGSPNBuilder const&)> const& janiProperyGetter) {
storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>();
if (exportSettings.isWriteToDotSet()) {
std::ofstream fs;
@ -55,7 +58,54 @@ namespace storm {
gspn.writeStatsToStream(fs);
storm::utility::closeFile(fs);
}
}
if (exportSettings.isWriteToJaniSet()) {
auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
storm::converter::JaniConversionOptions options(jani);
storm::builder::JaniGSPNBuilder builder(gspn);
storm::jani::Model* model = builder.build("gspn_automaton", exportSettings.isAddJaniPropertiesSet());
storm::api::postprocessJani(*model, options);
auto properties = janiProperyGetter(builder);
if (exportSettings.isAddJaniPropertiesSet()) {
properties.insert(properties.end(), builder.getStandardProperties().begin(), builder.getStandardProperties().end());
}
storm::api::exportJaniToFile(*model, properties, exportSettings.getWriteToJaniFilename(), jani.isCompactJsonSet());
delete model;
}
}
std::unordered_map<std::string, uint64_t> parseCapacitiesList(std::string const& filename, storm::gspn::GSPN const& gspn) {
storm::parser::ExpressionParser expressionParser(*gspn.getExpressionManager());
std::unordered_map<std::string, storm::expressions::Expression> identifierMapping;
for (auto const& var : gspn.getExpressionManager()->getVariables()) {
identifierMapping.emplace(var.getName(), var.getExpression());
}
expressionParser.setIdentifierMapping(identifierMapping);
expressionParser.setAcceptDoubleLiterals(false);
std::unordered_map<std::string, uint64_t> map;
std::ifstream stream;
storm::utility::openFile(filename, stream);
std::string line;
while ( std::getline(stream, line) ) {
std::vector<std::string> strs;
boost::split(strs, line, boost::is_any_of("\t "));
STORM_LOG_THROW(strs.size() == 2, storm::exceptions::WrongFormatException, "Expect key value pairs");
storm::expressions::Expression expr = expressionParser.parseFromString(strs[1]);
if (!gspn.getConstantsSubstitution().empty()) {
expr = expr.substitute(gspn.getConstantsSubstitution());
}
STORM_LOG_THROW(!expr.containsVariables(), storm::exceptions::WrongFormatException, "The capacity expression '" << strs[1] << "' still contains undefined constants.");
map[strs[0]] = expr.evaluateAsInt();
}
storm::utility::closeFile(stream);
return map;
}
}
}

8
src/storm-gspn/api/storm-gspn.h

@ -1,5 +1,7 @@
#pragma once
#include <unordered_map>
#include "storm/storage/jani/Model.h"
#include "storm-gspn/storage/gspn/GSPN.h"
#include "storm-gspn/builder/JaniGSPNBuilder.h"
@ -12,6 +14,10 @@ namespace storm {
*/
storm::jani::Model* buildJani(storm::gspn::GSPN const& gspn);
void handleGSPNExportSettings(storm::gspn::GSPN const& gspn);
void handleGSPNExportSettings(storm::gspn::GSPN const& gspn,
std::function<std::vector<storm::jani::Property>(storm::builder::JaniGSPNBuilder const&)> const& janiProperyGetter = [](storm::builder::JaniGSPNBuilder const&) { return std::vector<storm::jani::Property>(); });
std::unordered_map<std::string, uint64_t> parseCapacitiesList(std::string const& filename, storm::gspn::GSPN const& gspn);
}
}

2
src/storm-gspn/builder/ExplicitGspnModelBuilder.cpp

@ -5,7 +5,7 @@
//#include "storm/utility/macros.h"
//#include "storm/exceptions/NotImplementedException.h"
//#include "storm/storage/expressions/ExpressionManager.h"
//#include "storm/parser/FormulaParser.h"
//#include "storm-parsers/parser/FormulaParser.h"
//#include "storm/storage/expressions/ExpressionEvaluator.h"
//
//namespace storm {

157
src/storm-gspn/builder/JaniGSPNBuilder.cpp

@ -1,18 +1,36 @@
#include "JaniGSPNBuilder.h"
#include <memory>
#include "storm/logic/Formulas.h"
#include "storm/exceptions/InvalidModelException.h"
namespace storm {
namespace builder {
storm::jani::Model* JaniGSPNBuilder::build(std::string const& automatonName) {
storm::jani::Model* model = new storm::jani::Model(gspn.getName(), storm::jani::ModelType::MA, janiVersion, expressionManager);
storm::jani::Model* JaniGSPNBuilder::build(std::string const& automatonName, bool buildStandardProperties) {
storm::jani::ModelType modelType = storm::jani::ModelType::MA;
if (gspn.getNumberOfTimedTransitions() == 0) {
storm::jani::ModelType modelType = storm::jani::ModelType::MDP;
} else if (gspn.getNumberOfImmediateTransitions() == 0) {
storm::jani::ModelType modelType = storm::jani::ModelType::CTMC;
}
storm::jani::Model* model = new storm::jani::Model(gspn.getName(), modelType, janiVersion, expressionManager);
storm::jani::Automaton mainAutomaton(automatonName, expressionManager->declareIntegerVariable("loc"));
addVariables(model);
uint64_t locId = addLocation(mainAutomaton);
addEdges(mainAutomaton, locId);
model->addAutomaton(mainAutomaton);
model->setStandardSystemComposition();
if (buildStandardProperties) {
buildProperties(model);
}
return model;
}
std::vector<storm::jani::Property> const& JaniGSPNBuilder::getStandardProperties() const {
return standardProperties;
}
void JaniGSPNBuilder::addVariables(storm::jani::Model* model) {
for (auto const& place : gspn.getPlaces()) {
@ -122,7 +140,7 @@ namespace storm {
}
for (auto const& trans : gspn.getTimedTransitions()) {
storm::expressions::Expression guard = expressionManager->boolean(true);
std::vector<storm::jani::Assignment> assignments;
for (auto const& inPlaceEntry : trans.getInputPlaces()) {
guard = guard && (vars[inPlaceEntry.first]->getExpressionVariable() >= inPlaceEntry.second);
@ -143,12 +161,143 @@ namespace storm {
std::shared_ptr<storm::jani::TemplateEdge> templateEdge = std::make_shared<storm::jani::TemplateEdge>(guard);
automaton.registerTemplateEdge(templateEdge);
storm::expressions::Expression rate = expressionManager->rational(trans.getRate());
if (trans.hasInfiniteServerSemantics() || (trans.hasKServerSemantics() && !trans.hasSingleServerSemantics())) {
STORM_LOG_THROW(trans.hasKServerSemantics() || !trans.getInputPlaces().empty(), storm::exceptions::InvalidModelException, "Unclear semantics: Found a transition with infinite-server semantics and without input place.");
storm::expressions::Expression enablingDegree;
bool firstArgumentOfMinExpression = true;
if (trans.hasKServerSemantics()) {
enablingDegree = expressionManager->integer(trans.getNumberOfServers());
firstArgumentOfMinExpression = false;
}
for (auto const& inPlaceEntry : trans.getInputPlaces()) {
storm::expressions::Expression enablingDegreeInPlace = vars[inPlaceEntry.first]->getExpressionVariable() / expressionManager->integer(inPlaceEntry.second); // Integer division!
if (firstArgumentOfMinExpression == true) {
enablingDegree = enablingDegreeInPlace;
} else {
enablingDegree = storm::expressions::minimum(enablingDegree, enablingDegreeInPlace);
}
}
rate = rate * enablingDegree;
}
templateEdge->addDestination(assignments);
storm::jani::Edge e(locId, storm::jani::Model::SILENT_ACTION_INDEX, expressionManager->rational(trans.getRate()), templateEdge, {locId}, {expressionManager->integer(1)});
storm::jani::Edge e(locId, storm::jani::Model::SILENT_ACTION_INDEX, rate, templateEdge, {locId}, {expressionManager->integer(1)});
automaton.addEdge(e);
}
}
storm::jani::Variable const& JaniGSPNBuilder::addDeadlockTransientVariable(storm::jani::Model* model, std::string name, bool ignoreCapacities, bool ignoreInhibitorArcs, bool ignoreEmptyPlaces) {
storm::expressions::Expression transientValue = expressionManager->boolean(true);
// build the conjunction over all transitions
std::vector<storm::gspn::Transition const*> transitions;
transitions.reserve(gspn.getNumberOfImmediateTransitions() + gspn.getNumberOfTimedTransitions());
for (auto const& t : gspn.getImmediateTransitions()) {
transitions.push_back(&t);
}
for (auto const& t : gspn.getTimedTransitions()) {
transitions.push_back(&t);
}
bool firstTransition = true;
for (auto const& transition : transitions) {
// build the disjunction over all in/out places and inhibitor arcs
storm::expressions::Expression transitionDisabled = expressionManager->boolean(false);
bool firstPlace = true;
if (!ignoreEmptyPlaces) {
for (auto const& placeIdMult : transition->getInputPlaces()) {
storm::expressions::Expression placeBlocksTransition = (vars.at(placeIdMult.first)->getExpressionVariable() < expressionManager->integer(placeIdMult.second));
if (firstPlace) {
transitionDisabled = placeBlocksTransition;
firstPlace = false;
} else {
transitionDisabled = transitionDisabled || placeBlocksTransition;
}
}
}
if (!ignoreInhibitorArcs) {
for (auto const& placeIdMult : transition->getInhibitionPlaces()) {
storm::expressions::Expression placeBlocksTransition = (vars.at(placeIdMult.first)->getExpressionVariable() >= expressionManager->integer(placeIdMult.second));
if (firstPlace) {
transitionDisabled = placeBlocksTransition;
firstPlace = false;
} else {
transitionDisabled = transitionDisabled || placeBlocksTransition;
}
}
}
if (!ignoreCapacities) {
for (auto const& placeIdMult : transition->getOutputPlaces()) {
auto const& place = gspn.getPlace(placeIdMult.first);
if (place->hasRestrictedCapacity()) {
storm::expressions::Expression placeBlocksTransition = (vars.at(placeIdMult.first)->getExpressionVariable() + expressionManager->integer(placeIdMult.second) > expressionManager->integer(place->getCapacity()));
if (firstPlace) {
transitionDisabled = placeBlocksTransition;
firstPlace = false;
} else {
transitionDisabled = transitionDisabled || placeBlocksTransition;
}
}
}
}
if (firstTransition) {
transientValue = transitionDisabled;
firstTransition = false;
} else {
transientValue = transientValue && transitionDisabled;
}
}
auto exprVar = expressionManager->declareBooleanVariable(name);
auto const& janiVar = model->addVariable(*storm::jani::makeBooleanVariable(name, exprVar, expressionManager->boolean(false), true));
storm::jani::Assignment assignment(janiVar, transientValue);
model->getAutomata().front().getLocations().front().addTransientAssignment(assignment);
return janiVar;
}
std::string getUniqueVarName(storm::expressions::ExpressionManager const& manager, std::string name) {
std::string res = name;
while (manager.hasVariable(res)) {
res.append("_");
}
return res;
}
void JaniGSPNBuilder::buildProperties(storm::jani::Model* model) {
standardProperties.clear();
auto const& deadlockVar = addDeadlockTransientVariable(model, getUniqueVarName(*expressionManager, "deadl"));
auto deadlock = std::make_shared<storm::logic::AtomicExpressionFormula>(deadlockVar.getExpressionVariable().getExpression());
auto trueFormula = std::make_shared<storm::logic::BooleanLiteralFormula>(true);
auto maxReachDeadlock = std::make_shared<storm::logic::ProbabilityOperatorFormula>(
std::make_shared<storm::logic::EventuallyFormula>(deadlock, storm::logic::FormulaContext::Probability),
storm::logic::OperatorInformation(storm::solver::OptimizationDirection::Maximize));
standardProperties.emplace_back("MaxPrReachDeadlock", maxReachDeadlock, "The maximal probability to eventually reach a deadlock.");
auto exprTB = expressionManager->declareRationalVariable(getUniqueVarName(*expressionManager, "TIME_BOUND"));
auto janiTB = storm::jani::Constant(exprTB.getName(), exprTB);
model->addConstant(janiTB);
storm::logic::TimeBound tb(false, janiTB.getExpressionVariable().getExpression());
storm::logic::TimeBoundReference tbr(storm::logic::TimeBoundType::Time);
auto maxReachDeadlockTimeBounded = std::make_shared<storm::logic::ProbabilityOperatorFormula>(
std::make_shared<storm::logic::BoundedUntilFormula>(trueFormula, deadlock, boost::none, tb, tbr),
storm::logic::OperatorInformation(storm::solver::OptimizationDirection::Maximize));
standardProperties.emplace_back("MaxPrReachDeadlockTB", maxReachDeadlockTimeBounded, "The maximal probability to reach a deadlock within 'TIME_BOUND' steps.");
auto expTimeDeadlock = std::make_shared<storm::logic::TimeOperatorFormula>(
std::make_shared<storm::logic::EventuallyFormula>(deadlock, storm::logic::FormulaContext::Time),
storm::logic::OperatorInformation(storm::solver::OptimizationDirection::Maximize));
standardProperties.emplace_back("MinExpTimeDeadlock", expTimeDeadlock, "The minimal expected time to reach a deadlock.");
}
}
}

11
src/storm-gspn/builder/JaniGSPNBuilder.h

@ -19,11 +19,13 @@ namespace storm {
}
storm::jani::Model* build(std::string const& automatonName = "gspn_automaton");
storm::jani::Model* build(std::string const& automatonName = "gspn_automaton", bool buildStandardProperties = false);
storm::jani::Variable const& getPlaceVariable(uint64_t placeId) {
storm::jani::Variable const& getPlaceVariable(uint64_t placeId) const {
return *vars.at(placeId);
}
std::vector<storm::jani::Property> const& getStandardProperties() const;
private:
@ -33,11 +35,16 @@ namespace storm {
void addEdges(storm::jani::Automaton& automaton, uint64_t locId);
storm::jani::Variable const& addDeadlockTransientVariable(storm::jani::Model* model, std::string name, bool ignoreCapacities = false, bool ignoreInhibitorArcs = false, bool ignoreEmptyPlaces = false);
void buildProperties(storm::jani::Model* model);
const uint64_t janiVersion = 1;
storm::gspn::GSPN const& gspn;
std::map<uint64_t, storm::jani::Variable const*> vars;
std::shared_ptr<storm::expressions::ExpressionManager> expressionManager;
std::vector<storm::jani::Property> standardProperties;
};
}
}

153
src/storm-gspn/parser/GreatSpnEditorProjectParser.cpp

@ -9,6 +9,7 @@
#include "storm/exceptions/UnexpectedException.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/utility/macros.h"
namespace {
@ -22,17 +23,27 @@ namespace {
namespace storm {
namespace parser {
GreatSpnEditorProjectParser::GreatSpnEditorProjectParser(std::string const& constantDefinitionString) : manager(std::make_shared<storm::expressions::ExpressionManager>()) {
if (constantDefinitionString != "") {
std::vector<std::string> constDefs;
boost::split( constDefs, constantDefinitionString, boost::is_any_of(","));
for (auto const& pair : constDefs) {
std::vector<std::string> keyvaluepair;
boost::split( keyvaluepair, pair, boost::is_any_of("="));
STORM_LOG_THROW(keyvaluepair.size() == 2, storm::exceptions::WrongFormatException, "Expected a constant definition of the form N=42 but got " << pair);
constantDefinitions.emplace(keyvaluepair.at(0), keyvaluepair.at(1));
}
}
}
storm::gspn::GSPN* GreatSpnEditorProjectParser::parse(xercesc::DOMElement const* elementRoot) {
if (storm::adapters::XMLtoString(elementRoot->getTagName()) == "project") {
traverseProjectElement(elementRoot);
return builder.buildGspn();
return builder.buildGspn(manager, constantsSubstitution);
} else {
// If the top-level node is not a "pnml" or "" node, then throw an exception.
STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Failed to identify the root element.\n");
}
}
void GreatSpnEditorProjectParser::traverseProjectElement(xercesc::DOMNode const* const node) {
@ -118,6 +129,25 @@ namespace storm {
}
// traverse children
// First pass: find constant definitions
constantsSubstitution.clear();
expressionParser = std::make_shared<storm::parser::ExpressionParser>(*manager);
std::unordered_map<std::string, storm::expressions::Expression> identifierMapping;
expressionParser->setIdentifierMapping(identifierMapping);
for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) {
auto child = node->getChildNodes()->item(i);
auto name = storm::adapters::getName(child);
if (name.compare("constant") == 0 || name.compare("template") == 0) {
traverseConstantOrTemplateElement(child);
}
}
// Update the expression parser to make the newly created variables known to it
expressionParser = std::make_shared<storm::parser::ExpressionParser>(*manager);
for (auto const& var : manager->getVariables()) {
identifierMapping.emplace(var.getName(), var.getExpression());
}
expressionParser->setIdentifierMapping(identifierMapping);
// Second pass: traverse other children
for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) {
auto child = node->getChildNodes()->item(i);
auto name = storm::adapters::getName(child);
@ -126,6 +156,8 @@ namespace storm {
traversePlaceElement(child);
} else if(name.compare("transition") == 0) {
traverseTransitionElement(child);
} else if(name.compare("constant") == 0 || name.compare("template") == 0) {
// Ignore constant def in second pass
} else if (isOnlyWhitespace(name)) {
// ignore node (contains only whitespace)
} else {
@ -136,6 +168,70 @@ namespace storm {
}
}
void GreatSpnEditorProjectParser::traverseConstantOrTemplateElement(xercesc::DOMNode const* const node) {
std::string identifier;
storm::expressions::Type type;
std::string valueStr = "";
// traverse attributes
for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) {
auto attr = node->getAttributes()->item(i);
auto name = storm::adapters::getName(attr);
if (name.compare("name") == 0) {
identifier = storm::adapters::XMLtoString(attr->getNodeValue());
} else if (name.compare("consttype") == 0 || name.compare("type") == 0) {
if (storm::adapters::XMLtoString(attr->getNodeValue()).compare("REAL") == 0) {
type = manager->getRationalType();
} else if (storm::adapters::XMLtoString(attr->getNodeValue()).compare("INTEGER") == 0) {
type = manager->getIntegerType();
} else {
STORM_PRINT_AND_LOG("Unknown consttype: " << storm::adapters::XMLtoString(attr->getNodeValue()) << std::endl);
}
} else if (name.compare("value") == 0) {
valueStr = storm::adapters::XMLtoString(attr->getNodeValue());
} else if ((name == "x") || (name == "y")) {
// Ignore
} else {
// Found node or attribute which is at the moment not handled by this parser.
// Notify the user and continue the parsing.
STORM_PRINT_AND_LOG("unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) + "): " + name + "\n");
}
}
STORM_LOG_THROW(!manager->hasVariable(identifier), storm::exceptions::NotSupportedException, "Multiple definitions of constant '" << identifier << "' were found.");
if (valueStr == "") {
auto constDef = constantDefinitions.find(identifier);
STORM_LOG_THROW(constDef != constantDefinitions.end(), storm::exceptions::NotSupportedException, "Constant '" << identifier << "' has no value defined.");
valueStr = constDef->second;
}
storm::expressions::Variable var;
if (type.isRationalType()) {
var = manager->declareRationalVariable(identifier);
expressionParser->setAcceptDoubleLiterals(true);
} else if (type.isIntegerType()) {
var = manager->declareIntegerVariable(identifier);
expressionParser->setAcceptDoubleLiterals(false);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unknown type of constant" << type << ".");
}
constantsSubstitution.emplace(var, expressionParser->parseFromString(valueStr));
// traverse children
for (uint_fast64_t i = 0; i < node->getChildNodes()->getLength(); ++i) {
auto child = node->getChildNodes()->item(i);
auto name = storm::adapters::getName(child);
if (isOnlyWhitespace(name)) {
// ignore node (contains only whitespace)
} else {
// Found node or attribute which is at the moment nod handled by this parser.
// Notify the user and continue the parsing.
STORM_PRINT_AND_LOG("unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) + "): " + name + "\n");
}
}
}
void GreatSpnEditorProjectParser::traverseEdgesElement(xercesc::DOMNode const* const node) {
// traverse attributes
for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) {
@ -187,7 +283,7 @@ namespace storm {
if (name.compare("name") == 0) {
placeName = storm::adapters::XMLtoString(attr->getNodeValue());
} else if (name.compare("marking") == 0) {
initialTokens = std::stoull(storm::adapters::XMLtoString(attr->getNodeValue()));
initialTokens = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
} else if (ignorePlaceAttribute(name)) {
// ignore node
} else {
@ -217,7 +313,7 @@ namespace storm {
bool ignoreTransitionAttribute(std::string const& name) {
// TODO we should probably not ignore x-servers but check that it is 0.5.
if ((name == "label-x") || (name == "label-y") || (name == "x") || (name == "y") || (name == "nservers-x")) {
if ((name == "label-x") || (name == "label-y") || (name == "x") || (name == "y") || (name == "nservers-x") || (name == "delay-x") || (name == "delay-y") || (name == "rotation")) {
return true;
}
return false;
@ -227,6 +323,9 @@ namespace storm {
std::string transitionName;
bool immediateTransition;
double rate = 1.0; // The default rate in GreatSPN.
double weight = 1.0; // The default weight in GreatSpn
uint64_t priority = 1; // The default priority in GreatSpn
boost::optional<uint64_t> numServers;
// traverse attributes
for (uint_fast64_t i = 0; i < node->getAttributes()->getLength(); ++i) {
@ -238,11 +337,26 @@ namespace storm {
} else if (name.compare("type") == 0) {
if (storm::adapters::XMLtoString(attr->getNodeValue()).compare("EXP") == 0) {
immediateTransition = false;
} else {
} else if (storm::adapters::XMLtoString(attr->getNodeValue()).compare("IMM") == 0) {
immediateTransition = true;
} else {
STORM_PRINT_AND_LOG("unknown transition type: " << storm::adapters::XMLtoString(attr->getNodeValue()));
}
} else if(name.compare("delay") == 0) {
rate = std::stod(storm::adapters::XMLtoString(attr->getNodeValue()));
rate = parseReal(storm::adapters::XMLtoString(attr->getNodeValue()));
} else if(name.compare("weight") == 0) {
weight = parseReal(storm::adapters::XMLtoString(attr->getNodeValue()));
} else if(name.compare("priority") == 0) {
priority = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
} else if (name.compare("nservers") == 0) {
std::string nservers = storm::adapters::XMLtoString(attr->getNodeValue());
if (nservers == "Single") {
numServers = 1;
} else if (nservers == "Infinite") {
// Ignore this case as we assume infinite by default (similar to GreatSpn)
} else {
numServers = parseInt(nservers);
}
} else if (ignoreTransitionAttribute(name)) {
// ignore node
} else {
@ -254,9 +368,9 @@ namespace storm {
}
if (immediateTransition) {
builder.addImmediateTransition(0, 0, transitionName);
builder.addImmediateTransition(priority, weight, transitionName);
} else {
builder.addTimedTransition(0, rate, transitionName);
builder.addTimedTransition(0, rate, numServers, transitionName);
}
// traverse children
@ -303,10 +417,10 @@ namespace storm {
head = storm::adapters::XMLtoString(attr->getNodeValue());
} else if (name.compare("tail") == 0) {
tail = storm::adapters::XMLtoString(attr->getNodeValue());
} else if (name.compare("kind") == 0) {
} else if (name.compare("kind") == 0 || name.compare("type") == 0) {
kind = storm::adapters::XMLtoString(attr->getNodeValue());
} else if (name.compare("mult") == 0) {
mult = std::stoull(storm::adapters::XMLtoString(attr->getNodeValue()));
mult = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
} else if (ignoreArcAttribute(name)) {
// ignore node
} else {
@ -349,6 +463,21 @@ namespace storm {
}
}
int64_t GreatSpnEditorProjectParser::parseInt(std::string str) {
expressionParser->setAcceptDoubleLiterals(false);
auto expr = expressionParser->parseFromString(str).substitute(constantsSubstitution);
STORM_LOG_ASSERT(!expr.containsVariables(), "Can not evaluate expression " << str << " as it contains undefined variables.");
return expr.evaluateAsInt();
}
double GreatSpnEditorProjectParser::parseReal(std::string str) {
expressionParser->setAcceptDoubleLiterals(true);
auto expr = expressionParser->parseFromString(str).substitute(constantsSubstitution);
STORM_LOG_ASSERT(!expr.containsVariables(), "Can not evaluate expression " << str << " as it contains undefined variables.");
return expr.evaluateAsDouble();
}
}
}
#endif

13
src/storm-gspn/parser/GreatSpnEditorProjectParser.h

@ -7,6 +7,9 @@
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm-parsers/parser/ExpressionParser.h"
#include "storm-gspn/storage/gspn/GSPN.h"
#include "storm-gspn/storage/gspn/GspnBuilder.h"
@ -17,6 +20,8 @@ namespace storm {
public:
GreatSpnEditorProjectParser(std::string const& constantDefinitionString);
/*!
* Parses the given file into the GSPN.
*
@ -31,14 +36,20 @@ namespace storm {
void traverseNodesElement(xercesc::DOMNode const* const node);
void traverseEdgesElement(xercesc::DOMNode const* const node);
void traverseConstantOrTemplateElement(xercesc::DOMNode const* const node);
void traversePlaceElement(xercesc::DOMNode const* const node);
void traverseTransitionElement(xercesc::DOMNode const* const node);
void traverseArcElement(xercesc::DOMNode const* const node);
int64_t parseInt(std::string str);
double parseReal(std::string str);
// the constructed gspn
storm::gspn::GspnBuilder builder;
std::shared_ptr<storm::expressions::ExpressionManager> manager;
std::shared_ptr<storm::parser::ExpressionParser> expressionParser;
std::unordered_map<std::string, std::string> constantDefinitions;
std::map<storm::expressions::Variable, storm::expressions::Expression> constantsSubstitution;
};
}
}

5
src/storm-gspn/parser/GspnParser.cpp

@ -12,7 +12,7 @@
namespace storm {
namespace parser {
storm::gspn::GSPN* GspnParser::parse(std::string const& filename) {
storm::gspn::GSPN* GspnParser::parse(std::string const& filename, std::string const& constantDefinitions) {
#ifdef STORM_HAVE_XERCES
// initialize xercesc
try {
@ -62,10 +62,11 @@ namespace storm {
xercesc::DOMElement* elementRoot = parser->getDocument()->getDocumentElement();
if (storm::adapters::XMLtoString(elementRoot->getTagName()) == "pnml") {
STORM_LOG_WARN_COND(constantDefinitions == "", "Constant definitions for pnml files are currently not supported.");
PnmlParser p;
return p.parse(elementRoot);
} else if (storm::adapters::XMLtoString(elementRoot->getTagName()) == "project") {
GreatSpnEditorProjectParser p;
GreatSpnEditorProjectParser p(constantDefinitions);
return p.parse(elementRoot);
} else {
// If the top-level node is not a "pnml" or "" node, then throw an exception.

2
src/storm-gspn/parser/GspnParser.h

@ -4,7 +4,7 @@ namespace storm {
namespace parser {
class GspnParser {
public:
static storm::gspn::GSPN* parse(std::string const& filename);
static storm::gspn::GSPN* parse(std::string const& filename, std::string const& constantDefinitions = "");
};
}
}

17
src/storm-gspn/settings/modules/GSPNExportSettings.cpp

@ -1,5 +1,4 @@
#include "storm-gspn/settings/modules/GSPNExportSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/SettingMemento.h"
@ -20,6 +19,8 @@ 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::writeToJaniOptionName = "to-jani";
const std::string GSPNExportSettings::addJaniPropertiesOptionName = "addprops";
const std::string GSPNExportSettings::writeStatsOptionName = "to-stats";
const std::string GSPNExportSettings::displayStatsOptionName = "show-stats";
@ -31,6 +32,8 @@ namespace storm {
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, writeToJaniOptionName, false, "Destination for the jani output").addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, addJaniPropertiesOptionName, false, "If set, a set of standard properties is added to the exported jani model.").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());
}
@ -67,6 +70,18 @@ namespace storm {
return this->getOption(writeToJsonOptionName).getArgumentByName("filename").getValueAsString();
}
bool GSPNExportSettings::isWriteToJaniSet() const {
return this->getOption(writeToJaniOptionName).getHasOptionBeenSet();
}
std::string GSPNExportSettings::getWriteToJaniFilename() const {
return this->getOption(writeToJaniOptionName).getArgumentByName("filename").getValueAsString();
}
bool GSPNExportSettings::isAddJaniPropertiesSet() const {
return this->getOption(addJaniPropertiesOptionName).getHasOptionBeenSet();
}
bool GSPNExportSettings::isDisplayStatsSet() const {
return this->getOption(displayStatsOptionName).getHasOptionBeenSet();
}

17
src/storm-gspn/settings/modules/GSPNExportSettings.h

@ -10,7 +10,7 @@ namespace storm {
class GSPNExportSettings : public ModuleSettings {
public:
/*!
* Creates a new JaniExport setting
* Creates a new GSPNExport setting
*/
GSPNExportSettings();
@ -45,6 +45,19 @@ namespace storm {
*/
std::string getWriteToJsonFilename() const;
bool isWriteToJaniSet() const;
/**
*
*/
std::string getWriteToJaniFilename() const;
/*!
* Returns whether a set of standard properties is to be added when exporting to jani
*/
bool isAddJaniPropertiesSet() const;
bool isDisplayStatsSet() const;
bool isWriteStatsToFileSet() const;
@ -62,6 +75,8 @@ namespace storm {
static const std::string writeToPnmlOptionName;
static const std::string writeToPnproOptionName;
static const std::string writeToJsonOptionName;
static const std::string writeToJaniOptionName;
static const std::string addJaniPropertiesOptionName;
static const std::string displayStatsOptionName;
static const std::string writeStatsOptionName;

37
src/storm-gspn/settings/modules/GSPNSettings.cpp

@ -16,16 +16,19 @@ namespace storm {
const std::string GSPNSettings::gspnFileOptionName = "gspnfile";
const std::string GSPNSettings::gspnFileOptionShortName = "gspn";
const std::string GSPNSettings::gspnToJaniOptionName = "to-jani";
const std::string GSPNSettings::gspnToJaniOptionShortName = "tj";
const std::string GSPNSettings::capacitiesFileOptionName = "capacitiesfile";
const std::string GSPNSettings::capacitiesFileOptionShortName = "capacities";
const std::string GSPNSettings::capacityOptionName = "capacity";
const std::string GSPNSettings::constantsOptionName = "constants";
const std::string GSPNSettings::constantsOptionShortName = "const";
GSPNSettings::GSPNSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, gspnFileOptionName, false, "Parses the GSPN.").setShortName(gspnFileOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, gspnToJaniOptionName, false, "Transform to JANI.").setShortName(gspnToJaniOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, capacitiesFileOptionName, false, "Capacaties as invariants for places.").setShortName(capacitiesFileOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, capacityOptionName, false, "Global capacity as invariants for all places.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("value", "capacity").addValidatorUnsignedInteger(ArgumentValidatorFactory::createUnsignedGreaterValidator(0)).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, constantsOptionName, false, "Specifies the constant replacements to use.").setShortName(constantsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("values", "A comma separated list of constants and their value, e.g. a=1,b=2,c=3.").setDefaultValueString("").build()).build());
}
bool GSPNSettings::isGspnFileSet() const {
@ -36,10 +39,6 @@ namespace storm {
return this->getOption(gspnFileOptionName).getArgumentByName("filename").getValueAsString();
}
bool GSPNSettings::isToJaniSet() const {
return this->getOption(gspnToJaniOptionName).getHasOptionBeenSet();
}
bool GSPNSettings::isCapacitiesFileSet() const {
return this->getOption(capacitiesFileOptionName).getHasOptionBeenSet();
}
@ -48,19 +47,37 @@ namespace storm {
return this->getOption(capacitiesFileOptionName).getArgumentByName("filename").getValueAsString();
}
bool GSPNSettings::isCapacitySet() const {
return this->getOption(capacityOptionName).getHasOptionBeenSet();
}
uint64_t GSPNSettings::getCapacity() const {
return this->getOption(capacityOptionName).getArgumentByName("value").getValueAsUnsignedInteger();
}
bool GSPNSettings::isConstantsSet() const {
return this->getOption(constantsOptionName).getHasOptionBeenSet();
}
std::string GSPNSettings::getConstantDefinitionString() const {
return this->getOption(constantsOptionName).getArgumentByName("values").getValueAsString();
}
void GSPNSettings::finalize() {
}
bool GSPNSettings::check() const {
if(!isGspnFileSet()) {
if(isToJaniSet()) {
return false;
}
if(isCapacitiesFileSet()) {
return false;
}
}
if (isCapacitiesFileSet() && isCapacitySet()) {
STORM_LOG_ERROR("Conflicting settings: Capacity file AND capacity was set.");
return false;
}
return true;
}
}

31
src/storm-gspn/settings/modules/GSPNSettings.h

@ -24,11 +24,6 @@ namespace storm {
*/
std::string getGspnFilename() const;
/**
* Whether the gspn should be transformed to Jani
*/
bool isToJaniSet() const;
/**
* Retrievew whether the pgcl file option was set
*/
@ -39,6 +34,26 @@ namespace storm {
*/
std::string getCapacitiesFilename() const;
/**
* Retrievew whether a global capacity was set
*/
bool isCapacitySet() const;
/**
* Retrieves the global capacity
*/
uint64_t getCapacity() const;
/*!
* Retrieves whether the constants ption was set.
*/
bool isConstantsSet() const;
/*!
* Retrieves the string that defines the constants of a gspn
*/
std::string getConstantDefinitionString() const;
bool check() const override;
void finalize() override;
@ -48,11 +63,11 @@ namespace storm {
private:
static const std::string gspnFileOptionName;
static const std::string gspnFileOptionShortName;
static const std::string gspnToJaniOptionName;
static const std::string gspnToJaniOptionShortName;
static const std::string capacitiesFileOptionName;
static const std::string capacitiesFileOptionShortName;
static const std::string capacityOptionName;
static const std::string constantsOptionName;
static const std::string constantsOptionShortName;
};
}
}

20
src/storm-gspn/storage/gspn/GSPN.cpp

@ -26,8 +26,8 @@ namespace storm {
return tId;
}
GSPN::GSPN(std::string const& name, std::vector<Place> const& places, std::vector<ImmediateTransition<WeightType>> const& itransitions, std::vector<TimedTransition<RateType>> const& ttransitions, std::vector<TransitionPartition> const& partitions, std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager)
: name(name), places(places), immediateTransitions(itransitions), timedTransitions(ttransitions), partitions(partitions), exprManager(exprManager)
GSPN::GSPN(std::string const& name, std::vector<Place> const& places, std::vector<ImmediateTransition<WeightType>> const& itransitions, std::vector<TimedTransition<RateType>> const& ttransitions, std::vector<TransitionPartition> const& partitions, std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantsSubstitution)
: name(name), places(places), immediateTransitions(itransitions), timedTransitions(ttransitions), partitions(partitions), exprManager(exprManager), constantsSubstitution(constantsSubstitution)
{
}
@ -134,12 +134,16 @@ namespace storm {
return getImmediateTransition(id);
}
std::shared_ptr<storm::expressions::ExpressionManager> const& GSPN::getExpressionManager() const {
return exprManager;
}
std::map<storm::expressions::Variable, storm::expressions::Expression> const& GSPN::getConstantsSubstitution() const {
return constantsSubstitution;
}
std::shared_ptr<storm::expressions::ExpressionManager> const& GSPN::getExpressionManager() const {
return exprManager;
}
void GSPN::setCapacities(std::unordered_map<std::string, uint64_t> const& mapping) {
void GSPN::setCapacities(std::unordered_map<std::string, uint64_t> const& mapping) {
for(auto const& entry : mapping) {
storm::gspn::Place* place = getPlace(entry.first);
STORM_LOG_THROW(place != nullptr, storm::exceptions::InvalidArgumentException, "No place with name " << entry.first);
@ -168,6 +172,7 @@ namespace storm {
for (auto& trans : this->getTimedTransitions()) {
outStream << "\t" << trans.getName() << " [label=\"" << trans.getName();
outStream << "(" << trans.getRate() << ")\"];" << std::endl;
STORM_LOG_WARN_COND(trans.hasSingleServerSemantics(), "Unable to export non-trivial transition semantics"); // TODO
}
// print arcs
@ -561,6 +566,7 @@ namespace storm {
// add timed transitions
for (const auto &trans : timedTransitions) {
STORM_LOG_WARN_COND(trans.hasInfiniteServerSemantics(), "Unable to export non-trivial transition semantics"); // TODO
stream << space2 << "<transition id=\"" << trans.getName() << "\">" << std::endl;
stream << space3 << "<rate>" << std::endl;
stream << space4 << "<value>" << trans.getRate() << "</value>" << std::endl;

11
src/storm-gspn/storage/gspn/GSPN.h

@ -32,7 +32,7 @@ namespace storm {
GSPN(std::string const& name, std::vector<Place> const& places, std::vector<ImmediateTransition<WeightType>> const& itransitions,
std::vector<TimedTransition<RateType>> const& ttransitions, std::vector<TransitionPartition> const& partitions, std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager);
std::vector<TimedTransition<RateType>> const& ttransitions, std::vector<TransitionPartition> const& partitions, std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantsSubstitution = std::map<storm::expressions::Variable, storm::expressions::Expression>());
/*!
* Returns the number of places in this gspn.
@ -145,8 +145,13 @@ namespace storm {
*/
std::shared_ptr<storm::expressions::ExpressionManager> const& getExpressionManager() const;
/*!
* Gets an assignment of occurring constants of the GSPN to their value
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> const& getConstantsSubstitution() const;
/**
* Set Capacities according to name->capacity map.
* Set Capacities of places according to name->capacity map.
*/
void setCapacities(std::unordered_map<std::string, uint64_t> const& mapping);
@ -217,6 +222,8 @@ namespace storm {
std::vector<storm::gspn::TransitionPartition> partitions;
std::shared_ptr<storm::expressions::ExpressionManager> exprManager;
std::map<storm::expressions::Variable, storm::expressions::Expression> constantsSubstitution;
// Layout information
mutable std::map<uint64_t, LayoutInfo> placeLayout;

24
src/storm-gspn/storage/gspn/GspnBuilder.cpp

@ -65,13 +65,22 @@ namespace storm {
return newId;
}
uint_fast64_t GspnBuilder::addTimedTransition(uint_fast64_t const &priority, double const &rate, std::string const& name) {
return addTimedTransition(priority, rate, 1, name);
}
uint_fast64_t GspnBuilder::addTimedTransition(uint_fast64_t const &priority, double const &rate, boost::optional<uint64_t> numServers, std::string const& name) {
auto trans = storm::gspn::TimedTransition<double>();
auto newId = GSPN::timedTransitionIdToTransitionId(timedTransitions.size());
trans.setName(name);
trans.setPriority(priority);
trans.setRate(rate);
if (numServers) {
trans.setKServerSemantics(numServers.get());
} else {
trans.setInfiniteServerSemantics();
}
trans.setID(newId);
timedTransitions.push_back(trans);
@ -162,8 +171,13 @@ namespace storm {
storm::gspn::GSPN* GspnBuilder::buildGspn() const {
std::shared_ptr<storm::expressions::ExpressionManager> exprManager(new storm::expressions::ExpressionManager());
storm::gspn::GSPN* GspnBuilder::buildGspn(std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantsSubstitution) const {
std::shared_ptr<storm::expressions::ExpressionManager> actualExprManager;
if (exprManager) {
actualExprManager = exprManager;
} else {
actualExprManager = std::make_shared<storm::expressions::ExpressionManager>();
}
std::vector<TransitionPartition> orderedPartitions;
for(auto const& priorityPartitions : partitions) {
@ -179,10 +193,10 @@ namespace storm {
}
std::reverse(orderedPartitions.begin(), orderedPartitions.end());
for(auto const& placeEntry : placeNames) {
exprManager->declareIntegerVariable(placeEntry.first, false);
actualExprManager->declareIntegerVariable(placeEntry.first, false);
}
GSPN* result = new GSPN(gspnName, places, immediateTransitions, timedTransitions, orderedPartitions, exprManager);
GSPN* result = new GSPN(gspnName, places, immediateTransitions, timedTransitions, orderedPartitions, actualExprManager, constantsSubstitution);
result->setTransitionLayoutInfo(transitionLayout);
result->setPlaceLayoutInfo(placeLayout);
return result;

15
src/storm-gspn/storage/gspn/GspnBuilder.h

@ -39,11 +39,20 @@ namespace storm {
/**
* Adds an timed transition to the gspn.
* The transition is assumed to have Single-Server-Semantics
* @param priority The priority for the transtion.
* @param weight The weight for the transition.
* @param rate The rate for the transition.
*/
uint_fast64_t addTimedTransition(uint_fast64_t const &priority, RateType const& rate, std::string const& name = "");
/**
* Adds an timed transition to the gspn.
* @param priority The priority for the transtion.
* @param rate The rate for the transition.
* @param numServers The number of servers this transition has (in case of K-Server semantics) or boost::none (in case of Infinite-Server-Semantics).
*/
uint_fast64_t addTimedTransition(uint_fast64_t const &priority, RateType const& rate, boost::optional<uint64_t> numServers, std::string const& name = "");
void setTransitionLayoutInfo(uint64_t transitionId, LayoutInfo const& layoutInfo);
@ -91,10 +100,10 @@ namespace storm {
/**
*
* @param exprManager The expression manager that will be associated with the new gspn. If this is nullptr, a new expressionmanager will be created.
* @return The gspn which is constructed by the builder.
*/
storm::gspn::GSPN* buildGspn() const;
storm::gspn::GSPN* buildGspn(std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = nullptr, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantsSubstitution = std::map<storm::expressions::Variable, storm::expressions::Expression>()) const;
private:
bool isImmediateTransitionId(uint64_t) const;
bool isTimedTransitionId(uint64_t) const;

11
src/storm-gspn/storage/gspn/GspnJsonExporter.cpp

@ -160,7 +160,16 @@ namespace storm {
data["name"] = transition.getName();
data["rate"] = transition.getRate();
data["priority"] = transition.getPriority();
if (!transition.hasSingleServerSemantics()) {
if (transition.hasInfiniteServerSemantics()) {
data["server-semantics"] = "infinite";
} else if (transition.hasKServerSemantics()) {
data["server-semantics"] = transition.getNumberOfServers();
} else {
STORM_LOG_WARN("Unable to export transition semantics.");
}
}
modernjson::json position;
position["x"] = x * scaleFactor;
position["y"] = y * scaleFactor;

47
src/storm-gspn/storage/gspn/TimedTransition.h

@ -1,12 +1,18 @@
#pragma once
#include "storm-gspn/storage/gspn/Transition.h"
#include "storm/exceptions/InvalidArgumentException.h"
namespace storm {
namespace gspn {
template <typename RateType>
class TimedTransition : public storm::gspn::Transition {
public:
TimedTransition() {
setSingleServerSemantics();
}
/*!
* Sets the rate of this transition to the given value.
*
@ -15,7 +21,43 @@ namespace storm {
void setRate(RateType const& rate) {
this->rate = rate;
}
/*!
* Sets the semantics of this transition
*/
void setKServerSemantics(uint64_t k) {
STORM_LOG_THROW(k>0, storm::exceptions::InvalidArgumentException, "Invalid Parameter for server semantics: 0");
nServers = k;
}
void setSingleServerSemantics() {
nServers = 1;
}
void setInfiniteServerSemantics() {
nServers = 0;
}
/*!
* Retrieves the semantics of this transition
*/
bool hasKServerSemantics() const {
return nServers > 0;
}
bool hasSingleServerSemantics() const {
return nServers == 1;
}
bool hasInfiniteServerSemantics() const {
return nServers == 0;
}
uint64_t getNumberOfServers() const {
STORM_LOG_ASSERT(hasKServerSemantics(), "Tried to get the number of servers of a timed transition although it does not have K-Server-Semantics.");
return nServers;
}
/*!
* Retrieves the rate of this transition.
*
@ -28,6 +70,9 @@ namespace storm {
private:
// the rate of the transition
RateType rate;
// the number of servers of this transition. 0 means infinite server semantics.
uint64_t nServers;
};
}
}

2
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)

256
src/storm-pars-cli/storm-pars.cpp

@ -15,6 +15,8 @@
#include "storm/utility/Stopwatch.h"
#include "storm/utility/macros.h"
#include "storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/settings/modules/IOSettings.h"
@ -29,7 +31,20 @@ namespace storm {
typedef typename storm::cli::SymbolicInput SymbolicInput;
template <typename ValueType>
struct SampleInformation {
SampleInformation(bool graphPreserving = false, bool exact = false) : graphPreserving(graphPreserving), exact(exact) {
// Intentionally left empty.
}
bool empty() const {
return cartesianProducts.empty();
}
std::vector<std::map<typename utility::parametric::VariableType<ValueType>::type, std::vector<typename utility::parametric::CoefficientType<ValueType>::type>>> cartesianProducts;
bool graphPreserving;
bool exact;
};
template <typename ValueType>
std::vector<storm::storage::ParameterRegion<ValueType>> parseRegions(std::shared_ptr<storm::models::ModelBase> const& model) {
@ -41,6 +56,76 @@ namespace storm {
return result;
}
template <typename ValueType>
SampleInformation<ValueType> parseSamples(std::shared_ptr<storm::models::ModelBase> const& model, std::string const& sampleString, bool graphPreserving) {
STORM_LOG_THROW(!model || model->isSparseModel(), storm::exceptions::NotSupportedException, "Sampling is only supported for sparse models.");
SampleInformation<ValueType> sampleInfo(graphPreserving);
if (sampleString.empty()) {
return sampleInfo;
}
// Get all parameters from the model.
std::set<typename utility::parametric::VariableType<ValueType>::type> modelParameters;
auto const& sparseModel = *model->as<storm::models::sparse::Model<ValueType>>();
modelParameters = storm::models::sparse::getProbabilityParameters(sparseModel);
auto rewParameters = storm::models::sparse::getRewardParameters(sparseModel);
modelParameters.insert(rewParameters.begin(), rewParameters.end());
std::vector<std::string> cartesianProducts;
boost::split(cartesianProducts, sampleString, boost::is_any_of(";"));
for (auto& product : cartesianProducts) {
boost::trim(product);
// Get the values string for each variable.
std::vector<std::string> valuesForVariables;
boost::split(valuesForVariables, product, boost::is_any_of(","));
for (auto& values : valuesForVariables) {
boost::trim(values);
}
std::set<typename utility::parametric::VariableType<ValueType>::type> encounteredParameters;
sampleInfo.cartesianProducts.emplace_back();
auto& newCartesianProduct = sampleInfo.cartesianProducts.back();
for (auto const& varValues : valuesForVariables) {
auto equalsPosition = varValues.find("=");
STORM_LOG_THROW(equalsPosition != varValues.npos, storm::exceptions::WrongFormatException, "Incorrect format of samples.");
std::string variableName = varValues.substr(0, equalsPosition);
boost::trim(variableName);
std::string values = varValues.substr(equalsPosition + 1);
boost::trim(values);
bool foundParameter = false;
typename utility::parametric::VariableType<ValueType>::type theParameter;
for (auto const& parameter : modelParameters) {
std::stringstream parameterStream;
parameterStream << parameter;
if (parameterStream.str() == variableName) {
foundParameter = true;
theParameter = parameter;
encounteredParameters.insert(parameter);
}
}
STORM_LOG_THROW(foundParameter, storm::exceptions::WrongFormatException, "Unknown parameter '" << variableName << "'.");
std::vector<std::string> splitValues;
boost::split(splitValues, values, boost::is_any_of(":"));
STORM_LOG_THROW(!splitValues.empty(), storm::exceptions::WrongFormatException, "Expecting at least one value per parameter.");
auto& list = newCartesianProduct[theParameter];
for (auto& value : splitValues) {
boost::trim(value);
list.push_back(storm::utility::convertNumber<typename utility::parametric::CoefficientType<ValueType>::type>(value));
}
}
STORM_LOG_THROW(encounteredParameters == modelParameters, storm::exceptions::WrongFormatException, "Variables for all parameters are required when providing samples.");
}
return sampleInfo;
}
template <typename ValueType>
std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessSparseModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
@ -106,9 +191,24 @@ namespace storm {
}
template<typename ValueType>
void printInitialStatesResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::jani::Property const& property, storm::utility::Stopwatch* watch = nullptr) {
void printInitialStatesResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::jani::Property const& property, storm::utility::Stopwatch* watch = nullptr, storm::utility::parametric::Valuation<ValueType> const* valuation = nullptr) {
if (result) {
STORM_PRINT_AND_LOG("Result (initial states): " << std::endl);
STORM_PRINT_AND_LOG("Result (initial states)");
if (valuation) {
bool first = true;
std::stringstream ss;
for (auto const& entry : *valuation) {
if (!first) {
ss << ", ";
} else {
first = false;
}
ss << entry.first << "=" << entry.second;
}
STORM_PRINT_AND_LOG(" for instance [" << ss.str() << "]");
}
STORM_PRINT_AND_LOG(": ")
auto const* regionCheckResult = dynamic_cast<storm::modelchecker::RegionCheckResult<ValueType> const*>(result.get());
if (regionCheckResult != nullptr) {
@ -132,7 +232,7 @@ namespace storm {
STORM_PRINT_AND_LOG(*result << std::endl);
}
if (watch) {
STORM_PRINT_AND_LOG("Time for model checking: " << *watch << "." << std::endl);
STORM_PRINT_AND_LOG("Time for model checking: " << *watch << "." << std::endl << std::endl);
}
} else {
STORM_PRINT_AND_LOG(" failed, property is unsupported by selected engine/settings." << std::endl);
@ -151,24 +251,118 @@ namespace storm {
}
}
template<template<typename, typename> class ModelCheckerType, typename ModelType, typename ValueType, typename SolveValueType = double>
void verifyPropertiesAtSamplePoints(ModelType const& model, SymbolicInput const& input, SampleInformation<ValueType> const& samples) {
// When samples are provided, we create an instantiation model checker.
ModelCheckerType<ModelType, SolveValueType> modelchecker(model);
for (auto const& property : input.properties) {
storm::cli::printModelCheckingProperty(property);
modelchecker.specifyFormula(storm::api::createTask<ValueType>(property.getRawFormula(), true));
modelchecker.setInstantiationsAreGraphPreserving(samples.graphPreserving);
storm::utility::parametric::Valuation<ValueType> valuation;
std::vector<typename utility::parametric::VariableType<ValueType>::type> parameters;
std::vector<typename std::vector<typename utility::parametric::CoefficientType<ValueType>::type>::const_iterator> iterators;
std::vector<typename std::vector<typename utility::parametric::CoefficientType<ValueType>::type>::const_iterator> iteratorEnds;
storm::utility::Stopwatch watch(true);
for (auto const& product : samples.cartesianProducts) {
parameters.clear();
iterators.clear();
iteratorEnds.clear();
for (auto const& entry : product) {
parameters.push_back(entry.first);
iterators.push_back(entry.second.cbegin());
iteratorEnds.push_back(entry.second.cend());
}
bool done = false;
while (!done) {
// Read off valuation.
for (uint64_t i = 0; i < parameters.size(); ++i) {
valuation[parameters[i]] = *iterators[i];
}
storm::utility::Stopwatch valuationWatch(true);
std::unique_ptr<storm::modelchecker::CheckResult> result = modelchecker.check(Environment(), valuation);
valuationWatch.stop();
if (result) {
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model.getInitialStates()));
}
printInitialStatesResult<ValueType>(result, property, &valuationWatch, &valuation);
for (uint64_t i = 0; i < parameters.size(); ++i) {
++iterators[i];
if (iterators[i] == iteratorEnds[i]) {
// Reset iterator and proceed to move next iterator.
iterators[i] = product.at(parameters[i]).cbegin();
// If the last iterator was removed, we are done.
if (i == parameters.size() - 1) {
done = true;
}
} else {
// If an iterator was moved but not reset, we have another valuation to check.
break;
}
}
}
}
watch.stop();
STORM_PRINT_AND_LOG("Overall time for sampling all instances: " << watch << std::endl << std::endl);
}
}
template <typename ValueType, typename SolveValueType = double>
void verifyPropertiesAtSamplePoints(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input, SampleInformation<ValueType> const& samples) {
if (model->isOfType(storm::models::ModelType::Dtmc)) {
verifyPropertiesAtSamplePoints<storm::modelchecker::SparseDtmcInstantiationModelChecker, storm::models::sparse::Dtmc<ValueType>, ValueType, SolveValueType>(*model->template as<storm::models::sparse::Dtmc<ValueType>>(), input, samples);
} else if (model->isOfType(storm::models::ModelType::Ctmc)) {
verifyPropertiesAtSamplePoints<storm::modelchecker::SparseCtmcInstantiationModelChecker, storm::models::sparse::Ctmc<ValueType>, ValueType, SolveValueType>(*model->template as<storm::models::sparse::Ctmc<ValueType>>(), input, samples);
} else if (model->isOfType(storm::models::ModelType::Ctmc)) {
verifyPropertiesAtSamplePoints<storm::modelchecker::SparseMdpInstantiationModelChecker, storm::models::sparse::Mdp<ValueType>, ValueType, SolveValueType>(*model->template as<storm::models::sparse::Mdp<ValueType>>(), input, samples);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Sampling is currently only supported for DTMCs, CTMCs and MDPs.");
}
}
template <typename ValueType>
void verifyPropertiesWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
verifyProperties<ValueType>(input.properties,
[&model] (std::shared_ptr<storm::logic::Formula const> const& formula) {
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithSparseEngine<ValueType>(model, storm::api::createTask<ValueType>(formula, true));
if (result) {
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates()));
}
return result;
},
[&model] (std::unique_ptr<storm::modelchecker::CheckResult> const& result) {
auto parametricSettings = storm::settings::getModule<storm::settings::modules::ParametricSettings>();
if (parametricSettings.exportResultToFile() && model->isOfType(storm::models::ModelType::Dtmc)) {
auto dtmc = model->template as<storm::models::sparse::Dtmc<ValueType>>();
boost::optional<ValueType> rationalFunction = result->asExplicitQuantitativeCheckResult<ValueType>()[*model->getInitialStates().begin()];
storm::api::exportParametricResultToFile(rationalFunction, storm::analysis::ConstraintCollector<ValueType>(*dtmc), parametricSettings.exportResultPath());
}
});
void verifyPropertiesWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input, SampleInformation<ValueType> const& samples) {
if (samples.empty()) {
verifyProperties<ValueType>(input.properties,
[&model] (std::shared_ptr<storm::logic::Formula const> const& formula) {
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithSparseEngine<ValueType>(model, storm::api::createTask<ValueType>(formula, true));
if (result) {
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates()));
}
return result;
},
[&model] (std::unique_ptr<storm::modelchecker::CheckResult> const& result) {
auto parametricSettings = storm::settings::getModule<storm::settings::modules::ParametricSettings>();
if (parametricSettings.exportResultToFile() && model->isOfType(storm::models::ModelType::Dtmc)) {
auto dtmc = model->template as<storm::models::sparse::Dtmc<ValueType>>();
boost::optional<ValueType> rationalFunction = result->asExplicitQuantitativeCheckResult<ValueType>()[*model->getInitialStates().begin()];
storm::api::exportParametricResultToFile(rationalFunction, storm::analysis::ConstraintCollector<ValueType>(*dtmc), parametricSettings.exportResultPath());
}
});
} else {
STORM_LOG_TRACE("Sampling the model at given points.");
if (samples.exact) {
verifyPropertiesAtSamplePoints<ValueType, storm::RationalNumber>(model, input, samples);
} else {
verifyPropertiesAtSamplePoints<ValueType, double>(model, input, samples);
}
}
}
template <typename ValueType>
@ -226,18 +420,18 @@ namespace storm {
}
template <typename ValueType>
void verifyWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input, std::vector<storm::storage::ParameterRegion<ValueType>> const& regions) {
void verifyWithSparseEngine(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input, std::vector<storm::storage::ParameterRegion<ValueType>> const& regions, SampleInformation<ValueType> const& samples) {
if (regions.empty()) {
storm::pars::verifyPropertiesWithSparseEngine(model, input);
storm::pars::verifyPropertiesWithSparseEngine(model, input, samples);
} else {
storm::pars::verifyRegionsWithSparseEngine(model, input, regions);
}
}
template <storm::dd::DdType DdType, typename ValueType>
void verifyParametricModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input, std::vector<storm::storage::ParameterRegion<ValueType>> const& regions) {
void verifyParametricModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input, std::vector<storm::storage::ParameterRegion<ValueType>> const& regions, SampleInformation<ValueType> const& samples) {
STORM_LOG_ASSERT(model->isSparseModel(), "Unexpected model type.");
storm::pars::verifyWithSparseEngine<ValueType>(model->as<storm::models::sparse::Model<ValueType>>(), input, regions);
storm::pars::verifyWithSparseEngine<ValueType>(model->as<storm::models::sparse::Model<ValueType>>(), input, regions, samples);
}
template <storm::dd::DdType DdType, typename ValueType>
@ -271,9 +465,13 @@ namespace storm {
}
std::vector<storm::storage::ParameterRegion<ValueType>> regions = parseRegions<ValueType>(model);
std::string samplesAsString = parSettings.getSamples();
SampleInformation<ValueType> samples;
if (!samplesAsString.empty()) {
samples = parseSamples<ValueType>(model, samplesAsString, parSettings.isSamplesAreGraphPreservingSet());
samples.exact = parSettings.isSampleExactSet();
}
if (model) {
storm::cli::exportModel<DdType, ValueType>(model, input);
}
@ -285,7 +483,7 @@ namespace storm {
}
if (model) {
verifyParametricModel<DdType, ValueType>(model, input, regions);
verifyParametricModel<DdType, ValueType>(model, input, regions, samples);
}
}

2
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)

27
src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp

@ -0,0 +1,27 @@
#include "storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h"
#include "storm/modelchecker/csl/SparseCtmcCslModelChecker.h"
#include "storm/exceptions/InvalidStateException.h"
namespace storm {
namespace modelchecker {
template <typename SparseModelType, typename ConstantType>
SparseCtmcInstantiationModelChecker<SparseModelType, ConstantType>::SparseCtmcInstantiationModelChecker(SparseModelType const& parametricModel) : SparseInstantiationModelChecker<SparseModelType, ConstantType>(parametricModel), modelInstantiator(parametricModel) {
//Intentionally left empty
}
template <typename SparseModelType, typename ConstantType>
std::unique_ptr<CheckResult> SparseCtmcInstantiationModelChecker<SparseModelType, ConstantType>::check(Environment const& env, storm::utility::parametric::Valuation<typename SparseModelType::ValueType> const& valuation) {
STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before.");
auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
storm::modelchecker::SparseCtmcCslModelChecker<storm::models::sparse::Ctmc<ConstantType>> modelChecker(instantiatedModel);
return modelChecker.check(env, *this->currentCheckTask);
}
template class SparseCtmcInstantiationModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>, double>;
template class SparseCtmcInstantiationModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>, storm::RationalNumber>;
}
}

28
src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h

@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <boost/optional.hpp>
#include "storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.h"
#include "storm-pars/utility/ModelInstantiator.h"
#include "storm/models/sparse/Dtmc.h"
#include "storm/models/sparse/StandardRewardModel.h"
#include "storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
namespace storm {
namespace modelchecker {
/*!
* Class to efficiently check a formula on a parametric model with different parameter instantiations.
*/
template <typename SparseModelType, typename ConstantType>
class SparseCtmcInstantiationModelChecker : public SparseInstantiationModelChecker<SparseModelType, ConstantType> {
public:
SparseCtmcInstantiationModelChecker(SparseModelType const& parametricModel);
virtual std::unique_ptr<CheckResult> check(Environment const& env, storm::utility::parametric::Valuation<typename SparseModelType::ValueType> const& valuation) override;
storm::utility::ModelInstantiator<SparseModelType, storm::models::sparse::Ctmc<ConstantType>> modelInstantiator;
};
}
}

6
src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp

@ -20,11 +20,11 @@ namespace storm {
std::unique_ptr<CheckResult> SparseDtmcInstantiationModelChecker<SparseModelType, ConstantType>::check(Environment const& env, storm::utility::parametric::Valuation<typename SparseModelType::ValueType> const& valuation) {
STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before.");
auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
STORM_LOG_ASSERT(instantiatedModel.getTransitionMatrix().isProbabilistic(), "Instantiated matrix is not probabilistic!");
STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(), storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic.");
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<ConstantType>> modelChecker(instantiatedModel);
// Check if there are some optimizations implemented for the specified property
if(this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) {
if (this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) {
return checkReachabilityProbabilityFormula(env, modelChecker);
} else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional().setRewardOperatorsAllowed(true).setReachabilityRewardFormulasAllowed(true).setOperatorAtTopLevelRequired(true).setNestedOperatorsAllowed(false))) {
return checkReachabilityRewardFormula(env, modelChecker);
@ -144,4 +144,4 @@ namespace storm {
template class SparseDtmcInstantiationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::RationalNumber>;
}
}
}

6
src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp

@ -2,6 +2,7 @@
#include "storm/adapters/RationalFunctionAdapter.h"
#include "storm/models/sparse/Dtmc.h"
#include "storm/models/sparse/Ctmc.h"
#include "storm/models/sparse/Mdp.h"
#include "storm/models/sparse/StandardRewardModel.h"
@ -12,10 +13,9 @@ namespace storm {
template <typename SparseModelType, typename ConstantType>
SparseInstantiationModelChecker<SparseModelType, ConstantType>::SparseInstantiationModelChecker(SparseModelType const& parametricModel) : parametricModel(parametricModel), instantiationsAreGraphPreserving(false) {
//Intentionally left empty
// Intentionally left empty
}
template <typename SparseModelType, typename ConstantType>
void SparseInstantiationModelChecker<SparseModelType, ConstantType>::specifyFormula(storm::modelchecker::CheckTask<storm::logic::Formula, typename SparseModelType::ValueType> const& checkTask) {
currentFormula = checkTask.getFormula().asSharedPointer();
@ -33,9 +33,11 @@ namespace storm {
}
template class SparseInstantiationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, double>;
template class SparseInstantiationModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>, double>;
template class SparseInstantiationModelChecker<storm::models::sparse::Mdp<storm::RationalFunction>, double>;
template class SparseInstantiationModelChecker<storm::models::sparse::Dtmc<storm::RationalFunction>, storm::RationalNumber>;
template class SparseInstantiationModelChecker<storm::models::sparse::Ctmc<storm::RationalFunction>, storm::RationalNumber>;
template class SparseInstantiationModelChecker<storm::models::sparse::Mdp<storm::RationalFunction>, storm::RationalNumber>;
}

2
src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp

@ -23,7 +23,7 @@ namespace storm {
std::unique_ptr<CheckResult> SparseMdpInstantiationModelChecker<SparseModelType, ConstantType>::check(Environment const& env, storm::utility::parametric::Valuation<typename SparseModelType::ValueType> const& valuation) {
STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before.");
auto const& instantiatedModel = modelInstantiator.instantiate(valuation);
STORM_LOG_ASSERT(instantiatedModel.getTransitionMatrix().isProbabilistic(), "Instantiated matrix is not probabilistic!");
STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(), storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic.");
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<ConstantType>> modelChecker(instantiatedModel);
// Check if there are some optimizations implemented for the specified property

4
src/storm-pars/settings/ParsSettings.cpp

@ -1,4 +1,3 @@
#include <storm/settings/modules/CounterexampleGeneratorSettings.h>
#include "storm-pars/settings/ParsSettings.h"
#include "storm-pars/settings/modules/ParametricSettings.h"
@ -21,7 +20,6 @@
#include "storm/settings/modules/GameSolverSettings.h"
#include "storm/settings/modules/BisimulationSettings.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"
@ -38,7 +36,6 @@ namespace storm {
storm::settings::addModule<storm::settings::modules::ParametricSettings>();
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>();
@ -51,7 +48,6 @@ namespace storm {
storm::settings::addModule<storm::settings::modules::GameSolverSettings>();
storm::settings::addModule<storm::settings::modules::BisimulationSettings>();
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>();
}

23
src/storm-pars/settings/modules/ParametricSettings.cpp

@ -18,13 +18,20 @@ namespace storm {
const std::string ParametricSettings::transformContinuousOptionName = "transformcontinuous";
const std::string ParametricSettings::transformContinuousShortOptionName = "tc";
const std::string ParametricSettings::onlyWellformednessConstraintsOptionName = "onlyconstraints";
const std::string ParametricSettings::samplesOptionName = "samples";
const std::string ParametricSettings::samplesGraphPreservingOptionName = "samples-graph-preserving";
const std::string ParametricSettings::sampleExactOptionName = "sample-exact";
ParametricSettings::ParametricSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, exportResultOptionName, false, "A path to a file where the parametric result should be saved.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("path", "the location.").addValidatorString(ArgumentValidatorFactory::createWritableFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, derivativesOptionName, false, "Sets whether to generate the derivatives of the resulting rational function.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, transformContinuousOptionName, false, "Sets whether to transform a continuous time input model to a discrete time model.").setShortName(transformContinuousShortOptionName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, onlyWellformednessConstraintsOptionName, false, "Sets whether you only want to obtain the wellformedness constraints").build());
this->addOption(storm::settings::OptionBuilder(moduleName, samplesOptionName, false, "The points at which to sample the model.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("samples", "The samples are semicolon-separated entries of the form 'Var1=Val1:Val2:...:Valk,Var2=... that span the sample spaces.").setDefaultValueString("").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, samplesGraphPreservingOptionName, false, "Sets whether it can be assumed that the samples are graph-preserving.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, sampleExactOptionName, false, "Sets whether to sample using exact arithmetic.").build());
}
bool ParametricSettings::exportResultToFile() const {
@ -46,7 +53,19 @@ namespace storm {
bool ParametricSettings::onlyObtainConstraints() const {
return this->getOption(onlyWellformednessConstraintsOptionName).getHasOptionBeenSet();
}
std::string ParametricSettings::getSamples() const {
return this->getOption(samplesOptionName).getArgumentByName("samples").getValueAsString();
}
bool ParametricSettings::isSamplesAreGraphPreservingSet() const {
return this->getOption(samplesGraphPreservingOptionName).getHasOptionBeenSet();
}
bool ParametricSettings::isSampleExactSet() const {
return this->getOption(sampleExactOptionName).getHasOptionBeenSet();
}
} // namespace modules
} // namespace settings
} // namespace storm

20
src/storm-pars/settings/modules/ParametricSettings.h

@ -47,6 +47,23 @@ namespace storm {
*/
bool onlyObtainConstraints() const;
/*!
* Retrieves the samples as a comma-separated list of samples for each (relevant) variable, where the
* samples are colon-separated values. For example, 'N=1:2:3,K=2:4' means that N takes the values 1 to
* 3 and K either 2 or 4.
*/
std::string getSamples() const;
/*!
* Retrieves whether the samples are graph preserving.
*/
bool isSamplesAreGraphPreservingSet() const;
/*!
* Retrieves whether samples are to be computed exactly.
*/
bool isSampleExactSet() const;
const static std::string moduleName;
private:
@ -55,6 +72,9 @@ namespace storm {
const static std::string transformContinuousOptionName;
const static std::string transformContinuousShortOptionName;
const static std::string onlyWellformednessConstraintsOptionName;
const static std::string samplesOptionName;
const static std::string samplesGraphPreservingOptionName;
const static std::string sampleExactOptionName;
};
} // namespace modules

42
src/storm-parsers/CMakeLists.txt

@ -0,0 +1,42 @@
file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-parsers/*.h ${PROJECT_SOURCE_DIR}/src/storm-parsers/*.cpp)
register_source_groups_from_filestructure("${ALL_FILES}" storm-parsers)
file(GLOB_RECURSE STORM_PARSER_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-parsers/*/*.cpp)
file(GLOB_RECURSE STORM_PARSER_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-parsers/*/*.h)
# Disable Debug compiler flags for PrismParser to lessen memory consumption during compilation
SET_SOURCE_FILES_PROPERTIES(${PROJECT_SOURCE_DIR}/src/storm-parsers/parser/PrismParser.cpp PROPERTIES COMPILE_FLAGS -g0)
# Create storm-parsers.
add_library(storm-parsers SHARED ${STORM_PARSER_SOURCES} ${STORM_PARSER_HEADERS})
# Remove define symbol for shared libstorm.
set_target_properties(storm-parsers PROPERTIES DEFINE_SYMBOL "")
#add_dependencies(storm resources)
list(APPEND STORM_TARGETS storm-parsers)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-parsers PUBLIC storm)
# Install storm headers to include directory.
foreach(HEADER ${STORM_PARSER_HEADERS})
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/src/?" "" RELATIVE_HEADER_PATH ${HEADER})
string(REGEX MATCH "(.*)[/\\]" RELATIVE_DIRECTORY ${RELATIVE_HEADER_PATH})
string(REGEX REPLACE "${RELATIVE_DIRECTORY}/?" "" HEADER_FILENAME ${RELATIVE_HEADER_PATH})
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy ${HEADER} ${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}
DEPENDS ${HEADER}
)
list(APPEND STORM_PARSER_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}")
endforeach()
add_custom_target(copy_storm_parser_headers DEPENDS ${STORM_PARSER_OUTPUT_HEADERS} ${STORM_PARSER_HEADERS})
add_dependencies(storm-parsers copy_storm_parser_headers)
# installation
install(TARGETS storm-parsers EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

6
src/storm/api/model_descriptions.cpp → src/storm-parsers/api/model_descriptions.cpp

@ -1,7 +1,7 @@
#include "storm/api/model_descriptions.h"
#include "model_descriptions.h"
#include "storm/parser/PrismParser.h"
#include "storm/parser/JaniParser.h"
#include "storm-parsers/parser/PrismParser.h"
#include "storm-parsers/parser/JaniParser.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Property.h"

0
src/storm/api/model_descriptions.h → src/storm-parsers/api/model_descriptions.h

71
src/storm-parsers/api/properties.cpp

@ -0,0 +1,71 @@
#include "storm-parsers/api/properties.h"
#include "storm-parsers/parser/FormulaParser.h"
#include "storm/api/properties.h"
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/storage/prism/Program.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Property.h"
#include "storm/logic/Formula.h"
#include "storm/utility/cli.h"
namespace storm {
namespace api {
boost::optional <std::set<std::string>> parsePropertyFilter(std::string const &propertyFilter) {
if (propertyFilter == "all") {
return boost::none;
}
std::vector <std::string> propertyNames = storm::utility::cli::parseCommaSeparatedStrings(propertyFilter);
std::set <std::string> propertyNameSet(propertyNames.begin(), propertyNames.end());
return propertyNameSet;
}
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 is a file, we parse it as a file, otherwise we assume it's a property.
std::vector <storm::jani::Property> properties;
if (std::ifstream(inputString).good()) {
STORM_LOG_INFO("Loading properties from file: " << inputString << std::endl);
properties = formulaParser.parseFromFile(inputString);
} else {
properties = formulaParser.parseFromString(inputString);
}
return filterProperties(properties, propertyFilter);
}
std::vector <storm::jani::Property> parseProperties(std::string const &inputString, boost::optional <std::set<std::string>> const &propertyFilter) {
auto exprManager = std::make_shared<storm::expressions::ExpressionManager>();
storm::parser::FormulaParser formulaParser(exprManager);
return parseProperties(formulaParser, inputString, propertyFilter);
}
std::vector <storm::jani::Property> parsePropertiesForJaniModel(std::string const &inputString, storm::jani::Model const &model, boost::optional <std::set<std::string>> const &propertyFilter) {
storm::parser::FormulaParser formulaParser(model.getManager().getSharedPointer());
auto formulas = parseProperties(formulaParser, inputString, propertyFilter);
return substituteConstantsInProperties(formulas, model.getConstantsSubstitution());
}
std::vector <storm::jani::Property> parsePropertiesForPrismProgram(std::string const &inputString, storm::prism::Program const &program, boost::optional <std::set<std::string>> const &propertyFilter) {
storm::parser::FormulaParser formulaParser(program);
auto formulas = parseProperties(formulaParser, inputString, propertyFilter);
return substituteConstantsInProperties(formulas, program.getConstantsSubstitution());
}
std::vector <storm::jani::Property> parsePropertiesForSymbolicModelDescription(std::string const &inputString, storm::storage::SymbolicModelDescription const &modelDescription, boost::optional <std::set<std::string>> const &propertyFilter) {
std::vector <storm::jani::Property> result;
if (modelDescription.isPrismProgram()) {
result = storm::api::parsePropertiesForPrismProgram(inputString, modelDescription.asPrismProgram(), propertyFilter);
} else {
STORM_LOG_ASSERT(modelDescription.isJaniModel(), "Unknown model description type.");
result = storm::api::parsePropertiesForJaniModel(inputString, modelDescription.asJaniModel(), propertyFilter);
}
return result;
}
}
}

43
src/storm-parsers/api/properties.h

@ -0,0 +1,43 @@
#pragma once
#include <string>
#include <set>
#include <map>
#include <vector>
#include <memory>
#include <boost/optional.hpp>
namespace storm {
namespace parser {
class FormulaParser;
}
namespace jani {
class Property;
class Model;
}
namespace expressions {
class Variable;
class Expression;
}
namespace prism {
class Program;
}
namespace storage {
class SymbolicModelDescription;
}
namespace logic {
class Formula;
}
namespace api {
boost::optional<std::set<std::string>> parsePropertyFilter(std::string const& propertyFilter);
// Parsing properties.
std::vector<storm::jani::Property> parseProperties(storm::parser::FormulaParser& formulaParser, std::string const& inputString, boost::optional<std::set<std::string>> const& propertyFilter = boost::none);
std::vector<storm::jani::Property> parseProperties(std::string const& inputString, boost::optional<std::set<std::string>> const& propertyFilter = boost::none);
std::vector<storm::jani::Property> parsePropertiesForPrismProgram(std::string const& inputString, storm::prism::Program const& program, boost::optional<std::set<std::string>> const& propertyFilter = boost::none);
std::vector<storm::jani::Property> parsePropertiesForJaniModel(std::string const& inputString, storm::jani::Model const& model, boost::optional<std::set<std::string>> const& propertyFilter = boost::none);
std::vector<storm::jani::Property> parsePropertiesForSymbolicModelDescription(std::string const& inputString, storm::storage::SymbolicModelDescription const& modelDescription, boost::optional<std::set<std::string>> const& propertyFilter = boost::none);
}
}

4
src/storm-parsers/api/storm-parsers.h

@ -0,0 +1,4 @@
#pragma once
#include "storm-parsers/api/model_descriptions.h"
#include "storm-parsers/api/properties.h"

4
src/storm/parser/AtomicPropositionLabelingParser.cpp → src/storm-parsers/parser/AtomicPropositionLabelingParser.cpp

@ -5,14 +5,14 @@
* Author: Gereon Kremer
*/
#include "storm/parser/AtomicPropositionLabelingParser.h"
#include "storm-parsers/parser/AtomicPropositionLabelingParser.h"
#include <cstring>
#include <string>
#include <iostream>
#include "storm/utility/cstring.h"
#include "storm/parser/MappedFile.h"
#include "storm-parsers/parser/MappedFile.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/exceptions/FileIoException.h"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save