diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index b20410928d..1c7d6d61de 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -13,3 +13,4 @@ e58679da05190fe064ca063b07ac56428162a8fb 634053fe63e39b80fff2355bb4e5b50839cd1e68 a177724097d3f807a6b8950b1cd378c34d040d1b 5016fac7d4014f1113c3d410a65aa5b39a74be64 +c0dae886d1e8283a783ab884f64b443e436c106b diff --git a/.github/workflows/buildtest.yml b/.github/workflows/buildtest.yml index 4f2a1cb8f3..1f3f6aed9b 100644 --- a/.github/workflows/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -11,8 +11,8 @@ on: pull_request: env: - # GitHub runners currently have two cores - NR_JOBS: "2" + # GitHub runners currently have 4 cores + NR_JOBS: "4" jobs: # Perform in-depth tests with different configurations @@ -185,7 +185,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - distro: ["debian-11", "debian-12", "ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"] + distro: ["debian-12", "ubuntu-22.04", "ubuntu-24.04"] buildType: ["Release"] steps: - name: Git clone diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml index f4d1248c4a..bcc24a0333 100644 --- a/.github/workflows/doxygen.yml +++ b/.github/workflows/doxygen.yml @@ -12,8 +12,8 @@ env: BASE_IMG: "movesrwth/carl-storm:ci-release" STORM_GIT_URL: "${{ github.server_url }}/${{ github.repository }}.git" STORM_BRANCH: "master" - # github runners currently have two cores - NR_JOBS: "2" + # GitHub runners currently have 4 cores + NR_JOBS: "4" jobs: @@ -25,7 +25,7 @@ jobs: if: github.repository_owner == 'moves-rwth' steps: - name: Init Docker - run: sudo docker run -d -it --name storm --privileged ${BASE_IMG} + run: sudo docker run -d -it --name storm ${BASE_IMG} # We should not do partial updates :/ # but we need to install some dependencies diff --git a/.github/workflows/formatapply.yml b/.github/workflows/formatapply.yml index 2092d5f0f0..b9b70bfdc5 100644 --- a/.github/workflows/formatapply.yml +++ b/.github/workflows/formatapply.yml @@ -9,16 +9,16 @@ jobs: steps: - uses: actions/checkout@v4 # apply the formatting twice as a workaround for a clang-format bug - - uses: DoozyX/clang-format-lint-action@v0.17 + - uses: DoozyX/clang-format-lint-action@v0.18 with: source: './src' - clangFormatVersion: 17 + clangFormatVersion: 18 style: file inplace: True - - uses: DoozyX/clang-format-lint-action@v0.17 + - uses: DoozyX/clang-format-lint-action@v0.18 with: source: './src' - clangFormatVersion: 17 + clangFormatVersion: 18 style: file inplace: True - name: Commit Formatting diff --git a/.github/workflows/formatcheck.yml b/.github/workflows/formatcheck.yml index 6731e8e1d8..4c8db54ff4 100644 --- a/.github/workflows/formatcheck.yml +++ b/.github/workflows/formatcheck.yml @@ -8,8 +8,8 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: DoozyX/clang-format-lint-action@v0.17 + - uses: DoozyX/clang-format-lint-action@v0.18 with: source: './src' - clangFormatVersion: 17 + clangFormatVersion: 18 style: file diff --git a/.github/workflows/release_docker.yml b/.github/workflows/release_docker.yml index e18819011f..18f1178f09 100644 --- a/.github/workflows/release_docker.yml +++ b/.github/workflows/release_docker.yml @@ -10,8 +10,8 @@ on: default: 'x.y.z' env: - # GitHub runners currently have two cores - NR_JOBS: "2" + # GitHub runners currently have 4 cores + NR_JOBS: "4" jobs: deploy: diff --git a/CHANGELOG.md b/CHANGELOG.md index b970d4c8b8..ed120c416f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,21 +1,42 @@ - Changelog ============== This changelog lists only the most important changes. Smaller (bug)fixes as well as non-mature features are not part of the changelog. The releases of major and minor versions contain an overview of changes since the last major/minor update. -Version 1.8.x +Version 1.9.x ------------- -## Version 1.8.2 +## Version 1.9.0 (2024/08) +- Improved expected visiting times (EVTs) and steady state distribution computations. +- Support for interval-based models. +- Robust VI. +- Significantly improved compilation times. +- Support for logarithm expressions in PRISM and JANI. +- Support for sin and cos operators, and PI and Euler constants in JANI parser. +- Extraction of schedulers for minimal expected total rewards. +- More efficient MEC and SCC decompositions. +- Revised LP encoding for multi-objective verification under simple strategies. +- Added CLI option `--permute` to re-order the states after building. +- Added CLI option `--build:state limit ` to limit the number of explored states. - Print all linked libraries when using `--version`. -- Removed HyPro as dependency. +- Removed support for HyPro and Cuda. +- Moved gamebased-ar to own library. +- Various bug fixes. - `storm-conv`: Removed option `--stdout`. -- `storm-pars`: completely reworked the command-line interface (and partially the c++ API). +- `storm-dft`: Fixes and improvements for DFT symmetries and DFT simulation. +- `storm-pars`: Completely reworked the command-line interface (and partially the C++ API). +- `storm-pars`: "Time travelling" optimization. +- `storm-pgcl`: Removed the library. - Developer: Require at least CMake version 3.15. - Developer: Moved `storm-config.h.in` into `src` directory. -- Developer: Use Dockerfile in CI. +- Developer: Use various Dockerfiles in CI. +- Developer: Revised includes and use pre-compiled headers. +- Developer: Fixed various compiler warnings. + + +Version 1.8.x +------------- ## Version 1.8.1 (2023/06) - Workaround for issue with Boost >= 1.81 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b7804176d..2eb4743a44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required (VERSION 3.16) +cmake_minimum_required (VERSION 3.22) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) # Set project name project (storm CXX C) @@ -157,21 +157,25 @@ set(STORM_TEST_RESOURCES_DIR "${PROJECT_SOURCE_DIR}/resources/examples/testfiles # Auto-detect operating system. set(MACOSX 0) set(LINUX 0) +set(APPLE_SILICON 0) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Mac OS set(OPERATING_SYSTEM "Mac OS") set(MACOSX 1) + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES arm64) + set(APPLE_SILICON 1) + endif() elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # Linux + # Linux set(OPERATING_SYSTEM "Linux") set(LINUX 1) elseif(WIN32) - # Assuming Windows. - set(OPERATING_SYSTEM "Windows") + # Assuming Windows. + set(OPERATING_SYSTEM "Windows") else() - message(WARNING "We are unsure about your operating system.") - set(OPERATING_SYSTEM "Linux") - set(LINUX 1) + message(WARNING "We are unsure about your operating system.") + set(OPERATING_SYSTEM "Linux") + set(LINUX 1) ENDIF() message(STATUS "Storm - Detected operating system ${OPERATING_SYSTEM}.") @@ -184,20 +188,12 @@ else() set(SHIPPED_CARL_USE_GINAC OFF) endif() -# Detect Apple Silicon and adjust settings -if(APPLE AND ${CMAKE_SYSTEM_PROCESSOR} MATCHES arm64) - message(STATUS "Storm - Detected that target system uses Apple Silicon.") - message(WARNING "Compiling natively on Apple Silicon is experimental. Please report issues to support@stormchecker.org. For more information visit https://www.stormchecker.org/documentation/obtain-storm/apple-silicon.html") - set(APPLE_SILICON 1) - if(STORM_USE_CLN_EA OR STORM_USE_CLN_RF) - message(WARNING "CLN and GiNaC are currently not supported on Apple Silicon-based architectures. Disabling Storm and carl usage of the libraries.") - set(STORM_USE_CLN_EA OFF) - set(STORM_USE_CLN_RF OFF) - endif() - set(SHIPPED_CARL_USE_CLN_NUMBERS OFF) - set(SHIPPED_CARL_USE_GINAC OFF) +# Warning for Apple Silicon +if(APPLE_SILICON) + message(WARNING "Compiling natively on Apple Silicon is experimental. Please report any issues to support@stormchecker.org.") endif() + set(DYNAMIC_EXT ".so") set(STATIC_EXT ".a") set(LIB_PREFIX "lib") diff --git a/doc/offline_package.md b/doc/offline_package.md index b933cdf23e..e53ff073e1 100644 --- a/doc/offline_package.md +++ b/doc/offline_package.md @@ -51,7 +51,7 @@ cd storm mkdir -p build cd build cmake .. -make storm-main -j$THREADS +make storm-cli -j$THREADS cd ../../ echo "Installation successfull." diff --git a/resources/3rdparty/CMakeLists.txt b/resources/3rdparty/CMakeLists.txt index db4e85b233..b7e6855b90 100644 --- a/resources/3rdparty/CMakeLists.txt +++ b/resources/3rdparty/CMakeLists.txt @@ -379,7 +379,7 @@ if (STORM_SHIPPED_CARL) SOURCE_DIR ${STORM_3RDPARTY_BINARY_DIR}/carl CONFIGURE_COMMAND "" BUILD_IN_SOURCE 1 - BUILD_COMMAND make lib_carl + BUILD_COMMAND make lib_carl -j${STORM_RESOURCES_BUILD_JOBCOUNT} INSTALL_COMMAND make install -j${STORM_RESOURCES_BUILD_JOBCOUNT} LOG_BUILD ON LOG_INSTALL ON diff --git a/resources/3rdparty/include_cudd.cmake b/resources/3rdparty/include_cudd.cmake index a16230b81e..db70948724 100644 --- a/resources/3rdparty/include_cudd.cmake +++ b/resources/3rdparty/include_cudd.cmake @@ -51,8 +51,9 @@ ExternalProject_Add( PREFIX ${STORM_3RDPARTY_BINARY_DIR}/cudd-3.0.0 PATCH_COMMAND ${CMAKE_COMMAND} -E env ${CUDD_AUTOTOOLS_LOCATIONS} ${AUTORECONF} CONFIGURE_COMMAND ${STORM_3RDPARTY_SOURCE_DIR}/cudd-3.0.0/configure --enable-shared --enable-obj --with-pic=yes --prefix=${STORM_3RDPARTY_BINARY_DIR}/cudd-3.0.0 --libdir=${CUDD_LIB_DIR} CC=${CMAKE_C_COMPILER} CXX=${CUDD_CXX_COMPILER} ${CUDD_INCLUDE_FLAGS} - BUILD_COMMAND make ${STORM_CUDD_FLAGS} ${CUDD_AUTOTOOLS_LOCATIONS} - INSTALL_COMMAND make install -j${STORM_RESOURCES_BUILD_JOBCOUNT} ${CUDD_AUTOTOOLS_LOCATIONS} + # Multi-threaded compilation could lead to compile issues + BUILD_COMMAND make -j1 ${STORM_CUDD_FLAGS} ${CUDD_AUTOTOOLS_LOCATIONS} + INSTALL_COMMAND make install -j1 ${CUDD_AUTOTOOLS_LOCATIONS} BUILD_IN_SOURCE 0 LOG_CONFIGURE ON LOG_BUILD ON diff --git a/resources/3rdparty/include_glpk.cmake b/resources/3rdparty/include_glpk.cmake index d5620969e2..f869c31fa3 100644 --- a/resources/3rdparty/include_glpk.cmake +++ b/resources/3rdparty/include_glpk.cmake @@ -16,7 +16,7 @@ else() PREFIX ${STORM_3RDPARTY_BINARY_DIR}/glpk-5.0 SOURCE_DIR ${STORM_3RDPARTY_SOURCE_DIR}/glpk-5.0 CONFIGURE_COMMAND ${STORM_3RDPARTY_SOURCE_DIR}/glpk-5.0/configure --prefix=${STORM_3RDPARTY_BINARY_DIR}/glpk-5.0 --libdir=${GLPK_LIB_DIR} CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} ${GLPK_INCLUDE_FLAGS} - BUILD_COMMAND make "CFLAGS=-O3 -w" + BUILD_COMMAND make "CFLAGS=-O3 -w" -j${STORM_RESOURCES_BUILD_JOBCOUNT} INSTALL_COMMAND make install -j${STORM_RESOURCES_BUILD_JOBCOUNT} BUILD_IN_SOURCE 0 LOG_CONFIGURE ON @@ -35,4 +35,4 @@ set(STORM_HAVE_GLPK ON) message (STATUS "Storm - Linking with glpk ${GLPK_VERSION_STRING}") add_imported_library(glpk SHARED ${GLPK_LIBRARIES} ${GLPK_INCLUDE_DIR}) -list(APPEND STORM_DEP_TARGETS glpk_SHARED) \ No newline at end of file +list(APPEND STORM_DEP_TARGETS glpk_SHARED) diff --git a/resources/3rdparty/include_spot.cmake b/resources/3rdparty/include_spot.cmake index 2d5e7c3431..e69977303d 100644 --- a/resources/3rdparty/include_spot.cmake +++ b/resources/3rdparty/include_spot.cmake @@ -30,20 +30,20 @@ if(STORM_USE_SPOT_SHIPPED AND NOT STORM_HAVE_SPOT) # download and install shipped Spot ExternalProject_Add(spot - URL http://www.lrde.epita.fr/dload/spot/spot-2.10.4.tar.gz # When updating, also change version output below + URL https://www.lrde.epita.fr/dload/spot/spot-2.12.tar.gz # When updating, also change version output below DOWNLOAD_NO_PROGRESS TRUE DOWNLOAD_DIR ${STORM_3RDPARTY_BINARY_DIR}/spot_src SOURCE_DIR ${STORM_3RDPARTY_BINARY_DIR}/spot_src PREFIX ${STORM_3RDPARTY_BINARY_DIR}/spot CONFIGURE_COMMAND ${STORM_3RDPARTY_BINARY_DIR}/spot_src/configure --prefix=${STORM_3RDPARTY_BINARY_DIR}/spot --disable-python BUILD_COMMAND make -j${STORM_RESOURCES_BUILD_JOBCOUNT} - INSTALL_COMMAND make install + INSTALL_COMMAND make install -j${STORM_RESOURCES_BUILD_JOBCOUNT} LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON BUILD_BYPRODUCTS ${STORM_3RDPARTY_BINARY_DIR}/spot/lib/libspot${DYNAMIC_EXT} ) - add_dependencies(resources spot) + add_dependencies(resources spot) set(SPOT_INCLUDE_DIR "${STORM_3RDPARTY_BINARY_DIR}/spot/include/") set(SPOT_DIR "${STORM_3RDPARTY_BINARY_DIR}/spot/") set(SPOT_LIBRARIES ${STORM_3RDPARTY_BINARY_DIR}/spot/lib/libspot${DYNAMIC_EXT}) @@ -51,7 +51,7 @@ if(STORM_USE_SPOT_SHIPPED AND NOT STORM_HAVE_SPOT) set(STORM_HAVE_SPOT ON) set(STORM_SHIPPED_SPOT ON) - message(STATUS "Storm - Using shipped version of Spot 2.10.4 (include: ${SPOT_INCLUDE_DIR}, library ${SPOT_LIBRARIES}).") + message(STATUS "Storm - Using shipped version of Spot 2.12 (include: ${SPOT_INCLUDE_DIR}, library ${SPOT_LIBRARIES}).") endif() diff --git a/resources/examples/testfiles/ctmc/simple1.sm b/resources/examples/testfiles/ctmc/simple1.sm new file mode 100644 index 0000000000..98a6dd1dca --- /dev/null +++ b/resources/examples/testfiles/ctmc/simple1.sm @@ -0,0 +1,11 @@ +ctmc + +module main +x : [0..1] init 0; +[] x=0 -> 6 : (x'=1); +endmodule + +rewards + x=0: 1; +endrewards + diff --git a/resources/examples/testfiles/dft/symmetry7.dft b/resources/examples/testfiles/dft/symmetry7.dft new file mode 100644 index 0000000000..0beba5d8c9 --- /dev/null +++ b/resources/examples/testfiles/dft/symmetry7.dft @@ -0,0 +1,13 @@ +toplevel "A"; +"A" or "M" "N"; +"M" and "M1" "M2" "M3" "M4"; +"N" and "N1" "N2" "N3" "N4"; +"M1" lambda=0.5 dorm=0; +"M2" lambda=0.5 dorm=0; +"M3" lambda=0.5 dorm=0; +"M4" lambda=1 dorm=0; +"N1" lambda=0.5 dorm=0; +"N2" lambda=0.5 dorm=0; +"N3" lambda=1 dorm=0; +"N4" lambda=1 dorm=0; + diff --git a/resources/examples/testfiles/dtmc/test_trigonometry.jani b/resources/examples/testfiles/dtmc/test_trigonometry.jani new file mode 100644 index 0000000000..a98d0a901a --- /dev/null +++ b/resources/examples/testfiles/dtmc/test_trigonometry.jani @@ -0,0 +1,260 @@ +{ + "jani-version": 1, + "name": "test_trigonometry", + "type": "dtmc", + "metadata": { + "description": "Testing sin, cos and constants in Storm SMC tool." + }, + "features": [ + "trigonometric-functions" + ], + "variables": [ + { + "name": "orientation_deg", + "type": "int", + "initial-value": 0, + "comment": "Current orientation in degrees" + } + ], + "constants": [ + { + "name": "step_size_rad", + "type": { + "kind": "bounded", + "base": "real", + "lower-bound": { + "op": "/", + "left": { + "constant": "π" + }, + "right": 180 + }, + "upper-bound": { + "op": "*", + "left": { + "constant": "π" + }, + "right": 2 + } + + }, + "comment": "How much to turn in each step in radians. Bounds: [1 deg., 360 deg.]" + } + ], + "actions": [ + { + "name": "advance" + } + ], + "automata": [ + { + "name": "test_trig_automaton", + "locations": [ + { + "name": "increasing", + "comment": "A state were the angle is increased each transition" + }, + { + "name": "final", + "comment": "State reached when cos(angle) ~= 1" + } + ], + "initial-locations": [ + "increasing" + ], + "variables": [ + { + "name": "orientation_rad", + "type": "real", + "initial-value": 0.0, + "transient": true + } + ], + "edges": [ + { + "action": "advance", + "location": "increasing", + "guard": { + "exp": { + "op": "<", + "left": { + "op": "sin", + "exp": { + "op": "*", + "left": "orientation_deg", + "right": { + "op": "/", + "left": {"constant": "π"}, + "right": 180 + } + } + }, + "right": 0.99 + } + }, + "destinations": [ + { + "location": "increasing", + "assignments": [ + { + "ref": "orientation_rad", + "value": { + "op": "*", + "left": "orientation_deg", + "right": { + "op": "/", + "left": {"constant": "π"}, + "right": 180 + } + }, + "index": 0, + "comment": "Convert orientation from deg to rad" + }, + { + "ref": "orientation_rad", + "value": { + "op": "+", + "left": "orientation_rad", + "right": "step_size_rad" + }, + "index": 1, + "comment": "Turn by step_size" + }, + { + "ref": "orientation_deg", + "value": { + "op": "*", + "left": "orientation_rad", + "right": { + "op": "/", + "left": 180, + "right": {"constant": "π"} + } + }, + "index": 2, + "comment": "Convert orientation from rad to deg" + } + ] + } + ] + }, + { + "action": "advance", + "location": "increasing", + "guard": { + "exp": { + "op": "≥", + "left": { + "op": "sin", + "exp": { + "op": "*", + "left": "orientation_deg", + "right": { + "op": "/", + "left": {"constant": "π"}, + "right": 180 + } + } + }, + "right": 0.99 + } + }, + "destinations": [ + { + "location": "final" + } + ] + } + ] + } + ], + "system": { + "elements": [ + { + "automaton": "test_trig_automaton" + } + ], + "syncs": [ + { + "result": "advance", + "synchronise": [ + "advance" + ] + } + ] + }, + "properties": [ + { + "name": "destination_reached_sin", + "expression": { + "op": "filter", + "fun": "values", + "values": { + "op": "Pmin", + "exp": { + "op": "U", + "step-bounds": { + "upper": 1000 + }, + "left": true, + "right": { + "op": "≥", + "left": { + "op": "sin", + "exp": { + "op": "*", + "left": "orientation_deg", + "right": { + "op": "/", + "left": {"constant": "π"}, + "right": 180 + } + } + }, + "right": 0.99 + } + } + }, + "states": { + "op": "initial" + } + } + }, + { + "name": "test_int_trigonometry", + "expression": { + "op": "filter", + "fun": "values", + "values": { + "op": "Pmin", + "exp": { + "op": "U", + "left": true, + "right": { + "op": "∧", + "left": { + "op": "=", + "left": { + "op": "sin", + "exp": 0 + }, + "right": 0.0 + }, + "right": { + "op": "=", + "left": { + "op": "cos", + "exp": 0 + }, + "right": 1.0 + } + } + } + }, + "states": { + "op": "initial" + } + } + } + ] +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eeec8cf34e..32ce46c25c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,18 +11,19 @@ add_subdirectory(storm-gamebased-ar) add_subdirectory(storm-parsers) add_subdirectory(storm-version-info) add_subdirectory(storm-cli-utilities) -add_subdirectory(storm-gspn) -add_subdirectory(storm-gspn-cli) +add_subdirectory(storm-cli) +# Additional libraries +add_subdirectory(storm-conv) +add_subdirectory(storm-conv-cli) add_subdirectory(storm-dft) add_subdirectory(storm-dft-cli) +add_subdirectory(storm-gspn) +add_subdirectory(storm-gspn-cli) add_subdirectory(storm-pars) add_subdirectory(storm-pars-cli) add_subdirectory(storm-pomdp) add_subdirectory(storm-pomdp-cli) -add_subdirectory(storm-conv) -add_subdirectory(storm-conv-cli) - if (STORM_EXCLUDE_TESTS_FROM_ALL) add_subdirectory(test EXCLUDE_FROM_ALL) else() diff --git a/src/storm-cli-utilities/CMakeLists.txt b/src/storm-cli-utilities/CMakeLists.txt index 84adae58fc..6f43e020a5 100644 --- a/src/storm-cli-utilities/CMakeLists.txt +++ b/src/storm-cli-utilities/CMakeLists.txt @@ -2,8 +2,6 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-cli-utilities/*.h ${ register_source_groups_from_filestructure("${ALL_FILES}" storm-cli-utilities) - - file(GLOB_RECURSE STORM_CLI_UTIL_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-cli-utilities/*.cpp) file(GLOB_RECURSE STORM_CLI_UTIL_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-cli-utilities/*.h) @@ -12,10 +10,8 @@ file(GLOB_RECURSE STORM_CLI_UTIL_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-cli-uti add_library(storm-cli-utilities SHARED ${STORM_CLI_UTIL_SOURCES} ${STORM_CLI_UTIL_HEADERS}) target_precompile_headers(storm-cli-utilities REUSE_FROM storm) - # Remove define symbol for shared libstorm. set_target_properties(storm-cli-utilities PROPERTIES DEFINE_SYMBOL "") -#add_dependencies(storm resources) list(APPEND STORM_TARGETS storm-cli-utilities) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) @@ -23,16 +19,16 @@ target_link_libraries(storm-cli-utilities PUBLIC storm storm-counterexamples sto # Install storm headers to include directory. foreach(HEADER ${STORM_CLI_UTIL_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_CLI_UTIL_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") + 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_CLI_UTIL_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") endforeach() add_custom_target(copy_storm_cli_util_headers DEPENDS ${STORM_CLI_UTIL_OUTPUT_HEADERS} ${STORM_CLI_UTIL_HEADERS}) add_dependencies(storm-cli-utilities copy_storm_cli_util_headers) diff --git a/src/storm-cli/CMakeLists.txt b/src/storm-cli/CMakeLists.txt new file mode 100644 index 0000000000..54e870fef0 --- /dev/null +++ b/src/storm-cli/CMakeLists.txt @@ -0,0 +1,10 @@ +# Create main binary storm. +add_executable(storm-cli ${PROJECT_SOURCE_DIR}/src/storm-cli/storm-cli.cpp) +target_link_libraries(storm-cli storm storm-cli-utilities) +set_target_properties(storm-cli PROPERTIES OUTPUT_NAME "storm") +target_precompile_headers(storm-cli PRIVATE ${STORM_PRECOMPILED_HEADERS}) + +add_dependencies(binaries storm-cli) + +# installation +install(TARGETS storm-cli EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) diff --git a/src/storm/storm.cpp b/src/storm-cli/storm-cli.cpp similarity index 100% rename from src/storm/storm.cpp rename to src/storm-cli/storm-cli.cpp diff --git a/src/storm-conv-cli/CMakeLists.txt b/src/storm-conv-cli/CMakeLists.txt index a7c0b91a93..d767f3eb63 100644 --- a/src/storm-conv-cli/CMakeLists.txt +++ b/src/storm-conv-cli/CMakeLists.txt @@ -1,8 +1,8 @@ # 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 +target_link_libraries(storm-conv-cli storm-conv storm-cli-utilities) set_target_properties(storm-conv-cli PROPERTIES OUTPUT_NAME "storm-conv") -target_precompile_headers(storm-conv-cli REUSE_FROM storm-main) +target_precompile_headers(storm-conv-cli REUSE_FROM storm-cli) add_dependencies(binaries storm-conv-cli) diff --git a/src/storm-conv/CMakeLists.txt b/src/storm-conv/CMakeLists.txt index d5c224c878..d39af1a331 100644 --- a/src/storm-conv/CMakeLists.txt +++ b/src/storm-conv/CMakeLists.txt @@ -2,20 +2,16 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-conv/*.h ${PROJECT_S 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}) - target_precompile_headers(storm-conv REUSE_FROM storm) # 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) diff --git a/src/storm-conv/api/storm-conv.cpp b/src/storm-conv/api/storm-conv.cpp index 25370449a8..4bb5116071 100644 --- a/src/storm-conv/api/storm-conv.cpp +++ b/src/storm-conv/api/storm-conv.cpp @@ -22,7 +22,7 @@ void transformJani(storm::jani::Model& janiModel, std::vector::DFTStatePointer DftNextSta if (dependencySuccessful) { // Dependency was successful -> dependent BE fails - STORM_LOG_TRACE("With the successful triggering of PDEP " << dependency->name() << " [" << dependency->id() << "]" - << " in " << mDft.getStateString(origState)); + STORM_LOG_TRACE("With the successful triggering of PDEP " << dependency->name() << " [" << dependency->id() << "]" << " in " + << mDft.getStateString(origState)); newState->letDependencyTrigger(dependency, true); STORM_LOG_ASSERT(dependency->dependentEvents().size() == 1, "Dependency " << dependency->name() << " does not have unique dependent event."); STORM_LOG_ASSERT(dependency->dependentEvents().front()->isBasicElement(), @@ -223,8 +223,8 @@ typename DftNextStateGenerator::DFTStatePointer DftNextSta return createSuccessorState(newState, trigger); } else { // Dependency was unsuccessful -> no BE fails - STORM_LOG_TRACE("With the unsuccessful triggering of PDEP " << dependency->name() << " [" << dependency->id() << "]" - << " in " << mDft.getStateString(origState)); + STORM_LOG_TRACE("With the unsuccessful triggering of PDEP " << dependency->name() << " [" << dependency->id() << "]" << " in " + << mDft.getStateString(origState)); newState->letDependencyTrigger(dependency, false); return newState; } @@ -236,8 +236,7 @@ typename DftNextStateGenerator::DFTStatePointer DftNextSta // Construct new state as copy from original one DFTStatePointer newState = origState->copy(); - STORM_LOG_TRACE("With the failure of " << be->name() << " [" << be->id() << "]" - << " in " << mDft.getStateString(origState)); + STORM_LOG_TRACE("With the failure of " << be->name() << " [" << be->id() << "]" << " in " << mDft.getStateString(origState)); newState->letBEFail(be); // Propagate diff --git a/src/storm-dft/simulator/DFTTraceSimulator.cpp b/src/storm-dft/simulator/DFTTraceSimulator.cpp index c6f1e60913..f5cbb34015 100644 --- a/src/storm-dft/simulator/DFTTraceSimulator.cpp +++ b/src/storm-dft/simulator/DFTTraceSimulator.cpp @@ -8,7 +8,7 @@ DFTTraceSimulator::DFTTraceSimulator(storm::dft::storage::DFT @@ -18,7 +18,18 @@ void DFTTraceSimulator::setRandomNumberGenerator(boost::mt19937& rand template void DFTTraceSimulator::resetToInitial() { - state = generator.createInitialState(); + resetToState(generator.createInitialState()); + setTime(0); +} + +template +void DFTTraceSimulator::resetToState(DFTStatePointer state) { + this->state = state; +} + +template +void DFTTraceSimulator::setTime(double time) { + this->time = time; } template @@ -26,6 +37,11 @@ typename DFTTraceSimulator::DFTStatePointer DFTTraceSimulator +double DFTTraceSimulator::getCurrentTime() const { + return time; +} + template std::tuple DFTTraceSimulator::randomNextFailure() { auto iterFailable = state->getFailableElements().begin(); @@ -85,21 +101,29 @@ std::tuple } template -std::pair DFTTraceSimulator::randomStep() { - auto [nextFailable, time, successful] = this->randomNextFailure(); - if (time < 0) { - return std::make_pair(SimulationResult::UNSUCCESSFUL, -1); - } else { - // Apply next failure - return std::make_pair(step(nextFailable, successful), time); +SimulationStepResult DFTTraceSimulator::randomStep() { + // Randomly generate next failure + auto [nextFailable, addTime, successfulDependency] = this->randomNextFailure(); + if (addTime < 0) { + // No next state can be reached, because no element can fail anymore. + STORM_LOG_TRACE("No next state possible in state " << dft.getStateString(state) << " because no element can fail anymore"); + return SimulationStepResult::UNSUCCESSFUL; } + + // Apply next failure + auto stepResult = step(nextFailable, successfulDependency); + STORM_LOG_TRACE("Current state: " << dft.getStateString(state)); + + // Update time + this->time += addTime; + return stepResult; } template -SimulationResult DFTTraceSimulator::step(storm::dft::storage::FailableElements::const_iterator nextFailElement, bool dependencySuccessful) { +SimulationStepResult DFTTraceSimulator::step(storm::dft::storage::FailableElements::const_iterator nextFailElement, bool dependencySuccessful) { if (nextFailElement == state->getFailableElements().end()) { // No next failure possible - return SimulationResult::UNSUCCESSFUL; + return SimulationStepResult::UNSUCCESSFUL; } DFTStatePointer newState; @@ -111,73 +135,62 @@ SimulationResult DFTTraceSimulator::step(storm::dft::storage::Failabl if (newState->isInvalid() || newState->isTransient()) { STORM_LOG_TRACE("Step is invalid because new state " << (newState->isInvalid() ? "is invalid." : "has transient fault.")); - return SimulationResult::INVALID; + return SimulationStepResult::INVALID; } state = newState; - return SimulationResult::SUCCESSFUL; + return SimulationStepResult::SUCCESSFUL; } template -SimulationResult DFTTraceSimulator::simulateCompleteTrace(double timebound) { +SimulationTraceResult DFTTraceSimulator::simulateNextStep(double timebound) { + // Perform random step + SimulationStepResult stepResult = randomStep(); + + // Check current state + if (stepResult == SimulationStepResult::INVALID) { + // No next state can be reached, because the state is invalid. + STORM_LOG_TRACE("Invalid state " << dft.getStateString(state) << " was reached."); + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Handling of invalid states is not supported for simulation"); + return SimulationTraceResult::INVALID; + } else if (stepResult == SimulationStepResult::UNSUCCESSFUL) { + STORM_LOG_TRACE("No next state possible in state " << dft.getStateString(state) << " because no further failures are possible."); + return SimulationTraceResult::UNSUCCESSFUL; + } + STORM_LOG_ASSERT(stepResult == SimulationStepResult::SUCCESSFUL, "Simulation step should be successful."); + + if (getCurrentTime() > timebound) { + // Timebound was exceeded + return SimulationTraceResult::UNSUCCESSFUL; + } else if (state->hasFailed(dft.getTopLevelIndex())) { + // DFT is failed + STORM_LOG_TRACE("DFT has failed after " << getCurrentTime()); + return SimulationTraceResult::SUCCESSFUL; + } else { + // No conclusive outcome was reached yet + return SimulationTraceResult::CONTINUE; + } +} + +template +SimulationTraceResult DFTTraceSimulator::simulateCompleteTrace(double timebound) { resetToInitial(); // Check whether DFT is initially already failed. if (state->hasFailed(dft.getTopLevelIndex())) { STORM_LOG_TRACE("DFT is initially failed"); - return SimulationResult::SUCCESSFUL; + return SimulationTraceResult::SUCCESSFUL; } - double time = 0; - while (time <= timebound) { - // Generate next failure - auto retTuple = randomNextFailure(); - storm::dft::storage::FailableElements::const_iterator nextFailable = std::get<0>(retTuple); - double addTime = std::get<1>(retTuple); - bool successfulDependency = std::get<2>(retTuple); - if (addTime < 0) { - // No next state can be reached, because no element can fail anymore. - STORM_LOG_TRACE("No next state possible in state " << dft.getStateString(state) << " because no element can fail anymore"); - return SimulationResult::UNSUCCESSFUL; - } - - // TODO: exit if time would be up after this failure - // This is only correct if no invalid states are possible! (no restrictors and no transient failures) - - // Apply next failure - auto stepResult = step(nextFailable, successfulDependency); - STORM_LOG_TRACE("Current state: " << dft.getStateString(state)); - - // Check whether state is invalid - if (stepResult != SimulationResult::SUCCESSFUL) { - STORM_LOG_ASSERT(stepResult == SimulationResult::INVALID, "Result of simulation step should be invalid."); - // No next state can be reached, because the state is invalid. - STORM_LOG_TRACE("No next state possible in state " << dft.getStateString(state) << " because simulation was invalid"); - STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Handling of invalid states is not supported for simulation"); - return SimulationResult::INVALID; - } - - // Check whether time is up - // Checking whether the time is up must be performed after checking if a state is invalid. - // Otherwise we would erroneously mark invalid traces as unsuccessful. - time += addTime; - if (time > timebound) { - STORM_LOG_TRACE("Time limit" << timebound << " exceeded: " << time); - return SimulationResult::UNSUCCESSFUL; - } - - // Check whether DFT is failed - if (state->hasFailed(dft.getTopLevelIndex())) { - STORM_LOG_TRACE("DFT has failed after " << time); - return SimulationResult::SUCCESSFUL; - } - } - STORM_LOG_ASSERT(false, "Should not be reachable"); - return SimulationResult::UNSUCCESSFUL; + SimulationTraceResult result = SimulationTraceResult::CONTINUE; + do { + result = simulateNextStep(timebound); + } while (result == SimulationTraceResult::CONTINUE); + return result; } template<> -SimulationResult DFTTraceSimulator::simulateCompleteTrace(double timebound) { +SimulationTraceResult DFTTraceSimulator::simulateCompleteTrace(double timebound) { STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Simulation not support for parametric DFTs."); } diff --git a/src/storm-dft/simulator/DFTTraceSimulator.h b/src/storm-dft/simulator/DFTTraceSimulator.h index 94ee7eb615..4fa0b92002 100644 --- a/src/storm-dft/simulator/DFTTraceSimulator.h +++ b/src/storm-dft/simulator/DFTTraceSimulator.h @@ -11,10 +11,16 @@ namespace storm::dft { namespace simulator { /*! - * Simulation result. + * Result of a single simulation step. * */ -enum class SimulationResult { SUCCESSFUL, UNSUCCESSFUL, INVALID }; +enum class SimulationStepResult { SUCCESSFUL, UNSUCCESSFUL, INVALID }; + +/*! + * Result of a simulation trace. + * CONTINUE is only used for partial traces to indicate that no conclusive outcome has been reached yet. + */ +enum class SimulationTraceResult { SUCCESSFUL, UNSUCCESSFUL, INVALID, CONTINUE }; /*! * Simulator for DFTs. @@ -45,10 +51,20 @@ class DFTTraceSimulator { void setRandomNumberGenerator(boost::mt19937& randomNumberGenerator); /*! - * Set the current state back to the intial state in order to start a new simulation. + * Set the current state back to the initial state in order to start a new simulation. */ void resetToInitial(); + /*! + * Set the current state back to the given state. + */ + void resetToState(DFTStatePointer state); + + /*! + * Set the elapsed time so far. + */ + void setTime(double time); + /*! * Get the current DFT state. * @@ -56,15 +72,22 @@ class DFTTraceSimulator { */ DFTStatePointer getCurrentState() const; + /*! + * Get the total elapsed time so far. + * + * @return Elapsed time. + */ + double getCurrentTime() const; + /*! * Perform one simulation step by letting the next element fail. * * @param nextFailElement Iterator giving the next element which should fail. * @param dependencySuccessful Whether the triggering dependency was successful. - * If the dependency is unsuccessful, no BE fails and only the depedendy is marked as failed. - * @return Successful if step could be performed, unsuccesful if no element can fail or invalid if the next state is invalid (due to a restrictor). + * If the dependency is unsuccessful, no BE fails and only the dependency is marked as failed. + * @return Successful if step could be performed, unsuccessful if no element can fail or invalid if the next state is invalid (due to a restrictor). */ - SimulationResult step(storm::dft::storage::FailableElements::const_iterator nextFailElement, bool dependencySuccessful = true); + SimulationStepResult step(storm::dft::storage::FailableElements::const_iterator nextFailElement, bool dependencySuccessful = true); /*! * Randomly pick an element which fails next (either a BE or a dependency which triggers a BE) and the time after which it fails. @@ -78,9 +101,19 @@ class DFTTraceSimulator { /*! * Perform a random step by using the random number generator. * - * @return Pair of the simulation result (successful, unsuccesful, invalid) and the time which progessed between the last step and this step. + * @return Result of the simulation step (successful, unsuccessful, invalid). */ - std::pair randomStep(); + SimulationStepResult randomStep(); + + /*! + * Simulate the (randomly chosen) next step and return the outcome of the current (partial) trace. + * + * @param timebound Time bound in which the system failure should occur. + * @return Result of (partial) trace is (1) SUCCESSFUL if the current state corresponds to a system failure and the current time does not exceed the + * timebound. (2) UNSUCCESSFUL, if the current time exceeds the timebound, (3) INVALID, if an invalid state (due to a restrictor) was reached, or (4) + * CONTINUE, if the simulation should continue. + */ + SimulationTraceResult simulateNextStep(double timebound); /*! * Perform a complete simulation of a failure trace by using the random number generator. @@ -89,11 +122,11 @@ class DFTTraceSimulator { * If an invalid state (due to a restrictor) was reached, the simulated trace is invalid. * * @param timebound Time bound in which the system failure should occur. - * @return Simulation result is (1) successful if a system failure occurred for the generated trace within the time bound, - * (2) unsuccesfull, if no system failure occurred within the time bound, or - * (3) invalid, if an invalid state (due to a restrictor) was reached during the trace generation. + * @return Result of simulation trace is (1) SUCCESSFUL if a system failure occurred for the generated trace within the time bound, + * (2) UNSUCCESSFUL, if no system failure occurred within the time bound, or + * (3) INVALID, if an invalid state (due to a restrictor) was reached during the trace generation. */ - SimulationResult simulateCompleteTrace(double timebound); + SimulationTraceResult simulateCompleteTrace(double timebound); protected: // The DFT used for the generation of next states. @@ -108,6 +141,9 @@ class DFTTraceSimulator { // Current state DFTStatePointer state; + // Currently elapsed time + double time; + // Random number generator boost::mt19937& randomGenerator; }; diff --git a/src/storm-dft/simulator/ImportanceFunction.cpp b/src/storm-dft/simulator/ImportanceFunction.cpp new file mode 100644 index 0000000000..312fda6349 --- /dev/null +++ b/src/storm-dft/simulator/ImportanceFunction.cpp @@ -0,0 +1,32 @@ +#include "ImportanceFunction.h" + +namespace storm::dft { +namespace simulator { + +template +ImportanceFunction::ImportanceFunction(storm::dft::storage::DFT const& dft) : dft(dft) {} + +template +BECountImportanceFunction::BECountImportanceFunction(storm::dft::storage::DFT const& dft) : ImportanceFunction(dft) {} + +template +double BECountImportanceFunction::getImportance(typename ImportanceFunction::DFTStatePointer state) const { + size_t count = 0; + for (auto be : this->dft.getBasicElements()) { + if (state->hasFailed(be->id())) { + ++count; + } + } + return count; +} + +template +std::pair BECountImportanceFunction::getImportanceRange() const { + return std::make_pair(0, this->dft.nrBasicElements()); +} + +template class BECountImportanceFunction; +template class BECountImportanceFunction; + +} // namespace simulator +} // namespace storm::dft diff --git a/src/storm-dft/simulator/ImportanceFunction.h b/src/storm-dft/simulator/ImportanceFunction.h new file mode 100644 index 0000000000..a31023eaed --- /dev/null +++ b/src/storm-dft/simulator/ImportanceFunction.h @@ -0,0 +1,73 @@ +#pragma once + +#include "storm-dft/storage/DFT.h" +#include "storm-dft/storage/DFTState.h" + +namespace storm::dft { +namespace simulator { + +/*! + * Abstract class for importance functions. + */ +template +class ImportanceFunction { + protected: + using DFTStatePointer = std::shared_ptr>; + + public: + /*! + * Constructor. + * + * @param dft DFT. + */ + ImportanceFunction(storm::dft::storage::DFT const& dft); + + /*! + * Get the importance for a given state. + * @param state DFT state. + * @return Importance value. + */ + virtual double getImportance(DFTStatePointer state) const = 0; + + /*! + * Get the lower and upper bounds of possible importance values computed by this importance function. + * + * @return Lower, upper bound of possible importance values. + */ + virtual std::pair getImportanceRange() const = 0; + + protected: + // The DFT used for the generation of next states. + storm::dft::storage::DFT const& dft; +}; + +/*! + * Importance function based on counting the number of currently failed BEs. + */ +template +class BECountImportanceFunction : public ImportanceFunction { + public: + /*! + * Constructor. + * + * @param dft DFT. + */ + BECountImportanceFunction(storm::dft::storage::DFT const& dft); + + /*! + * Get the importance for a given state. + * @param state DFT state. + * @return Importance value. + */ + double getImportance(typename ImportanceFunction::DFTStatePointer state) const override; + + /*! + * Get the lower and upper bounds of possible importance values computed by this importance function. + * + * @return Lower, upper bound of possible importance values. + */ + std::pair getImportanceRange() const override; +}; + +} // namespace simulator +} // namespace storm::dft diff --git a/src/storm-dft/storage/DFTIsomorphism.h b/src/storm-dft/storage/DFTIsomorphism.h index 4a4abb434f..c7f585685f 100644 --- a/src/storm-dft/storage/DFTIsomorphism.h +++ b/src/storm-dft/storage/DFTIsomorphism.h @@ -4,12 +4,9 @@ #include #include -#include "storm/exceptions/InvalidArgumentException.h" - #include "storm-dft/storage/DFT.h" #include "storm-dft/storage/elements/DFTElementType.h" #include "storm-dft/storage/elements/DFTElements.h" - #include "storm/exceptions/InvalidArgumentException.h" namespace storm::dft { @@ -380,7 +377,7 @@ class DFTIsomorphismCheck { public: DFTIsomorphismCheck(BijectionCandidates const& left, BijectionCandidates const& right, DFT const& dft) : bleft(left), bright(right), dft(dft) { - checkCompatibility(); + candidatesCompatible = checkCompatibility(); } /** @@ -565,52 +562,50 @@ class DFTIsomorphismCheck { } private: - /** - * Returns true if the colours are compatible. + /*! + * Check compatibility of colour classes for specific type. + * @param left Left candidates. + * @param right Right candidates. + * @return True iff left and right are compatible. */ - bool checkCompatibility() { - if (bleft.gateCandidates.size() != bright.gateCandidates.size()) { - candidatesCompatible = false; - return false; - } - if (bleft.beCandidates.size() != bright.beCandidates.size()) { - candidatesCompatible = false; - return false; - } - if (bleft.pdepCandidates.size() != bright.pdepCandidates.size()) { - candidatesCompatible = false; - return false; - } - if (bleft.restrictionCandidates.size() != bright.restrictionCandidates.size()) { - candidatesCompatible = false; + template + bool checkCompatibility(std::unordered_map> const& left, std::unordered_map> const& right) { + if (left.size() != right.size()) { + // Different number of colour classes return false; } - for (auto const& gc : bleft.gateCandidates) { - if (bright.gateCandidates.count(gc.first) == 0) { - candidatesCompatible = false; + for (auto const& gc : left) { + auto it = right.find(gc.first); + if (it == right.end()) { + // No corresponding colour return false; - } - } - for (auto const& bc : bleft.beCandidates) { - if (bright.beCandidates.count(bc.first) == 0) { - candidatesCompatible = false; + } else if (it->second.size() != gc.second.size()) { + // Corresponding colour classes have different number of elements return false; } } + return true; + } - for (auto const& dc : bleft.pdepCandidates) { - if (bright.pdepCandidates.count(dc.first) == 0) { - candidatesCompatible = false; - return false; - } + /*! + * Check if colour classes are compatible in principle. + * This checks only excludes non-compatible colour classes. In the positive case, further checks are necessary. + * + * @return True iff colours are compatible. + */ + bool checkCompatibility() { + if (!checkCompatibility(bleft.gateCandidates, bright.gateCandidates)) { + return false; } - - for (auto const& dc : bleft.restrictionCandidates) { - if (bright.restrictionCandidates.count(dc.first) == 0) { - candidatesCompatible = false; - return false; - } + if (!checkCompatibility(bleft.beCandidates, bright.beCandidates)) { + return false; + } + if (!checkCompatibility(bleft.pdepCandidates, bright.pdepCandidates)) { + return false; + } + if (!checkCompatibility(bleft.restrictionCandidates, bright.restrictionCandidates)) { + return false; } return true; } diff --git a/src/storm-dft/utility/SymmetryFinder.cpp b/src/storm-dft/utility/SymmetryFinder.cpp index 0d71c92954..744ff4ef19 100644 --- a/src/storm-dft/utility/SymmetryFinder.cpp +++ b/src/storm-dft/utility/SymmetryFinder.cpp @@ -1,8 +1,7 @@ #include "SymmetryFinder.h" #include "storm-dft/storage/DFTIsomorphism.h" - -#include "storm/utility/iota_n.h" +#include "storm/utility/vector.h" namespace storm::dft { namespace utility { @@ -12,10 +11,8 @@ storm::dft::storage::DftSymmetries SymmetryFinder::findSymmetries(sto // Colour the DFT elements to find candidates for symmetries storm::dft::storage::DFTColouring colouring(dft); - std::vector vec; - vec.reserve(dft.nrElements()); - storm::utility::iota_n(std::back_inserter(vec), dft.nrElements(), 0); - storm::dft::storage::BijectionCandidates completeCategories = colouring.colourSubdft(vec); + std::vector subDftIndices(storm::utility::vector::buildVectorForRange(size_t(0), dft.nrElements())); + storm::dft::storage::BijectionCandidates completeCategories = colouring.colourSubdft(subDftIndices); std::map>> res; // Find symmetries for gates diff --git a/src/storm-gamebased-ar/CMakeLists.txt b/src/storm-gamebased-ar/CMakeLists.txt index ee399a0445..f1809e592c 100644 --- a/src/storm-gamebased-ar/CMakeLists.txt +++ b/src/storm-gamebased-ar/CMakeLists.txt @@ -5,8 +5,10 @@ register_source_groups_from_filestructure("${ALL_FILES}" storm-gamebased-ar) file(GLOB_RECURSE STORM_GBAR_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-gamebased-ar/*/*.cpp) file(GLOB_RECURSE STORM_GBAR_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-gamebased-ar/*/*.h) + # Create storm-gamebased-ar. add_library(storm-gamebased-ar SHARED ${STORM_GBAR_SOURCES} ${STORM_GBAR_HEADERS}) +target_precompile_headers(storm-gamebased-ar REUSE_FROM storm) # Remove define symbol for shared libstorm. set_target_properties(storm-gamebased-ar PROPERTIES DEFINE_SYMBOL "") @@ -14,21 +16,20 @@ list(APPEND STORM_TARGETS storm-gamebased-ar) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) target_link_libraries(storm-gamebased-ar PUBLIC storm) -target_precompile_headers(storm-gamebased-ar REUSE_FROM storm) # Install storm headers to include directory. foreach (HEADER ${STORM_GBAR_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_GBAR_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") -endforeach () + 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_GBAR_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") +endforeach() add_custom_target(copy_storm_gbar_headers DEPENDS ${STORM_GBAR_OUTPUT_HEADERS} ${STORM_GBAR_HEADERS}) add_dependencies(storm-gamebased-ar copy_storm_gbar_headers) diff --git a/src/storm-gamebased-ar/abstraction/MenuGameAbstractor.cpp b/src/storm-gamebased-ar/abstraction/MenuGameAbstractor.cpp index 9287d62a60..b0d283b9cb 100644 --- a/src/storm-gamebased-ar/abstraction/MenuGameAbstractor.cpp +++ b/src/storm-gamebased-ar/abstraction/MenuGameAbstractor.cpp @@ -140,8 +140,7 @@ void MenuGameAbstractor::exportToDot(storm::gbar::abstraction uint_fast64_t index = abstractionInformation.decodePlayer1Choice(stateValue.first, abstractionInformation.getPlayer1VariableCount()); out << stateName << "_" << index; out << " [ shape=\"square\", width=0, height=0, margin=0, label=\"" << index << "\" ];\n"; - out << "\tpl1_" << stateName << " -> " - << "pl2_" << stateName << "_" << index << " [ label=\"" << index << "\" ];\n"; + out << "\tpl1_" << stateName << " -> " << "pl2_" << stateName << "_" << index << " [ label=\"" << index << "\" ];\n"; } // Create the nodes of the probabilistic player. @@ -157,8 +156,7 @@ void MenuGameAbstractor::exportToDot(storm::gbar::abstraction index = abstractionInformation.decodePlayer2Choice(stateValue.first, currentGame.getPlayer2Variables().size()); out << stateName << "_" << index; out << " [ shape=\"point\", label=\"\" ];\n"; - out << "\tpl2_" << stateName << " -> " - << "plp_" << stateName << "_" << index << " [ label=\"" << index << "\" ];\n"; + out << "\tpl2_" << stateName << " -> " << "plp_" << stateName << "_" << index << " [ label=\"" << index << "\" ];\n"; } for (auto stateValue : filteredTransitions) { diff --git a/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp b/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp index 141b55893b..17c66abe38 100644 --- a/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp +++ b/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.cpp @@ -1,43 +1,34 @@ #include "storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.h" -#include "storm/storage/dd/Add.h" -#include "storm/storage/dd/Bdd.h" -#include "storm/storage/dd/DdManager.h" - +#include "storm-gamebased-ar/abstraction/QualitativeResultMinMax.h" +#include "storm-gamebased-ar/abstraction/StateSet.h" +#include "storm-gamebased-ar/abstraction/SymbolicQualitativeGameResultMinMax.h" +#include "storm-gamebased-ar/abstraction/SymbolicQualitativeMdpResult.h" +#include "storm-gamebased-ar/abstraction/SymbolicQualitativeMdpResultMinMax.h" +#include "storm-gamebased-ar/abstraction/SymbolicStateSet.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/NotSupportedException.h" #include "storm/logic/Formulas.h" #include "storm/logic/FragmentSpecification.h" - -#include "storm/models/symbolic/Dtmc.h" -#include "storm/models/symbolic/Mdp.h" -#include "storm/models/symbolic/StandardRewardModel.h" -#include "storm/models/symbolic/StochasticTwoPlayerGame.h" - #include "storm/modelchecker/CheckTask.h" +#include "storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h" +#include "storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h" #include "storm/modelchecker/results/CheckResult.h" #include "storm/modelchecker/results/QuantitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" - -#include "storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h" -#include "storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h" - -#include "storm/solver/SymbolicGameSolver.h" - -#include "storm-gamebased-ar/abstraction/QualitativeResultMinMax.h" -#include "storm-gamebased-ar/abstraction/StateSet.h" -#include "storm-gamebased-ar/abstraction/SymbolicQualitativeGameResultMinMax.h" -#include "storm-gamebased-ar/abstraction/SymbolicQualitativeMdpResult.h" -#include "storm-gamebased-ar/abstraction/SymbolicQualitativeMdpResultMinMax.h" -#include "storm-gamebased-ar/abstraction/SymbolicStateSet.h" - +#include "storm/models/symbolic/Dtmc.h" +#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/models/symbolic/StochasticTwoPlayerGame.h" #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/AbstractionSettings.h" - -#include "storm/utility/graph.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/NotSupportedException.h" +#include "storm/solver/SymbolicGameSolver.h" +#include "storm/storage/dd/Add.h" +#include "storm/storage/dd/Bdd.h" +#include "storm/storage/dd/DdManager.h" #include "storm/utility/constants.h" +#include "storm/utility/graph.h" #include "storm/utility/macros.h" namespace storm::gbar { @@ -91,8 +82,7 @@ std::unique_ptr AbstractAbstractionRefinementM template std::unique_ptr AbstractAbstractionRefinementModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - storm::modelchecker::CheckTask const& checkTask) { + Environment const& env, storm::modelchecker::CheckTask const& checkTask) { this->setCheckTask(checkTask.template substituteFormula(checkTask.getFormula())); return performAbstractionRefinement(env); } diff --git a/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.h b/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.h index 491222552f..6f3b932703 100644 --- a/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.h +++ b/src/storm-gamebased-ar/modelchecker/abstraction/AbstractAbstractionRefinementModelChecker.h @@ -87,8 +87,7 @@ class AbstractAbstractionRefinementModelChecker : public storm::modelchecker::Ab virtual std::unique_ptr computeReachabilityProbabilities( Environment const& env, storm::modelchecker::CheckTask const& checkTask) override; virtual std::unique_ptr computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - storm::modelchecker::CheckTask const& checkTask) override; + Environment const& env, storm::modelchecker::CheckTask const& checkTask) override; protected: /// -------- Methods that need to be overwritten/defined by implementations in subclasses. diff --git a/src/storm-gspn-cli/CMakeLists.txt b/src/storm-gspn-cli/CMakeLists.txt index 2c5e80f123..64ab3c63fb 100644 --- a/src/storm-gspn-cli/CMakeLists.txt +++ b/src/storm-gspn-cli/CMakeLists.txt @@ -1,8 +1,8 @@ # 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 +target_link_libraries(storm-gspn-cli storm-gspn storm-cli-utilities) set_target_properties(storm-gspn-cli PROPERTIES OUTPUT_NAME "storm-gspn") -target_precompile_headers(storm-gspn-cli REUSE_FROM storm-main) +target_precompile_headers(storm-gspn-cli REUSE_FROM storm-cli) add_dependencies(binaries storm-gspn-cli) diff --git a/src/storm-gspn/CMakeLists.txt b/src/storm-gspn/CMakeLists.txt index be2e2a30c5..0b61ef9cb1 100644 --- a/src/storm-gspn/CMakeLists.txt +++ b/src/storm-gspn/CMakeLists.txt @@ -2,8 +2,6 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-gspn/*.h ${PROJECT_S register_source_groups_from_filestructure("${ALL_FILES}" storm-gspn) - - file(GLOB_RECURSE STORM_GSPN_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-gspn/*/*.cpp) file(GLOB_RECURSE STORM_GSPN_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-gspn/*/*.h) @@ -14,9 +12,9 @@ target_precompile_headers(storm-gspn REUSE_FROM storm) # 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 PUBLIC storm storm-conv storm-parsers ${STORM_GSPN_LINK_LIBRARIES}) # Install storm headers to include directory. @@ -37,3 +35,4 @@ add_dependencies(storm-gspn copy_storm_gspn_headers) # installation install(TARGETS storm-gspn EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) + diff --git a/src/storm-gspn/storage/gspn/GSPN.cpp b/src/storm-gspn/storage/gspn/GSPN.cpp index 988b0257ac..8e414baacc 100644 --- a/src/storm-gspn/storage/gspn/GSPN.cpp +++ b/src/storm-gspn/storage/gspn/GSPN.cpp @@ -155,16 +155,14 @@ void GSPN::writeDotToStream(std::ostream& outStream) const { outStream << "digraph " << this->getName() << " {\n"; // print places with initial marking (not printed is the capacity) - outStream << "\t" - << "node [shape=ellipse]\n"; + outStream << "\t" << "node [shape=ellipse]\n"; for (auto& place : this->getPlaces()) { outStream << "\t" << place.getName() << " [label=\"" << place.getName() << "(" << place.getNumberOfInitialTokens(); outStream << ")\"];\n"; } // print transitions with weight/rate - outStream << "\t" - << "node [shape=box]\n"; + outStream << "\t" << "node [shape=box]\n"; for (auto& trans : this->getImmediateTransitions()) { outStream << "\t" << trans.getName() << " [fontcolor=white, style=filled, fillcolor=black, label=<" << trans.getName() diff --git a/src/storm-pars-cli/CMakeLists.txt b/src/storm-pars-cli/CMakeLists.txt index 64f367ad1d..b5f7900443 100644 --- a/src/storm-pars-cli/CMakeLists.txt +++ b/src/storm-pars-cli/CMakeLists.txt @@ -3,11 +3,10 @@ add_executable(storm-pars-cli ${PROJECT_SOURCE_DIR}/src/storm-pars-cli/storm-par ${PROJECT_SOURCE_DIR}/src/storm-pars-cli/print.cpp ${PROJECT_SOURCE_DIR}/src/storm-pars-cli/monotonicity.cpp ${PROJECT_SOURCE_DIR}/src/storm-pars-cli/feasibility.cpp - ) -target_link_libraries(storm-pars-cli storm-pars storm-cli-utilities) # Adding headers for xcode +) +target_link_libraries(storm-pars-cli storm-pars storm-cli-utilities) set_target_properties(storm-pars-cli PROPERTIES OUTPUT_NAME "storm-pars") -target_precompile_headers(storm-pars-cli REUSE_FROM storm-main) - +target_precompile_headers(storm-pars-cli REUSE_FROM storm-cli) add_dependencies(binaries storm-pars-cli) diff --git a/src/storm-pars/CMakeLists.txt b/src/storm-pars/CMakeLists.txt index 2a1790eece..8dca2969b6 100644 --- a/src/storm-pars/CMakeLists.txt +++ b/src/storm-pars/CMakeLists.txt @@ -2,24 +2,20 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-pars/*.h ${PROJECT_S register_source_groups_from_filestructure("${ALL_FILES}" storm-pars) - - file(GLOB_RECURSE STORM_PARS_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-pars/*/*.cpp) file(GLOB_RECURSE STORM_PARS_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-pars/*/*.h) # Create storm-pars. add_library(storm-pars SHARED ${STORM_PARS_SOURCES} ${STORM_PARS_HEADERS}) +target_precompile_headers(storm-pars REUSE_FROM storm) # Remove define symbol for shared libstorm. set_target_properties(storm-pars PROPERTIES DEFINE_SYMBOL "") -#add_dependencies(storm resources) list(APPEND STORM_TARGETS storm-pars) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) target_link_libraries(storm-pars PUBLIC storm ${STORM_PARS_LINK_LIBRARIES}) -target_precompile_headers(storm-pars REUSE_FROM storm) - # Install storm headers to include directory. foreach(HEADER ${STORM_PARS_HEADERS}) diff --git a/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp index 68044ed7bd..4e1309e3f5 100644 --- a/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp +++ b/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp @@ -119,9 +119,7 @@ std::unique_ptr SparseDtmcInstantiationModelCheckercurrentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula()); newCheckTask.setQualitative(true); newCheckTask.setOnlyInitialStatesRelevant(false); - qualitativeResult = modelChecker.computeRewards(env, this->currentCheckTask->getFormula().asRewardOperatorFormula().getMeasureType(), newCheckTask) - ->template asExplicitQuantitativeCheckResult() - .getValueVector(); + qualitativeResult = modelChecker.computeRewards(env, newCheckTask)->template asExplicitQuantitativeCheckResult().getValueVector(); } storm::storage::BitVector maybeStates = storm::utility::vector::filter(qualitativeResult, [](ConstantType const& value) -> bool { return !(storm::utility::isZero(value) || storm::utility::isInfinity(value)); @@ -142,8 +140,7 @@ std::unique_ptr SparseDtmcInstantiationModelCheckercurrentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula()) .setOnlyInitialStatesRelevant(false); - std::unique_ptr quantitativeResult = - modelChecker.computeRewards(env, this->currentCheckTask->getFormula().asRewardOperatorFormula().getMeasureType(), newCheckTask); + std::unique_ptr quantitativeResult = modelChecker.computeRewards(env, newCheckTask); result = quantitativeResult->template asExplicitQuantitativeCheckResult().compareAgainstBound( this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(), this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs()); diff --git a/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp index 1aaf9112a8..e42edf2233 100644 --- a/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp +++ b/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp @@ -150,9 +150,7 @@ std::unique_ptr SparseMdpInstantiationModelCheckercurrentCheckTask->getFormula().asRewardOperatorFormula().getMeasureType(), newCheckTask) - ->template asExplicitQuantitativeCheckResult() - .getValueVector(); + qualitativeResult = modelChecker.computeRewards(env, newCheckTask)->template asExplicitQuantitativeCheckResult().getValueVector(); } storm::storage::BitVector maybeStates = storm::utility::vector::filter(qualitativeResult, [](ConstantType const& value) -> bool { return !(storm::utility::isZero(value) || storm::utility::isInfinity(value)); @@ -181,8 +179,7 @@ std::unique_ptr SparseMdpInstantiationModelCheckercurrentCheckTask->substituteFormula(this->currentCheckTask->getFormula().asOperatorFormula().getSubformula()) .setOnlyInitialStatesRelevant(false); - std::unique_ptr quantitativeResult = - modelChecker.computeRewards(env, this->currentCheckTask->getFormula().asRewardOperatorFormula().getMeasureType(), newCheckTask); + std::unique_ptr quantitativeResult = modelChecker.computeRewards(env, newCheckTask); result = quantitativeResult->template asExplicitQuantitativeCheckResult().compareAgainstBound( this->currentCheckTask->getFormula().asOperatorFormula().getComparisonType(), this->currentCheckTask->getFormula().asOperatorFormula().template getThresholdAs()); diff --git a/src/storm-pars/transformer/SparseParametricDtmcSimplifier.cpp b/src/storm-pars/transformer/SparseParametricDtmcSimplifier.cpp index dbe9f7de25..7258cbb5b2 100644 --- a/src/storm-pars/transformer/SparseParametricDtmcSimplifier.cpp +++ b/src/storm-pars/transformer/SparseParametricDtmcSimplifier.cpp @@ -1,7 +1,8 @@ #include "storm-pars/transformer/SparseParametricDtmcSimplifier.h" #include "storm/adapters/RationalFunctionAdapter.h" - +#include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/UnexpectedException.h" #include "storm/logic/CloneVisitor.h" #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" @@ -10,9 +11,6 @@ #include "storm/transformer/GoalStateMerger.h" #include "storm/utility/graph.h" -#include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/UnexpectedException.h" - namespace storm { namespace transformer { @@ -186,8 +184,8 @@ bool SparseParametricDtmcSimplifier::simplifyForReachabilityRew // obtain the simplified formula for the simplified model auto labelFormula = std::make_shared(targetLabel); auto eventuallyFormula = std::make_shared(labelFormula, storm::logic::FormulaContext::Reward); - this->simplifiedFormula = std::make_shared( - eventuallyFormula, rewardModelNameAsVector.front(), formula.getOperatorInformation(), storm::logic::RewardMeasureType::Expectation); + this->simplifiedFormula = + std::make_shared(eventuallyFormula, rewardModelNameAsVector.front(), formula.getOperatorInformation()); // Eliminate all states for which all outgoing transitions are constant storm::storage::BitVector considerForElimination = ~this->simplifiedModel->getInitialStates(); diff --git a/src/storm-pars/transformer/SparseParametricMdpSimplifier.cpp b/src/storm-pars/transformer/SparseParametricMdpSimplifier.cpp index 776ddb493a..375690682f 100644 --- a/src/storm-pars/transformer/SparseParametricMdpSimplifier.cpp +++ b/src/storm-pars/transformer/SparseParametricMdpSimplifier.cpp @@ -1,7 +1,8 @@ #include "storm-pars/transformer/SparseParametricMdpSimplifier.h" #include "storm/adapters/RationalFunctionAdapter.h" - +#include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/UnexpectedException.h" #include "storm/logic/CloneVisitor.h" #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" @@ -12,9 +13,6 @@ #include "storm/utility/graph.h" #include "storm/utility/vector.h" -#include "storm/exceptions/NotSupportedException.h" -#include "storm/exceptions/UnexpectedException.h" - namespace storm { namespace transformer { @@ -233,8 +231,8 @@ bool SparseParametricMdpSimplifier::simplifyForReachabilityRewa // obtain the simplified formula for the simplified model auto labelFormula = std::make_shared(targetLabel); auto eventuallyFormula = std::make_shared(labelFormula, storm::logic::FormulaContext::Reward); - this->simplifiedFormula = std::make_shared( - eventuallyFormula, rewardModelNameAsVector.front(), formula.getOperatorInformation(), storm::logic::RewardMeasureType::Expectation); + this->simplifiedFormula = + std::make_shared(eventuallyFormula, rewardModelNameAsVector.front(), formula.getOperatorInformation()); // Eliminate all states for which all outgoing transitions are constant storm::storage::BitVector considerForElimination = ~this->simplifiedModel->getInitialStates(); diff --git a/src/storm-parsers/CMakeLists.txt b/src/storm-parsers/CMakeLists.txt index ed64ce298c..3832c90d7e 100644 --- a/src/storm-parsers/CMakeLists.txt +++ b/src/storm-parsers/CMakeLists.txt @@ -2,25 +2,23 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-parsers/*.h ${PROJEC 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}) +target_precompile_headers(storm-parsers REUSE_FROM storm) # 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) -target_precompile_headers(storm-parsers REUSE_FROM storm) # Install storm headers to include directory. foreach(HEADER ${STORM_PARSER_HEADERS}) diff --git a/src/storm-parsers/parser/FormulaParserGrammar.cpp b/src/storm-parsers/parser/FormulaParserGrammar.cpp index 25934927a6..74f72678ec 100644 --- a/src/storm-parsers/parser/FormulaParserGrammar.cpp +++ b/src/storm-parsers/parser/FormulaParserGrammar.cpp @@ -1,8 +1,9 @@ #include "FormulaParserGrammar.h" -#include "storm/storage/expressions/ExpressionManager.h" #include +#include "storm/storage/expressions/ExpressionManager.h" + namespace storm { namespace parser { @@ -32,7 +33,6 @@ void FormulaParserGrammar::initialize() { nonStandardKeywords_.name("non-standard Storm-specific keyword"); relationalOperator_.name("relational operator"); optimalityOperator_.name("optimality operator"); - rewardMeasureType_.name("reward measure"); operatorKeyword_.name("Operator keyword"); filterType_.name("filter type"); @@ -68,13 +68,9 @@ void FormulaParserGrammar::initialize() { operatorSubFormula.name("operator subformula"); rewardModelName = qi::eps(qi::_r1 == storm::logic::FormulaContext::Reward) >> (qi::lit("{\"") > label > qi::lit("\"}")); rewardModelName.name("reward model name"); - rewardMeasureType = qi::eps(qi::_r1 == storm::logic::FormulaContext::Reward || qi::_r1 == storm::logic::FormulaContext::Time) >> qi::lit("[") >> - rewardMeasureType_ >> qi::lit("]"); - rewardMeasureType.name("reward measure type"); operatorFormula = - (operatorKeyword_[qi::_a = qi::_1] > -rewardMeasureType(qi::_a) > -rewardModelName(qi::_a) > operatorInformation > qi::lit("[") > - operatorSubFormula(qi::_a) > - qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorFormula, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_4, qi::_5)]; + (operatorKeyword_[qi::_a = qi::_1] > -rewardModelName(qi::_a) > operatorInformation > qi::lit("[") > operatorSubFormula(qi::_a) > + qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createOperatorFormula, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_4)]; operatorFormula.name("operator formula"); // Atomic propositions @@ -247,7 +243,6 @@ void FormulaParserGrammar::initialize() { // Enable the following lines to print debug output for most the rules. // debug(rewardModelName) - // debug(rewardMeasureType) // debug(operatorFormula) // debug(labelFormula) // debug(expressionFormula) @@ -286,7 +281,6 @@ void FormulaParserGrammar::initialize() { // Enable error reporting. qi::on_error(rewardModelName, handler(qi::_1, qi::_2, qi::_3, qi::_4)); - qi::on_error(rewardMeasureType, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error(operatorFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error(labelFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); qi::on_error(expressionFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4)); @@ -514,22 +508,22 @@ storm::logic::OperatorInformation FormulaParserGrammar::createOperatorInformatio } } -std::shared_ptr FormulaParserGrammar::createOperatorFormula( - storm::logic::FormulaContext const& context, boost::optional const& rewardMeasureType, - boost::optional const& rewardModelName, storm::logic::OperatorInformation const& operatorInformation, - std::shared_ptr const& subformula) { +std::shared_ptr FormulaParserGrammar::createOperatorFormula(storm::logic::FormulaContext const& context, + boost::optional const& rewardModelName, + storm::logic::OperatorInformation const& operatorInformation, + std::shared_ptr const& subformula) { switch (context) { case storm::logic::FormulaContext::Probability: - STORM_LOG_ASSERT(!rewardMeasureType && !rewardModelName, "Probability operator with reward information parsed"); + STORM_LOG_ASSERT(!rewardModelName, "Probability operator with reward information parsed"); return createProbabilityOperatorFormula(operatorInformation, subformula); case storm::logic::FormulaContext::Reward: - return createRewardOperatorFormula(rewardMeasureType, rewardModelName, operatorInformation, subformula); + return createRewardOperatorFormula(rewardModelName, operatorInformation, subformula); case storm::logic::FormulaContext::LongRunAverage: - STORM_LOG_ASSERT(!rewardMeasureType && !rewardModelName, "LRA operator with reward information parsed"); + STORM_LOG_ASSERT(!rewardModelName, "LRA operator with reward information parsed"); return createLongRunAverageOperatorFormula(operatorInformation, subformula); case storm::logic::FormulaContext::Time: STORM_LOG_ASSERT(!rewardModelName, "Time operator with reward model name parsed"); - return createTimeOperatorFormula(rewardMeasureType, operatorInformation, subformula); + return createTimeOperatorFormula(operatorInformation, subformula); default: STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Unexpected formula context."); } @@ -541,23 +535,14 @@ std::shared_ptr FormulaParserGrammar::createLongRun } std::shared_ptr FormulaParserGrammar::createRewardOperatorFormula( - boost::optional const& rewardMeasureType, boost::optional const& rewardModelName, - storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula) const { - storm::logic::RewardMeasureType measureType = storm::logic::RewardMeasureType::Expectation; - if (rewardMeasureType) { - measureType = rewardMeasureType.get(); - } - return std::shared_ptr(new storm::logic::RewardOperatorFormula(subformula, rewardModelName, operatorInformation, measureType)); + boost::optional const& rewardModelName, storm::logic::OperatorInformation const& operatorInformation, + std::shared_ptr const& subformula) const { + return std::shared_ptr(new storm::logic::RewardOperatorFormula(subformula, rewardModelName, operatorInformation)); } std::shared_ptr FormulaParserGrammar::createTimeOperatorFormula( - boost::optional const& rewardMeasureType, storm::logic::OperatorInformation const& operatorInformation, - std::shared_ptr const& subformula) const { - storm::logic::RewardMeasureType measureType = storm::logic::RewardMeasureType::Expectation; - if (rewardMeasureType) { - measureType = rewardMeasureType.get(); - } - return std::shared_ptr(new storm::logic::TimeOperatorFormula(subformula, operatorInformation, measureType)); + storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula) const { + return std::shared_ptr(new storm::logic::TimeOperatorFormula(subformula, operatorInformation)); } std::shared_ptr FormulaParserGrammar::createProbabilityOperatorFormula( diff --git a/src/storm-parsers/parser/FormulaParserGrammar.h b/src/storm-parsers/parser/FormulaParserGrammar.h index b0e13a62d0..ae5dcca9fb 100644 --- a/src/storm-parsers/parser/FormulaParserGrammar.h +++ b/src/storm-parsers/parser/FormulaParserGrammar.h @@ -1,20 +1,17 @@ #pragma once +#include #include #include -#include - #include "storm-parsers/parser/ConstantDataType.h" #include "storm-parsers/parser/ExpressionParser.h" #include "storm-parsers/parser/SpiritErrorHandler.h" #include "storm/exceptions/WrongFormatException.h" #include "storm/logic/Formulas.h" -#include "storm/storage/jani/Property.h" - #include "storm/modelchecker/results/FilterType.h" - #include "storm/storage/expressions/ExpressionEvaluator.h" +#include "storm/storage/jani/Property.h" namespace storm { namespace logic { @@ -81,15 +78,6 @@ class FormulaParserGrammar : public qi::grammar { - rewardMeasureTypeStruct() { - add("exp", storm::logic::RewardMeasureType::Expectation)("var", storm::logic::RewardMeasureType::Variance); - } - }; - - // A parser used for recognizing the reward measure types. - rewardMeasureTypeStruct rewardMeasureType_; - struct filterTypeStruct : qi::symbols { filterTypeStruct() { add("min", storm::modelchecker::FilterType::MIN)("max", storm::modelchecker::FilterType::MAX)("sum", storm::modelchecker::FilterType::SUM)( @@ -140,7 +128,6 @@ class FormulaParserGrammar : public qi::grammar>, Skipper> operatorInformation; qi::rule(storm::logic::FormulaContext), Skipper> operatorSubFormula; qi::rule rewardModelName; - qi::rule rewardMeasureType; qi::rule(), qi::locals, Skipper> operatorFormula; // Atomic propositions @@ -255,18 +242,15 @@ class FormulaParserGrammar : public qi::grammar const& comparisonType, boost::optional const& threshold) const; std::shared_ptr createOperatorFormula(storm::logic::FormulaContext const& context, - boost::optional const& rewardMeasureType, boost::optional const& rewardModelName, storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula); std::shared_ptr createLongRunAverageOperatorFormula(storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula) const; - std::shared_ptr createRewardOperatorFormula(boost::optional const& rewardMeasureType, - boost::optional const& rewardModelName, + std::shared_ptr createRewardOperatorFormula(boost::optional const& rewardModelName, storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula) const; - std::shared_ptr createTimeOperatorFormula(boost::optional const& rewardMeasureType, - storm::logic::OperatorInformation const& operatorInformation, + std::shared_ptr createTimeOperatorFormula(storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula) const; std::shared_ptr createProbabilityOperatorFormula(storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr const& subformula); diff --git a/src/storm-parsers/parser/JaniParser.cpp b/src/storm-parsers/parser/JaniParser.cpp index 2997cda243..40e48619d0 100644 --- a/src/storm-parsers/parser/JaniParser.cpp +++ b/src/storm-parsers/parser/JaniParser.cpp @@ -12,6 +12,7 @@ #include "storm/storage/jani/TemplateEdge.h" #include "storm/storage/jani/expressions/JaniExpressions.h" #include "storm/storage/jani/visitor/CompositionInformationVisitor.h" +#include "storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.h" #include "storm/storage/jani/types/ArrayType.h" #include "storm/storage/jani/types/BasicType.h" @@ -47,8 +48,8 @@ template const bool JaniParser::defaultVariableTransient = false; const std::string VARIABLE_AUTOMATON_DELIMITER = "_"; template -const std::set JaniParser::unsupportedOpstrings({"sin", "cos", "tan", "cot", "sec", "csc", "asin", "acos", - "atan", "acot", "asec", "acsc", "sinh", "cosh", "tanh", "coth", +const std::set JaniParser::unsupportedOpstrings({"tan", "cot", "sec", "csc", "asin", "acos", "atan", + "acot", "asec", "acsc", "sinh", "cosh", "tanh", "coth", "sech", "csch", "asinh", "acosh", "atanh", "asinh", "acosh"}); template @@ -125,7 +126,7 @@ std::pair> JaniParser(feature, "Model feature"); bool found = false; @@ -758,7 +759,8 @@ std::shared_ptr JaniParser::parseConstant(Json // variable occurs also on the assignment. definingExpression = parseExpression(constantStructure.at("value"), scope.refine("Value of constant " + name)); assert(definingExpression.isInitialized()); - STORM_LOG_THROW((type.second == definingExpression.getType() || type.second.isRationalType() && definingExpression.getType().isIntegerType()), + // Check that the defined and actual expression value match OR the defined value is a rational and the actual value is a numerical type. + STORM_LOG_THROW((type.second == definingExpression.getType() || type.second.isRationalType() && definingExpression.getType().isNumericalType()), storm::exceptions::InvalidJaniException, "Type of value for constant '" + name + "' (scope: " + scope.description + ") does not match the given type '" + type.first->getStringRepresentation() + "."); @@ -846,7 +848,11 @@ std::pair, storm::expressions::Type> Jani "Upper bound for bounded real variable " << variableName << "(scope: " << scope.description << ") must be numeric"); if (lowerboundExpr.isInitialized() && upperboundExpr.isInitialized() && !lowerboundExpr.containsVariables() && !upperboundExpr.containsVariables()) { - STORM_LOG_THROW(lowerboundExpr.evaluateAsRational() <= upperboundExpr.evaluateAsRational(), storm::exceptions::InvalidJaniException, + using SubMap = std::map; + storm::expressions::JaniExpressionSubstitutionVisitor transcendentalVisitor(SubMap(), true); + const storm::RationalNumber lowerboundValue = transcendentalVisitor.substitute(lowerboundExpr).evaluateAsRational(); + const storm::RationalNumber upperboundValue = transcendentalVisitor.substitute(upperboundExpr).evaluateAsRational(); + STORM_LOG_THROW(lowerboundValue <= upperboundValue, storm::exceptions::InvalidJaniException, "Lower bound must not be larger than upper bound for bounded real variable " << variableName << "(scope: " << scope.description << ")."); } @@ -1333,6 +1339,16 @@ storm::expressions::Expression JaniParser::parseExpression(Json const ensureNumericalType(arguments[0], opstring, 0, scope.description); ensureNumericalType(arguments[1], opstring, 1, scope.description); return storm::expressions::logarithm(arguments[0], arguments[1]); + } else if (opstring == "cos") { + arguments = parseUnaryExpressionArguments(expressionStructure, opstring, scope, returnNoneInitializedOnUnknownOperator, auxiliaryVariables); + assert(arguments.size() == 1); + ensureNumericalType(arguments[0], opstring, 0, scope.description); + return storm::expressions::cos(arguments[0]); + } else if (opstring == "sin") { + arguments = parseUnaryExpressionArguments(expressionStructure, opstring, scope, returnNoneInitializedOnUnknownOperator, auxiliaryVariables); + assert(arguments.size() == 1); + ensureNumericalType(arguments[0], opstring, 0, scope.description); + return storm::expressions::sin(arguments[0]); } else if (opstring == "aa") { STORM_LOG_THROW(expressionStructure.count("exp") == 1, storm::exceptions::InvalidJaniException, "Array access operator requires exactly one exp (at " + scope.description + ")."); @@ -1432,6 +1448,20 @@ storm::expressions::Expression JaniParser::parseExpression(Json const STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Unknown operator " << opstring << " in " << scope.description << "."); } } + if (expressionStructure.count("constant") == 1) { + // Convert constants to a numeric value (only PI and Euler number, as in Jani specification) + const std::string constantStr = getString(expressionStructure.at("constant"), scope.description); + if (constantStr == "π") { + return std::make_shared( + *expressionManager, storm::expressions::TranscendentalNumberLiteralExpression::TranscendentalNumber::PI) + ->toExpression(); + } + if (constantStr == "e") { + return std::make_shared( + *expressionManager, storm::expressions::TranscendentalNumberLiteralExpression::TranscendentalNumber::E) + ->toExpression(); + } + } STORM_LOG_THROW( false, storm::exceptions::InvalidJaniException, "No supported operator declaration found for complex expressions as " << expressionStructure.dump() << " in " << scope.description << "."); diff --git a/src/storm-parsers/parser/SpiritErrorHandler.h b/src/storm-parsers/parser/SpiritErrorHandler.h index 6ea93ce5ff..d2eca180da 100644 --- a/src/storm-parsers/parser/SpiritErrorHandler.h +++ b/src/storm-parsers/parser/SpiritErrorHandler.h @@ -18,8 +18,7 @@ struct SpiritErrorHandler { std::string line(lineStart, lineEnd); std::stringstream stream; - stream << "Parsing error at " << get_line(where) << ":" << boost::spirit::get_column(lineStart, where) << ": " - << " expecting " << what << ", here:\n"; + stream << "Parsing error at " << get_line(where) << ":" << boost::spirit::get_column(lineStart, where) << ": " << " expecting " << what << ", here:\n"; stream << "\t" << line << '\n'; auto caretColumn = boost::spirit::get_column(lineStart, where); stream << "\t" << std::string(caretColumn - 1, ' ') << "^\n"; diff --git a/src/storm-permissive/CMakeLists.txt b/src/storm-permissive/CMakeLists.txt index cf28faa834..7a25c23ff7 100644 --- a/src/storm-permissive/CMakeLists.txt +++ b/src/storm-permissive/CMakeLists.txt @@ -5,8 +5,10 @@ register_source_groups_from_filestructure("${ALL_FILES}" storm-permissive) file(GLOB_RECURSE STORM_PERMISSIVE_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-permissive/*/*.cpp) file(GLOB_RECURSE STORM_PERMISSIVE_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-permissive/*/*.h) + # Create storm-permissive. add_library(storm-permissive SHARED ${STORM_PERMISSIVE_SOURCES} ${STORM_PERMISSIVE_HEADERS}) +target_precompile_headers(storm-permissive REUSE_FROM storm) # Remove define symbol for shared libstorm. set_target_properties(storm-permissive PROPERTIES DEFINE_SYMBOL "") @@ -14,21 +16,20 @@ list(APPEND STORM_TARGETS storm-permissive) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) target_link_libraries(storm-permissive PUBLIC storm) -target_precompile_headers(storm-permissive REUSE_FROM storm) # Install storm headers to include directory. foreach (HEADER ${STORM_PERMISSIVE_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_PERMISSIVE_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") -endforeach () + 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_PERMISSIVE_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") +endforeach() add_custom_target(copy_storm_permissive_headers DEPENDS ${STORM_PERMISSIVE_OUTPUT_HEADERS} ${STORM_PERMISSIVE_HEADERS}) add_dependencies(storm-permissive copy_storm_permissive_headers) diff --git a/src/storm-pomdp-cli/CMakeLists.txt b/src/storm-pomdp-cli/CMakeLists.txt index 75c15ed65d..8611dcd377 100644 --- a/src/storm-pomdp-cli/CMakeLists.txt +++ b/src/storm-pomdp-cli/CMakeLists.txt @@ -1,11 +1,10 @@ # Create storm-pomdp. - file(GLOB_RECURSE STORM_POMDP_CLI_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-pomdp-cli/*/*.cpp) + add_executable(storm-pomdp-cli ${PROJECT_SOURCE_DIR}/src/storm-pomdp-cli/storm-pomdp.cpp ${STORM_POMDP_CLI_SOURCES}) -target_link_libraries(storm-pomdp-cli storm-pomdp storm-cli-utilities) # Adding headers for xcode +target_link_libraries(storm-pomdp-cli storm-pomdp storm-cli-utilities) set_target_properties(storm-pomdp-cli PROPERTIES OUTPUT_NAME "storm-pomdp") -target_precompile_headers(storm-pomdp-cli REUSE_FROM storm-main) - +target_precompile_headers(storm-pomdp-cli REUSE_FROM storm-cli) add_dependencies(binaries storm-pomdp-cli) diff --git a/src/storm-pomdp/CMakeLists.txt b/src/storm-pomdp/CMakeLists.txt index 50805fc617..2a9b8cdfe6 100644 --- a/src/storm-pomdp/CMakeLists.txt +++ b/src/storm-pomdp/CMakeLists.txt @@ -2,8 +2,6 @@ file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-pomdp/*.h ${PROJECT_ register_source_groups_from_filestructure("${ALL_FILES}" storm-pomdp) - - file(GLOB_RECURSE STORM_POMDP_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-pomdp/*/*.cpp) file(GLOB_RECURSE STORM_POMDP_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-pomdp/*/*.h) @@ -11,9 +9,9 @@ file(GLOB_RECURSE STORM_POMDP_HEADERS ${PROJECT_SOURCE_DIR}/src/storm-pomdp/*/*. # Create storm-pomdp. add_library(storm-pomdp SHARED ${STORM_POMDP_SOURCES} ${STORM_POMDP_HEADERS}) target_precompile_headers(storm-pomdp REUSE_FROM storm) + # Remove define symbol for shared libstorm. set_target_properties(storm-pomdp PROPERTIES DEFINE_SYMBOL "") -#add_dependencies(storm resources) list(APPEND STORM_TARGETS storm-pomdp) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) @@ -21,16 +19,16 @@ target_link_libraries(storm-pomdp PUBLIC storm storm-parsers storm-pars ${STORM_ # Install storm headers to include directory. foreach(HEADER ${STORM_POMDP_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_POMDP_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") + 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_POMDP_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") endforeach() add_custom_target(copy_storm_pomdp_headers DEPENDS ${STORM_POMDP_OUTPUT_HEADERS} ${STORM_POMDP_HEADERS}) add_dependencies(storm-pomdp copy_storm_pomdp_headers) diff --git a/src/storm-pomdp/modelchecker/BeliefExplorationPomdpModelChecker.cpp b/src/storm-pomdp/modelchecker/BeliefExplorationPomdpModelChecker.cpp index 8fdfd8e81a..2dc5b31f5f 100644 --- a/src/storm-pomdp/modelchecker/BeliefExplorationPomdpModelChecker.cpp +++ b/src/storm-pomdp/modelchecker/BeliefExplorationPomdpModelChecker.cpp @@ -721,8 +721,7 @@ void BeliefExplorationPomdpModelChecker::UnfoldingControl::Pause && - !storm::utility::resources::isTerminate()) - ; + !storm::utility::resources::isTerminate()); } STORM_LOG_INFO("\tInteractive Unfolding terminated.\n"); } @@ -1090,8 +1089,8 @@ bool BeliefExplorationPomdpModelChecker= 60) { printUpdateStopwatch.restart(); - STORM_PRINT_AND_LOG("### " << underApproximation->getCurrentNumberOfMdpStates() << " beliefs in underapproximation MDP" - << " ##### " << underApproximation->getUnexploredStates().size() << " beliefs queued\n"); + STORM_PRINT_AND_LOG("### " << underApproximation->getCurrentNumberOfMdpStates() << " beliefs in underapproximation MDP" << " ##### " + << underApproximation->getUnexploredStates().size() << " beliefs queued\n"); if (underApproximation->getCurrentNumberOfMdpStates() > heuristicParameters.sizeThreshold && options.useClipping) { STORM_PRINT_AND_LOG("##### Clipping Attempts: " << statistics.nrClippingAttempts.value() << " ##### " << "Clipped States: " << statistics.nrClippedStates.value() << "\n"); diff --git a/src/storm-pomdp/modelchecker/PreprocessingPomdpValueBoundsModelChecker.cpp b/src/storm-pomdp/modelchecker/PreprocessingPomdpValueBoundsModelChecker.cpp index d678a5d86a..dbcf2b2cc7 100644 --- a/src/storm-pomdp/modelchecker/PreprocessingPomdpValueBoundsModelChecker.cpp +++ b/src/storm-pomdp/modelchecker/PreprocessingPomdpValueBoundsModelChecker.cpp @@ -18,8 +18,7 @@ namespace pomdp { namespace modelchecker { template PreprocessingPomdpValueBoundsModelChecker::PreprocessingPomdpValueBoundsModelChecker(storm::models::sparse::Pomdp const& pomdp) - : pomdp(pomdp) { /* Intentionally left empty */ -} + : pomdp(pomdp) { /* Intentionally left empty */ } template typename PreprocessingPomdpValueBoundsModelChecker::ValueBounds PreprocessingPomdpValueBoundsModelChecker::getValueBounds( diff --git a/src/storm-version-info/CMakeLists.txt b/src/storm-version-info/CMakeLists.txt index ab3b8a85d5..272c176e35 100644 --- a/src/storm-version-info/CMakeLists.txt +++ b/src/storm-version-info/CMakeLists.txt @@ -1,5 +1,5 @@ - file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-version-info/*.h ${PROJECT_SOURCE_DIR}/src/storm-version-info/*.cpp) + register_source_groups_from_filestructure("${ALL_FILES}" storm-version-info) file(GLOB_RECURSE STORM_VERSION_INFO_SOURCES ${PROJECT_SOURCE_DIR}/src/storm-version-info/*.cpp) @@ -20,7 +20,6 @@ add_library(storm-version-info SHARED ${STORM_VERSION_INFO_SOURCES} ${STORM_VERS # Remove define symbol for shared libstorm. set_target_properties(storm-version-info PROPERTIES DEFINE_SYMBOL "") - # Add dependency to core storm libary. We are not going to link against it to avoid unnecessary linking steps, but we still want to build storm-version-info as often as possible. add_dependencies(storm storm-version-info) list(APPEND STORM_TARGETS storm-version-info) @@ -28,16 +27,16 @@ set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) # Install storm headers to include directory. foreach(HEADER ${STORM_VERSION_INFO_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_VERSION_INFO_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") + 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_VERSION_INFO_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") endforeach() add_custom_target(copy_storm_version_info_headers DEPENDS ${STORM_VERSION_INFO_OUTPUT_HEADERS} ${STORM_VERSION_INFO_HEADERS}) add_dependencies(storm-version-info copy_storm_version_info_headers) diff --git a/src/storm/CMakeLists.txt b/src/storm/CMakeLists.txt index 943b4cfaee..0a1e20d444 100644 --- a/src/storm/CMakeLists.txt +++ b/src/storm/CMakeLists.txt @@ -1,15 +1,3 @@ -# Storm versions before 1.6.0 generated an in-source .cpp file containing version information. -# When users upgrade from such a version, the generated file will still be there. -# We now delete this file to prevent building issues as there is no corresponding .h file (anymore). -if ((EXISTS "${PROJECT_SOURCE_DIR}/src/storm/utility/storm-version.cpp")) - file(READ "${PROJECT_SOURCE_DIR}/src/storm/utility/storm-version.cpp" STORM_OLD_VERSION_FILE) - string(FIND "${STORM_OLD_VERSION_FILE}" "// AUTO GENERATED -- DO NOT CHANGE" STORM_OLD_VERSION_FILE_DETECTED) - if (STORM_OLD_VERSION_FILE_DETECTED EQUAL 0) - message(WARNING "Storm - The file ${PROJECT_SOURCE_DIR}/src/storm/utility/storm-version.cpp was probably generated by an old Storm version and will be deleted now.") - file(REMOVE "${PROJECT_SOURCE_DIR}/src/storm/utility/storm-version.cpp") - endif(STORM_OLD_VERSION_FILE_DETECTED EQUAL 0) -endif() - file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm/*.h ${PROJECT_SOURCE_DIR}/src/storm/*.cpp) register_source_groups_from_filestructure("${ALL_FILES}" storm) @@ -19,17 +7,12 @@ register_source_groups_from_filestructure("${ALL_FILES}" storm) ## Source file aggregation and clustering ## ############################################################# +file(GLOB_RECURSE STORM_SOURCES ${PROJECT_SOURCE_DIR}/src/storm/*/*.cpp) file(GLOB_RECURSE STORM_HEADERS ${PROJECT_SOURCE_DIR}/src/storm/*.h) -file(GLOB_RECURSE STORM_SOURCES_WITHOUT_MAIN ${PROJECT_SOURCE_DIR}/src/storm/*/*.cpp) -file(GLOB_RECURSE STORM_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm/storm.cpp) # Additional include files like the storm-config.h file(GLOB_RECURSE STORM_BUILD_HEADERS ${PROJECT_BINARY_DIR}/include/*.h) -set(STORM_LIB_SOURCES ${STORM_3RDPARTY_SOURCES} ${STORM_SOURCES_WITHOUT_MAIN}) -set(STORM_LIB_HEADERS ${STORM_HEADERS}) -set(STORM_MAIN_SOURCES ${STORM_MAIN_FILE}) - # Add custom additional include or link directories if (ADDITIONAL_INCLUDE_DIRS) message(STATUS "Storm - Using additional include directories ${ADDITIONAL_INCLUDE_DIRS}") @@ -48,7 +31,7 @@ endif(ADDITIONAL_LINK_DIRS) ############################################################################### # Create libstorm. -add_library(storm SHARED ${STORM_LIB_SOURCES} ${STORM_LIB_HEADERS}) +add_library(storm SHARED ${STORM_3RDPARTY_SOURCES} ${STORM_SOURCES} ${STORM_HEADERS}) target_precompile_headers(storm PRIVATE ${STORM_PRECOMPILED_HEADERS}) # Remove define symbol for shared libstorm. set_target_properties(storm PROPERTIES DEFINE_SYMBOL "") @@ -58,14 +41,8 @@ target_link_libraries(storm PUBLIC ${STORM_DEP_TARGETS} ${STORM_DEP_IMP_TARGETS} list(APPEND STORM_TARGETS storm) set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE) -# Create storm. -add_executable(storm-main ${STORM_MAIN_SOURCES} ${STORM_MAIN_HEADERS}) -target_link_libraries(storm-main PUBLIC storm storm-cli-utilities) -set_target_properties(storm-main PROPERTIES OUTPUT_NAME "storm") -target_precompile_headers(storm-main PRIVATE ${STORM_PRECOMPILED_HEADERS}) - # Install storm headers to include directory. -foreach(HEADER ${STORM_LIB_HEADERS}) +foreach(HEADER ${STORM_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}) @@ -77,14 +54,12 @@ foreach(HEADER ${STORM_LIB_HEADERS}) ) list(APPEND STORM_OUTPUT_HEADERS "${CMAKE_BINARY_DIR}/include/${RELATIVE_DIRECTORY}${HEADER_FILENAME}") endforeach() -add_custom_target(copy_storm_headers DEPENDS ${STORM_OUTPUT_HEADERS} ${STORM_LIB_HEADERS}) +add_custom_target(copy_storm_headers DEPENDS ${STORM_OUTPUT_HEADERS} ${STORM_HEADERS}) add_dependencies(storm copy_storm_headers) add_dependencies(storm copy_resources_headers) -add_dependencies(binaries storm-main) # installation install(TARGETS storm EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib) -install(TARGETS storm-main EXPORT storm_Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL) install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION include/storm FILES_MATCHING PATTERN "*.h") diff --git a/src/storm/adapters/Smt2ExpressionAdapter.h b/src/storm/adapters/Smt2ExpressionAdapter.h index c5e49e1766..aa89d50527 100644 --- a/src/storm/adapters/Smt2ExpressionAdapter.h +++ b/src/storm/adapters/Smt2ExpressionAdapter.h @@ -61,9 +61,7 @@ class Smt2ExpressionAdapter { */ std::string translateExpression(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation) { std::stringstream ss; - ss << "(" << relation << " " << leftHandSide.toString(false, useReadableVarNames) << " " - << "0 " - << ")"; + ss << "(" << relation << " " << leftHandSide.toString(false, useReadableVarNames) << " " << "0 " << ")"; return ss.str(); } diff --git a/src/storm/api/properties.cpp b/src/storm/api/properties.cpp index d0063d8833..db27cea362 100644 --- a/src/storm/api/properties.cpp +++ b/src/storm/api/properties.cpp @@ -22,6 +22,14 @@ std::vector substituteConstantsInProperties(std::vector substituteTranscendentalNumbersInProperties(std::vector const& properties) { + std::vector preprocessedProperties; + for (auto const& property : properties) { + preprocessedProperties.emplace_back(property.substituteTranscendentalNumbers()); + } + return preprocessedProperties; +} + std::vector filterProperties(std::vector const& properties, boost::optional> const& propertyFilter) { if (propertyFilter) { diff --git a/src/storm/api/properties.h b/src/storm/api/properties.h index bc22dcc360..5562133185 100644 --- a/src/storm/api/properties.h +++ b/src/storm/api/properties.h @@ -32,6 +32,7 @@ namespace api { // Process properties. std::vector substituteConstantsInProperties(std::vector const& properties, std::map const& substitution); +std::vector substituteTranscendentalNumbersInProperties(std::vector const& properties); std::vector filterProperties(std::vector const& properties, boost::optional> const& propertyFilter); std::vector> extractFormulasFromProperties(std::vector const& properties); diff --git a/src/storm/automata/DeterministicAutomaton.cpp b/src/storm/automata/DeterministicAutomaton.cpp index 5455b1b01d..d5922620ff 100644 --- a/src/storm/automata/DeterministicAutomaton.cpp +++ b/src/storm/automata/DeterministicAutomaton.cpp @@ -65,8 +65,7 @@ void DeterministicAutomaton::printHOA(std::ostream& out) const { out << "Acceptance: " << acceptance->getNumberOfAcceptanceSets() << " " << *acceptance->getAcceptanceExpression() << "\n"; - out << "--BODY--" - << "\n"; + out << "--BODY--" << "\n"; for (std::size_t s = 0; s < getNumberOfStates(); s++) { out << "State: " << s; diff --git a/src/storm/automata/LTL2DeterministicAutomaton.cpp b/src/storm/automata/LTL2DeterministicAutomaton.cpp index 048f0b89ef..b21b2f6f1c 100644 --- a/src/storm/automata/LTL2DeterministicAutomaton.cpp +++ b/src/storm/automata/LTL2DeterministicAutomaton.cpp @@ -79,8 +79,7 @@ std::shared_ptr LTL2DeterministicAutomaton::ltl2daExtern int status; // wait for completion - while (wait(&status) != pid) - ; + while (wait(&status) != pid); int rv; if (WIFEXITED(status)) { diff --git a/src/storm/builder/ExplicitModelBuilder.cpp b/src/storm/builder/ExplicitModelBuilder.cpp index 4871df253b..e6f7aad7de 100644 --- a/src/storm/builder/ExplicitModelBuilder.cpp +++ b/src/storm/builder/ExplicitModelBuilder.cpp @@ -205,47 +205,50 @@ void ExplicitModelBuilder::buildMatrices( behavior = generator->expand(stateToIdCallback); } - // If there is no behavior, we might have to introduce a self-loop. if (behavior.empty()) { - if (options.fixDeadlocks || !behavior.wasExpanded()) { - // If the behavior was actually expanded and yet there are no transitions, then we have a deadlock state. - if (behavior.wasExpanded()) { - this->stateStorage.deadlockStateIndices.push_back(currentIndex); - } else { + // There are three possible cases for missing behavior: + if (behavior.wasExpanded()) { + // (a) The state is a deadlock state, i.e. there is no behavior even though the state was expanded + STORM_LOG_THROW(options.fixDeadlocks, storm::exceptions::WrongFormatException, + "Error while creating sparse matrix from probabilistic program: found deadlock state (" + << generator->stateToString(currentState) << "). For fixing these, please provide the appropriate option."); + this->stateStorage.deadlockStateIndices.push_back(currentIndex); + } else { + if (stateLimitExceeded) { + // (b) The state was not expanded because the state limit is reached this->stateStorage.unexploredStateIndices.push_back(currentIndex); } + // (c) the state was not expanded because it is terminal, i.e., exploration from that state is not required for the given property/ies + } - if (!generator->isDeterministicModel()) { - transitionMatrixBuilder.newRowGroup(currentRow); - } + // In all cases, we need to add a self-loop to the transition matrix. - transitionMatrixBuilder.addNextValue(currentRow, currentIndex, storm::utility::one()); + if (!generator->isDeterministicModel()) { + transitionMatrixBuilder.newRowGroup(currentRow); + } - for (auto& rewardModelBuilder : rewardModelBuilders) { - if (rewardModelBuilder.hasStateRewards()) { - rewardModelBuilder.addStateReward(storm::utility::zero()); - } + transitionMatrixBuilder.addNextValue(currentRow, currentIndex, storm::utility::one()); - if (rewardModelBuilder.hasStateActionRewards()) { - rewardModelBuilder.addStateActionReward(storm::utility::zero()); - } + for (auto& rewardModelBuilder : rewardModelBuilders) { + if (rewardModelBuilder.hasStateRewards()) { + rewardModelBuilder.addStateReward(storm::utility::zero()); } - // This state shall be Markovian (to not introduce Zeno behavior) - if (stateAndChoiceInformationBuilder.isBuildMarkovianStates()) { - stateAndChoiceInformationBuilder.addMarkovianState(currentRowGroup); + if (rewardModelBuilder.hasStateActionRewards()) { + rewardModelBuilder.addStateActionReward(storm::utility::zero()); } - // Other state-based information does not need to be treated, in particular: - // * StateValuations have already been set above - // * The associated player shall be the "default" player, i.e. INVALID_PLAYER_INDEX + } - ++currentRow; - ++currentRowGroup; - } else { - STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, - "Error while creating sparse matrix from probabilistic program: found deadlock state (" - << generator->stateToString(currentState) << "). For fixing these, please provide the appropriate option."); + // This state shall be Markovian (to not introduce Zeno behavior) + if (stateAndChoiceInformationBuilder.isBuildMarkovianStates()) { + stateAndChoiceInformationBuilder.addMarkovianState(currentRowGroup); } + // Other state-based information does not need to be treated, in particular: + // * StateValuations have already been set above + // * The associated player shall be the "default" player, i.e. INVALID_PLAYER_INDEX + + ++currentRow; + ++currentRowGroup; } else { // Add the state rewards to the corresponding reward models. auto stateRewardIt = behavior.getStateRewards().begin(); diff --git a/src/storm/generator/JaniNextStateGenerator.cpp b/src/storm/generator/JaniNextStateGenerator.cpp index f036d96849..9fb2596e23 100644 --- a/src/storm/generator/JaniNextStateGenerator.cpp +++ b/src/storm/generator/JaniNextStateGenerator.cpp @@ -42,7 +42,7 @@ namespace generator { template JaniNextStateGenerator::JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options) - : JaniNextStateGenerator(model.substituteConstantsFunctions(), options, false) { + : JaniNextStateGenerator(model.substituteConstantsFunctionsTranscendentals(), options, false) { // Intentionally left empty. } @@ -60,6 +60,7 @@ JaniNextStateGenerator::JaniNextStateGenerator(storm::jani auto features = this->model.getModelFeatures(); features.remove(storm::jani::ModelFeature::DerivedOperators); features.remove(storm::jani::ModelFeature::StateExitRewards); + features.remove(storm::jani::ModelFeature::TrigonometricFunctions); // Eliminate arrays if necessary. if (features.hasArrays()) { arrayEliminatorData = this->model.eliminateArrays(true); @@ -144,6 +145,7 @@ storm::jani::ModelFeatures JaniNextStateGenerator::getSupp features.add(storm::jani::ModelFeature::DerivedOperators); features.add(storm::jani::ModelFeature::StateExitRewards); features.add(storm::jani::ModelFeature::Arrays); + features.add(storm::jani::ModelFeature::TrigonometricFunctions); // We do not add Functions as these should ideally be substituted before creating this generator. // This is because functions may also occur in properties and the user of this class should take care of that. return features; @@ -156,6 +158,7 @@ bool JaniNextStateGenerator::canHandle(storm::jani::Model features.remove(storm::jani::ModelFeature::DerivedOperators); features.remove(storm::jani::ModelFeature::Functions); // can be substituted features.remove(storm::jani::ModelFeature::StateExitRewards); + features.remove(storm::jani::ModelFeature::TrigonometricFunctions); if (!features.empty()) { STORM_LOG_INFO("The model can not be build as it contains these unsupported features: " << features.toString()); return false; diff --git a/src/storm/logic/ExpressionSubstitutionVisitor.cpp b/src/storm/logic/ExpressionSubstitutionVisitor.cpp index f31df2f309..7f0bf9d657 100644 --- a/src/storm/logic/ExpressionSubstitutionVisitor.cpp +++ b/src/storm/logic/ExpressionSubstitutionVisitor.cpp @@ -90,7 +90,11 @@ boost::any ExpressionSubstitutionVisitor::visit(CumulativeRewardFormula const& f bounds.emplace_back(TimeBound(f.isBoundStrict(i), substitutionFunction(f.getBound(i)))); timeBoundReferences.push_back(f.getTimeBoundReference(i)); } - return std::static_pointer_cast(std::make_shared(bounds, timeBoundReferences)); + boost::optional optionalRewardAccumulation; + if (f.hasRewardAccumulation()) { + optionalRewardAccumulation = f.getRewardAccumulation(); + } + return std::static_pointer_cast(std::make_shared(bounds, timeBoundReferences, optionalRewardAccumulation)); } boost::any ExpressionSubstitutionVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const { diff --git a/src/storm/logic/Formula.cpp b/src/storm/logic/Formula.cpp index db597192ee..76f3998931 100644 --- a/src/storm/logic/Formula.cpp +++ b/src/storm/logic/Formula.cpp @@ -504,7 +504,7 @@ std::shared_ptr Formula::clone() const { } std::shared_ptr Formula::substitute(std::map const& substitution) const { - storm::expressions::JaniExpressionSubstitutionVisitor> v(substitution); + storm::expressions::JaniExpressionSubstitutionVisitor> v(substitution, false); return substitute([&v](storm::expressions::Expression const& exp) { return v.substitute(exp); }); } @@ -529,6 +529,12 @@ std::shared_ptr Formula::substituteRewardModelNames(std::map Formula::substituteTranscendentalNumbers() const { + using SubMap = std::map; + storm::expressions::JaniExpressionSubstitutionVisitor transcendentalsVisitor(SubMap(), true); + return substitute([&transcendentalsVisitor](storm::expressions::Expression const& exp) { return transcendentalsVisitor.substitute(exp); }); +} + storm::expressions::Expression Formula::toExpression(storm::expressions::ExpressionManager const& manager, std::map const& labelToExpressionMapping) const { ToExpressionVisitor visitor; diff --git a/src/storm/logic/Formula.h b/src/storm/logic/Formula.h index 7d8c584d3b..192c4e2e63 100644 --- a/src/storm/logic/Formula.h +++ b/src/storm/logic/Formula.h @@ -227,6 +227,7 @@ class Formula : public std::enable_shared_from_this { std::shared_ptr substitute(std::map const& labelSubstitution) const; std::shared_ptr substitute(std::map const& labelSubstitution) const; std::shared_ptr substituteRewardModelNames(std::map const& rewardModelNameSubstitution) const; + std::shared_ptr substituteTranscendentalNumbers() const; /*! * Takes the formula and converts it to an equivalent expression. The formula may contain atomic labels, but diff --git a/src/storm/logic/FragmentChecker.cpp b/src/storm/logic/FragmentChecker.cpp index 07523b8232..d7ce369104 100644 --- a/src/storm/logic/FragmentChecker.cpp +++ b/src/storm/logic/FragmentChecker.cpp @@ -1,6 +1,6 @@ #include "storm/logic/FragmentChecker.h" -#include +#include #include "storm/logic/Formulas.h" namespace storm { @@ -179,7 +179,6 @@ boost::any FragmentChecker::visit(TimeOperatorFormula const& f, boost::any const result = result && (!f.hasQualitativeResult() || inherited.getSpecification().areQualitativeOperatorResultsAllowed()); result = result && (!f.hasQuantitativeResult() || inherited.getSpecification().areQuantitativeOperatorResultsAllowed()); result = result && f.getSubformula().isTimePathFormula(); - result = result && (inherited.getSpecification().isVarianceMeasureTypeAllowed() || f.getMeasureType() == RewardMeasureType::Expectation); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { result = result && boost::any_cast(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false)))); @@ -290,7 +289,6 @@ boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any con result = result && (!f.hasQualitativeResult() || inherited.getSpecification().areQualitativeOperatorResultsAllowed()); result = result && (!f.hasQuantitativeResult() || inherited.getSpecification().areQuantitativeOperatorResultsAllowed()); result = result && (f.getSubformula().isRewardPathFormula() || f.getSubformula().isConditionalRewardFormula()); - result = result && (inherited.getSpecification().isVarianceMeasureTypeAllowed() || f.getMeasureType() == RewardMeasureType::Expectation); if (!inherited.getSpecification().areNestedOperatorsAllowed()) { result = result && diff --git a/src/storm/logic/FragmentSpecification.cpp b/src/storm/logic/FragmentSpecification.cpp index 3c6da43dfd..ca754a710d 100644 --- a/src/storm/logic/FragmentSpecification.cpp +++ b/src/storm/logic/FragmentSpecification.cpp @@ -289,7 +289,6 @@ FragmentSpecification::FragmentSpecification() { timeBoundedCumulativeRewardFormulas = false; rewardBoundedCumulativeRewardFormulas = false; multiDimensionalCumulativeRewardFormulas = false; - varianceAsMeasureType = false; qualitativeOperatorResults = true; quantitativeOperatorResults = true; @@ -685,15 +684,6 @@ FragmentSpecification& FragmentSpecification::setLongRunAverageProbabilitiesAllo return *this; } -bool FragmentSpecification::isVarianceMeasureTypeAllowed() const { - return varianceAsMeasureType; -} - -FragmentSpecification& FragmentSpecification::setVarianceMeasureTypeAllowed(bool newValue) { - this->varianceAsMeasureType = newValue; - return *this; -} - bool FragmentSpecification::areQuantitativeOperatorResultsAllowed() const { return this->quantitativeOperatorResults; } diff --git a/src/storm/logic/FragmentSpecification.h b/src/storm/logic/FragmentSpecification.h index 79486aa530..96d5c64b00 100644 --- a/src/storm/logic/FragmentSpecification.h +++ b/src/storm/logic/FragmentSpecification.h @@ -1,5 +1,4 @@ -#ifndef STORM_LOGIC_FRAGMENTSPECIFICATION_H_ -#define STORM_LOGIC_FRAGMENTSPECIFICATION_H_ +#pragma once #include #include @@ -139,9 +138,6 @@ class FragmentSpecification { bool areMultiDimensionalCumulativeRewardFormulasAllowed() const; FragmentSpecification& setMultiDimensionalCumulativeRewardFormulasAllowed(bool newValue); - bool isVarianceMeasureTypeAllowed() const; - FragmentSpecification& setVarianceMeasureTypeAllowed(bool newValue); - bool areQuantitativeOperatorResultsAllowed() const; FragmentSpecification& setQuantitativeOperatorResultsAllowed(bool newValue); @@ -222,7 +218,6 @@ class FragmentSpecification { bool timeBoundedCumulativeRewardFormulas; bool rewardBoundedCumulativeRewardFormulas; bool multiDimensionalCumulativeRewardFormulas; - bool varianceAsMeasureType; bool quantitativeOperatorResults; bool qualitativeOperatorResults; bool operatorAtTopLevelRequired; @@ -279,5 +274,3 @@ FragmentSpecification quantiles(); } // namespace logic } // namespace storm - -#endif /* STORM_LOGIC_FRAGMENTSPECIFICATION_H_ */ diff --git a/src/storm/logic/RewardMeasureType.cpp b/src/storm/logic/RewardMeasureType.cpp deleted file mode 100644 index cc84eff5a4..0000000000 --- a/src/storm/logic/RewardMeasureType.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "storm/logic/RewardMeasureType.h" -#include - -namespace storm { -namespace logic { - -std::ostream& operator<<(std::ostream& out, RewardMeasureType const& type) { - switch (type) { - case RewardMeasureType::Expectation: - out << "exp"; - break; - case RewardMeasureType::Variance: - out << "var"; - break; - } - return out; -} - -} // namespace logic -} // namespace storm diff --git a/src/storm/logic/RewardMeasureType.h b/src/storm/logic/RewardMeasureType.h deleted file mode 100644 index b52ed490d4..0000000000 --- a/src/storm/logic/RewardMeasureType.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef STORM_LOGIC_REWARDMEASURETYPE_H_ -#define STORM_LOGIC_REWARDMEASURETYPE_H_ - -#include - -namespace storm { -namespace logic { - -enum class RewardMeasureType { Expectation, Variance }; - -std::ostream& operator<<(std::ostream& out, RewardMeasureType const& type); - -} // namespace logic -} // namespace storm - -#endif /* STORM_LOGIC_REWARDMEASURETYPE_H_ */ diff --git a/src/storm/logic/RewardOperatorFormula.cpp b/src/storm/logic/RewardOperatorFormula.cpp index 3803f368a8..61b1c26aaf 100644 --- a/src/storm/logic/RewardOperatorFormula.cpp +++ b/src/storm/logic/RewardOperatorFormula.cpp @@ -2,16 +2,15 @@ #include #include -#include "storm/logic/FormulaVisitor.h" - #include "storm/exceptions/InvalidPropertyException.h" +#include "storm/logic/FormulaVisitor.h" #include "storm/utility/macros.h" namespace storm { namespace logic { RewardOperatorFormula::RewardOperatorFormula(std::shared_ptr const& subformula, boost::optional const& rewardModelName, - OperatorInformation const& operatorInformation, RewardMeasureType rewardMeasureType) - : OperatorFormula(subformula, operatorInformation), rewardModelName(rewardModelName), rewardMeasureType(rewardMeasureType) { + OperatorInformation const& operatorInformation) + : OperatorFormula(subformula, operatorInformation), rewardModelName(rewardModelName) { // Intentionally left empty. } @@ -44,14 +43,9 @@ void RewardOperatorFormula::gatherReferencedRewardModels(std::set& this->getSubformula().gatherReferencedRewardModels(referencedRewardModels); } -RewardMeasureType RewardOperatorFormula::getMeasureType() const { - return rewardMeasureType; -} - std::ostream& RewardOperatorFormula::writeToStream(std::ostream& out, bool /* allowParentheses */) const { // No parentheses necessary out << "R"; - out << "[" << rewardMeasureType << "]"; if (this->hasRewardModelName()) { out << "{\"" << this->getRewardModelName() << "\"}"; } diff --git a/src/storm/logic/RewardOperatorFormula.h b/src/storm/logic/RewardOperatorFormula.h index f86377d93f..77f278c1d3 100644 --- a/src/storm/logic/RewardOperatorFormula.h +++ b/src/storm/logic/RewardOperatorFormula.h @@ -1,16 +1,13 @@ -#ifndef STORM_LOGIC_REWARDOPERATORFORMULA_H_ -#define STORM_LOGIC_REWARDOPERATORFORMULA_H_ +#pragma once #include "storm/logic/OperatorFormula.h" -#include "storm/logic/RewardMeasureType.h" namespace storm { namespace logic { class RewardOperatorFormula : public OperatorFormula { public: RewardOperatorFormula(std::shared_ptr const& subformula, boost::optional const& rewardModelName = boost::none, - OperatorInformation const& operatorInformation = OperatorInformation(), - RewardMeasureType rewardMeasureType = RewardMeasureType::Expectation); + OperatorInformation const& operatorInformation = OperatorInformation()); virtual ~RewardOperatorFormula() { // Intentionally left empty. @@ -46,21 +43,9 @@ class RewardOperatorFormula : public OperatorFormula { */ std::string const& getRewardModelName() const; - /*! - * Retrieves the measure type of the operator. - * - * @return The measure type. - */ - RewardMeasureType getMeasureType() const; - private: // The (optional) name of the reward model this property refers to. boost::optional rewardModelName; - - // The measure type of the operator. - RewardMeasureType rewardMeasureType; }; } // namespace logic } // namespace storm - -#endif /* STORM_LOGIC_REWARDOPERATORFORMULA_H_ */ diff --git a/src/storm/logic/TimeOperatorFormula.cpp b/src/storm/logic/TimeOperatorFormula.cpp index e958c4e3a4..eac69b154b 100644 --- a/src/storm/logic/TimeOperatorFormula.cpp +++ b/src/storm/logic/TimeOperatorFormula.cpp @@ -1,18 +1,16 @@ #include "storm/logic/TimeOperatorFormula.h" -#include +#include #include +#include "storm/exceptions/InvalidPropertyException.h" #include "storm/logic/EventuallyFormula.h" #include "storm/logic/FormulaVisitor.h" - -#include "storm/exceptions/InvalidPropertyException.h" #include "storm/utility/macros.h" namespace storm { namespace logic { -TimeOperatorFormula::TimeOperatorFormula(std::shared_ptr const& subformula, OperatorInformation const& operatorInformation, - RewardMeasureType rewardMeasureType) - : OperatorFormula(subformula, operatorInformation), rewardMeasureType(rewardMeasureType) { +TimeOperatorFormula::TimeOperatorFormula(std::shared_ptr const& subformula, OperatorInformation const& operatorInformation) + : OperatorFormula(subformula, operatorInformation) { assert(subformula->isTimePathFormula()); // Intentionally left empty. } @@ -25,14 +23,9 @@ boost::any TimeOperatorFormula::accept(FormulaVisitor const& visitor, boost::any return visitor.visit(*this, data); } -RewardMeasureType TimeOperatorFormula::getMeasureType() const { - return rewardMeasureType; -} - std::ostream& TimeOperatorFormula::writeToStream(std::ostream& out, bool /* allowParentheses */) const { // No parentheses necessary out << "T"; - out << "[" << rewardMeasureType << "]"; OperatorFormula::writeToStream(out); return out; } diff --git a/src/storm/logic/TimeOperatorFormula.h b/src/storm/logic/TimeOperatorFormula.h index d5311496b2..3c9e253e89 100644 --- a/src/storm/logic/TimeOperatorFormula.h +++ b/src/storm/logic/TimeOperatorFormula.h @@ -1,16 +1,13 @@ -#ifndef STORM_LOGIC_EXPECTEDTIMEOPERATORFORMULA_H_ -#define STORM_LOGIC_EXPECTEDTIMEOPERATORFORMULA_H_ +#pragma once #include "storm/logic/FormulaVisitor.h" #include "storm/logic/OperatorFormula.h" -#include "storm/logic/RewardMeasureType.h" namespace storm { namespace logic { class TimeOperatorFormula : public OperatorFormula { public: - TimeOperatorFormula(std::shared_ptr const& subformula, OperatorInformation const& operatorInformation = OperatorInformation(), - RewardMeasureType rewardMeasureType = RewardMeasureType::Expectation); + TimeOperatorFormula(std::shared_ptr const& subformula, OperatorInformation const& operatorInformation = OperatorInformation()); virtual ~TimeOperatorFormula() { // Intentionally left empty. @@ -21,19 +18,6 @@ class TimeOperatorFormula : public OperatorFormula { virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override; virtual std::ostream& writeToStream(std::ostream& out, bool allowParentheses = false) const override; - - /*! - * Retrieves the measure type of the operator. - * - * @return The measure type of the operator. - */ - RewardMeasureType getMeasureType() const; - - private: - // The measure type of the operator. - RewardMeasureType rewardMeasureType; }; } // namespace logic } // namespace storm - -#endif /* STORM_LOGIC_EXPECTEDTIMEOPERATORFORMULA_H_ */ diff --git a/src/storm/modelchecker/AbstractModelChecker.cpp b/src/storm/modelchecker/AbstractModelChecker.cpp index 4ceb162f8d..5b4d3f92e9 100644 --- a/src/storm/modelchecker/AbstractModelChecker.cpp +++ b/src/storm/modelchecker/AbstractModelChecker.cpp @@ -1,23 +1,19 @@ #include "storm/modelchecker/AbstractModelChecker.h" -#include "storm/adapters/RationalFunctionAdapter.h" - -#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" -#include "storm/modelchecker/results/QualitativeCheckResult.h" -#include "storm/modelchecker/results/QuantitativeCheckResult.h" -#include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" +#include +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/environment/Environment.h" +#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" #include "storm/exceptions/InternalTypeErrorException.h" #include "storm/exceptions/InvalidArgumentException.h" #include "storm/exceptions/InvalidOperationException.h" #include "storm/exceptions/NotImplementedException.h" -#include "storm/utility/constants.h" -#include "storm/utility/macros.h" - -#include "storm/environment/Environment.h" -#include "storm/environment/modelchecker/MultiObjectiveModelCheckerEnvironment.h" - #include "storm/logic/FormulaInformation.h" +#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" +#include "storm/modelchecker/results/QualitativeCheckResult.h" +#include "storm/modelchecker/results/QuantitativeCheckResult.h" +#include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "storm/models/ModelRepresentation.h" #include "storm/models/sparse/Ctmc.h" #include "storm/models/sparse/Dtmc.h" @@ -34,8 +30,8 @@ #include "storm/models/symbolic/StochasticTwoPlayerGame.h" #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" - -#include +#include "storm/utility/constants.h" +#include "storm/utility/macros.h" namespace storm { namespace modelchecker { @@ -164,55 +160,55 @@ std::unique_ptr AbstractModelChecker::computeStateFormul } template -std::unique_ptr AbstractModelChecker::computeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, +std::unique_ptr AbstractModelChecker::computeRewards(Environment const& env, CheckTask const& checkTask) { storm::logic::Formula const& rewardFormula = checkTask.getFormula(); if (rewardFormula.isCumulativeRewardFormula()) { - return this->computeCumulativeRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asCumulativeRewardFormula())); + return this->computeCumulativeRewards(env, checkTask.substituteFormula(rewardFormula.asCumulativeRewardFormula())); } else if (rewardFormula.isInstantaneousRewardFormula()) { - return this->computeInstantaneousRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asInstantaneousRewardFormula())); + return this->computeInstantaneousRewards(env, checkTask.substituteFormula(rewardFormula.asInstantaneousRewardFormula())); } else if (rewardFormula.isReachabilityRewardFormula()) { - return this->computeReachabilityRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asReachabilityRewardFormula())); + return this->computeReachabilityRewards(env, checkTask.substituteFormula(rewardFormula.asReachabilityRewardFormula())); } else if (rewardFormula.isTotalRewardFormula()) { - return this->computeTotalRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asTotalRewardFormula())); + return this->computeTotalRewards(env, checkTask.substituteFormula(rewardFormula.asTotalRewardFormula())); } else if (rewardFormula.isLongRunAverageRewardFormula()) { - return this->computeLongRunAverageRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula())); + return this->computeLongRunAverageRewards(env, checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula())); } else if (rewardFormula.isConditionalRewardFormula()) { - return this->computeConditionalRewards(env, rewardMeasureType, checkTask.substituteFormula(rewardFormula.asConditionalFormula())); + return this->computeConditionalRewards(env, checkTask.substituteFormula(rewardFormula.asConditionalFormula())); } STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardFormula << "' is invalid."); } template std::unique_ptr AbstractModelChecker::computeConditionalRewards( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } template std::unique_ptr AbstractModelChecker::computeCumulativeRewards( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } template std::unique_ptr AbstractModelChecker::computeInstantaneousRewards( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } template std::unique_ptr AbstractModelChecker::computeReachabilityRewards( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } template -std::unique_ptr AbstractModelChecker::computeTotalRewards(Environment const&, storm::logic::RewardMeasureType, +std::unique_ptr AbstractModelChecker::computeTotalRewards(Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); @@ -220,7 +216,7 @@ std::unique_ptr AbstractModelChecker::computeTotalReward template std::unique_ptr AbstractModelChecker::computeLongRunAverageRewards( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } @@ -233,11 +229,11 @@ std::unique_ptr AbstractModelChecker::computeLongRunAver } template -std::unique_ptr AbstractModelChecker::computeTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, +std::unique_ptr AbstractModelChecker::computeTimes(Environment const& env, CheckTask const& checkTask) { storm::logic::Formula const& timeFormula = checkTask.getFormula(); if (timeFormula.isReachabilityTimeFormula()) { - return this->computeReachabilityTimes(env, rewardMeasureType, checkTask.substituteFormula(timeFormula.asReachabilityTimeFormula())); + return this->computeReachabilityTimes(env, checkTask.substituteFormula(timeFormula.asReachabilityTimeFormula())); } STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); @@ -245,7 +241,7 @@ std::unique_ptr AbstractModelChecker::computeTimes(Envir template std::unique_ptr AbstractModelChecker::computeReachabilityTimes( - Environment const&, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker (" << getClassName() << ") does not support the formula: " << checkTask.getFormula() << "."); } @@ -356,7 +352,7 @@ template std::unique_ptr AbstractModelChecker::checkRewardOperatorFormula( Environment const& env, CheckTask const& checkTask) { storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula(); - std::unique_ptr result = this->computeRewards(env, stateFormula.getMeasureType(), checkTask.substituteFormula(stateFormula.getSubformula())); + std::unique_ptr result = this->computeRewards(env, checkTask.substituteFormula(stateFormula.getSubformula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, @@ -373,7 +369,7 @@ std::unique_ptr AbstractModelChecker::checkTimeOperatorF storm::logic::TimeOperatorFormula const& stateFormula = checkTask.getFormula(); STORM_LOG_THROW(stateFormula.getSubformula().isReachabilityTimeFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); - std::unique_ptr result = this->computeTimes(env, stateFormula.getMeasureType(), checkTask.substituteFormula(stateFormula.getSubformula())); + std::unique_ptr result = this->computeTimes(env, checkTask.substituteFormula(stateFormula.getSubformula())); if (checkTask.isBoundSet()) { STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, diff --git a/src/storm/modelchecker/AbstractModelChecker.h b/src/storm/modelchecker/AbstractModelChecker.h index 23c8d08656..45ba3fcac7 100644 --- a/src/storm/modelchecker/AbstractModelChecker.h +++ b/src/storm/modelchecker/AbstractModelChecker.h @@ -1,5 +1,4 @@ -#ifndef STORM_MODELCHECKER_ABSTRACTMODELCHECKER_H_ -#define STORM_MODELCHECKER_ABSTRACTMODELCHECKER_H_ +#pragma once #include @@ -14,8 +13,6 @@ class Environment; namespace modelchecker { class CheckResult; -enum class RewardType { Expectation, Variance }; - template class AbstractModelChecker { public: @@ -73,27 +70,25 @@ class AbstractModelChecker { std::unique_ptr computeStateFormulaProbabilities(Environment const& env, CheckTask const& checkTask); // The methods to compute the rewards for path formulas. - virtual std::unique_ptr computeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask); - virtual std::unique_ptr computeConditionalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeRewards(Environment const& env, CheckTask const& checkTask); + virtual std::unique_ptr computeConditionalRewards(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeTotalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeTotalRewards(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeLongRunAverageRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeLongRunAverageRewards(Environment const& env, CheckTask const& checkTask); // The methods to compute the long-run average probabilities and timing measures. virtual std::unique_ptr computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask); - virtual std::unique_ptr computeTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask); - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeTimes(Environment const& env, CheckTask const& checkTask); + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask); // The methods to check state formulas. @@ -133,5 +128,3 @@ class AbstractModelChecker { }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_ABSTRACTMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp index fe0bfe523e..1af05372f1 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp @@ -2,26 +2,20 @@ #include "storm/adapters/RationalFunctionAdapter.h" -#include "storm/models/symbolic/StandardRewardModel.h" - +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/csl/helper/HybridCtmcCslHelper.h" #include "storm/modelchecker/csl/helper/SparseCtmcCslHelper.h" #include "storm/modelchecker/helper/infinitehorizon/HybridInfiniteHorizonHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" - #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" - +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/storage/dd/DdManager.h" #include "storm/utility/FilteredRewardModel.h" -#include "storm/adapters/RationalFunctionAdapter.h" - -#include "storm/logic/FragmentSpecification.h" - -#include "storm/exceptions/NotImplementedException.h" - namespace storm { namespace modelchecker { template @@ -76,7 +70,7 @@ std::unique_ptr HybridCtmcCslModelChecker::computeNextPr template std::unique_ptr HybridCtmcCslModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); @@ -88,7 +82,7 @@ std::unique_ptr HybridCtmcCslModelChecker::computeReacha template std::unique_ptr HybridCtmcCslModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); @@ -129,7 +123,7 @@ std::unique_ptr HybridCtmcCslModelChecker::computeBounde template std::unique_ptr HybridCtmcCslModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, @@ -142,7 +136,7 @@ std::unique_ptr HybridCtmcCslModelChecker::computeInstan template std::unique_ptr HybridCtmcCslModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, @@ -169,8 +163,7 @@ std::unique_ptr HybridCtmcCslModelChecker::computeLongRu template std::unique_ptr HybridCtmcCslModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); auto probabilisticTransitions = this->getModel().computeProbabilityMatrix(); storm::modelchecker::helper::HybridInfiniteHorizonHelper helper(this->getModel(), probabilisticTransitions, diff --git a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h index 329a037bbe..1f7d323ce2 100644 --- a/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h @@ -1,16 +1,11 @@ -#ifndef STORM_MODELCHECKER_HYBRIDCTMCCSLMODELCHECKER_H_ -#define STORM_MODELCHECKER_HYBRIDCTMCCSLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" - #include "storm/models/symbolic/Ctmc.h" - #include "storm/solver/LinearEquationSolver.h" - #include "storm/utility/NumberTraits.h" namespace storm { - namespace modelchecker { template @@ -36,19 +31,16 @@ class HybridCtmcCslModelChecker : public SymbolicPropositionalModelChecker const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_HYBRIDCTMCCSLMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.cpp b/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.cpp index a169530f6a..baeeaef551 100644 --- a/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.cpp @@ -1,26 +1,21 @@ #include "storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h" #include "storm/adapters/RationalNumberAdapter.h" -#include "storm/models/symbolic/StandardRewardModel.h" - +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/csl/helper/HybridMarkovAutomatonCslHelper.h" #include "storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h" #include "storm/modelchecker/helper/infinitehorizon/HybridInfiniteHorizonHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h" - #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" - +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/storage/dd/DdManager.h" #include "storm/utility/FilteredRewardModel.h" -#include "storm/logic/FragmentSpecification.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/NotImplementedException.h" - namespace storm { namespace modelchecker { template @@ -72,7 +67,7 @@ std::unique_ptr HybridMarkovAutomatonCslModelChecker::co template std::unique_ptr HybridMarkovAutomatonCslModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); @@ -86,7 +81,7 @@ std::unique_ptr HybridMarkovAutomatonCslModelChecker::co template std::unique_ptr HybridMarkovAutomatonCslModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -149,8 +144,7 @@ std::unique_ptr HybridMarkovAutomatonCslModelChecker::co template std::unique_ptr HybridMarkovAutomatonCslModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); diff --git a/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h b/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h index 222d7df618..335fb6e1ad 100644 --- a/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h +++ b/src/storm/modelchecker/csl/HybridMarkovAutomatonCslModelChecker.h @@ -1,11 +1,8 @@ #pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" - #include "storm/models/symbolic/MarkovAutomaton.h" - #include "storm/solver/LinearEquationSolver.h" - #include "storm/utility/NumberTraits.h" namespace storm { @@ -27,15 +24,14 @@ class HybridMarkovAutomatonCslModelChecker : public SymbolicPropositionalModelCh CheckTask const& checkTask) override; virtual std::unique_ptr computeUntilProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; + Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp index ffd9a295db..e996985a72 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp @@ -1,30 +1,23 @@ #include "storm/modelchecker/csl/SparseCtmcCslModelChecker.h" +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/csl/helper/SparseCtmcCslHelper.h" #include "storm/modelchecker/helper/indefinitehorizon/visitingtimes/SparseDeterministicVisitingTimesHelper.h" #include "storm/modelchecker/helper/infinitehorizon/SparseDeterministicInfiniteHorizonHelper.h" +#include "storm/modelchecker/helper/ltl/SparseLTLHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" - +#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" +#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/models/sparse/StandardRewardModel.h" - #include "storm/utility/FilteredRewardModel.h" #include "storm/utility/graph.h" #include "storm/utility/macros.h" -#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" - -#include "storm/modelchecker/helper/ltl/SparseLTLHelper.h" - -#include "storm/logic/FragmentSpecification.h" - -#include "storm/adapters/RationalFunctionAdapter.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/NotImplementedException.h" - namespace storm { namespace modelchecker { template @@ -159,7 +152,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported."); @@ -172,7 +165,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException, "Currently step-bounded and reward-bounded properties on CTMCs are not supported."); @@ -185,7 +178,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); @@ -199,7 +192,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeTotalRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); std::vector numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeTotalRewards( env, storm::solver::SolveGoal(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), @@ -224,8 +217,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); auto probabilisticTransitions = this->getModel().computeProbabilityMatrix(); storm::modelchecker::helper::SparseDeterministicInfiniteHorizonHelper helper(probabilisticTransitions, this->getModel().getExitRateVector()); @@ -236,7 +228,7 @@ std::unique_ptr SparseCtmcCslModelChecker::com template std::unique_ptr SparseCtmcCslModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult(); diff --git a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h index 66522ae1d9..96b8dc4792 100644 --- a/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseCtmcCslModelChecker.h @@ -1,16 +1,11 @@ -#ifndef STORM_MODELCHECKER_SPARSECTMCCSLMODELCHECKER_H_ -#define STORM_MODELCHECKER_SPARSECTMCCSLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" - #include "storm/models/sparse/Ctmc.h" - #include "storm/solver/LinearEquationSolver.h" - #include "storm/utility/NumberTraits.h" namespace storm { - namespace modelchecker { template @@ -41,19 +36,18 @@ class SparseCtmcCslModelChecker : public SparsePropositionalModelChecker computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeTotalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeTotalRewards(Environment const& env, CheckTask const& checkTask) override; /*! @@ -76,5 +70,3 @@ class SparseCtmcCslModelChecker : public SparsePropositionalModelChecker @@ -205,7 +198,7 @@ std::unique_ptr SparseMarkovAutomatonCslModelChecker std::unique_ptr SparseMarkovAutomatonCslModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -228,7 +221,7 @@ std::unique_ptr SparseMarkovAutomatonCslModelChecker std::unique_ptr SparseMarkovAutomatonCslModelChecker::computeTotalRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, @@ -270,8 +263,7 @@ std::unique_ptr SparseMarkovAutomatonCslModelChecker std::unique_ptr SparseMarkovAutomatonCslModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, @@ -292,7 +284,7 @@ std::unique_ptr SparseMarkovAutomatonCslModelChecker std::unique_ptr SparseMarkovAutomatonCslModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); diff --git a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index ab279c3ca6..0e0207281b 100644 --- a/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/storm/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -1,10 +1,7 @@ -#ifndef STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ -#define STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" - #include "storm/models/sparse/MarkovAutomaton.h" - #include "storm/solver/MinMaxLinearEquationSolver.h" namespace storm { @@ -39,21 +36,18 @@ class SparseMarkovAutomatonCslModelChecker : public SparsePropositionalModelChec CheckTask const& checkTask) override; virtual std::unique_ptr computeHOAPathProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeTotalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeTotalRewards(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr checkMultiObjectiveFormula(Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_CSL_SPARSEMARKOVAUTOMATONCSLMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp index d9dce882b6..5d5b732d03 100644 --- a/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp +++ b/src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp @@ -671,12 +671,28 @@ std::vector SparseCtmcCslHelper::computeTransientProbabilities(Enviro // If the cumulative reward is to be computed, we need to adjust the weights. if (useMixedPoissonProbabilities) { - ValueType sum = storm::utility::zero(); - - for (auto& element : foxGlynnResult.weights) { - sum += element; - element = (foxGlynnResult.totalWeight - sum) / uniformizationRate; + // The following computes a vector v such that + // v[i] = foxGlynnResult.totalWeight - sum_{j=0}^{i} foxGlynnResult.weights[j] + // = sum_{j=i+1}^{n} foxGlynnResult.weights[j] for i=0,...,n-1 + // and then sets foxGlynnResult.totalWeight = v / uniformizationRate. + // We do this in place and with numerical stability in mind. Note that the weights commonly range to values from 1e-200 to 1e+200 + uint64_t l{0ull}, r{foxGlynnResult.weights.size()}; + ValueType sumLeft{storm::utility::zero()}, sumRight{storm::utility::zero()}; + while (l < r) { + if (foxGlynnResult.weights[l] < foxGlynnResult.weights[r]) { + sumLeft += foxGlynnResult.weights[l]; + foxGlynnResult.weights[l] = (foxGlynnResult.totalWeight - sumLeft) / uniformizationRate; + ++l; + } else { + --r; + auto const tmp = foxGlynnResult.weights[r]; + foxGlynnResult.weights[r] = sumRight / uniformizationRate; + sumRight += tmp; + } } + auto const relDiff = storm::utility::abs(foxGlynnResult.totalWeight - (sumLeft + sumRight)) / foxGlynnResult.totalWeight; + STORM_LOG_WARN_COND(relDiff < storm::utility::convertNumber(1e-8), + "Numerical instability when adjusting the FoxGlynn weights. Relative Difference: " << relDiff << "."); } STORM_LOG_DEBUG("Starting iterations with " << uniformizedMatrix.getRowCount() << " x " << uniformizedMatrix.getColumnCount() << " matrix."); @@ -717,7 +733,9 @@ std::vector SparseCtmcCslHelper::computeTransientProbabilities(Enviro // To make sure that the values obtained before the left truncation point have the same 'impact' on the total result as the values obtained // between the left and right truncation point, we scale them here with the total sum of the weights. // Note that we divide with this value afterwards. This is to improve numerical stability. - storm::utility::vector::scaleVectorInPlace(result, foxGlynnResult.totalWeight); + if (foxGlynnResult.left > 0) { + storm::utility::vector::scaleVectorInPlace(result, foxGlynnResult.totalWeight); + } } // For the indices that fall in between the truncation points, we need to perform the matrix-vector diff --git a/src/storm/modelchecker/multiobjective/preprocessing/SparseMultiObjectiveRewardAnalysis.cpp b/src/storm/modelchecker/multiobjective/preprocessing/SparseMultiObjectiveRewardAnalysis.cpp index e534212e99..8e4d80e844 100644 --- a/src/storm/modelchecker/multiobjective/preprocessing/SparseMultiObjectiveRewardAnalysis.cpp +++ b/src/storm/modelchecker/multiobjective/preprocessing/SparseMultiObjectiveRewardAnalysis.cpp @@ -3,6 +3,10 @@ #include #include +#include "storm/adapters/RationalNumberAdapter.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/exceptions/UnexpectedException.h" #include "storm/modelchecker/prctl/helper/BaierUpperRewardBoundsComputer.h" #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" @@ -16,10 +20,6 @@ #include "storm/utility/macros.h" #include "storm/utility/vector.h" -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/NotImplementedException.h" -#include "storm/exceptions/UnexpectedException.h" - namespace storm { namespace modelchecker { namespace multiobjective { diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp index 70eebf6672..d958872fbe 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp @@ -1,31 +1,24 @@ #include "storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h" +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/exceptions/InvalidArgumentException.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/helper/infinitehorizon/HybridInfiniteHorizonHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h" #include "storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" - +#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" +#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" +#include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/storage/dd/DdManager.h" #include "storm/storage/dd/Odd.h" - #include "storm/utility/FilteredRewardModel.h" #include "storm/utility/graph.h" #include "storm/utility/macros.h" -#include "storm/models/symbolic/StandardRewardModel.h" - -#include "storm/modelchecker/results/HybridQuantitativeCheckResult.h" -#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" -#include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" - -#include "storm/logic/FragmentSpecification.h" - -#include "storm/exceptions/InvalidArgumentException.h" -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidStateException.h" - -#include "storm/adapters/RationalFunctionAdapter.h" - namespace storm { namespace modelchecker { template @@ -100,7 +93,7 @@ std::unique_ptr HybridDtmcPrctlModelChecker::computeBoun template std::unique_ptr HybridDtmcPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); @@ -110,7 +103,7 @@ std::unique_ptr HybridDtmcPrctlModelChecker::computeCumu template std::unique_ptr HybridDtmcPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); return storm::modelchecker::helper::HybridDtmcPrctlHelper::computeInstantaneousRewards( @@ -121,7 +114,7 @@ std::unique_ptr HybridDtmcPrctlModelChecker::computeInst template std::unique_ptr HybridDtmcPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); @@ -132,7 +125,7 @@ std::unique_ptr HybridDtmcPrctlModelChecker::computeReac template std::unique_ptr HybridDtmcPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); @@ -155,8 +148,7 @@ std::unique_ptr HybridDtmcPrctlModelChecker::computeLong template std::unique_ptr HybridDtmcPrctlModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); storm::modelchecker::helper::HybridInfiniteHorizonHelper helper(this->getModel(), this->getModel().getTransitionMatrix()); diff --git a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h index cae3a8e286..1e04c2e5b6 100644 --- a/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.h @@ -1,14 +1,10 @@ -#ifndef STORM_MODELCHECKER_HYBRIDDTMCPRCTLMODELCHECKER_H_ -#define STORM_MODELCHECKER_HYBRIDDTMCPRCTLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" - #include "storm/models/symbolic/Dtmc.h" - #include "storm/solver/LinearEquationSolver.h" namespace storm { - namespace modelchecker { template @@ -38,19 +34,16 @@ class HybridDtmcPrctlModelChecker : public SymbolicPropositionalModelChecker const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_HYBRIDDTMCPRCTLMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp index 21fe5964e3..9866194907 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp @@ -1,34 +1,25 @@ #include "storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h" +#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/exceptions/UnexpectedException.h" +#include "storm/logic/FragmentSpecification.h" +#include "storm/modelchecker/multiobjective/multiObjectiveModelChecking.h" #include "storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.h" - -#include "storm/models/symbolic/Mdp.h" -#include "storm/models/symbolic/StandardRewardModel.h" - -#include "storm/storage/dd/DdManager.h" - #include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicParetoCurveCheckResult.h" #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" - -#include "storm/logic/FragmentSpecification.h" - -#include "storm/modelchecker/multiobjective/multiObjectiveModelChecking.h" - -#include "storm/solver/MinMaxLinearEquationSolver.h" -#include "storm/utility/FilteredRewardModel.h" - #include "storm/models/sparse/StandardRewardModel.h" +#include "storm/models/symbolic/Mdp.h" +#include "storm/models/symbolic/StandardRewardModel.h" +#include "storm/solver/MinMaxLinearEquationSolver.h" +#include "storm/storage/dd/DdManager.h" #include "storm/transformer/SymbolicToSparseTransformer.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidStateException.h" -#include "storm/exceptions/UnexpectedException.h" - -#include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/utility/FilteredRewardModel.h" namespace storm { namespace modelchecker { @@ -125,7 +116,7 @@ std::unique_ptr HybridMdpPrctlModelChecker::computeBound template std::unique_ptr HybridMdpPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -138,7 +129,7 @@ std::unique_ptr HybridMdpPrctlModelChecker::computeCumul template std::unique_ptr HybridMdpPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -151,7 +142,7 @@ std::unique_ptr HybridMdpPrctlModelChecker::computeInsta template std::unique_ptr HybridMdpPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -165,7 +156,7 @@ std::unique_ptr HybridMdpPrctlModelChecker::computeReach template std::unique_ptr HybridMdpPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); diff --git a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h index 26f7e5bbee..2d132eb244 100644 --- a/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.h @@ -1,14 +1,11 @@ -#ifndef STORM_MODELCHECKER_HYBRIDMDPPRCTLMODELCHECKER_H_ -#define STORM_MODELCHECKER_HYBRIDMDPPRCTLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" - #include "storm/solver/MinMaxLinearEquationSolver.h" #include "storm/solver/OptimizationDirection.h" #include "storm/storage/dd/DdType.h" namespace storm { - namespace models { namespace symbolic { template @@ -42,13 +39,13 @@ class HybridMdpPrctlModelChecker : public SymbolicPropositionalModelChecker computeGloballyProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr checkMultiObjectiveFormula(Environment const& env, CheckTask const& checkTask) override; @@ -56,5 +53,3 @@ class HybridMdpPrctlModelChecker : public SymbolicPropositionalModelChecker #include -#include "storm/utility/FilteredRewardModel.h" -#include "storm/utility/macros.h" - -#include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" -#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" -#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" - #include "storm/adapters/RationalFunctionAdapter.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/csl/helper/SparseCtmcCslHelper.h" +#include "storm/modelchecker/helper/finitehorizon/SparseDeterministicStepBoundedHorizonHelper.h" #include "storm/modelchecker/helper/indefinitehorizon/visitingtimes/SparseDeterministicVisitingTimesHelper.h" #include "storm/modelchecker/helper/infinitehorizon/SparseDeterministicInfiniteHorizonHelper.h" #include "storm/modelchecker/helper/ltl/SparseLTLHelper.h" #include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" #include "storm/modelchecker/prctl/helper/rewardbounded/QuantileHelper.h" - -#include "storm/logic/FragmentSpecification.h" - -#include "storm/solver/SolveGoal.h" - +#include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h" +#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" +#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/models/sparse/Dtmc.h" #include "storm/models/sparse/StandardRewardModel.h" - -#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/solver/SolveGoal.h" +#include "storm/utility/FilteredRewardModel.h" +#include "storm/utility/macros.h" namespace storm { namespace modelchecker { @@ -181,7 +175,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); if (rewardPathFormula.isMultiDimensional() || rewardPathFormula.getTimeBoundReference().isRewardBound()) { STORM_LOG_THROW(checkTask.isOnlyInitialStatesRelevantSet(), storm::exceptions::InvalidOperationException, @@ -207,7 +201,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); std::vector numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper::computeInstantaneousRewards( @@ -219,7 +213,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); @@ -232,7 +226,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); @@ -244,7 +238,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeTotalRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); std::vector numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper::computeTotalRewards( env, storm::solver::SolveGoal(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), @@ -268,8 +262,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); storm::modelchecker::helper::SparseDeterministicInfiniteHorizonHelper helper(this->getModel().getTransitionMatrix()); storm::modelchecker::helper::setInformationFromCheckTaskDeterministic(helper, checkTask, this->getModel()); @@ -299,7 +292,7 @@ std::unique_ptr SparseDtmcPrctlModelChecker::c template std::unique_ptr SparseDtmcPrctlModelChecker::computeConditionalRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula(); STORM_LOG_THROW(conditionalFormula.getSubformula().isReachabilityRewardFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); diff --git a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index e6ae703599..dc970d128f 100644 --- a/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -1,5 +1,4 @@ -#ifndef STORM_MODELCHECKER_SPARSEDTMCPRCTLMODELCHECKER_H_ -#define STORM_MODELCHECKER_SPARSEDTMCPRCTLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/models/sparse/Dtmc.h" @@ -40,20 +39,19 @@ class SparseDtmcPrctlModelChecker : public SparsePropositionalModelChecker computeLTLProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeTotalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeTotalRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeConditionalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeConditionalRewards(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr checkQuantileFormula(Environment const& env, CheckTask const& checkTask) override; @@ -73,5 +71,3 @@ class SparseDtmcPrctlModelChecker : public SparsePropositionalModelChecker SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -325,7 +316,7 @@ std::unique_ptr SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -339,7 +330,7 @@ std::unique_ptr SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -359,7 +350,7 @@ std::unique_ptr SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -378,7 +369,7 @@ std::unique_ptr SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeTotalRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); @@ -419,8 +410,7 @@ std::unique_ptr SparseMdpPrctlModelChecker::com template std::unique_ptr SparseMdpPrctlModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { if constexpr (std::is_same_v) { STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "We have not yet implemented lra with intervals"); } else { diff --git a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h index 01f5707b65..4164ca67a2 100644 --- a/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h @@ -36,22 +36,20 @@ class SparseMdpPrctlModelChecker : public SparsePropositionalModelChecker const& checkTask) override; virtual std::unique_ptr computeConditionalProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; - virtual std::unique_ptr computeTotalRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + Environment const& env, CheckTask const& checkTask) override; + virtual std::unique_ptr computeTotalRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; + Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLTLProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeHOAPathProbabilities(Environment const& env, diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp index d6c9c84d38..2601aa8dcc 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp @@ -1,23 +1,16 @@ #include "storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.h" - -#include "storm/storage/dd/Add.h" - -#include "storm/utility/FilteredRewardModel.h" -#include "storm/utility/macros.h" - -#include "storm/models/symbolic/StandardRewardModel.h" - #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" - -#include "storm/logic/FragmentSpecification.h" - +#include "storm/models/symbolic/StandardRewardModel.h" #include "storm/solver/SymbolicLinearEquationSolver.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidStateException.h" +#include "storm/storage/dd/Add.h" +#include "storm/utility/FilteredRewardModel.h" +#include "storm/utility/macros.h" namespace storm { namespace modelchecker { @@ -97,7 +90,7 @@ std::unique_ptr SymbolicDtmcPrctlModelChecker::computeBo template std::unique_ptr SymbolicDtmcPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); @@ -109,7 +102,7 @@ std::unique_ptr SymbolicDtmcPrctlModelChecker::computeCu template std::unique_ptr SymbolicDtmcPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound."); storm::dd::Add numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper::computeInstantaneousRewards( @@ -121,7 +114,7 @@ std::unique_ptr SymbolicDtmcPrctlModelChecker::computeIn template std::unique_ptr SymbolicDtmcPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); @@ -133,7 +126,7 @@ std::unique_ptr SymbolicDtmcPrctlModelChecker::computeRe template std::unique_ptr SymbolicDtmcPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); std::unique_ptr subResultPointer = this->check(env, eventuallyFormula.getSubformula()); SymbolicQualitativeCheckResult const& subResult = subResultPointer->asSymbolicQualitativeCheckResult(); diff --git a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h index 2d31e9c141..359aae868c 100644 --- a/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h @@ -1,13 +1,10 @@ -#ifndef STORM_MODELCHECKER_SYMBOLICDTMCPRCTLMODELCHECKER_H_ -#define STORM_MODELCHECKER_SYMBOLICDTMCPRCTLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" #include "storm/models/symbolic/Dtmc.h" - #include "storm/solver/SymbolicLinearEquationSolver.h" namespace storm { - namespace modelchecker { template class SymbolicDtmcPrctlModelChecker : public SymbolicPropositionalModelChecker { @@ -30,17 +27,15 @@ class SymbolicDtmcPrctlModelChecker : public SymbolicPropositionalModelChecker const& checkTask) override; virtual std::unique_ptr computeGloballyProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker -} // namespace storm - -#endif /* STORM_MODELCHECKER_SYMBOLICDTMCPRCTLMODELCHECKER_H_ */ +} // namespace storm \ No newline at end of file diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp index 75eabe4677..ca696a1785 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp @@ -1,23 +1,17 @@ #include "storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h" +#include "storm/exceptions/InvalidArgumentException.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h" - #include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "storm/modelchecker/results/SymbolicQuantitativeCheckResult.h" - -#include "storm/logic/FragmentSpecification.h" - #include "storm/models/symbolic/StandardRewardModel.h" - #include "storm/utility/FilteredRewardModel.h" #include "storm/utility/graph.h" #include "storm/utility/macros.h" -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidStateException.h" - -#include "storm/exceptions/InvalidArgumentException.h" - namespace storm { namespace modelchecker { @@ -101,7 +95,7 @@ std::unique_ptr SymbolicMdpPrctlModelChecker::computeBou template std::unique_ptr SymbolicMdpPrctlModelChecker::computeCumulativeRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -114,7 +108,7 @@ std::unique_ptr SymbolicMdpPrctlModelChecker::computeCum template std::unique_ptr SymbolicMdpPrctlModelChecker::computeInstantaneousRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -127,7 +121,7 @@ std::unique_ptr SymbolicMdpPrctlModelChecker::computeIns template std::unique_ptr SymbolicMdpPrctlModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); @@ -141,7 +135,7 @@ std::unique_ptr SymbolicMdpPrctlModelChecker::computeRea template std::unique_ptr SymbolicMdpPrctlModelChecker::computeReachabilityTimes( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); diff --git a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h index 416cbb3540..aa5cc8550b 100644 --- a/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h +++ b/src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h @@ -1,10 +1,7 @@ -#ifndef STORM_MODELCHECKER_SYMBOLICMDPPRCTLMODELCHECKER_H_ -#define STORM_MODELCHECKER_SYMBOLICMDPPRCTLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SymbolicPropositionalModelChecker.h" - #include "storm/models/symbolic/Mdp.h" - #include "storm/solver/SymbolicMinMaxLinearEquationSolver.h" namespace storm { @@ -31,17 +28,15 @@ class SymbolicMdpPrctlModelChecker : public SymbolicPropositionalModelChecker const& checkTask) override; virtual std::unique_ptr computeGloballyProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeCumulativeRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeInstantaneousRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityTimes(Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_SYMBOLICMDPPRCTLMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp index 434a94bd12..43296a4d13 100644 --- a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp +++ b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp @@ -5,36 +5,29 @@ #include #include "storm/adapters/RationalFunctionAdapter.h" - -#include "storm/settings/SettingsManager.h" -#include "storm/settings/modules/CoreSettings.h" -#include "storm/settings/modules/EliminationSettings.h" - -#include "storm/storage/StronglyConnectedComponentDecomposition.h" - +#include "storm/exceptions/IllegalArgumentException.h" +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/InvalidSettingsException.h" +#include "storm/exceptions/InvalidStateException.h" +#include "storm/logic/FragmentSpecification.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/models/sparse/StandardRewardModel.h" - -#include "storm/logic/FragmentSpecification.h" - +#include "storm/settings/SettingsManager.h" +#include "storm/settings/modules/CoreSettings.h" +#include "storm/settings/modules/EliminationSettings.h" #include "storm/solver/stateelimination/ConditionalStateEliminator.h" #include "storm/solver/stateelimination/DynamicStatePriorityQueue.h" #include "storm/solver/stateelimination/MultiValueStateEliminator.h" #include "storm/solver/stateelimination/PrioritizedStateEliminator.h" #include "storm/solver/stateelimination/StaticStatePriorityQueue.h" - +#include "storm/storage/StronglyConnectedComponentDecomposition.h" #include "storm/utility/constants.h" #include "storm/utility/graph.h" #include "storm/utility/macros.h" #include "storm/utility/stateelimination.h" #include "storm/utility/vector.h" -#include "storm/exceptions/IllegalArgumentException.h" -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/InvalidSettingsException.h" -#include "storm/exceptions/InvalidStateException.h" - namespace storm { namespace modelchecker { @@ -126,7 +119,7 @@ std::unique_ptr SparseDtmcEliminationModelChecker std::unique_ptr SparseDtmcEliminationModelChecker::computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { // Do some sanity checks to establish some required properties. RewardModelType const& rewardModel = this->getModel().getRewardModel(checkTask.isRewardModelSet() ? checkTask.getRewardModel() : ""); STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::IllegalArgumentException, "Input model does not have a reward model."); @@ -539,7 +532,7 @@ std::unique_ptr SparseDtmcEliminationModelChecker std::unique_ptr SparseDtmcEliminationModelChecker::computeReachabilityRewards( - Environment const& env, storm::logic::RewardMeasureType, CheckTask const& checkTask) { + Environment const& env, CheckTask const& checkTask) { storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula(); // Retrieve the appropriate bitvectors by model checking the subformulas. diff --git a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.h b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.h index 58546501d2..fe6b211a2b 100644 --- a/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.h +++ b/src/storm/modelchecker/reachability/SparseDtmcEliminationModelChecker.h @@ -1,10 +1,7 @@ -#ifndef STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ -#define STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" - #include "storm/models/sparse/Dtmc.h" - #include "storm/solver/stateelimination/StatePriorityQueue.h" #include "storm/storage/FlexibleSparseMatrix.h" #include "storm/storage/sparse/StateType.h" @@ -44,11 +41,10 @@ class SparseDtmcEliminationModelChecker : public SparsePropositionalModelChecker CheckTask const& checkTask) override; virtual std::unique_ptr computeUntilProbabilities(Environment const& env, CheckTask const& checkTask) override; - virtual std::unique_ptr computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, + virtual std::unique_ptr computeReachabilityRewards(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; + Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeConditionalProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageProbabilities(Environment const& env, @@ -123,5 +119,3 @@ class SparseDtmcEliminationModelChecker : public SparsePropositionalModelChecker } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCELIMINATIONMODELCHECKER_H_ */ diff --git a/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.cpp b/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.cpp index fc2b1d886a..f608a3065b 100644 --- a/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.cpp +++ b/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.cpp @@ -1,3 +1,5 @@ +#include "storm/adapters/RationalNumberAdapter.h" // Must come first + #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/adapters/JsonAdapter.h" diff --git a/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.h b/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.h index 659ed142de..3bc603216f 100644 --- a/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.h +++ b/src/storm/modelchecker/results/ExplicitQualitativeCheckResult.h @@ -1,6 +1,4 @@ -#ifndef STORM_MODELCHECKER_EXPLICITQUALITATIVECHECKRESULT_H_ -#define STORM_MODELCHECKER_EXPLICITQUALITATIVECHECKRESULT_H_ - +#pragma once #include #include #include @@ -76,5 +74,3 @@ class ExplicitQualitativeCheckResult : public QualitativeCheckResult { }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_EXPLICITQUALITATIVECHECKRESULT_H_ */ diff --git a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.cpp b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.cpp index d0bdedebe3..3464ee9381 100644 --- a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.cpp +++ b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.cpp @@ -1,3 +1,5 @@ +#include "storm/adapters/RationalNumberAdapter.h" // Must come first + #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "storm/adapters/JsonAdapter.h" diff --git a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h index 843ca00061..ca6ea5fe31 100644 --- a/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h +++ b/src/storm/modelchecker/results/ExplicitQuantitativeCheckResult.h @@ -1,6 +1,4 @@ -#ifndef STORM_MODELCHECKER_EXPLICITQUANTITATIVECHECKRESULT_H_ -#define STORM_MODELCHECKER_EXPLICITQUANTITATIVECHECKRESULT_H_ - +#pragma once #include #include #include @@ -93,5 +91,3 @@ class ExplicitQuantitativeCheckResult : public QuantitativeCheckResult #include "storm/adapters/RationalNumberAdapter.h" -#include "storm/utility/FilteredRewardModel.h" -#include "storm/utility/macros.h" - +#include "storm/exceptions/InvalidPropertyException.h" +#include "storm/exceptions/NotImplementedException.h" +#include "storm/logic/FragmentSpecification.h" +#include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" #include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h" - -#include "storm/modelchecker/helper/utility/SetInformationFromCheckTask.h" - -#include "storm/logic/FragmentSpecification.h" - #include "storm/models/sparse/StandardRewardModel.h" - -#include "storm/exceptions/InvalidPropertyException.h" -#include "storm/exceptions/NotImplementedException.h" +#include "storm/utility/FilteredRewardModel.h" +#include "storm/utility/macros.h" namespace storm { namespace modelchecker { @@ -64,7 +59,7 @@ std::unique_ptr SparseSmgRpatlModelChecker::com template std::unique_ptr SparseSmgRpatlModelChecker::computeLongRunAverageRewards( - Environment const&, storm::logic::RewardMeasureType rewardMeasureType, CheckTask const& checkTask) { + Environment const&, CheckTask const& checkTask) { auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask); STORM_LOG_THROW(checkTask.isPlayerCoalitionSet(), storm::exceptions::InvalidPropertyException, "No player coalition was set."); auto coalitionStates = this->getModel().computeStatesOfCoalition(checkTask.getPlayerCoalition()); @@ -73,8 +68,6 @@ std::unique_ptr SparseSmgRpatlModelChecker::com } template class SparseSmgRpatlModelChecker>; -#ifdef STORM_HAVE_CARL template class SparseSmgRpatlModelChecker>; -#endif } // namespace modelchecker } // namespace storm diff --git a/src/storm/modelchecker/rpatl/SparseSmgRpatlModelChecker.h b/src/storm/modelchecker/rpatl/SparseSmgRpatlModelChecker.h index 0d2405fc27..448a02a1ca 100644 --- a/src/storm/modelchecker/rpatl/SparseSmgRpatlModelChecker.h +++ b/src/storm/modelchecker/rpatl/SparseSmgRpatlModelChecker.h @@ -1,5 +1,4 @@ -#ifndef STORM_MODELCHECKER_SPARSESMGRPATLMODELCHECKER_H_ -#define STORM_MODELCHECKER_SPARSESMGRPATLMODELCHECKER_H_ +#pragma once #include "storm/modelchecker/propositional/SparsePropositionalModelChecker.h" #include "storm/models/sparse/Smg.h" @@ -31,10 +30,7 @@ class SparseSmgRpatlModelChecker : public SparsePropositionalModelChecker computeLongRunAverageProbabilities(Environment const& env, CheckTask const& checkTask) override; virtual std::unique_ptr computeLongRunAverageRewards( - Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, - CheckTask const& checkTask) override; + Environment const& env, CheckTask const& checkTask) override; }; } // namespace modelchecker } // namespace storm - -#endif /* STORM_MODELCHECKER_SPARSESMGRPATLMODELCHECKER_H_ */ diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp index f614ea6c31..09bed34cd7 100644 --- a/src/storm/models/symbolic/Model.cpp +++ b/src/storm/models/symbolic/Model.cpp @@ -375,8 +375,7 @@ void Model::printDdVariableInformationToStream(std::ostream& ou columnVariableCount += this->getManager().getMetaVariable(metaVariable).getNumberOfDdVariables(); } - out << "Variables: \t" - << "rows: " << this->rowVariables.size() << " meta variables (" << rowVariableCount << " DD variables)" + out << "Variables: \t" << "rows: " << this->rowVariables.size() << " meta variables (" << rowVariableCount << " DD variables)" << ", columns: " << this->columnVariables.size() << " meta variables (" << columnVariableCount << " DD variables)"; } diff --git a/src/storm/settings/modules/GmmxxEquationSolverSettings.cpp b/src/storm/settings/modules/GmmxxEquationSolverSettings.cpp index 90b5fcd610..da9a7a7f44 100644 --- a/src/storm/settings/modules/GmmxxEquationSolverSettings.cpp +++ b/src/storm/settings/modules/GmmxxEquationSolverSettings.cpp @@ -25,7 +25,7 @@ const std::string GmmxxEquationSolverSettings::maximalIterationsOptionShortName const std::string GmmxxEquationSolverSettings::precisionOptionName = "precision"; GmmxxEquationSolverSettings::GmmxxEquationSolverSettings() : ModuleSettings(moduleName) { - std::vector methods = {"bicgstab", "qmr", "gmres", "jacobi"}; + std::vector methods = {"bicgstab", "qmr", "gmres"}; this->addOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the gmm++ engine.") .setIsAdvanced() diff --git a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp index 7f497452d4..7197e1157d 100644 --- a/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp +++ b/src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp @@ -367,8 +367,9 @@ MinMaxLinearEquationSolverRequirements IterativeMinMaxLinearEquationSolverhasUniqueSolution() && - (env.solver().minMax().isForceRequireUnique() || !direction || direction.get() == OptimizationDirection::Minimize || this->isTrackSchedulerSet())) { + if (!this->hasUniqueSolution()) { + // RationalSearch guesses and verifies a fixpoint and terminates once a fixpoint is found. To ensure that the guessed fixpoint is the + // correct one, we enforce uniqueness. requirements.requireUniqueSolution(); } } else if (method == MinMaxMethod::PolicyIteration) { @@ -672,6 +673,8 @@ bool IterativeMinMaxLinearEquationSolver::solveEquation { Environment viEnv = env; viEnv.solver().minMax().setMethod(MinMaxMethod::ValueIteration); + viEnv.solver().setForceExact(false); + viEnv.solver().setForceSoundness(false); auto impreciseSolver = GeneralMinMaxLinearEquationSolverFactory().create(viEnv, this->A->template toValueType()); impreciseSolver->setHasUniqueSolution(this->hasUniqueSolution()); impreciseSolver->setTrackScheduler(true); @@ -679,8 +682,10 @@ bool IterativeMinMaxLinearEquationSolver::solveEquation auto initSched = this->getInitialScheduler(); impreciseSolver->setInitialScheduler(std::move(initSched)); } - STORM_LOG_THROW(!impreciseSolver->getRequirements(viEnv, dir).hasEnabledCriticalRequirement(), storm::exceptions::UnmetRequirementException, - "The value-iteration based solver has an unmet requirement."); + auto impreciseSolverReq = impreciseSolver->getRequirements(viEnv, dir); + STORM_LOG_THROW(!impreciseSolverReq.hasEnabledCriticalRequirement(), storm::exceptions::UnmetRequirementException, + "The value-iteration based solver has an unmet requirement: " << impreciseSolverReq.getEnabledRequirementsAsString()); + impreciseSolver->setRequirementsChecked(true); auto xVi = storm::utility::vector::convertNumericVector(x); auto bVi = storm::utility::vector::convertNumericVector(b); impreciseSolver->solveEquations(viEnv, dir, xVi, bVi); diff --git a/src/storm/storage/Scheduler.cpp b/src/storm/storage/Scheduler.cpp index 84652762df..108f2b5f31 100644 --- a/src/storm/storage/Scheduler.cpp +++ b/src/storm/storage/Scheduler.cpp @@ -191,8 +191,8 @@ void Scheduler::printToStream(std::ostream& out, std::shared_ptrgetTransitionMatrix().getRowGroupSize(state) == 1) { diff --git a/src/storm/storage/SparseMatrix.cpp b/src/storm/storage/SparseMatrix.cpp index b9f8546da0..3c012646e2 100644 --- a/src/storm/storage/SparseMatrix.cpp +++ b/src/storm/storage/SparseMatrix.cpp @@ -386,8 +386,7 @@ void print(std::vector::index_type> const& rowG for (typename SparseMatrix::index_type i = rowGroupIndices[group]; i < endGroups; ++i) { endRows = i < rowIndications.size() - 1 ? rowIndications[i + 1] : columnsAndValues.size(); // Print the actual row. - std::cout << "Row " << i << " (" << rowIndications[i] << " - " << endRows << ")" - << ": "; + std::cout << "Row " << i << " (" << rowIndications[i] << " - " << endRows << ")" << ": "; for (typename SparseMatrix::index_type pos = rowIndications[i]; pos < endRows; ++pos) { std::cout << "(" << columnsAndValues[pos].getColumn() << ": " << columnsAndValues[pos].getValue() << ") "; } @@ -2388,16 +2387,29 @@ typename SparseMatrix::const_iterator SparseMatrix::begin( template typename SparseMatrix::iterator SparseMatrix::begin(index_type row) { + STORM_LOG_ASSERT(row < this->getRowCount(), "Row " << row << " exceeds row count " << this->getRowCount() << "."); return this->columnsAndValues.begin() + this->rowIndications[row]; } +template +typename SparseMatrix::const_iterator SparseMatrix::begin() const { + return this->columnsAndValues.begin(); +} + +template +typename SparseMatrix::iterator SparseMatrix::begin() { + return this->columnsAndValues.begin(); +} + template typename SparseMatrix::const_iterator SparseMatrix::end(index_type row) const { + STORM_LOG_ASSERT(row < this->getRowCount(), "Row " << row << " exceeds row count " << this->getRowCount() << "."); return this->columnsAndValues.begin() + this->rowIndications[row + 1]; } template typename SparseMatrix::iterator SparseMatrix::end(index_type row) { + STORM_LOG_ASSERT(row < this->getRowCount(), "Row " << row << " exceeds row count " << this->getRowCount() << "."); return this->columnsAndValues.begin() + this->rowIndications[row + 1]; } diff --git a/src/storm/storage/SparseMatrix.h b/src/storm/storage/SparseMatrix.h index 3c1ddb5aa5..b0e881cdd3 100644 --- a/src/storm/storage/SparseMatrix.h +++ b/src/storm/storage/SparseMatrix.h @@ -1149,7 +1149,7 @@ class SparseMatrix { * @param row The row to the beginning of which the iterator has to point. * @return An iterator that points to the beginning of the given row. */ - const_iterator begin(index_type row = 0) const; + const_iterator begin(index_type row) const; /*! * Retrieves an iterator that points to the beginning of the given row. @@ -1157,7 +1157,21 @@ class SparseMatrix { * @param row The row to the beginning of which the iterator has to point. * @return An iterator that points to the beginning of the given row. */ - iterator begin(index_type row = 0); + iterator begin(index_type row); + + /*! + * Retrieves an iterator that points to the beginning of the first row of the matrix. + * + * @return An iterator that points to the beginning of the first row of the matrix. + */ + const_iterator begin() const; + + /*! + * Retrieves an iterator that points to the beginning of the first row of the matrix. + * + * @return An iterator that points to the beginning of the first row of the matrix. + */ + iterator begin(); /*! * Retrieves an iterator that points past the end of the given row. diff --git a/src/storm/storage/expressions/Expression.cpp b/src/storm/storage/expressions/Expression.cpp index f1c40990b9..f590d9f837 100644 --- a/src/storm/storage/expressions/Expression.cpp +++ b/src/storm/storage/expressions/Expression.cpp @@ -548,6 +548,20 @@ Expression logarithm(Expression const& first, Expression const& second) { second.getBaseExpressionPointer(), BinaryNumericalFunctionExpression::OperatorType::Logarithm))); } +Expression cos(Expression const& first) { + STORM_LOG_THROW(first.hasNumericalType(), storm::exceptions::InvalidTypeException, "Operator 'cos' requires numerical operand."); + return Expression(std::shared_ptr(new UnaryNumericalFunctionExpression(first.getBaseExpression().getManager(), + first.getType().trigonometric(), first.getBaseExpressionPointer(), + UnaryNumericalFunctionExpression::OperatorType::Cos))); +} + +Expression sin(Expression const& first) { + STORM_LOG_THROW(first.hasNumericalType(), storm::exceptions::InvalidTypeException, "Operator 'sin' requires numerical operand."); + return Expression(std::shared_ptr(new UnaryNumericalFunctionExpression(first.getBaseExpression().getManager(), + first.getType().trigonometric(), first.getBaseExpressionPointer(), + UnaryNumericalFunctionExpression::OperatorType::Sin))); +} + Expression apply(std::vector const& expressions, std::function const& function) { STORM_LOG_THROW(!expressions.empty(), storm::exceptions::InvalidArgumentException, "Cannot build function application of empty expression list."); diff --git a/src/storm/storage/expressions/Expression.h b/src/storm/storage/expressions/Expression.h index ef0b7278e3..4f2ec5464a 100644 --- a/src/storm/storage/expressions/Expression.h +++ b/src/storm/storage/expressions/Expression.h @@ -454,6 +454,8 @@ Expression ceil(Expression const& first); Expression round(Expression const& first); Expression modulo(Expression const& first, Expression const& second); Expression logarithm(Expression const& first, Expression const& second); +Expression cos(Expression const& first); +Expression sin(Expression const& first); Expression minimum(Expression const& first, Expression const& second); Expression maximum(Expression const& first, Expression const& second); Expression atLeastOneOf(std::vector const& expressions); diff --git a/src/storm/storage/expressions/ExpressionManager.cpp b/src/storm/storage/expressions/ExpressionManager.cpp index e1eaa737bf..eb3b6192e1 100644 --- a/src/storm/storage/expressions/ExpressionManager.cpp +++ b/src/storm/storage/expressions/ExpressionManager.cpp @@ -137,6 +137,13 @@ Type const& ExpressionManager::getArrayType(Type elementType) const { return *arrayTypes.insert(type).first; } +Type const& ExpressionManager::getTranscendentalNumberType() const { + if (!transcendentalNumberType) { + transcendentalNumberType = Type(this->getSharedPointer(), std::shared_ptr(new TranscendentalNumberType())); + } + return transcendentalNumberType.get(); +} + bool ExpressionManager::isValidVariableName(std::string const& name) { return name.size() < 2 || name.at(0) != '_' || name.at(1) != '_'; } diff --git a/src/storm/storage/expressions/ExpressionManager.h b/src/storm/storage/expressions/ExpressionManager.h index 6156b868d5..ce4372a45c 100644 --- a/src/storm/storage/expressions/ExpressionManager.h +++ b/src/storm/storage/expressions/ExpressionManager.h @@ -162,6 +162,12 @@ class ExpressionManager : public std::enable_shared_from_this */ Type const& getArrayType(Type elementType) const; + /*! + * Retrieves the transcendental numbers type (i.e. pi and e) + * @return The transcendental numbers type + */ + Type const& getTranscendentalNumberType() const; + /*! * Declares a variable that is a copy of the provided variable (i.e. has the same type). * @@ -486,6 +492,7 @@ class ExpressionManager : public std::enable_shared_from_this mutable std::unordered_set bitvectorTypes; mutable boost::optional rationalType; mutable std::unordered_set arrayTypes; + mutable boost::optional transcendentalNumberType; // A mask that can be used to query whether a variable is an auxiliary variable. static const uint64_t auxiliaryMask = (1ull << 50); diff --git a/src/storm/storage/expressions/OperatorType.h b/src/storm/storage/expressions/OperatorType.h index d2a5b8aacd..6ded87a006 100644 --- a/src/storm/storage/expressions/OperatorType.h +++ b/src/storm/storage/expressions/OperatorType.h @@ -21,6 +21,8 @@ enum class OperatorType { Power, Modulo, Logarithm, + Cos, + Sin, Equal, NotEqual, Less, diff --git a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp index 446d2bb434..b7bd50833f 100644 --- a/src/storm/storage/expressions/ToExprtkStringVisitor.cpp +++ b/src/storm/storage/expressions/ToExprtkStringVisitor.cpp @@ -228,6 +228,16 @@ boost::any ToExprtkStringVisitor::visit(UnaryNumericalFunctionExpression const& expression.getOperand()->accept(*this, data); stream << ")"; break; + case UnaryNumericalFunctionExpression::OperatorType::Cos: + stream << "cos("; + expression.getOperand()->accept(*this, data); + stream << ")"; + break; + case UnaryNumericalFunctionExpression::OperatorType::Sin: + stream << "sin("; + expression.getOperand()->accept(*this, data); + stream << ")"; + break; } return boost::any(); } diff --git a/src/storm/storage/expressions/Type.cpp b/src/storm/storage/expressions/Type.cpp index 72d240bfa7..a9bb6b22e7 100644 --- a/src/storm/storage/expressions/Type.cpp +++ b/src/storm/storage/expressions/Type.cpp @@ -66,6 +66,14 @@ bool ArrayType::isArrayType() const { return true; } +bool BaseType::isTranscendentalNumberType() const { + return false; +} + +bool TranscendentalNumberType::isTranscendentalNumberType() const { + return true; +} + uint64_t BooleanType::getMask() const { return BooleanType::mask; } @@ -130,6 +138,14 @@ std::string ArrayType::getStringRepresentation() const { return "array[" + elementType.getStringRepresentation() + "]"; } +uint64_t TranscendentalNumberType::getMask() const { + return TranscendentalNumberType::mask; +} + +std::string TranscendentalNumberType::getStringRepresentation() const { + return "transcendental"; +} + bool operator<(BaseType const& first, BaseType const& second) { if (first.getMask() < second.getMask()) { return true; @@ -172,13 +188,17 @@ bool Type::isBitVectorType() const { } bool Type::isNumericalType() const { - return this->isIntegerType() || this->isRationalType(); + return this->isIntegerType() || this->isRationalType() || this->isTranscendentalNumberType(); } bool Type::isArrayType() const { return this->innerType->isArrayType(); } +bool Type::isTranscendentalNumberType() const { + return this->innerType->isTranscendentalNumberType(); +} + std::string Type::getStringRepresentation() const { return this->innerType->getStringRepresentation(); } @@ -236,6 +256,11 @@ Type Type::power(Type const& other, bool allowIntegerType) const { } } +Type Type::trigonometric() const { + STORM_LOG_THROW(this->isNumericalType(), storm::exceptions::InvalidTypeException, "Operator requires numerical operand."); + return this->getManager().getRationalType(); +} + Type Type::logicalConnective(Type const& other) const { STORM_LOG_THROW(this->isBooleanType() && other.isBooleanType(), storm::exceptions::InvalidTypeException, "Operator requires boolean operands."); return *this; diff --git a/src/storm/storage/expressions/Type.h b/src/storm/storage/expressions/Type.h index 18cf1ce676..eab74aa1de 100644 --- a/src/storm/storage/expressions/Type.h +++ b/src/storm/storage/expressions/Type.h @@ -88,6 +88,13 @@ class Type { */ bool isArrayType() const; + /*! + * Checks whether this type is a transcendental number type. + * + * @return True iff the type is a transcendental number. + */ + bool isTranscendentalNumberType() const; + /*! * Retrieves the bit width of the type, provided that it is a bitvector type. * @@ -116,6 +123,7 @@ class Type { Type modulo(Type const& other) const; Type logarithm(Type const& other) const; Type power(Type const& other, bool allowIntegerType = false) const; + Type trigonometric() const; Type logicalConnective(Type const& other) const; Type logicalConnective() const; Type numericalComparison(Type const& other) const; @@ -168,6 +176,7 @@ class BaseType { virtual bool isBitVectorType() const; virtual bool isRationalType() const; virtual bool isArrayType() const; + virtual bool isTranscendentalNumberType() const; }; class BooleanType : public BaseType { @@ -177,7 +186,7 @@ class BooleanType : public BaseType { virtual bool isBooleanType() const override; private: - static const uint64_t mask = (1ull << 60); + static const uint64_t mask = (1ull << 56); }; class IntegerType : public BaseType { @@ -187,7 +196,7 @@ class IntegerType : public BaseType { virtual bool isIntegerType() const override; private: - static const uint64_t mask = (1ull << 62); + static const uint64_t mask = (1ull << 58); }; class BitVectorType : public BaseType { @@ -213,7 +222,7 @@ class BitVectorType : public BaseType { virtual bool isBitVectorType() const override; private: - static const uint64_t mask = (1ull << 61); + static const uint64_t mask = (1ull << 57); // The bit width of the type. std::size_t width; @@ -226,7 +235,7 @@ class RationalType : public BaseType { virtual bool isRationalType() const override; private: - static const uint64_t mask = (1ull << 63); + static const uint64_t mask = (1ull << 59); }; class ArrayType : public BaseType { @@ -241,12 +250,22 @@ class ArrayType : public BaseType { virtual bool isArrayType() const override; private: - static const uint64_t mask = (1ull << 59); + static const uint64_t mask = (1ull << 55); // The type of the array elements (can again be of type array). Type elementType; }; +class TranscendentalNumberType : public BaseType { + public: + virtual uint64_t getMask() const override; + virtual std::string getStringRepresentation() const override; + virtual bool isTranscendentalNumberType() const override; + + private: + static const uint64_t mask = (1ull << 60); +}; + class ErrorType : public BaseType { public: virtual uint64_t getMask() const override; diff --git a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp index 97320748d0..9df22e8719 100644 --- a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp +++ b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp @@ -36,6 +36,12 @@ storm::expressions::OperatorType UnaryNumericalFunctionExpression::getOperator() case OperatorType::Ceil: result = storm::expressions::OperatorType::Ceil; break; + case OperatorType::Cos: + result = storm::expressions::OperatorType::Cos; + break; + case OperatorType::Sin: + result = storm::expressions::OperatorType::Sin; + break; } return result; } @@ -78,6 +84,12 @@ double UnaryNumericalFunctionExpression::evaluateAsDouble(Valuation const* valua case OperatorType::Ceil: result = std::ceil(result); break; + case OperatorType::Cos: + result = std::cos(result); + break; + case OperatorType::Sin: + result = std::sin(result); + break; } return result; } @@ -87,18 +99,32 @@ std::shared_ptr UnaryNumericalFunctionExpression::simplify if (operandSimplified->isLiteral()) { if (operandSimplified->hasIntegerType()) { - int_fast64_t value = operandSimplified->evaluateAsInt(); + int_fast64_t intValue = operandSimplified->evaluateAsInt(); + storm::RationalNumber rationalValue; + bool useInteger = true; switch (this->getOperatorType()) { case OperatorType::Minus: - value = -value; + intValue = -intValue; break; // Nothing to be done for the other cases: case OperatorType::Floor: case OperatorType::Ceil: break; + case OperatorType::Cos: + useInteger = false; + rationalValue = storm::utility::cos(storm::utility::convertNumber(intValue)); + break; + case OperatorType::Sin: + useInteger = false; + rationalValue = storm::utility::sin(storm::utility::convertNumber(intValue)); + break; } - return std::shared_ptr(new IntegerLiteralExpression(this->getManager(), value)); - } else { + if (useInteger) { + return std::shared_ptr(new IntegerLiteralExpression(this->getManager(), intValue)); + } else { + return std::shared_ptr(new RationalLiteralExpression(this->getManager(), rationalValue)); + } + } else if (operandSimplified->hasRationalType()) { storm::RationalNumber value = operandSimplified->evaluateAsRational(); bool convertToInteger = false; switch (this->getOperatorType()) { @@ -113,6 +139,12 @@ std::shared_ptr UnaryNumericalFunctionExpression::simplify value = storm::utility::ceil(value); convertToInteger = true; break; + case OperatorType::Cos: + value = storm::utility::cos(value); + break; + case OperatorType::Sin: + value = storm::utility::sin(value); + break; } if (convertToInteger) { return std::shared_ptr(new IntegerLiteralExpression(this->getManager(), storm::utility::convertNumber(value))); @@ -149,6 +181,12 @@ void UnaryNumericalFunctionExpression::printToStream(std::ostream& stream) const case OperatorType::Ceil: stream << "ceil("; break; + case OperatorType::Cos: + stream << "cos("; + break; + case OperatorType::Sin: + stream << "sin("; + break; } stream << *this->getOperand() << ")"; } diff --git a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.h b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.h index 7bad6ba29b..f329993536 100644 --- a/src/storm/storage/expressions/UnaryNumericalFunctionExpression.h +++ b/src/storm/storage/expressions/UnaryNumericalFunctionExpression.h @@ -11,7 +11,7 @@ class UnaryNumericalFunctionExpression : public UnaryExpression { /*! * An enum type specifying the different functions applicable. */ - enum class OperatorType { Minus, Floor, Ceil }; + enum class OperatorType { Minus, Floor, Ceil, Cos, Sin }; /*! * Creates a unary numerical function expression with the given return type, operand and operator. diff --git a/src/storm/storage/jani/Assignment.cpp b/src/storm/storage/jani/Assignment.cpp index 099cf2d815..c0bf8ee3e3 100644 --- a/src/storm/storage/jani/Assignment.cpp +++ b/src/storm/storage/jani/Assignment.cpp @@ -62,12 +62,13 @@ bool Assignment::isTransient() const { return lValue.isTransient(); } -void Assignment::substitute(std::map const& substitution) { - this->setAssignedExpression(substituteJaniExpression(this->getAssignedExpression(), substitution).simplify()); +void Assignment::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + this->setAssignedExpression(substituteJaniExpression(this->getAssignedExpression(), substitution, substituteTranscendentalNumbers).simplify()); if (lValue.isArrayAccess()) { std::vector substitutedExpressions; for (auto& index : lValue.getArrayIndexVector()) { - substitutedExpressions.push_back(substituteJaniExpression(index, substitution).simplify()); + substitutedExpressions.push_back(substituteJaniExpression(index, substitution, substituteTranscendentalNumbers).simplify()); } lValue = LValue(lValue.getVariable(), substitutedExpressions); diff --git a/src/storm/storage/jani/Assignment.h b/src/storm/storage/jani/Assignment.h index 910e5a5c22..112d29c0b3 100644 --- a/src/storm/storage/jani/Assignment.h +++ b/src/storm/storage/jani/Assignment.h @@ -68,7 +68,7 @@ class Assignment { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /** * Retrieves whether the assignment assigns to a transient variable. diff --git a/src/storm/storage/jani/Automaton.cpp b/src/storm/storage/jani/Automaton.cpp index e9eb336492..ce36ab09d8 100644 --- a/src/storm/storage/jani/Automaton.cpp +++ b/src/storm/storage/jani/Automaton.cpp @@ -38,7 +38,9 @@ Automaton Automaton::clone(storm::expressions::ExpressionManager& manager, std:: oldToNewVarMap[v] = cloneVariable(manager, v, variablePrefix).getExpression(); } result.variables.substituteExpressionVariables(oldToNewVarMap); - result.substitute(oldToNewVarMap); + // When cloning an automaton, keep the transcendental numbers as they are. + const bool substituteTranscendentalNumbers = false; + result.substitute(oldToNewVarMap, substituteTranscendentalNumbers); return result; } @@ -429,22 +431,23 @@ std::vector Automaton::getAllRangeExpressions() return result; } -void Automaton::substitute(std::map const& substitution) { +void Automaton::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { for (auto& functionDefinition : this->getFunctionDefinitions()) { - functionDefinition.second.substitute(substitution); + functionDefinition.second.substitute(substitution, substituteTranscendentalNumbers); } - this->getVariables().substitute(substitution); + this->getVariables().substitute(substitution, substituteTranscendentalNumbers); for (auto& location : this->getLocations()) { - location.substitute(substitution); + location.substitute(substitution, substituteTranscendentalNumbers); } if (hasInitialStatesRestriction()) { - this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), substitution)); + this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), substitution, substituteTranscendentalNumbers)); } - edges.substitute(substitution); + edges.substitute(substitution, substituteTranscendentalNumbers); } void Automaton::registerTemplateEdge(std::shared_ptr const& te) { edges.insertTemplateEdge(te); diff --git a/src/storm/storage/jani/Automaton.h b/src/storm/storage/jani/Automaton.h index b44d659054..c79033805f 100644 --- a/src/storm/storage/jani/Automaton.h +++ b/src/storm/storage/jani/Automaton.h @@ -284,7 +284,7 @@ class Automaton { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Changes all variables in assignments based on the given mapping. diff --git a/src/storm/storage/jani/Edge.cpp b/src/storm/storage/jani/Edge.cpp index 88a803d064..8de786b752 100644 --- a/src/storm/storage/jani/Edge.cpp +++ b/src/storm/storage/jani/Edge.cpp @@ -90,12 +90,12 @@ OrderedAssignments const& Edge::getAssignments() const { return templateEdge->getAssignments(); } -void Edge::substitute(std::map const& substitution) { +void Edge::substitute(std::map const& substitution, bool const substituteTranscendentalNumbers) { if (this->hasRate()) { - this->setRate(substituteJaniExpression(this->getRate(), substitution)); + this->setRate(substituteJaniExpression(this->getRate(), substitution, substituteTranscendentalNumbers)); } for (auto& destination : destinations) { - destination.substitute(substitution); + destination.substitute(substitution, substituteTranscendentalNumbers); } } diff --git a/src/storm/storage/jani/Edge.h b/src/storm/storage/jani/Edge.h index 7e1247c62b..fabf84caf1 100644 --- a/src/storm/storage/jani/Edge.h +++ b/src/storm/storage/jani/Edge.h @@ -93,7 +93,7 @@ class Edge { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Retrieves a set of (global) variables that are written by at least one of the edge's destinations. diff --git a/src/storm/storage/jani/EdgeContainer.cpp b/src/storm/storage/jani/EdgeContainer.cpp index dd6f186b2f..d586df9276 100644 --- a/src/storm/storage/jani/EdgeContainer.cpp +++ b/src/storm/storage/jani/EdgeContainer.cpp @@ -94,12 +94,13 @@ void EdgeContainer::liftTransientDestinationAssignments(int64_t maxLevel) { } } -void EdgeContainer::substitute(std::map const& substitution) { +void EdgeContainer::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { for (auto& templateEdge : templates) { - templateEdge->substitute(substitution); + templateEdge->substitute(substitution, substituteTranscendentalNumbers); } for (auto& edge : edges) { - edge.substitute(substitution); + edge.substitute(substitution, substituteTranscendentalNumbers); } } diff --git a/src/storm/storage/jani/EdgeContainer.h b/src/storm/storage/jani/EdgeContainer.h index 2c476bb9ed..cedc386dbb 100644 --- a/src/storm/storage/jani/EdgeContainer.h +++ b/src/storm/storage/jani/EdgeContainer.h @@ -103,7 +103,7 @@ class EdgeContainer { std::set getActionIndices() const; - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); void liftTransientDestinationAssignments(int64_t maxLevel = 0); void pushAssignmentsToDestinations(); void insertEdge(Edge const& e, uint64_t locStart, uint64_t locEnd); diff --git a/src/storm/storage/jani/EdgeDestination.cpp b/src/storm/storage/jani/EdgeDestination.cpp index 49b008871f..f57d835a51 100644 --- a/src/storm/storage/jani/EdgeDestination.cpp +++ b/src/storm/storage/jani/EdgeDestination.cpp @@ -40,8 +40,9 @@ OrderedAssignments const& EdgeDestination::getOrderedAssignments() const { return templateEdgeDestination.get().getOrderedAssignments(); } -void EdgeDestination::substitute(std::map const& substitution) { - this->setProbability(substituteJaniExpression(this->getProbability(), substitution)); +void EdgeDestination::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + this->setProbability(substituteJaniExpression(this->getProbability(), substitution, substituteTranscendentalNumbers)); } bool EdgeDestination::hasAssignment(Assignment const& assignment) const { diff --git a/src/storm/storage/jani/EdgeDestination.h b/src/storm/storage/jani/EdgeDestination.h index f1ae65e2f1..096827b6b5 100644 --- a/src/storm/storage/jani/EdgeDestination.h +++ b/src/storm/storage/jani/EdgeDestination.h @@ -34,7 +34,7 @@ class EdgeDestination { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Retrieves the mapping from variables to their assigned expressions that corresponds to the assignments diff --git a/src/storm/storage/jani/FunctionDefinition.cpp b/src/storm/storage/jani/FunctionDefinition.cpp index 54041eaab9..b5af242814 100644 --- a/src/storm/storage/jani/FunctionDefinition.cpp +++ b/src/storm/storage/jani/FunctionDefinition.cpp @@ -33,15 +33,17 @@ storm::expressions::Expression FunctionDefinition::call(std::vector parameterSubstitution; for (uint64_t i = 0; i < arguments.size(); ++i) { parameterSubstitution.emplace(parameters[i], arguments[i]); } - return substituteJaniExpression(functionBody, parameterSubstitution); + return substituteJaniExpression(functionBody, parameterSubstitution, substituteTranscendentalNumbers); } -void FunctionDefinition::substitute(std::map const& substitution) { - this->setFunctionBody(substituteJaniExpression(this->getFunctionBody(), substitution)); +void FunctionDefinition::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + this->setFunctionBody(substituteJaniExpression(this->getFunctionBody(), substitution, substituteTranscendentalNumbers)); } void FunctionDefinition::setFunctionBody(storm::expressions::Expression const& body) { diff --git a/src/storm/storage/jani/FunctionDefinition.h b/src/storm/storage/jani/FunctionDefinition.h index 8534cdf2d7..94d4708a9e 100644 --- a/src/storm/storage/jani/FunctionDefinition.h +++ b/src/storm/storage/jani/FunctionDefinition.h @@ -49,7 +49,7 @@ class FunctionDefinition { */ storm::expressions::Expression call(std::vector> const& arguments) const; - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); private: // The name of the function. diff --git a/src/storm/storage/jani/JaniLocationExpander.cpp b/src/storm/storage/jani/JaniLocationExpander.cpp index 13b944526b..4c05f8e86e 100644 --- a/src/storm/storage/jani/JaniLocationExpander.cpp +++ b/src/storm/storage/jani/JaniLocationExpander.cpp @@ -41,6 +41,7 @@ JaniLocationExpander::AutomatonAndIndices JaniLocationExpander::transformAutomat bool isGlobalVariable = !automaton.hasVariable(variableName); VariableSet &containingSet = isGlobalVariable ? newModel.getGlobalVariables() : newAutomaton.getVariables(); + const bool substituteTranscendentalNumbers = false; auto &var = containingSet.getVariable(variableName); bool isBoundedInteger = var.getType().isBoundedType() && var.getType().asBoundedType().isIntegerType(); bool isBool = var.getType().isBasicType() && var.getType().asBasicType().isBooleanType(); @@ -116,7 +117,7 @@ JaniLocationExpander::AutomatonAndIndices JaniLocationExpander::transformAutomat substitutionMap[eliminatedExpressionVariable] = newIndices.variableDomain[i]; OrderedAssignments newAssignments = loc.getAssignments().clone(); - newAssignments.substitute(substitutionMap); + newAssignments.substitute(substitutionMap, substituteTranscendentalNumbers); Location newLoc(newLocationName, newAssignments); @@ -140,7 +141,7 @@ JaniLocationExpander::AutomatonAndIndices JaniLocationExpander::transformAutomat substitutionMap[eliminatedExpressionVariable] = newIndices.variableDomain[currentValueIndex]; uint64_t newSourceIndex = newValueAndLocation.second; - storm::expressions::Expression newGuard = substituteJaniExpression(edge.getGuard(), substitutionMap).simplify(); + storm::expressions::Expression newGuard = substituteJaniExpression(edge.getGuard(), substitutionMap, substituteTranscendentalNumbers).simplify(); if (!newGuard.containsVariables() && !newGuard.evaluateAsBool()) { continue; } @@ -153,7 +154,7 @@ JaniLocationExpander::AutomatonAndIndices JaniLocationExpander::transformAutomat std::vector> destinationLocationsAndProbabilities; for (auto const &destination : edge.getDestinations()) { OrderedAssignments oa(destination.getOrderedAssignments().clone()); - oa.substitute(substitutionMap); + oa.substitute(substitutionMap, substituteTranscendentalNumbers); int64_t newValueIndex = currentValueIndex; for (auto const &assignment : oa) { @@ -188,16 +189,18 @@ JaniLocationExpander::AutomatonAndIndices JaniLocationExpander::transformAutomat TemplateEdgeDestination ted(oa); templateEdge->addDestination(ted); - destinationLocationsAndProbabilities.emplace_back(newIndices.locationVariableValueMap[destination.getLocationIndex()][newValueIndex], - substituteJaniExpression(destination.getProbability(), substitutionMap)); + destinationLocationsAndProbabilities.emplace_back( + newIndices.locationVariableValueMap[destination.getLocationIndex()][newValueIndex], + substituteJaniExpression(destination.getProbability(), substitutionMap, substituteTranscendentalNumbers)); } if (!isEdgeInvalid) { templateEdge->finalize(newModel); - newAutomaton.addEdge(storm::jani::Edge( - newSourceIndex, edge.getActionIndex(), - edge.hasRate() ? boost::optional(substituteJaniExpression(edge.getRate(), substitutionMap)) : boost::none, - templateEdge, destinationLocationsAndProbabilities)); + newAutomaton.addEdge(storm::jani::Edge(newSourceIndex, edge.getActionIndex(), + edge.hasRate() ? boost::optional(substituteJaniExpression( + edge.getRate(), substitutionMap, substituteTranscendentalNumbers)) + : boost::none, + templateEdge, destinationLocationsAndProbabilities)); newAutomaton.registerTemplateEdge(templateEdge); } } diff --git a/src/storm/storage/jani/Location.cpp b/src/storm/storage/jani/Location.cpp index fae5f5cb17..b39e1deb3b 100644 --- a/src/storm/storage/jani/Location.cpp +++ b/src/storm/storage/jani/Location.cpp @@ -45,12 +45,13 @@ void Location::setTimeProgressInvariant(storm::expressions::Expression const& ex timeProgressInvariant = expression; } -void Location::substitute(std::map const& substitution) { +void Location::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { for (auto& assignment : assignments) { - assignment.substitute(substitution); + assignment.substitute(substitution, substituteTranscendentalNumbers); } if (hasTimeProgressInvariant()) { - setTimeProgressInvariant(substituteJaniExpression(getTimeProgressInvariant(), substitution)); + setTimeProgressInvariant(substituteJaniExpression(getTimeProgressInvariant(), substitution, substituteTranscendentalNumbers)); } } diff --git a/src/storm/storage/jani/Location.h b/src/storm/storage/jani/Location.h index 5eefba79d5..c439656a56 100644 --- a/src/storm/storage/jani/Location.h +++ b/src/storm/storage/jani/Location.h @@ -59,7 +59,7 @@ class Location { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Changes all variables in assignments based on the given mapping. diff --git a/src/storm/storage/jani/Model.cpp b/src/storm/storage/jani/Model.cpp index efc2c50d26..d7e690b4b4 100644 --- a/src/storm/storage/jani/Model.cpp +++ b/src/storm/storage/jani/Model.cpp @@ -1066,6 +1066,12 @@ Model Model::defineUndefinedConstants(std::map; + storm::expressions::JaniExpressionSubstitutionVisitor transcendentalsVisitor(SubMap(), true); + constant.setConstraintExpression(transcendentalsVisitor.substitute(constant.getConstraintExpression())); + } constant.define(variableExpressionPair->second); } } @@ -1100,52 +1106,52 @@ Model& Model::replaceUnassignedVariablesWithConstants() { return *this; } -Model& Model::substituteConstantsInPlace() { +Model& Model::substituteConstantsInPlace(bool const substituteTranscendentalNumbers) { // Gather all defining expressions of constants. std::map constantSubstitution; for (auto& constant : this->getConstants()) { if (constant.hasConstraint()) { - constant.setConstraintExpression(substituteJaniExpression(constant.getConstraintExpression(), constantSubstitution)); + constant.setConstraintExpression( + substituteJaniExpression(constant.getConstraintExpression(), constantSubstitution, substituteTranscendentalNumbers)); } if (constant.isDefined()) { - constant.define(substituteJaniExpression(constant.getExpression(), constantSubstitution)); + constant.define(substituteJaniExpression(constant.getExpression(), constantSubstitution, substituteTranscendentalNumbers)); constantSubstitution[constant.getExpressionVariable()] = constant.getExpression(); } } for (auto& functionDefinition : this->getGlobalFunctionDefinitions()) { - functionDefinition.second.substitute(constantSubstitution); + functionDefinition.second.substitute(constantSubstitution, substituteTranscendentalNumbers); } // Substitute constants in all global variables. - this->getGlobalVariables().substitute(constantSubstitution); + this->getGlobalVariables().substitute(constantSubstitution, substituteTranscendentalNumbers); // Substitute constants in initial states expression. - this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), constantSubstitution)); + this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), constantSubstitution, substituteTranscendentalNumbers)); for (auto& rewMod : this->getNonTrivialRewardExpressions()) { - rewMod.second = substituteJaniExpression(rewMod.second, constantSubstitution); + rewMod.second = substituteJaniExpression(rewMod.second, constantSubstitution, substituteTranscendentalNumbers); } // Substitute constants in variables of automata and their edges. for (auto& automaton : this->getAutomata()) { - automaton.substitute(constantSubstitution); + automaton.substitute(constantSubstitution, substituteTranscendentalNumbers); } - return *this; } Model Model::substituteConstants() const { Model result(*this); result.replaceUnassignedVariablesWithConstants(); - result.substituteConstantsInPlace(); + result.substituteConstantsInPlace(false); return result; } -Model Model::substituteConstantsFunctions() const { +Model Model::substituteConstantsFunctionsTranscendentals() const { Model result(*this); result.replaceUnassignedVariablesWithConstants(); - result.substituteConstantsInPlace(); + result.substituteConstantsInPlace(true); result.substituteFunctions(); return result; } @@ -1162,42 +1168,42 @@ std::map Model::ge return result; } -void Model::substitute(std::map const& substitution) { +void Model::substitute(std::map const& substitution, bool const substituteTranscendentalNumbers) { // substitute in all defining expressions of constants for (auto& constant : this->getConstants()) { if (constant.hasConstraint()) { - constant.setConstraintExpression(substituteJaniExpression(constant.getConstraintExpression(), substitution)); + constant.setConstraintExpression(substituteJaniExpression(constant.getConstraintExpression(), substitution, substituteTranscendentalNumbers)); } if (constant.isDefined()) { - constant.define(substituteJaniExpression(constant.getExpression(), substitution)); + constant.define(substituteJaniExpression(constant.getExpression(), substitution, substituteTranscendentalNumbers)); } } for (auto& functionDefinition : this->getGlobalFunctionDefinitions()) { - functionDefinition.second.substitute(substitution); + functionDefinition.second.substitute(substitution, substituteTranscendentalNumbers); } // Substitute in all global variables. for (auto& variable : this->getGlobalVariables().getBoundedIntegerVariables()) { - variable.substitute(substitution); + variable.substitute(substitution, substituteTranscendentalNumbers); } for (auto& variable : this->getGlobalVariables().getArrayVariables()) { - variable.substitute(substitution); + variable.substitute(substitution, substituteTranscendentalNumbers); } for (auto& variable : this->getGlobalVariables().getClockVariables()) { - variable.substitute(substitution); + variable.substitute(substitution, substituteTranscendentalNumbers); } // Substitute in initial states expression. - this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), substitution)); + this->setInitialStatesRestriction(substituteJaniExpression(this->getInitialStatesRestriction(), substitution, substituteTranscendentalNumbers)); for (auto& rewMod : getNonTrivialRewardExpressions()) { - rewMod.second = substituteJaniExpression(rewMod.second, substitution); + rewMod.second = substituteJaniExpression(rewMod.second, substitution, substituteTranscendentalNumbers); } // Substitute in variables of automata and their edges. for (auto& automaton : this->getAutomata()) { - automaton.substitute(substitution); + automaton.substitute(substitution, substituteTranscendentalNumbers); } } @@ -1263,6 +1269,11 @@ ModelFeatures Model::restrictToFeatures(ModelFeatures const& features, std::vect uncheckedFeatures.remove(ModelFeature::DerivedOperators); } + // There is no elimination of trigonometric operators + if (features.hasTrigonometricFunctions()) { + uncheckedFeatures.remove(ModelFeature::TrigonometricFunctions); + } + return uncheckedFeatures; } @@ -1620,8 +1631,7 @@ Model Model::createModelFromAutomaton(Automaton const& automaton) const { std::string filterName(std::string const& text) { std::string result = text; - std::replace_if( - result.begin(), result.end(), [](const char& c) { return std::ispunct(c); }, '_'); + std::replace_if(result.begin(), result.end(), [](const char& c) { return std::ispunct(c); }, '_'); return result; } diff --git a/src/storm/storage/jani/Model.h b/src/storm/storage/jani/Model.h index e3df645b18..168ad4c95a 100644 --- a/src/storm/storage/jani/Model.h +++ b/src/storm/storage/jani/Model.h @@ -421,7 +421,7 @@ class Model { /*! * Substitutes all constants in all expressions of the model. */ - Model& substituteConstantsInPlace(); + Model& substituteConstantsInPlace(bool const substituteTranscendentalNumbers); /*! * Substitutes all constants in all expressions of the model. The original model is not modified, but @@ -439,7 +439,7 @@ class Model { * Substitutes all expression variables in all expressions of the model. The original model is not modified, but * instead a new model is created. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Substitutes all function calls with the corresponding function definition @@ -451,10 +451,11 @@ class Model { /*! * 1. Tries to replace variables by constants (if possible). * 2. Substitutes all constants in all expressions of the model. - * 3. Afterwards, all function calls are substituted with the defining expression. + * 3. Substitutes transcendental numbers by their actual value + * 4. Afterwards, all function calls are substituted with the defining expression. * The original model is not modified, but instead a new model is created. */ - Model substituteConstantsFunctions() const; + Model substituteConstantsFunctionsTranscendentals() const; /*! * Returns true if at least one array variable occurs in the model. diff --git a/src/storm/storage/jani/ModelFeatures.cpp b/src/storm/storage/jani/ModelFeatures.cpp index 6d48d20cea..a390673e0e 100644 --- a/src/storm/storage/jani/ModelFeatures.cpp +++ b/src/storm/storage/jani/ModelFeatures.cpp @@ -15,6 +15,8 @@ std::string toString(ModelFeature const& modelFeature) { return "functions"; case ModelFeature::StateExitRewards: return "state-exit-rewards"; + case ModelFeature::TrigonometricFunctions: + return "trigonometric-functions"; } STORM_LOG_ASSERT(false, "Unhandled model feature"); return "Unhandled-feature"; @@ -50,6 +52,10 @@ bool ModelFeatures::hasStateExitRewards() const { return features.count(ModelFeature::StateExitRewards) > 0; } +bool ModelFeatures::hasTrigonometricFunctions() const { + return features.count(ModelFeature::TrigonometricFunctions) > 0; +} + std::set const& ModelFeatures::asSet() const { return features; } @@ -68,7 +74,12 @@ void ModelFeatures::remove(ModelFeature const& modelFeature) { } ModelFeatures getAllKnownModelFeatures() { - return ModelFeatures().add(ModelFeature::Arrays).add(ModelFeature::DerivedOperators).add(ModelFeature::Functions).add(ModelFeature::StateExitRewards); + return ModelFeatures() + .add(ModelFeature::Arrays) + .add(ModelFeature::DerivedOperators) + .add(ModelFeature::Functions) + .add(ModelFeature::StateExitRewards) + .add(ModelFeature::TrigonometricFunctions); } } // namespace jani } // namespace storm diff --git a/src/storm/storage/jani/ModelFeatures.h b/src/storm/storage/jani/ModelFeatures.h index a114fd6a44..7f47185f0a 100644 --- a/src/storm/storage/jani/ModelFeatures.h +++ b/src/storm/storage/jani/ModelFeatures.h @@ -6,7 +6,7 @@ namespace storm { namespace jani { -enum class ModelFeature { Arrays, DerivedOperators, Functions, StateExitRewards }; +enum class ModelFeature { Arrays, DerivedOperators, Functions, StateExitRewards, TrigonometricFunctions }; std::string toString(ModelFeature const& modelFeature); @@ -18,6 +18,7 @@ class ModelFeatures { bool hasFunctions() const; bool hasDerivedOperators() const; bool hasStateExitRewards() const; + bool hasTrigonometricFunctions() const; // Returns true, if no model feature is enabled. bool empty() const; diff --git a/src/storm/storage/jani/OrderedAssignments.cpp b/src/storm/storage/jani/OrderedAssignments.cpp index d6d47ddb8d..2da1282222 100644 --- a/src/storm/storage/jani/OrderedAssignments.cpp +++ b/src/storm/storage/jani/OrderedAssignments.cpp @@ -238,9 +238,10 @@ detail::ConstAssignments::iterator OrderedAssignments::end() const { return detail::ConstAssignments::make_iterator(allAssignments.end()); } -void OrderedAssignments::substitute(std::map const& substitution) { +void OrderedAssignments::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { for (auto& assignment : allAssignments) { - assignment->substitute(substitution); + assignment->substitute(substitution, substituteTranscendentalNumbers); } } diff --git a/src/storm/storage/jani/OrderedAssignments.h b/src/storm/storage/jani/OrderedAssignments.h index b81456ca6c..0b50af5993 100644 --- a/src/storm/storage/jani/OrderedAssignments.h +++ b/src/storm/storage/jani/OrderedAssignments.h @@ -139,7 +139,7 @@ class OrderedAssignments { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Changes all variables in assignments based on the given mapping. diff --git a/src/storm/storage/jani/Property.cpp b/src/storm/storage/jani/Property.cpp index 3bb3e7373e..75614d7bf4 100644 --- a/src/storm/storage/jani/Property.cpp +++ b/src/storm/storage/jani/Property.cpp @@ -77,6 +77,10 @@ Property Property::substituteRewardModelNames(std::map return Property(name, filterExpression.substituteRewardModelNames(rewardModelNameSubstitution), undefinedConstants, comment); } +Property Property::substituteTranscendentalNumbers() const { + return Property(name, filterExpression.substituteTranscendentalNumbers(), undefinedConstants, comment); +} + Property Property::clone() const { return Property(name, filterExpression.clone(), undefinedConstants, comment); } diff --git a/src/storm/storage/jani/Property.h b/src/storm/storage/jani/Property.h index 612d9e15c7..91784f0658 100644 --- a/src/storm/storage/jani/Property.h +++ b/src/storm/storage/jani/Property.h @@ -78,6 +78,10 @@ class FilterExpression { statesFormula->substituteRewardModelNames(rewardModelNameSubstitution)); } + FilterExpression substituteTranscendentalNumbers() const { + return FilterExpression(formula->substituteTranscendentalNumbers(), ft, statesFormula->substituteTranscendentalNumbers()); + } + FilterExpression clone() const { storm::logic::CloneVisitor cv; return FilterExpression(cv.clone(*formula), ft, cv.clone(*statesFormula)); @@ -131,6 +135,7 @@ class Property { Property substitute(std::function const& substitutionFunction) const; Property substituteLabels(std::map const& labelSubstitution) const; Property substituteRewardModelNames(std::map const& rewardModelNameSubstitution) const; + Property substituteTranscendentalNumbers() const; Property clone() const; FilterExpression const& getFilter() const; diff --git a/src/storm/storage/jani/TemplateEdge.cpp b/src/storm/storage/jani/TemplateEdge.cpp index dfaa9e5796..208513f165 100644 --- a/src/storm/storage/jani/TemplateEdge.cpp +++ b/src/storm/storage/jani/TemplateEdge.cpp @@ -85,15 +85,16 @@ OrderedAssignments& TemplateEdge::getAssignments() { return assignments; } -void TemplateEdge::substitute(std::map const& substitution) { - guard = substituteJaniExpression(guard, substitution); +void TemplateEdge::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + guard = substituteJaniExpression(guard, substitution, substituteTranscendentalNumbers); for (auto& assignment : assignments) { - assignment.substitute(substitution); + assignment.substitute(substitution, substituteTranscendentalNumbers); } for (auto& destination : destinations) { - destination.substitute(substitution); + destination.substitute(substitution, substituteTranscendentalNumbers); } } diff --git a/src/storm/storage/jani/TemplateEdge.h b/src/storm/storage/jani/TemplateEdge.h index fa74dac236..10db194f92 100644 --- a/src/storm/storage/jani/TemplateEdge.h +++ b/src/storm/storage/jani/TemplateEdge.h @@ -55,7 +55,7 @@ class TemplateEdge { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Changes all variables in assignments based on the given mapping. diff --git a/src/storm/storage/jani/TemplateEdgeDestination.cpp b/src/storm/storage/jani/TemplateEdgeDestination.cpp index a597c50367..98967c08d5 100644 --- a/src/storm/storage/jani/TemplateEdgeDestination.cpp +++ b/src/storm/storage/jani/TemplateEdgeDestination.cpp @@ -15,8 +15,9 @@ TemplateEdgeDestination::TemplateEdgeDestination(std::vector const& // Intentionally left empty. } -void TemplateEdgeDestination::substitute(std::map const& substitution) { - assignments.substitute(substitution); +void TemplateEdgeDestination::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + assignments.substitute(substitution, substituteTranscendentalNumbers); } void TemplateEdgeDestination::changeAssignmentVariables(std::map> const& remapping) { diff --git a/src/storm/storage/jani/TemplateEdgeDestination.h b/src/storm/storage/jani/TemplateEdgeDestination.h index 824e5251dd..e1247ca276 100644 --- a/src/storm/storage/jani/TemplateEdgeDestination.h +++ b/src/storm/storage/jani/TemplateEdgeDestination.h @@ -15,7 +15,7 @@ class TemplateEdgeDestination { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Changes all variables in assignments based on the given mapping. diff --git a/src/storm/storage/jani/Variable.cpp b/src/storm/storage/jani/Variable.cpp index f3702e5708..38051208b5 100644 --- a/src/storm/storage/jani/Variable.cpp +++ b/src/storm/storage/jani/Variable.cpp @@ -56,11 +56,12 @@ void Variable::setInitExpression(storm::expressions::Expression const& initialEx this->init = initialExpression; } -void Variable::substitute(std::map const& substitution) { +void Variable::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { if (this->hasInitExpression()) { - this->setInitExpression(substituteJaniExpression(this->getInitExpression(), substitution)); + this->setInitExpression(substituteJaniExpression(this->getInitExpression(), substitution, substituteTranscendentalNumbers)); } - type->substitute(substitution); + type->substitute(substitution, substituteTranscendentalNumbers); } JaniType& Variable::getType() { diff --git a/src/storm/storage/jani/Variable.h b/src/storm/storage/jani/Variable.h index 6ad076cef6..5fdca78e4d 100644 --- a/src/storm/storage/jani/Variable.h +++ b/src/storm/storage/jani/Variable.h @@ -82,7 +82,7 @@ class Variable { /*! * Substitutes all variables in all expressions according to the given substitution. */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /** * Convenience functions to call the appropriate constructor and return a shared pointer to the variable. diff --git a/src/storm/storage/jani/VariableSet.cpp b/src/storm/storage/jani/VariableSet.cpp index cebfb9b041..d1d5d77b64 100644 --- a/src/storm/storage/jani/VariableSet.cpp +++ b/src/storm/storage/jani/VariableSet.cpp @@ -351,9 +351,10 @@ std::map> VariableSet::getNa return result; } -void VariableSet::substitute(std::map const& substitution) { +void VariableSet::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { for (auto& variable : variables) { - variable->substitute(substitution); + variable->substitute(substitution, substituteTranscendentalNumbers); } } diff --git a/src/storm/storage/jani/VariableSet.h b/src/storm/storage/jani/VariableSet.h index 9bb4734128..417cb80cf4 100644 --- a/src/storm/storage/jani/VariableSet.h +++ b/src/storm/storage/jani/VariableSet.h @@ -261,7 +261,7 @@ class VariableSet { * The substitution does not apply to the variables itself, but to initial expressions, variable bounds, ... * @param substitution */ - void substitute(std::map const& substitution); + void substitute(std::map const& substitution, bool const substituteTranscendentalNumbers); /*! * Substitutes the actual variables according to the given substitution. diff --git a/src/storm/storage/jani/eliminator/ArrayEliminator.cpp b/src/storm/storage/jani/eliminator/ArrayEliminator.cpp index 0fb91e5a5e..73bbc91066 100644 --- a/src/storm/storage/jani/eliminator/ArrayEliminator.cpp +++ b/src/storm/storage/jani/eliminator/ArrayEliminator.cpp @@ -280,6 +280,11 @@ class ArrayReplacementsCollectorExpressionVisitor : public storm::expressions::E "Found Function call expression within an array expression. This is not expected since functions are expected to be eliminated at this point."); } + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const&, boost::any const&) override { + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected type of expression."); + return boost::any(); + } + private: storm::jani::Variable const& addReplacementVariable(std::vector const& indices) { auto& manager = model.getExpressionManager(); @@ -801,6 +806,10 @@ class ArrayExpressionEliminationVisitor : public storm::expressions::ExpressionV return false; } + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const& expression, boost::any const&) override { + return ResultType(expression.getSharedPointer()); + } + private: std::unordered_map const& replacements; }; diff --git a/src/storm/storage/jani/eliminator/FunctionEliminator.cpp b/src/storm/storage/jani/eliminator/FunctionEliminator.cpp index 71fa8fa640..4f8a1949bd 100644 --- a/src/storm/storage/jani/eliminator/FunctionEliminator.cpp +++ b/src/storm/storage/jani/eliminator/FunctionEliminator.cpp @@ -212,6 +212,10 @@ class FunctionEliminationExpressionVisitor : public storm::expressions::Expressi return boost::any_cast(funDef->call(expression.getArguments()).getBaseExpression().accept(*this, data)); } + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const& expression, boost::any const&) override { + return expression.getSharedPointer(); + } + private: std::unordered_map const* globalFunctions; std::unordered_map const* localFunctions; diff --git a/src/storm/storage/jani/expressions/ConstructorArrayExpression.cpp b/src/storm/storage/jani/expressions/ConstructorArrayExpression.cpp index 0975db21dc..b4061caab7 100644 --- a/src/storm/storage/jani/expressions/ConstructorArrayExpression.cpp +++ b/src/storm/storage/jani/expressions/ConstructorArrayExpression.cpp @@ -60,7 +60,7 @@ std::shared_ptr ConstructorArrayExpression::size() const { std::shared_ptr ConstructorArrayExpression::at(uint64_t i) const { std::map substitution; substitution.emplace(indexVar, this->getManager().integer(i)); - return storm::jani::substituteJaniExpression(elementExpression->toExpression(), substitution).getBaseExpressionPointer(); + return storm::jani::substituteJaniExpression(elementExpression->toExpression(), substitution, false).getBaseExpressionPointer(); } std::shared_ptr const& ConstructorArrayExpression::getElementExpression() const { diff --git a/src/storm/storage/jani/expressions/JaniExpressions.h b/src/storm/storage/jani/expressions/JaniExpressions.h index 7f105fd4bf..40ccba3bdc 100644 --- a/src/storm/storage/jani/expressions/JaniExpressions.h +++ b/src/storm/storage/jani/expressions/JaniExpressions.h @@ -2,4 +2,5 @@ #include "storm/storage/jani/expressions/ArrayAccessExpression.h" #include "storm/storage/jani/expressions/ConstructorArrayExpression.h" #include "storm/storage/jani/expressions/FunctionCallExpression.h" +#include "storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.h" #include "storm/storage/jani/expressions/ValueArrayExpression.h" diff --git a/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.cpp b/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.cpp new file mode 100644 index 0000000000..db90c343fc --- /dev/null +++ b/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.cpp @@ -0,0 +1,71 @@ +#include "storm/exceptions/UnexpectedException.h" + +#include "storm/storage/expressions/ExpressionManager.h" +#include "storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.h" +#include "storm/storage/jani/visitor/JaniExpressionVisitor.h" + +#include "storm/utility/constants.h" + +namespace storm { +namespace expressions { +TranscendentalNumberLiteralExpression::TranscendentalNumberLiteralExpression(ExpressionManager const& manager, TranscendentalNumber const& value) + : BaseExpression(manager, manager.getTranscendentalNumberType()), value(value) { + // Intentionally left empty. +} + +double TranscendentalNumberLiteralExpression::evaluateAsDouble(Valuation const*) const { + switch (value) { + case TranscendentalNumber::PI: + return M_PI; + break; + case TranscendentalNumber::E: + return std::exp(1.0); + break; + default: + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected constant value."); + break; + } +} + +bool TranscendentalNumberLiteralExpression::isLiteral() const { + return true; +} + +void TranscendentalNumberLiteralExpression::gatherVariables(std::set&) const { + // A constant value is not supposed to have any variable + return; +} + +std::shared_ptr TranscendentalNumberLiteralExpression::simplify() const { + // No further simplification for constant values + return this->shared_from_this(); +} + +boost::any TranscendentalNumberLiteralExpression::accept(ExpressionVisitor& visitor, boost::any const& data) const { + auto janiVisitor = dynamic_cast(&visitor); + STORM_LOG_ASSERT(janiVisitor != nullptr, "Visitor of jani expression should be of type JaniVisitor."); + STORM_LOG_THROW(janiVisitor != nullptr, storm::exceptions::UnexpectedException, "Visitor of jani expression should be of type JaniVisitor."); + return janiVisitor->visit(*this, data); +} + +TranscendentalNumberLiteralExpression::TranscendentalNumber const& TranscendentalNumberLiteralExpression::getTranscendentalNumber() const { + return value; +} + +std::string TranscendentalNumberLiteralExpression::asString() const { + switch (value) { + case TranscendentalNumber::PI: + return "π"; + case TranscendentalNumber::E: + return "e"; + default: + STORM_LOG_THROW(false, storm::exceptions::UnexpectedException, "Unexpected constant value."); + } + return ""; +} + +void TranscendentalNumberLiteralExpression::printToStream(std::ostream& stream) const { + stream << asString(); +} +} // namespace expressions +} // namespace storm diff --git a/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.h b/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.h new file mode 100644 index 0000000000..8955cb9360 --- /dev/null +++ b/src/storm/storage/jani/expressions/TranscendentalNumberLiteralExpression.h @@ -0,0 +1,64 @@ +#ifndef STORM_STORAGE_EXPRESSIONS_TRANSCENDENTALNUMBERLITERALEXPRESSION_H_ +#define STORM_STORAGE_EXPRESSIONS_TRANSCENDENTALNUMBERLITERALEXPRESSION_H_ + +#include "storm/storage/expressions/BaseExpression.h" +#include "storm/storage/expressions/RationalLiteralExpression.h" +#include "storm/utility/OsDetection.h" + +namespace storm { +namespace expressions { +class TranscendentalNumberLiteralExpression : public BaseExpression { + public: + /*! + * @brief Enum class to represent the supported TranscendentalNumbers + */ + enum class TranscendentalNumber { + PI, // π + E // EulerNumber + }; + /*! + * Creates a unary expression with the given return type and operand. + * + * @param manager The manager responsible for this expression. + * @param value The constant value assigned to the variable + */ + TranscendentalNumberLiteralExpression(ExpressionManager const& manager, TranscendentalNumber const& value); + + // Instantiate constructors and assignments with their default implementations. + TranscendentalNumberLiteralExpression(TranscendentalNumberLiteralExpression const& other) = default; + TranscendentalNumberLiteralExpression& operator=(TranscendentalNumberLiteralExpression const& other) = delete; + TranscendentalNumberLiteralExpression(TranscendentalNumberLiteralExpression&&) = default; + TranscendentalNumberLiteralExpression& operator=(TranscendentalNumberLiteralExpression&&) = delete; + virtual ~TranscendentalNumberLiteralExpression() = default; + + // Override base class methods. + virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const override; + virtual bool isLiteral() const override; + virtual void gatherVariables(std::set& variables) const override; + virtual std::shared_ptr simplify() const override; + virtual boost::any accept(ExpressionVisitor& visitor, boost::any const& data) const override; + + /*! + * @brief Getter for the constant value stored by the object + * @return A reference to the stored TranscendentalNumber + */ + TranscendentalNumber const& getTranscendentalNumber() const; + + /*! + * @brief Get the Transcendental number as string, like in the Jani file (single character) + * @return A string representing the transcendental number + */ + std::string asString() const; + + protected: + // Override base class method. + virtual void printToStream(std::ostream& stream) const override; + + private: + // The operand of the unary expression. + const TranscendentalNumber value; +}; +} // namespace expressions +} // namespace storm + +#endif /* STORM_STORAGE_EXPRESSIONS_TRANSCENDENTALNUMBERLITERALEXPRESSION_H_ */ diff --git a/src/storm/storage/jani/traverser/ArrayExpressionFinder.cpp b/src/storm/storage/jani/traverser/ArrayExpressionFinder.cpp index a9ce6ff4ec..da70784a36 100644 --- a/src/storm/storage/jani/traverser/ArrayExpressionFinder.cpp +++ b/src/storm/storage/jani/traverser/ArrayExpressionFinder.cpp @@ -78,6 +78,10 @@ class ArrayExpressionFinderExpressionVisitor : public storm::expressions::Expres } return false; } + + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const&, boost::any const&) override { + return false; + } }; class ArrayExpressionFinderTraverser : public ConstJaniTraverser { diff --git a/src/storm/storage/jani/traverser/FunctionCallExpressionFinder.cpp b/src/storm/storage/jani/traverser/FunctionCallExpressionFinder.cpp index 88d601c6d5..9fb8a846d0 100644 --- a/src/storm/storage/jani/traverser/FunctionCallExpressionFinder.cpp +++ b/src/storm/storage/jani/traverser/FunctionCallExpressionFinder.cpp @@ -93,6 +93,10 @@ class FunctionCallExpressionFinderExpressionVisitor : public storm::expressions: } return boost::any(); } + + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const&, boost::any const&) override { + return boost::any(); + } }; class FunctionCallExpressionFinderTraverser : public ConstJaniTraverser { diff --git a/src/storm/storage/jani/traverser/RewardModelInformation.cpp b/src/storm/storage/jani/traverser/RewardModelInformation.cpp index 5c69a8966c..0a76fcb340 100644 --- a/src/storm/storage/jani/traverser/RewardModelInformation.cpp +++ b/src/storm/storage/jani/traverser/RewardModelInformation.cpp @@ -41,7 +41,7 @@ RewardModelInformation::RewardModelInformation(Model const& model, storm::expres } } } - auto initExpr = storm::jani::substituteJaniExpression(rewardModelExpression, initialSubstitution).simplify(); + auto initExpr = storm::jani::substituteJaniExpression(rewardModelExpression, initialSubstitution, true).simplify(); if (containsNonTransientVariable || initExpr.containsVariables() || !storm::utility::isZero(initExpr.evaluateAsRational())) { stateRewards = true; actionRewards = true; diff --git a/src/storm/storage/jani/types/ArrayType.cpp b/src/storm/storage/jani/types/ArrayType.cpp index 678136ccac..960ad87745 100644 --- a/src/storm/storage/jani/types/ArrayType.cpp +++ b/src/storm/storage/jani/types/ArrayType.cpp @@ -43,9 +43,10 @@ std::string ArrayType::getStringRepresentation() const { return "array[" + getBaseType().getStringRepresentation() + "]"; } -void ArrayType::substitute(std::map const& substitution) { - JaniType::substitute(substitution); - baseType->substitute(substitution); +void ArrayType::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + JaniType::substitute(substitution, substituteTranscendentalNumbers); + baseType->substitute(substitution, substituteTranscendentalNumbers); } std::unique_ptr ArrayType::clone() const { diff --git a/src/storm/storage/jani/types/ArrayType.h b/src/storm/storage/jani/types/ArrayType.h index d5686d6fc4..54334cb28c 100644 --- a/src/storm/storage/jani/types/ArrayType.h +++ b/src/storm/storage/jani/types/ArrayType.h @@ -29,7 +29,8 @@ class ArrayType : public JaniType { uint64_t getNestingDegree() const; virtual std::string getStringRepresentation() const override; - virtual void substitute(std::map const& substitution) override; + virtual void substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) override; virtual std::unique_ptr clone() const override; private: diff --git a/src/storm/storage/jani/types/BoundedType.cpp b/src/storm/storage/jani/types/BoundedType.cpp index 2453bbf363..ea5dbb326a 100644 --- a/src/storm/storage/jani/types/BoundedType.cpp +++ b/src/storm/storage/jani/types/BoundedType.cpp @@ -63,13 +63,14 @@ storm::expressions::Expression const& BoundedType::getUpperBound() const { return this->upperBound; } -void BoundedType::substitute(std::map const& substitution) { - JaniType::substitute(substitution); +void BoundedType::substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) { + JaniType::substitute(substitution, substituteTranscendentalNumbers); if (this->hasLowerBound()) { - this->setLowerBound(substituteJaniExpression(this->getLowerBound(), substitution)); + this->setLowerBound(substituteJaniExpression(this->getLowerBound(), substitution, substituteTranscendentalNumbers)); } if (this->hasUpperBound()) { - this->setUpperBound(substituteJaniExpression(this->getUpperBound(), substitution)); + this->setUpperBound(substituteJaniExpression(this->getUpperBound(), substitution, substituteTranscendentalNumbers)); } } diff --git a/src/storm/storage/jani/types/BoundedType.h b/src/storm/storage/jani/types/BoundedType.h index 02b62d36ab..c1e30d69b6 100644 --- a/src/storm/storage/jani/types/BoundedType.h +++ b/src/storm/storage/jani/types/BoundedType.h @@ -19,7 +19,8 @@ class BoundedType : public JaniType { bool isNumericalType() const; /// true iff type is either real or int (i.e. it's always true but let's make it explicit) virtual std::string getStringRepresentation() const override; - virtual void substitute(std::map const& substitution) override; + virtual void substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers) override; virtual std::unique_ptr clone() const override; void setLowerBound(storm::expressions::Expression const& expression); diff --git a/src/storm/storage/jani/types/JaniType.cpp b/src/storm/storage/jani/types/JaniType.cpp index ed778724e2..58af132000 100644 --- a/src/storm/storage/jani/types/JaniType.cpp +++ b/src/storm/storage/jani/types/JaniType.cpp @@ -68,7 +68,8 @@ ContinuousType& JaniType::asContinuousType() { return dynamic_cast(*this); } -void JaniType::substitute(std::map const& /*substitution*/) { +void JaniType::substitute(std::map const& /*substitution*/, + bool const /*substituteTranscendentalNumbers*/) { // intentionally left empty } diff --git a/src/storm/storage/jani/types/JaniType.h b/src/storm/storage/jani/types/JaniType.h index b0002621d4..92da319e5c 100644 --- a/src/storm/storage/jani/types/JaniType.h +++ b/src/storm/storage/jani/types/JaniType.h @@ -47,7 +47,8 @@ class JaniType { /*! * Substitutes all variables in all expressions according to the given substitution. */ - virtual void substitute(std::map const& substitution); + virtual void substitute(std::map const& substitution, + bool const substituteTranscendentalNumbers); friend std::ostream& operator<<(std::ostream& stream, JaniType const& type); }; diff --git a/src/storm/storage/jani/visitor/JSONExporter.cpp b/src/storm/storage/jani/visitor/JSONExporter.cpp index 280046a513..5be4d55e3a 100644 --- a/src/storm/storage/jani/visitor/JSONExporter.cpp +++ b/src/storm/storage/jani/visitor/JSONExporter.cpp @@ -634,6 +634,10 @@ std::string operatorTypeToJaniString(storm::expressions::OperatorType optype) { return "ceil"; case OpType::Ite: return "ite"; + case OpType::Sin: + return "sin"; + case OpType::Cos: + return "cos"; default: STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Operator not supported by Jani"); } @@ -793,6 +797,12 @@ boost::any ExpressionToJson::visit(storm::expressions::FunctionCallExpression co return opDecl; } +boost::any ExpressionToJson::visit(storm::expressions::TranscendentalNumberLiteralExpression const& expression, boost::any const&) { + ExportJsonType constantDecl; + constantDecl["constant"] = expression.asString(); + return constantDecl; +} + void JsonExporter::toFile(storm::jani::Model const& janiModel, std::vector const& formulas, std::string const& filepath, bool checkValid, bool compact) { std::ofstream stream; diff --git a/src/storm/storage/jani/visitor/JSONExporter.h b/src/storm/storage/jani/visitor/JSONExporter.h index d911d6097d..c7b9aa1918 100644 --- a/src/storm/storage/jani/visitor/JSONExporter.h +++ b/src/storm/storage/jani/visitor/JSONExporter.h @@ -34,6 +34,7 @@ class ExpressionToJson : public storm::expressions::ExpressionVisitor, public st virtual boost::any visit(storm::expressions::ConstructorArrayExpression const& expression, boost::any const& data); virtual boost::any visit(storm::expressions::ArrayAccessExpression const& expression, boost::any const& data); virtual boost::any visit(storm::expressions::FunctionCallExpression const& expression, boost::any const& data); + virtual boost::any visit(storm::expressions::TranscendentalNumberLiteralExpression const& expression, boost::any const& data); private: ExpressionToJson(std::vector const& constants, VariableSet const& globalVariables, VariableSet const& localVariables, diff --git a/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.cpp b/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.cpp index 13118bff0a..18faff4ee2 100644 --- a/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.cpp +++ b/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.cpp @@ -5,18 +5,20 @@ namespace storm { namespace jani { -storm::expressions::Expression substituteJaniExpression( - storm::expressions::Expression const& expression, std::map const& identifierToExpressionMap) { +storm::expressions::Expression substituteJaniExpression(storm::expressions::Expression const& expression, + std::map const& identifierToExpressionMap, + bool const substituteTranscendentalNumbers) { return storm::expressions::JaniExpressionSubstitutionVisitor>( - identifierToExpressionMap) + identifierToExpressionMap, substituteTranscendentalNumbers) .substitute(expression); } storm::expressions::Expression substituteJaniExpression( storm::expressions::Expression const& expression, - std::unordered_map const& identifierToExpressionMap) { + std::unordered_map const& identifierToExpressionMap, + bool const substituteTranscendentalNumbers) { return storm::expressions::JaniExpressionSubstitutionVisitor>( - identifierToExpressionMap) + identifierToExpressionMap, substituteTranscendentalNumbers) .substitute(expression); } } // namespace jani @@ -24,8 +26,9 @@ storm::expressions::Expression substituteJaniExpression( namespace expressions { template -JaniExpressionSubstitutionVisitor::JaniExpressionSubstitutionVisitor(MapType const& variableToExpressionMapping) - : SubstitutionVisitor(variableToExpressionMapping) { +JaniExpressionSubstitutionVisitor::JaniExpressionSubstitutionVisitor(MapType const& variableToExpressionMapping, + bool const substituteTranscendentalNumbers) + : SubstitutionVisitor(variableToExpressionMapping), shallSubstituteTranscendentalNumbers(substituteTranscendentalNumbers) { // Intentionally left empty. } @@ -91,6 +94,16 @@ boost::any JaniExpressionSubstitutionVisitor::visit(FunctionCallExpress new FunctionCallExpression(expression.getManager(), expression.getType(), expression.getFunctionIdentifier(), newArguments))); } +template +boost::any JaniExpressionSubstitutionVisitor::visit(TranscendentalNumberLiteralExpression const& expression, boost::any const&) { + if (shallSubstituteTranscendentalNumbers) { + return std::const_pointer_cast( + std::shared_ptr(new RationalLiteralExpression(expression.getManager(), expression.evaluateAsDouble()))); + } + // No substitution requested for transcendental numbers + return expression.getSharedPointer(); +} + // Explicitly instantiate the class with map and unordered_map. template class JaniExpressionSubstitutionVisitor>; template class JaniExpressionSubstitutionVisitor>; diff --git a/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.h b/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.h index 2088cffb22..1eb9ff2c5e 100644 --- a/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.h +++ b/src/storm/storage/jani/visitor/JaniExpressionSubstitutionVisitor.h @@ -7,11 +7,13 @@ namespace storm { namespace jani { -storm::expressions::Expression substituteJaniExpression( - storm::expressions::Expression const& expression, std::map const& identifierToExpressionMap); +storm::expressions::Expression substituteJaniExpression(storm::expressions::Expression const& expression, + std::map const& identifierToExpressionMap, + bool const substituteTranscendentalNumbers); storm::expressions::Expression substituteJaniExpression( storm::expressions::Expression const& expression, - std::unordered_map const& identifierToExpressionMap); + std::unordered_map const& identifierToExpressionMap, + bool const substituteTranscendentalNumbers); } // namespace jani namespace expressions { @@ -22,14 +24,19 @@ class JaniExpressionSubstitutionVisitor : public SubstitutionVisitor, p * Creates a new substitution visitor that uses the given map to replace variables. * * @param variableToExpressionMapping A mapping from variables to expressions. + * @param substituteTranscendentalNumbers Enables transcendental numbers substitution */ - JaniExpressionSubstitutionVisitor(MapType const& variableToExpressionMapping); + JaniExpressionSubstitutionVisitor(MapType const& variableToExpressionMapping, bool const substituteTranscendentalNumbers); using SubstitutionVisitor::visit; virtual boost::any visit(ValueArrayExpression const& expression, boost::any const& data) override; virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) override; virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) override; virtual boost::any visit(FunctionCallExpression const& expression, boost::any const& data) override; + virtual boost::any visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) override; + + protected: + const bool shallSubstituteTranscendentalNumbers; }; } // namespace expressions } // namespace storm \ No newline at end of file diff --git a/src/storm/storage/jani/visitor/JaniExpressionVisitor.h b/src/storm/storage/jani/visitor/JaniExpressionVisitor.h index 554c4c2ea5..ed420f3b7d 100644 --- a/src/storm/storage/jani/visitor/JaniExpressionVisitor.h +++ b/src/storm/storage/jani/visitor/JaniExpressionVisitor.h @@ -11,6 +11,7 @@ class JaniExpressionVisitor { virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) = 0; virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) = 0; virtual boost::any visit(FunctionCallExpression const& expression, boost::any const& data) = 0; + virtual boost::any visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) = 0; }; } // namespace expressions } // namespace storm diff --git a/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.cpp b/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.cpp index 5d286dafc8..625b877cbb 100644 --- a/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.cpp +++ b/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.cpp @@ -70,5 +70,10 @@ boost::any JaniReduceNestingExpressionVisitor::visit(FunctionCallExpression cons return std::const_pointer_cast(std::shared_ptr( new FunctionCallExpression(expression.getManager(), expression.getType(), expression.getFunctionIdentifier(), newArguments))); } + +boost::any JaniReduceNestingExpressionVisitor::visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) { + // No substitution is required for constants + return expression.getSharedPointer(); +} } // namespace expressions } // namespace storm diff --git a/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.h b/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.h index 240334f3f3..390156e07c 100644 --- a/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.h +++ b/src/storm/storage/jani/visitor/JaniReduceNestingExpressionVisitor.h @@ -20,6 +20,7 @@ class JaniReduceNestingExpressionVisitor : public ReduceNestingVisitor, public J virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) override; virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) override; virtual boost::any visit(FunctionCallExpression const& expression, boost::any const& data) override; + virtual boost::any visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) override; }; } // namespace expressions } // namespace storm \ No newline at end of file diff --git a/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.cpp b/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.cpp index 144227f7e0..ce4255dfec 100644 --- a/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.cpp +++ b/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.cpp @@ -72,5 +72,16 @@ boost::any JaniSyntacticalEqualityCheckVisitor::visit(FunctionCallExpression con return false; } } + +boost::any JaniSyntacticalEqualityCheckVisitor::visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) { + BaseExpression const& otherBaseExpression = boost::any_cast>(data).get(); + auto const rhs = std::dynamic_pointer_cast(otherBaseExpression.getSharedPointer()); + if (rhs) { + return expression.getTranscendentalNumber() == rhs->getTranscendentalNumber(); + } else { + return false; + } +} + } // namespace expressions } // namespace storm diff --git a/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.h b/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.h index c6713d91a9..b1cb8e1b3b 100644 --- a/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.h +++ b/src/storm/storage/jani/visitor/JaniSyntacticalEqualityCheckVisitor.h @@ -21,6 +21,7 @@ class JaniSyntacticalEqualityCheckVisitor : public SyntacticalEqualityCheckVisit virtual boost::any visit(ConstructorArrayExpression const& expression, boost::any const& data) override; virtual boost::any visit(ArrayAccessExpression const& expression, boost::any const& data) override; virtual boost::any visit(FunctionCallExpression const& expression, boost::any const& data) override; + virtual boost::any visit(TranscendentalNumberLiteralExpression const& expression, boost::any const& data) override; }; } // namespace expressions } // namespace storm diff --git a/src/storm/storage/memorystructure/SparseModelMemoryProduct.cpp b/src/storm/storage/memorystructure/SparseModelMemoryProduct.cpp index 24cedff50f..a16f2e2ced 100644 --- a/src/storm/storage/memorystructure/SparseModelMemoryProduct.cpp +++ b/src/storm/storage/memorystructure/SparseModelMemoryProduct.cpp @@ -450,13 +450,19 @@ std::unordered_map SparseModelMemoryProduct> transitionRewards; if (rewardModel.second.hasTransitionRewards()) { - storm::storage::SparseMatrixBuilder builder(resultTransitionMatrix.getRowCount(), resultTransitionMatrix.getColumnCount()); + bool const useRowGrouping = !resultTransitionMatrix.hasTrivialRowGrouping(); + storm::storage::SparseMatrixBuilder builder(resultTransitionMatrix.getRowCount(), resultTransitionMatrix.getColumnCount(), 0ull, + true, useRowGrouping, + useRowGrouping ? resultTransitionMatrix.getRowGroupCount() : 0ull); uint64_t stateIndex = 0; for (auto const& resState : toResultStateMapping) { if (resState < numResStates) { uint64_t modelState = stateIndex / memoryStateCount; uint64_t memoryState = stateIndex % memoryStateCount; uint64_t rowGroupSize = resultTransitionMatrix.getRowGroupSize(resState); + if (useRowGrouping) { + builder.newRowGroup(resultTransitionMatrix.getRowGroupIndices()[resState]); + } if (scheduler && scheduler->getChoice(modelState, memoryState).isDefined()) { std::map rewards; for (uint64_t rowOffset = 0; rowOffset < rowGroupSize; ++rowOffset) { diff --git a/src/storm/storage/prism/ClockVariable.cpp b/src/storm/storage/prism/ClockVariable.cpp index 47f988362d..7ed77fcd94 100644 --- a/src/storm/storage/prism/ClockVariable.cpp +++ b/src/storm/storage/prism/ClockVariable.cpp @@ -17,8 +17,7 @@ void ClockVariable::createMissingInitialValue() { } std::ostream& operator<<(std::ostream& stream, ClockVariable const& variable) { - stream << variable.getName() << ": clock" - << ";"; + stream << variable.getName() << ": clock" << ";"; return stream; } diff --git a/src/storm/storage/prism/Constant.cpp b/src/storm/storage/prism/Constant.cpp index f34e8509ca..48f6c8bfba 100644 --- a/src/storm/storage/prism/Constant.cpp +++ b/src/storm/storage/prism/Constant.cpp @@ -46,8 +46,7 @@ Constant Constant::substitute(std::map const& HidingComposition::getActionsToHide() const { } void HidingComposition::writeToStream(std::ostream& stream) const { - stream << "(" << *sub << ")" - << " " - << "{" << boost::join(actionsToHide, ", ") << "}"; + stream << "(" << *sub << ")" << " " << "{" << boost::join(actionsToHide, ", ") << "}"; } } // namespace prism diff --git a/src/storm/storage/prism/Program.cpp b/src/storm/storage/prism/Program.cpp index 0fbc5f3091..d765f9575a 100644 --- a/src/storm/storage/prism/Program.cpp +++ b/src/storm/storage/prism/Program.cpp @@ -442,7 +442,7 @@ std::map Program:: std::map newSubstitution; for (auto const& substVarExpr : substitution) { - newSubstitution.emplace(substVarExpr.first, storm::jani::substituteJaniExpression(substVarExpr.second, renamingAsSubstitution)); + newSubstitution.emplace(substVarExpr.first, storm::jani::substituteJaniExpression(substVarExpr.second, renamingAsSubstitution, false)); } return newSubstitution; } diff --git a/src/storm/storage/prism/ToJaniConverter.cpp b/src/storm/storage/prism/ToJaniConverter.cpp index cbeefa6920..d36b4af7cb 100644 --- a/src/storm/storage/prism/ToJaniConverter.cpp +++ b/src/storm/storage/prism/ToJaniConverter.cpp @@ -122,11 +122,12 @@ storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program functionBodySubstitution[var] = functionParameters.back().getExpression(); } for (auto const& formulaVar : placeholdersInFormula) { - functionBodySubstitution[formulaVar] = storm::jani::substituteJaniExpression(formulaToFunctionCallMap[formulaVar], functionBodySubstitution); + functionBodySubstitution[formulaVar] = + storm::jani::substituteJaniExpression(formulaToFunctionCallMap[formulaVar], functionBodySubstitution, false); } storm::jani::FunctionDefinition funDef(formula.getName(), formula.getType(), functionParameters, - storm::jani::substituteJaniExpression(formula.getExpression(), functionBodySubstitution)); + storm::jani::substituteJaniExpression(formula.getExpression(), functionBodySubstitution, false)); janiModel.addFunctionDefinition(funDef); auto functionCallExpression = std::make_shared(*manager, formula.getType(), formula.getName(), functionArguments); @@ -514,7 +515,7 @@ storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program // formula placeholders. Note that the formula placeholders of non-renamed modules are replaced later. if (program.getNumberOfFormulas() > 0 && module.isRenamedFromModule()) { auto renamedFormulaToFunctionCallMap = program.getSubstitutionForRenamedModule(module, formulaToFunctionCallMap); - automaton.substitute(renamedFormulaToFunctionCallMap); + automaton.substitute(renamedFormulaToFunctionCallMap, false); } janiModel.addAutomaton(automaton); @@ -532,7 +533,7 @@ storm::jani::Model ToJaniConverter::convert(storm::prism::Program const& program // if there are formulas, replace the remaining placeholder variables by actual function calls in all expressions if (program.getNumberOfFormulas() > 0) { janiModel.getModelFeatures().add(storm::jani::ModelFeature::Functions); - janiModel.substitute(formulaToFunctionCallMap); + janiModel.substitute(formulaToFunctionCallMap, false); } janiModel.finalize(); diff --git a/src/storm/transformer/StatePermuter.h b/src/storm/transformer/StatePermuter.h index a41bf9d873..4bba53e8db 100644 --- a/src/storm/transformer/StatePermuter.h +++ b/src/storm/transformer/StatePermuter.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/src/storm/utility/constants.cpp b/src/storm/utility/constants.cpp index 60fd2ae326..eb159b664d 100644 --- a/src/storm/utility/constants.cpp +++ b/src/storm/utility/constants.cpp @@ -253,6 +253,16 @@ ValueType log10(ValueType const& number) { return std::log10(number); } +template +ValueType cos(ValueType const& number) { + return std::cos(number); +} + +template +ValueType sin(ValueType const& number) { + return std::sin(number); +} + template typename NumberTraits::IntegerType trunc(ValueType const& number) { return static_cast::IntegerType>(std::trunc(number)); @@ -419,6 +429,16 @@ ClnRationalNumber log10(ClnRationalNumber const& number) { return carl::log10(number); } +template<> +ClnRationalNumber cos(ClnRationalNumber const& number) { + return carl::cos(number); +} + +template<> +ClnRationalNumber sin(ClnRationalNumber const& number) { + return carl::sin(number); +} + template<> typename NumberTraits::IntegerType trunc(ClnRationalNumber const& number) { return cln::truncate1(number); @@ -624,6 +644,16 @@ GmpRationalNumber log10(GmpRationalNumber const& number) { return carl::log10(number); } +template<> +GmpRationalNumber cos(GmpRationalNumber const& number) { + return carl::cos(number); +} + +template<> +GmpRationalNumber sin(GmpRationalNumber const& number) { + return carl::sin(number); +} + template<> typename NumberTraits::IntegerType trunc(GmpRationalNumber const& number) { return carl::getNum(number) / carl::getDenom(number); @@ -955,6 +985,8 @@ template double ceil(double const& number); template double round(double const& number); template double log(double const& number); template double log10(double const& number); +template double cos(double const& number); +template double sin(double const& number); template typename NumberTraits::IntegerType trunc(double const& number); template double mod(double const& first, double const& second); template std::string to_string(double const& value); diff --git a/src/storm/utility/constants.h b/src/storm/utility/constants.h index 1fdb7ee679..4fce01d485 100644 --- a/src/storm/utility/constants.h +++ b/src/storm/utility/constants.h @@ -167,6 +167,12 @@ ValueType log(ValueType const& number); template ValueType log10(ValueType const& number); +template +ValueType cos(ValueType const& number); + +template +ValueType sin(ValueType const& number); + template typename NumberTraits::IntegerType trunc(ValueType const& number); diff --git a/src/storm/utility/iota_n.h b/src/storm/utility/iota_n.h deleted file mode 100644 index 9f3115090e..0000000000 --- a/src/storm/utility/iota_n.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace storm { -namespace utility { -template -void iota_n(OutputIterator first, Size n, Assignable value) { - std::generate_n(first, n, [&value]() { return value++; }); -} -} // namespace utility -} // namespace storm diff --git a/src/test/storm-dft/simulator/DftSimulatorTest.cpp b/src/test/storm-dft/simulator/DftSimulatorTest.cpp index 8b56ab90e9..ca75d1f431 100644 --- a/src/test/storm-dft/simulator/DftSimulatorTest.cpp +++ b/src/test/storm-dft/simulator/DftSimulatorTest.cpp @@ -30,12 +30,12 @@ std::pair simulateDft(std::string const& file, double timebound, size_t count = 0; size_t invalid = 0; - storm::dft::simulator::SimulationResult res; + storm::dft::simulator::SimulationTraceResult res; for (size_t i = 0; i < noRuns; ++i) { res = simulator.simulateCompleteTrace(timebound); - if (res == storm::dft::simulator::SimulationResult::SUCCESSFUL) { + if (res == storm::dft::simulator::SimulationTraceResult::SUCCESSFUL) { ++count; - } else if (res == storm::dft::simulator::SimulationResult::INVALID) { + } else if (res == storm::dft::simulator::SimulationTraceResult::INVALID) { // Discard invalid traces ++invalid; } diff --git a/src/test/storm-dft/simulator/DftTraceGeneratorTest.cpp b/src/test/storm-dft/simulator/DftTraceGeneratorTest.cpp index 38ed1c8a03..95448d650c 100644 --- a/src/test/storm-dft/simulator/DftTraceGeneratorTest.cpp +++ b/src/test/storm-dft/simulator/DftTraceGeneratorTest.cpp @@ -158,23 +158,67 @@ TYPED_TEST(DftTraceGeneratorTest, RandomStepsAnd) { auto state = simulator.getCurrentState(); EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); - storm::dft::simulator::SimulationResult res; - double timebound; // First random step - std::tie(res, timebound) = simulator.randomStep(); - EXPECT_EQ(res, storm::dft::simulator::SimulationResult::SUCCESSFUL); + storm::dft::simulator::SimulationStepResult res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); #if BOOST_VERSION > 106400 // Older Boost versions yield different value - EXPECT_NEAR(timebound, 0.522079, 1e-6); + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079, 1e-6); #endif state = simulator.getCurrentState(); EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); - std::tie(res, timebound) = simulator.randomStep(); - EXPECT_EQ(res, storm::dft::simulator::SimulationResult::SUCCESSFUL); + res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); #if BOOST_VERSION > 106400 // Older Boost versions yield different value - EXPECT_NEAR(timebound, 0.9497214, 1e-6); + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079 + 0.9497214, 1e-6); +#endif + state = simulator.getCurrentState(); + EXPECT_TRUE(state->hasFailed(dft->getTopLevelIndex())); +} + +TYPED_TEST(DftTraceGeneratorTest, Reset) { + auto pair = this->prepareDFT(STORM_TEST_RESOURCES_DIR "/dft/and.dft"); + auto dft = pair.first; + EXPECT_EQ(this->getConfig().useSR && this->getConfig().useDC, pair.second.hasSymmetries()); + + // Init random number generator + boost::mt19937 gen(5u); + storm::dft::simulator::DFTTraceSimulator simulator(*dft, pair.second, gen); + + auto state = simulator.getCurrentState(); + EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); + + // First random step + storm::dft::simulator::SimulationStepResult res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); +#if BOOST_VERSION > 106400 + // Older Boost versions yield different value + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079, 1e-6); +#endif + auto stateStep1 = simulator.getCurrentState(); + EXPECT_FALSE(stateStep1->hasFailed(dft->getTopLevelIndex())); + + res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); +#if BOOST_VERSION > 106400 + // Older Boost versions yield different value + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079 + 0.9497214, 1e-6); +#endif + state = simulator.getCurrentState(); + EXPECT_TRUE(state->hasFailed(dft->getTopLevelIndex())); + + // Reset to previous state + simulator.resetToState(stateStep1); + state = simulator.getCurrentState(); + EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); + + res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); +#if BOOST_VERSION > 106400 + // Older Boost versions yield different value + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079 + 0.9497214 + 2.4686932, 1e-6); #endif state = simulator.getCurrentState(); EXPECT_TRUE(state->hasFailed(dft->getTopLevelIndex())); @@ -204,8 +248,8 @@ TYPED_TEST(DftTraceGeneratorTest, Fdep) { auto nextBE = iterFailable.asBE(*dft); EXPECT_EQ(nextBE->name(), "B_Power"); - storm::dft::simulator::SimulationResult res = simulator.step(iterFailable); - EXPECT_EQ(res, storm::dft::simulator::SimulationResult::SUCCESSFUL); + storm::dft::simulator::SimulationStepResult res = simulator.step(iterFailable); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); state = simulator.getCurrentState(); EXPECT_TRUE(state->hasFailed(4)); @@ -220,7 +264,7 @@ TYPED_TEST(DftTraceGeneratorTest, Fdep) { EXPECT_EQ(dependency->dependentEvents().front()->name(), "B"); res = simulator.step(iterFailable); - EXPECT_EQ(res, storm::dft::simulator::SimulationResult::SUCCESSFUL); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); state = simulator.getCurrentState(); EXPECT_TRUE(state->hasFailed(dft->getTopLevelIndex())); } diff --git a/src/test/storm-dft/simulator/ImportanceFunction.cpp b/src/test/storm-dft/simulator/ImportanceFunction.cpp new file mode 100644 index 0000000000..8a3ee078cb --- /dev/null +++ b/src/test/storm-dft/simulator/ImportanceFunction.cpp @@ -0,0 +1,66 @@ +#include "storm-config.h" +#include "test/storm_gtest.h" + +#include "storm-dft/api/storm-dft.h" +#include "storm-dft/generator/DftNextStateGenerator.h" +#include "storm-dft/simulator/DFTTraceSimulator.h" +#include "storm-dft/simulator/ImportanceFunction.h" +#include "storm-dft/storage/DftSymmetries.h" + +namespace { + +std::pair>, storm::dft::storage::DFTStateGenerationInfo> prepareDFT(std::string const& file) { + // Load, build and prepare DFT + std::shared_ptr> dft = + storm::dft::api::prepareForMarkovAnalysis(*(storm::dft::api::loadDFTGalileoFile(file))); + EXPECT_TRUE(storm::dft::api::isWellFormed(*dft).first); + + // Compute relevant events + storm::dft::utility::RelevantEvents relevantEvents = storm::dft::api::computeRelevantEvents({}, {"all"}); + dft->setRelevantEvents(relevantEvents, false); + + storm::dft::storage::DFTStateGenerationInfo stateGenerationInfo(dft->buildStateGenerationInfo(storm::dft::storage::DftSymmetries())); + return std::make_pair(dft, stateGenerationInfo); +} + +TEST(ImportanceFunctionTest, RandomStepsAnd) { + auto pair = prepareDFT(STORM_TEST_RESOURCES_DIR "/dft/and.dft"); + auto dft = pair.first; + + // Init random number generator + boost::mt19937 gen(5u); + storm::dft::simulator::DFTTraceSimulator simulator(*dft, pair.second, gen); + + // Init importance function + storm::dft::simulator::BECountImportanceFunction imp = storm::dft::simulator::BECountImportanceFunction(*dft); + auto range = imp.getImportanceRange(); + EXPECT_EQ(range.first, 0); + EXPECT_EQ(range.second, 2); + + auto state = simulator.getCurrentState(); + EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); + EXPECT_EQ(imp.getImportance(state), 0); + + // First random step + storm::dft::simulator::SimulationStepResult res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); +#if BOOST_VERSION > 106400 + // Older Boost versions yield different value + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079, 1e-6); +#endif + state = simulator.getCurrentState(); + EXPECT_FALSE(state->hasFailed(dft->getTopLevelIndex())); + EXPECT_EQ(imp.getImportance(state), 1); + + res = simulator.randomStep(); + EXPECT_EQ(res, storm::dft::simulator::SimulationStepResult::SUCCESSFUL); +#if BOOST_VERSION > 106400 + // Older Boost versions yield different value + EXPECT_NEAR(simulator.getCurrentTime(), 0.522079 + 0.9497214, 1e-6); +#endif + state = simulator.getCurrentState(); + EXPECT_TRUE(state->hasFailed(dft->getTopLevelIndex())); + EXPECT_EQ(imp.getImportance(state), 2); +} + +} // namespace diff --git a/src/test/storm-dft/storage/SymmetryTest.cpp b/src/test/storm-dft/storage/SymmetryTest.cpp index 6323dd215e..4bbe21ac31 100644 --- a/src/test/storm-dft/storage/SymmetryTest.cpp +++ b/src/test/storm-dft/storage/SymmetryTest.cpp @@ -136,6 +136,15 @@ TEST(SymmetryTest, SymmetricFT) { EXPECT_EQ(symmetries.getSymmetryGroup(2).size(), 3ul); EXPECT_EQ(symmetries.getSymmetryGroup(2)[0].size(), 3ul); + symmetries = findSymmetries(STORM_TEST_RESOURCES_DIR "/dft/symmetry7.dft"); + EXPECT_EQ(symmetries.nrSymmetries(), 3ul); + EXPECT_EQ(symmetries.getSymmetryGroup(0).size(), 1ul); + EXPECT_EQ(symmetries.getSymmetryGroup(0)[0].size(), 3ul); + EXPECT_EQ(symmetries.getSymmetryGroup(5).size(), 1ul); + EXPECT_EQ(symmetries.getSymmetryGroup(5)[0].size(), 2ul); + EXPECT_EQ(symmetries.getSymmetryGroup(7).size(), 1ul); + EXPECT_EQ(symmetries.getSymmetryGroup(7)[0].size(), 2ul); + symmetries = findSymmetries(STORM_TEST_RESOURCES_DIR "/dft/pdep_symmetry.dft"); EXPECT_EQ(symmetries.nrSymmetries(), 2ul); EXPECT_EQ(symmetries.getSymmetryGroup(2).size(), 4ul); diff --git a/src/test/storm-pars/CMakeLists.txt b/src/test/storm-pars/CMakeLists.txt index 39b80ae5e5..9ee0749b87 100644 --- a/src/test/storm-pars/CMakeLists.txt +++ b/src/test/storm-pars/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories(${GTEST_INCLUDE_DIR}) foreach (testsuite analysis modelchecker utility derivative transformer) file(GLOB_RECURSE TEST_${testsuite}_FILES ${STORM_TESTS_BASE_PATH}/${testsuite}/*.h ${STORM_TESTS_BASE_PATH}/${testsuite}/*.cpp ${STORM_TESTS_BASE_PATH}/../storm_gtest.cpp) - add_executable (test-pars-${testsuite} ${TEST_${testsuite}_FILES} ${STORM_TESTS_BASE_PATH}/storm-test.cpp analysis/MonotonicityCheckerTest.cpp) + add_executable (test-pars-${testsuite} ${TEST_${testsuite}_FILES} ${STORM_TESTS_BASE_PATH}/storm-test.cpp) target_link_libraries(test-pars-${testsuite} storm-pars storm-parsers) target_link_libraries(test-pars-${testsuite} ${STORM_TEST_LINK_LIBRARIES}) target_precompile_headers(test-pars-${testsuite} REUSE_FROM test-builder) diff --git a/src/test/storm-pomdp/api/BeliefExplorationAPITest.cpp b/src/test/storm-pomdp/api/BeliefExplorationAPITest.cpp index 9ad686de23..c3ee258092 100644 --- a/src/test/storm-pomdp/api/BeliefExplorationAPITest.cpp +++ b/src/test/storm-pomdp/api/BeliefExplorationAPITest.cpp @@ -24,8 +24,7 @@ class DefaultDoubleVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } }; template @@ -215,7 +214,7 @@ TYPED_TEST(BeliefExplorationAPITest, simple_slippery_Rmin) { TYPED_TEST(BeliefExplorationAPITest, maze2_Rmin) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0"); auto task = storm::api::createTask(data.formula, false); auto result = storm::pomdp::api::underapproximateWithCutoffs(data.model, task, 100); @@ -231,7 +230,7 @@ TYPED_TEST(BeliefExplorationAPITest, maze2_Rmin) { TYPED_TEST(BeliefExplorationAPITest, maze2_slippery_Rmin) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0.075"); auto task = storm::api::createTask(data.formula, false); auto result = storm::pomdp::api::underapproximateWithCutoffs(data.model, task, 100); diff --git a/src/test/storm-pomdp/modelchecker/BeliefExplorationPomdpModelCheckerTest.cpp b/src/test/storm-pomdp/modelchecker/BeliefExplorationPomdpModelCheckerTest.cpp index e522618b2d..62e8d71619 100644 --- a/src/test/storm-pomdp/modelchecker/BeliefExplorationPomdpModelCheckerTest.cpp +++ b/src/test/storm-pomdp/modelchecker/BeliefExplorationPomdpModelCheckerTest.cpp @@ -27,8 +27,7 @@ class DefaultDoubleVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::None; }; @@ -45,8 +44,7 @@ class SelfloopReductionDefaultDoubleVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::SelfloopReduction; }; @@ -63,8 +61,7 @@ class QualitativeReductionDefaultDoubleVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::QualitativeReduction; }; @@ -81,8 +78,7 @@ class PreprocessedDefaultDoubleVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::All; }; @@ -159,8 +155,7 @@ class DefaultDoubleOVIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::None; }; @@ -177,8 +172,7 @@ class DefaultRationalPIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::None; }; @@ -195,8 +189,7 @@ class PreprocessedDefaultRationalPIEnvironment { static ValueType precision() { return storm::utility::convertNumber(0.12); } // there actually aren't any precision guarantees, but we still want to detect if results are weird. - static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ - } + static void adaptOptions(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions&) { /* intentionally left empty */ } static PreprocessingType const preprocessingType = PreprocessingType::All; }; @@ -572,7 +565,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, simple_slippery_Rmin_SE) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmin) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->options()); auto result = checker.check(this->env(), *data.formula); @@ -588,7 +581,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmin) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmin_SE) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithStateElimination()); auto result = checker.check(this->env(), *data.formula); @@ -605,7 +598,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmin_SE) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmax) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->options()); auto result = checker.check(this->env(), *data.formula); @@ -616,7 +609,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmax) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmax_SE) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithStateElimination()); auto result = checker.check(this->env(), *data.formula); @@ -628,7 +621,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmax_SE) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmin) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->options()); auto result = checker.check(this->env(), *data.formula); @@ -644,7 +637,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmin) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmin_SE) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithStateElimination()); auto result = checker.check(this->env(), *data.formula); @@ -661,7 +654,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmin_SE) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmax) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->options()); auto result = checker.check(this->env(), *data.formula); @@ -672,7 +665,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmax) { TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmax_SE) { typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithStateElimination()); auto result = checker.check(this->env(), *data.formula); @@ -907,7 +900,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmin_Clip) { } typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithClipping()); auto result = checker.check(this->env(), *data.formula); @@ -926,7 +919,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_Rmax_Clip) { } typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithClipping()); auto result = checker.check(this->env(), *data.formula); @@ -940,7 +933,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmin_Clip) { } typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]min=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmin=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithClipping()); auto result = checker.check(this->env(), *data.formula); @@ -959,7 +952,7 @@ TYPED_TEST(BeliefExplorationPomdpModelCheckerTest, maze2_slippery_Rmax_Clip) { } typedef typename TestFixture::ValueType ValueType; - auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "R[exp]max=? [F \"goal\"]", "sl=0.075"); + auto data = this->buildPrism(STORM_TEST_RESOURCES_DIR "/pomdp/maze2.prism", "Rmax=? [F \"goal\"]", "sl=0.075"); storm::pomdp::modelchecker::BeliefExplorationPomdpModelChecker> checker(data.model, this->optionsWithClipping()); auto result = checker.check(this->env(), *data.formula); diff --git a/src/test/storm/builder/ExplicitJaniModelBuilderTest.cpp b/src/test/storm/builder/ExplicitJaniModelBuilderTest.cpp index b9e5e02624..7acdb172f0 100644 --- a/src/test/storm/builder/ExplicitJaniModelBuilderTest.cpp +++ b/src/test/storm/builder/ExplicitJaniModelBuilderTest.cpp @@ -68,6 +68,13 @@ TEST_F(ExplicitJaniModelBuilderTest, Dtmc) { model = storm::builder::ExplicitModelBuilder(janiModel).build(); EXPECT_EQ(1728ul, model->getNumberOfStates()); EXPECT_EQ(2505ul, model->getNumberOfTransitions()); + + janiModel = storm::api::parseJaniModel(STORM_TEST_RESOURCES_DIR "/dtmc/test_trigonometry.jani").first; + auto constants = storm::utility::cli::parseConstantDefinitionString(janiModel.getManager(), "step_size_rad=0.523599"); // step_size = 30 deg + janiModel = janiModel.defineUndefinedConstants(constants); + model = storm::builder::ExplicitModelBuilder(janiModel).build(); + EXPECT_EQ(5ul, model->getNumberOfStates()); + EXPECT_EQ(5ul, model->getNumberOfTransitions()); } TEST_F(ExplicitJaniModelBuilderTest, pdtmc) { @@ -78,7 +85,7 @@ TEST_F(ExplicitJaniModelBuilderTest, pdtmc) { EXPECT_EQ(20ul, model->getNumberOfTransitions()); janiModel = storm::api::parseJaniModel(STORM_TEST_RESOURCES_DIR "/pdtmc/die_array_nested.jani").first; - janiModel.substituteConstantsFunctions(); + janiModel.substituteConstantsFunctionsTranscendentals(); model = storm::builder::ExplicitModelBuilder(janiModel).build(); EXPECT_EQ(13ul, model->getNumberOfStates()); EXPECT_EQ(20ul, model->getNumberOfTransitions()); diff --git a/src/test/storm/modelchecker/csl/CtmcCslModelCheckerTest.cpp b/src/test/storm/modelchecker/csl/CtmcCslModelCheckerTest.cpp index 6a219c390b..16eef952aa 100644 --- a/src/test/storm/modelchecker/csl/CtmcCslModelCheckerTest.cpp +++ b/src/test/storm/modelchecker/csl/CtmcCslModelCheckerTest.cpp @@ -399,6 +399,39 @@ TYPED_TEST(CtmcCslModelCheckerTest, Tandem) { EXPECT_NEAR(this->parseNumber("262.85103824276308"), this->getQuantitativeResultAtInitialState(model, result), this->precision()); } +TYPED_TEST(CtmcCslModelCheckerTest, simple1) { + std::string formulasString = "P=? [ F<=0.5 x=1 ]"; + formulasString += "; R=? [ C<=0.1 ]"; + formulasString += "; R=? [ C<=1 ]"; + formulasString += "; R=? [ C<=10 ]"; + + auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR "/ctmc/simple1.sm", formulasString); + auto model = std::move(modelFormulas.first); + auto tasks = this->getTasks(modelFormulas.second); + EXPECT_EQ(2ul, model->getNumberOfStates()); + EXPECT_EQ(2ul, model->getNumberOfTransitions()); + ASSERT_EQ(model->getType(), storm::models::ModelType::Ctmc); + auto checker = this->createModelChecker(model); + std::unique_ptr result; + + uint64_t propertyIndex = 0; + auto expected = this->parseNumber("0.9502129316"); // integrate 6* e^(-6*t) dt from 0 to 0.5 = 1 - 1/(e^3) + result = checker->check(this->env(), tasks[propertyIndex++]); + EXPECT_NEAR(expected, this->getQuantitativeResultAtInitialState(model, result), this->precision()); + + expected = this->parseNumber("0.075198060651"); // integrate min(t,0.1) * 6* e^(-6*t) dt from 0 to infty = 1/6 - 1/(6*e^0.6) + result = checker->check(this->env(), tasks[propertyIndex++]); + EXPECT_NEAR(expected, this->getQuantitativeResultAtInitialState(model, result), this->precision()); + + expected = this->parseNumber("0.1662535413"); // = 1/6 - 1/(6*e^6) + result = checker->check(this->env(), tasks[propertyIndex++]); + EXPECT_NEAR(expected, this->getQuantitativeResultAtInitialState(model, result), this->precision()); + + expected = this->parseNumber("0.16666666667"); // = 1/6 - 1/(6*e^60) + result = checker->check(this->env(), tasks[propertyIndex++]); + EXPECT_NEAR(expected, this->getQuantitativeResultAtInitialState(model, result), this->precision()); +} + TYPED_TEST(CtmcCslModelCheckerTest, simple2) { std::string formulasString = "R{\"rew1\"}=? [ C ]"; formulasString += "; R{\"rew2\"}=? [ C ]"; diff --git a/src/test/storm/parser/JaniParserTest.cpp b/src/test/storm/parser/JaniParserTest.cpp index fcc3a95ab7..46a8f6b744 100644 --- a/src/test/storm/parser/JaniParserTest.cpp +++ b/src/test/storm/parser/JaniParserTest.cpp @@ -414,3 +414,14 @@ TEST(JaniParser, UnassignedVariablesTest) { EXPECT_TRUE(result.first.hasConstant("c")); EXPECT_EQ(2ul, result.first.getNumberOfAutomata()); } + +TEST(JaniParser, TrigonometryAndTranscendentalNumbersTest) { + std::pair> result; + EXPECT_NO_THROW(result = storm::api::parseJaniModel(STORM_TEST_RESOURCES_DIR "/dtmc/test_trigonometry.jani")); + auto& model = result.first; + auto& properties = result.second; + EXPECT_EQ(storm::jani::ModelType::DTMC, model.getModelType()); + EXPECT_EQ(model.getNumberOfAutomata(), 1U); + EXPECT_EQ(properties.size(), 2U); + EXPECT_NO_THROW(model.substitute({}, true)); +} diff --git a/src/test/storm/storage/SparseMatrixTest.cpp b/src/test/storm/storage/SparseMatrixTest.cpp index b2c442f279..476923a995 100644 --- a/src/test/storm/storage/SparseMatrixTest.cpp +++ b/src/test/storm/storage/SparseMatrixTest.cpp @@ -6,6 +6,16 @@ #include "storm/utility/permutation.h" #include "test/storm_gtest.h" +TEST(SparseMatrixBuilder, CreationEmpty) { + storm::storage::SparseMatrixBuilder matrixBuilder; + storm::storage::SparseMatrix matrix; + ASSERT_NO_THROW(matrix = matrixBuilder.build()); + + ASSERT_EQ(0ul, matrix.getRowCount()); + ASSERT_EQ(0ul, matrix.getColumnCount()); + ASSERT_EQ(0ul, matrix.getEntryCount()); +} + TEST(SparseMatrixBuilder, CreationWithDimensions) { storm::storage::SparseMatrixBuilder matrixBuilder(3, 4, 5); ASSERT_NO_THROW(matrixBuilder.addNextValue(0, 1, 1.0)); @@ -979,4 +989,4 @@ TEST(SparseMatrix, DropZeroEntries) { ASSERT_TRUE(matrixX == matrix4); ASSERT_FALSE(matrixX.getEntryCount() == matrix4.getEntryCount()); -} \ No newline at end of file +} diff --git a/version.cmake b/version.cmake index c4c844edfb..214c98d784 100644 --- a/version.cmake +++ b/version.cmake @@ -1,4 +1,4 @@ set(STORM_VERSION_MAJOR 1) -set(STORM_VERSION_MINOR 8) -set(STORM_VERSION_PATCH 1) +set(STORM_VERSION_MINOR 9) +set(STORM_VERSION_PATCH 0)