Browse Source

Merge remote-tracking branch 'origin/master' into symbolic_bisimulation

main
dehnert 8 years ago
parent
commit
04a24a2108
  1. 4
      .gitignore
  2. 296
      .travis.yml
  3. 7
      CHANGELOG.md
  4. 24
      README.md
  5. 2
      resources/3rdparty/CMakeLists.txt
  6. 4
      resources/3rdparty/carl/CMakeLists.txt
  7. 1
      src/CMakeLists.txt
  8. 40
      src/storm-cli-utilities/CMakeLists.txt
  9. 265
      src/storm-cli-utilities/cli.cpp
  10. 0
      src/storm-cli-utilities/cli.h
  11. 509
      src/storm-cli-utilities/model-handling.h
  12. 2
      src/storm-dft-cli/CMakeLists.txt
  13. 4
      src/storm-dft-cli/storm-dyftee.cpp
  14. 2
      src/storm-dft/modelchecker/dft/DFTModelChecker.cpp
  15. 8
      src/storm-dft/storage/dft/OrderDFTElementsById.cpp
  16. 2
      src/storm-gspn-cli/CMakeLists.txt
  17. 4
      src/storm-gspn-cli/storm-gspn.cpp
  18. 60
      src/storm-pars-cli/storm-pars.cpp
  19. 13
      src/storm-pars/transformer/SparseParametricModelSimplifier.cpp
  20. 2
      src/storm-pgcl-cli/CMakeLists.txt
  21. 2
      src/storm-pgcl-cli/storm-pgcl.cpp
  22. 2
      src/storm/CMakeLists.txt
  23. 3
      src/storm/adapters/RationalFunctionAdapter.h
  24. 30
      src/storm/adapters/Smt2ExpressionAdapter.h
  25. 30
      src/storm/analysis/GraphConditions.cpp
  26. 24
      src/storm/analysis/GraphConditions.h
  27. 44
      src/storm/api/builder.h
  28. 8
      src/storm/builder/BuilderOptions.cpp
  29. 63
      src/storm/builder/BuilderOptions.h
  30. 20
      src/storm/models/sparse/Mdp.cpp
  31. 15
      src/storm/models/sparse/Mdp.h
  32. 7
      src/storm/models/sparse/NondeterministicModel.cpp
  33. 8
      src/storm/models/sparse/NondeterministicModel.h
  34. 4
      src/storm/permissivesched/PermissiveSchedulers.h
  35. 10
      src/storm/settings/Argument.cpp
  36. 5
      src/storm/settings/Argument.h
  37. 4
      src/storm/settings/ArgumentBase.h
  38. 15
      src/storm/settings/SettingsManager.cpp
  39. 6
      src/storm/settings/SettingsManager.h
  40. 4
      src/storm/settings/modules/CoreSettings.cpp
  41. 7
      src/storm/settings/modules/CoreSettings.h
  42. 4
      src/storm/settings/modules/MinMaxEquationSolverSettings.cpp
  43. 11
      src/storm/settings/modules/MinMaxEquationSolverSettings.h
  44. 4
      src/storm/settings/modules/NativeEquationSolverSettings.cpp
  45. 7
      src/storm/settings/modules/NativeEquationSolverSettings.h
  46. 2
      src/storm/solver/IterativeMinMaxLinearEquationSolver.h
  47. 15
      src/storm/solver/MinMaxLinearEquationSolver.cpp
  48. 27
      src/storm/solver/SmtlibSmtSolver.cpp
  49. 12
      src/storm/solver/SmtlibSmtSolver.h
  50. 28
      src/storm/solver/SymbolicLinearEquationSolver.cpp
  51. 6
      src/storm/solver/SymbolicLinearEquationSolver.h
  52. 4
      src/storm/storage/expressions/Variable.h
  53. 2
      src/storm/storm.cpp
  54. 26
      src/storm/transformer/ChoiceSelector.cpp
  55. 30
      src/storm/transformer/ChoiceSelector.h
  56. 164
      travis/build-helper.sh
  57. 71
      travis/build.sh
  58. 16
      travis/dockerfiles/Dockerfile.debian-9
  59. 8
      travis/dockerfiles/Dockerfile.storm
  60. 17
      travis/dockerfiles/Dockerfile.ubuntu-16.10
  61. 9
      travis/dockerfiles/build_carl.sh
  62. 9
      travis/dockerfiles/build_docker.sh
  63. 9
      travis/dockerfiles/build_storm.sh
  64. 123
      travis/generate_travis.py
  65. 11
      travis/install_linux.sh
  66. 73
      travis/install_osx.sh
  67. 5
      travis/mtime_cache/globs.txt
  68. 178
      travis/mtime_cache/mtime_cache.rb

4
.gitignore

@ -52,3 +52,7 @@ nbproject/
*.out
resources/3rdparty/cudd-3.0.0/Makefile.in
resources/3rdparty/cudd-3.0.0/aclocal.m4
# Python config
stormpy/setup.cfg
# Travis helpers
travis/mtime_cache/cache.json

296
.travis.yml

@ -0,0 +1,296 @@
# This file was inspired from https://github.com/google/fruit
#
# General config
#
branches:
only:
- master
- stable
dist: trusty
language: cpp
# Enable caching
cache:
timeout: 1000
directories:
- build
- travis/mtime_cache
# Enable docker support
services:
- docker
sudo: required
notifications:
email:
on_failure: always
on_success: change
recipients:
secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w="
#
# Configurations
#
jobs:
include:
###
# Stage: Build (1st run)
###
# osx
- stage: Build (1st run)
os: osx
compiler: clang
env: CONFIG=DefaultDebug COMPILER=clang-4.0 STL=libc++
install:
- rm -rf build
- travis/install_osx.sh
script:
- travis/build.sh Build1
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (1st run)
os: osx
compiler: clang
env: CONFIG=DefaultRelease COMPILER=clang-4.0 STL=libc++
install:
- rm -rf build
- travis/install_osx.sh
script:
- travis/build.sh Build1
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-16.10
- stage: Build (1st run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- rm -rf build
- travis/install_linux.sh
script:
- travis/build.sh Build1
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (1st run)
os: linux
compiler: gcc
env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- rm -rf build
- travis/install_linux.sh
script:
- travis/build.sh Build1
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
###
# Stage: Build (2nd run)
###
# osx
- stage: Build (2nd run)
os: osx
compiler: clang
env: CONFIG=DefaultDebug COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build2
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (2nd run)
os: osx
compiler: clang
env: CONFIG=DefaultRelease COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build2
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-16.10
- stage: Build (2nd run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build2
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (2nd run)
os: linux
compiler: gcc
env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build2
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
###
# Stage: Build (3rd run)
###
# osx
- stage: Build (3rd run)
os: osx
compiler: clang
env: CONFIG=DefaultDebug COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build3
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (3rd run)
os: osx
compiler: clang
env: CONFIG=DefaultRelease COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build3
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-16.10
- stage: Build (3rd run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build3
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (3rd run)
os: linux
compiler: gcc
env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build3
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
###
# Stage: Build (4th run)
###
# osx
- stage: Build (4th run)
os: osx
compiler: clang
env: CONFIG=DefaultDebug COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build4
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (4th run)
os: osx
compiler: clang
env: CONFIG=DefaultRelease COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh Build4
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-16.10
- stage: Build (4th run)
os: linux
compiler: gcc
env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build4
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Build (4th run)
os: linux
compiler: gcc
env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh Build4
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
###
# Stage: Test all
###
# osx
- stage: Test all
os: osx
compiler: clang
env: CONFIG=DefaultDebug COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh TestAll
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Test all
os: osx
compiler: clang
env: CONFIG=DefaultRelease COMPILER=clang-4.0 STL=libc++
install:
- travis/install_osx.sh
script:
- travis/build.sh TestAll
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
# ubuntu-16.10
- stage: Test all
os: linux
compiler: gcc
env: CONFIG=DefaultDebug LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh TestAll
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;
- stage: Test all
os: linux
compiler: gcc
env: CONFIG=DefaultRelease LINUX=ubuntu-16.10 COMPILER=gcc-6
install:
- travis/install_linux.sh
script:
- travis/build.sh TestAll
before_cache:
- docker cp storm:/storm/. .
after_failure:
- find build -iname '*err*.log' -type f -print -exec cat {} \;

7
CHANGELOG.md

@ -6,7 +6,12 @@ The releases of major and minor versions contain an overview of changes since th
Version 1.1.x
-------------
Long run average computation via LRA, LP based MDP model checking, parametric model checking has an own binary
Long run average computation via ValueIteration, LP based MDP model checking, parametric model checking has an own binary
### Version 1.1.1
- c++ api changes: Building model takes BuilderOptions instead of extended list of Booleans, does not depend on settings anymore.
- storm-cli-utilities now contains cli related stuff, instead of storm-lib
- storm-pars: support for welldefinedness constraints in mdps.
### Version 1.1.0 (2017/8)

24
README.md

@ -1,23 +1,23 @@
Storm
==============================
Storm - A Modern Probabilistic Model Checker
============================================
[![Build Status](https://travis-ci.org/moves-rwth/storm.svg?branch=master)](https://travis-ci.org/moves-rwth/storm)
For more instructions, check out the documentation found in [Getting Started](https://moves-rwth.github.io/storm/getting-started.html)
For more instructions, check out the documentation found in [Getting Started](http://www.stormchecker.org/getting-started.html).
Benchmarks
----------------------------
Example input files for storm can be obtained from
https://github.com/moves-rwth/storm-examples.
Running make example-files automatically obtains these files.
Example input files for Storm can be obtained from
https://github.com/moves-rwth/storm-examples.
Further examples and benchmarks found in the following repositories:
Further examples and benchmarks can be found in the following repositories:
* **Prism files** (DTMC, MDP, CTMC):
http://www.prismmodelchecker.org/benchmarks/
http://www.prismmodelchecker.org/benchmarks
* **Jani files** (DTMC, MDP, CTMC, MA):
http://jani-spec.org/
* **GSPN**s:
http://jani-spec.org
* **GSPN**s:
(private, contact: sebastian.junges@cs.rwth-aachen.de)
* **DFT**s:
https://github.com/moves-rwth/dft-examples
@ -31,8 +31,8 @@ Storm has been developed at RWTH Aachen University.
###### Principal developers
* Christian Dehnert
* Joost-Pieter Katoen
* Sebastian Junges
* Joost-Pieter Katoen
* Matthias Volk
###### Developers (lexicographical order)
@ -40,7 +40,7 @@ Storm has been developed at RWTH Aachen University.
* David Korzeniewski
* Tim Quatmann
###### Contributors (lexicographical order)
###### Contributors (lexicographical order)
* Dimitri Bohlender
* Harold Bruintjes
* Michael Deutschen

2
resources/3rdparty/CMakeLists.txt

@ -208,7 +208,7 @@ include(${STORM_3RDPARTY_SOURCE_DIR}/include_cudd.cmake)
set(STORM_HAVE_CARL OFF)
set(CARL_MINYEAR 17)
set(CARL_MINMONTH 06)
set(CARL_MINMONTH 08)
set(CARL_MINPATCH 0)
if (NOT STORM_FORCE_SHIPPED_CARL)
if (NOT "${STORM_CARL_DIR_HINT}" STREQUAL "")

4
resources/3rdparty/carl/CMakeLists.txt

@ -8,11 +8,11 @@ message(STORM_3RDPARTY_BINARY_DIR: ${STORM_3RDPARTY_BINARY_DIR})
ExternalProject_Add(carl-config
GIT_REPOSITORY https://github.com/smtrat/carl
GIT_TAG master
GIT_TAG 17.08
PREFIX here
SOURCE_DIR source_dir
BINARY_DIR ${STORM_3RDPARTY_BINARY_DIR}/carl
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBOOST_INCLUDEDIR=${Boost_INCLUDE_DIRS} -DBOOST_LIBRARYDIR=${Boost_LIBRARY_DIRS} -DBoost_NO_SYSTEM_PATHS=ON -DEXPORT_TO_CMAKE=OFF -DTHREAD_SAFE=ON -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON -DCMAKE_INSTALL_PREFIX:PATH=${STORM_3RDPARTY_BINARY_DIR}/carl
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DBOOST_INCLUDEDIR=${Boost_INCLUDE_DIRS} -DBOOST_LIBRARYDIR=${Boost_LIBRARY_DIRS} -DBoost_NO_SYSTEM_PATHS=ON -DEXPORT_TO_CMAKE=ON -DTHREAD_SAFE=ON -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON -DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=ON -DCMAKE_INSTALL_PREFIX:PATH=${STORM_3RDPARTY_BINARY_DIR}/carl
BUILD_IN_SOURCE 0
LOG_UPDATE OFF
LOG_CONFIGURE OFF

1
src/CMakeLists.txt

@ -5,6 +5,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_custom_target(binaries)
add_subdirectory(storm)
add_subdirectory(storm-cli-utilities)
add_subdirectory(storm-pgcl)
add_subdirectory(storm-pgcl-cli)
add_subdirectory(storm-gspn)

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

@ -0,0 +1,40 @@
file(GLOB_RECURSE ALL_FILES ${PROJECT_SOURCE_DIR}/src/storm-cli-utilities/*.h ${PROJECT_SOURCE_DIR}/src/storm-cli-utilities/*.cpp)
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)
# Create storm-pars.
add_library(storm-cli-utilities SHARED ${STORM_CLI_UTIL_SOURCES} ${STORM_CLI_UTIL_HEADERS})
# 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)
target_link_libraries(storm-cli-utilities PUBLIC storm)
# 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}")
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_pars_headers)
# installation
install(TARGETS storm-cli-utilities RUNTIME DESTINATION bin LIBRARY DESTINATION lib OPTIONAL)

265
src/storm-cli-utilities/cli.cpp

@ -0,0 +1,265 @@
#include "cli.h"
#include "storm/utility/resources.h"
#include "storm/utility/file.h"
#include "storm/utility/storm-version.h"
#include "storm/utility/macros.h"
#include "storm/utility/initialize.h"
#include "storm/utility/Stopwatch.h"
#include <type_traits>
#include "storm-cli-utilities/model-handling.h"
// Includes for the linked libraries and versions header.
#ifdef STORM_HAVE_INTELTBB
# include "tbb/tbb_stddef.h"
#endif
#ifdef STORM_HAVE_GLPK
# include "glpk.h"
#endif
#ifdef STORM_HAVE_GUROBI
# include "gurobi_c.h"
#endif
#ifdef STORM_HAVE_Z3
# include "z3.h"
#endif
#ifdef STORM_HAVE_MSAT
# include "mathsat.h"
#endif
#ifdef STORM_HAVE_CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#endif
#ifdef STORM_HAVE_SMTRAT
#include "lib/smtrat.h"
#endif
namespace storm {
namespace cli {
int64_t process(const int argc, const char** argv) {
storm::utility::setUp();
storm::cli::printHeader("Storm", argc, argv);
storm::settings::initializeAll("Storm", "storm");
storm::utility::Stopwatch totalTimer(true);
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
}
processOptions();
totalTimer.stop();
if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) {
storm::cli::printTimeAndMemoryStatistics(totalTimer.getTimeInMilliseconds());
}
storm::utility::cleanUp();
return 0;
}
void printHeader(std::string const& name, const int argc, const char* argv[]) {
STORM_PRINT(name << " " << storm::utility::StormVersion::shortVersionString() << std::endl << std::endl);
// "Compute" the command line argument string with which storm was invoked.
std::stringstream commandStream;
for (int i = 1; i < argc; ++i) {
commandStream << argv[i] << " ";
}
std::string command = commandStream.str();
if (!command.empty()) {
STORM_PRINT("Command line arguments: " << commandStream.str() << std::endl);
STORM_PRINT("Current working directory: " << storm::utility::cli::getCurrentWorkingDirectory() << std::endl << std::endl);
}
}
void printVersion(std::string const& name) {
STORM_PRINT(storm::utility::StormVersion::longVersionString() << std::endl);
STORM_PRINT(storm::utility::StormVersion::buildInfo() << std::endl);
#ifdef STORM_HAVE_INTELTBB
STORM_PRINT("Linked with Intel Threading Building Blocks v" << TBB_VERSION_MAJOR << "." << TBB_VERSION_MINOR << " (Interface version " << TBB_INTERFACE_VERSION << ")." << std::endl);
#endif
#ifdef STORM_HAVE_GLPK
STORM_PRINT("Linked with GNU Linear Programming Kit v" << GLP_MAJOR_VERSION << "." << GLP_MINOR_VERSION << "." << std::endl);
#endif
#ifdef STORM_HAVE_GUROBI
STORM_PRINT("Linked with Gurobi Optimizer v" << GRB_VERSION_MAJOR << "." << GRB_VERSION_MINOR << "." << GRB_VERSION_TECHNICAL << "." << std::endl);
#endif
#ifdef STORM_HAVE_Z3
unsigned int z3Major, z3Minor, z3BuildNumber, z3RevisionNumber;
Z3_get_version(&z3Major, &z3Minor, &z3BuildNumber, &z3RevisionNumber);
STORM_PRINT("Linked with Microsoft Z3 Optimizer v" << z3Major << "." << z3Minor << " Build " << z3BuildNumber << " Rev " << z3RevisionNumber << "." << std::endl);
#endif
#ifdef STORM_HAVE_MSAT
char* msatVersion = msat_get_version();
STORM_PRINT("Linked with " << msatVersion << "." << std::endl);
msat_free(msatVersion);
#endif
#ifdef STORM_HAVE_SMTRAT
STORM_PRINT("Linked with SMT-RAT " << SMTRAT_VERSION << "." << std::endl);
#endif
#ifdef STORM_HAVE_CARL
// TODO get version string
STORM_PRINT("Linked with CArL." << std::endl);
#endif
#ifdef STORM_HAVE_CUDA
int deviceCount = 0;
cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
if (error_id == cudaSuccess) {
STORM_PRINT("Compiled with CUDA support, ");
// This function call returns 0 if there are no CUDA capable devices.
if (deviceCount == 0){
STORM_PRINT("but there are no available device(s) that support CUDA." << std::endl);
} else {
STORM_PRINT("detected " << deviceCount << " CUDA capable device(s):" << std::endl);
}
int dev, driverVersion = 0, runtimeVersion = 0;
for (dev = 0; dev < deviceCount; ++dev) {
cudaSetDevice(dev);
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
STORM_PRINT("CUDA device " << dev << ": \"" << deviceProp.name << "\"" << std::endl);
// Console log
cudaDriverGetVersion(&driverVersion);
cudaRuntimeGetVersion(&runtimeVersion);
STORM_PRINT(" CUDA Driver Version / Runtime Version " << driverVersion / 1000 << "." << (driverVersion % 100) / 10 << " / " << runtimeVersion / 1000 << "." << (runtimeVersion % 100) / 10 << std::endl);
STORM_PRINT(" CUDA Capability Major/Minor version number: " << deviceProp.major << "." << deviceProp.minor << std::endl);
}
STORM_PRINT(std::endl);
}
else {
STORM_PRINT("Compiled with CUDA support, but an error occured trying to find CUDA devices." << std::endl);
}
#endif
}
bool parseOptions(const int argc, const char* argv[]) {
try {
storm::settings::mutableManager().setFromCommandLine(argc, argv);
} catch (storm::exceptions::OptionParserException& e) {
storm::settings::manager().printHelp();
throw e;
return false;
}
storm::settings::modules::GeneralSettings const& general = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
bool result = true;
if (general.isHelpSet()) {
storm::settings::manager().printHelp(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getHelpModuleName());
result = false;
}
if (general.isVersionSet()) {
printVersion("storm");
result = false;;
}
return result;
}
void setResourceLimits() {
storm::settings::modules::ResourceSettings const& resources = storm::settings::getModule<storm::settings::modules::ResourceSettings>();
// If we were given a time limit, we put it in place now.
if (resources.isTimeoutSet()) {
storm::utility::resources::setCPULimit(resources.getTimeoutInSeconds());
}
}
void setLogLevel() {
storm::settings::modules::GeneralSettings const& general = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
storm::settings::modules::DebugSettings const& debug = storm::settings::getModule<storm::settings::modules::DebugSettings>();
if (general.isVerboseSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::INFO);
}
if (debug.isDebugSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::DEBUG);
}
if (debug.isTraceSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::TRACE);
}
if (debug.isLogfileSet()) {
storm::utility::initializeFileLogging();
}
}
void setFileLogging() {
storm::settings::modules::DebugSettings const& debug = storm::settings::getModule<storm::settings::modules::DebugSettings>();
if (debug.isLogfileSet()) {
storm::utility::initializeFileLogging();
}
}
void setUrgentOptions() {
setResourceLimits();
setLogLevel();
setFileLogging();
}
void processOptions() {
// Start by setting some urgent options (log levels, resources, etc.)
setUrgentOptions();
// Parse and preprocess symbolic input (PRISM, JANI, properties, etc.)
SymbolicInput symbolicInput = parseAndPreprocessSymbolicInput();
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
if (generalSettings.isParametricSet()) {
#ifdef STORM_HAVE_CARL
processInputWithValueType<storm::RationalFunction>(symbolicInput);
#else
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "No parameters are supported in this build.");
#endif
} else if (generalSettings.isExactSet()) {
#ifdef STORM_HAVE_CARL
processInputWithValueType<storm::RationalNumber>(symbolicInput);
#else
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "No exact numbers are supported in this build.");
#endif
} else {
processInputWithValueType<double>(symbolicInput);
}
}
void printTimeAndMemoryStatistics(uint64_t wallclockMilliseconds) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
std::cout << std::endl << "Performance statistics:" << std::endl;
#ifdef MACOS
// For Mac OS, this is returned in bytes.
uint64_t maximumResidentSizeInMegabytes = ru.ru_maxrss / 1024 / 1024;
#endif
#ifdef LINUX
// For Linux, this is returned in kilobytes.
uint64_t maximumResidentSizeInMegabytes = ru.ru_maxrss / 1024;
#endif
std::cout << " * peak memory usage: " << maximumResidentSizeInMegabytes << "MB" << std::endl;
char oldFillChar = std::cout.fill('0');
std::cout << " * CPU time: " << ru.ru_utime.tv_sec << "." << std::setw(3) << ru.ru_utime.tv_usec/1000 << "s" << std::endl;
if (wallclockMilliseconds != 0) {
std::cout << " * wallclock time: " << (wallclockMilliseconds/1000) << "." << std::setw(3) << (wallclockMilliseconds % 1000) << "s" << std::endl;
}
std::cout.fill(oldFillChar);
}
}
}

0
src/storm/cli/cli.h → src/storm-cli-utilities/cli.h

509
src/storm/cli/cli.cpp → src/storm-cli-utilities/model-handling.h

@ -1,259 +1,52 @@
#include "storm/cli/cli.h"
#pragma once
#include "storm/api/storm.h"
#include "storm/utility/resources.h"
#include "storm/utility/file.h"
#include "storm/utility/storm-version.h"
#include "storm/utility/macros.h"
#include "storm/utility/initialize.h"
#include "storm/utility/Stopwatch.h"
#include <type_traits>
#include <chrono>
#include <ctime>
#include <sstream>
#include <iomanip>
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/models/ModelBase.h"
#include "storm/settings/modules/DebugSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/exceptions/OptionParserException.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "storm/models/sparse/StandardRewardModel.h"
#include "storm/models/symbolic/StandardRewardModel.h"
#include "storm/utility/resources.h"
#include "storm/utility/file.h"
#include "storm/utility/storm-version.h"
#include "storm/utility/cli.h"
#include "storm/utility/initialize.h"
#include "storm/utility/Stopwatch.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/JitBuilderSettings.h"
#include "storm/settings/modules/DebugSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/settings/modules/ResourceSettings.h"
#include "storm/settings/modules/JaniExportSettings.h"
#include <type_traits>
#include "storm/api/storm.h"
#include "storm/utility/macros.h"
// Includes for the linked libraries and versions header.
#ifdef STORM_HAVE_INTELTBB
# include "tbb/tbb_stddef.h"
#endif
#ifdef STORM_HAVE_GLPK
# include "glpk.h"
#endif
#ifdef STORM_HAVE_GUROBI
# include "gurobi_c.h"
#endif
#ifdef STORM_HAVE_Z3
# include "z3.h"
#endif
#ifdef STORM_HAVE_MSAT
# include "mathsat.h"
#endif
#ifdef STORM_HAVE_CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#endif
#ifdef STORM_HAVE_SMTRAT
#include "lib/smtrat.h"
#endif
#include "storm/utility/Stopwatch.h"
namespace storm {
namespace cli {
int64_t process(const int argc, const char** argv) {
storm::utility::setUp();
storm::cli::printHeader("Storm", argc, argv);
storm::settings::initializeAll("Storm", "storm");
storm::utility::Stopwatch totalTimer(true);
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
}
processOptions();
totalTimer.stop();
if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) {
storm::cli::printTimeAndMemoryStatistics(totalTimer.getTimeInMilliseconds());
}
storm::utility::cleanUp();
return 0;
}
std::string currentTimeAndDate() {
auto now = std::chrono::system_clock::now();
auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&in_time_t), "%d/%m/%Y %X");
return ss.str();
}
void printHeader(std::string const& name, const int argc, const char* argv[]) {
STORM_PRINT(name << " " << storm::utility::StormVersion::shortVersionString() << std::endl << std::endl);
// "Compute" the command line argument string with which storm was invoked.
std::stringstream commandStream;
for (int i = 1; i < argc; ++i) {
commandStream << argv[i] << " ";
}
std::string command = commandStream.str();
if (!command.empty()) {
STORM_PRINT("Command line arguments: " << commandStream.str() << std::endl);
STORM_PRINT("Current working directory: " << storm::utility::cli::getCurrentWorkingDirectory() << std::endl);
STORM_PRINT("Current date/time: " << currentTimeAndDate() << std::endl << std::endl);
}
}
void printVersion(std::string const& name) {
STORM_PRINT(storm::utility::StormVersion::longVersionString() << std::endl);
STORM_PRINT(storm::utility::StormVersion::buildInfo() << std::endl);
#ifdef STORM_HAVE_INTELTBB
STORM_PRINT("Linked with Intel Threading Building Blocks v" << TBB_VERSION_MAJOR << "." << TBB_VERSION_MINOR << " (Interface version " << TBB_INTERFACE_VERSION << ")." << std::endl);
#endif
#ifdef STORM_HAVE_GLPK
STORM_PRINT("Linked with GNU Linear Programming Kit v" << GLP_MAJOR_VERSION << "." << GLP_MINOR_VERSION << "." << std::endl);
#endif
#ifdef STORM_HAVE_GUROBI
STORM_PRINT("Linked with Gurobi Optimizer v" << GRB_VERSION_MAJOR << "." << GRB_VERSION_MINOR << "." << GRB_VERSION_TECHNICAL << "." << std::endl);
#endif
#ifdef STORM_HAVE_Z3
unsigned int z3Major, z3Minor, z3BuildNumber, z3RevisionNumber;
Z3_get_version(&z3Major, &z3Minor, &z3BuildNumber, &z3RevisionNumber);
STORM_PRINT("Linked with Microsoft Z3 Optimizer v" << z3Major << "." << z3Minor << " Build " << z3BuildNumber << " Rev " << z3RevisionNumber << "." << std::endl);
#endif
#ifdef STORM_HAVE_MSAT
char* msatVersion = msat_get_version();
STORM_PRINT("Linked with " << msatVersion << "." << std::endl);
msat_free(msatVersion);
#endif
#ifdef STORM_HAVE_SMTRAT
STORM_PRINT("Linked with SMT-RAT " << SMTRAT_VERSION << "." << std::endl);
#endif
#ifdef STORM_HAVE_CARL
// TODO get version string
STORM_PRINT("Linked with CArL." << std::endl);
#endif
#ifdef STORM_HAVE_CUDA
int deviceCount = 0;
cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
if (error_id == cudaSuccess) {
STORM_PRINT("Compiled with CUDA support, ");
// This function call returns 0 if there are no CUDA capable devices.
if (deviceCount == 0){
STORM_PRINT("but there are no available device(s) that support CUDA." << std::endl);
} else {
STORM_PRINT("detected " << deviceCount << " CUDA capable device(s):" << std::endl);
}
int dev, driverVersion = 0, runtimeVersion = 0;
for (dev = 0; dev < deviceCount; ++dev) {
cudaSetDevice(dev);
cudaDeviceProp deviceProp;
cudaGetDeviceProperties(&deviceProp, dev);
STORM_PRINT("CUDA device " << dev << ": \"" << deviceProp.name << "\"" << std::endl);
// Console log
cudaDriverGetVersion(&driverVersion);
cudaRuntimeGetVersion(&runtimeVersion);
STORM_PRINT(" CUDA Driver Version / Runtime Version " << driverVersion / 1000 << "." << (driverVersion % 100) / 10 << " / " << runtimeVersion / 1000 << "." << (runtimeVersion % 100) / 10 << std::endl);
STORM_PRINT(" CUDA Capability Major/Minor version number: " << deviceProp.major << "." << deviceProp.minor << std::endl);
}
STORM_PRINT(std::endl);
}
else {
STORM_PRINT("Compiled with CUDA support, but an error occured trying to find CUDA devices." << std::endl);
}
#endif
}
bool parseOptions(const int argc, const char* argv[]) {
try {
storm::settings::mutableManager().setFromCommandLine(argc, argv);
} catch (storm::exceptions::OptionParserException& e) {
storm::settings::manager().printHelp();
throw e;
return false;
}
storm::settings::modules::GeneralSettings const& general = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
bool result = true;
if (general.isHelpSet()) {
storm::settings::manager().printHelp(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getHelpModuleName());
result = false;
}
if (general.isVersionSet()) {
printVersion("storm");
result = false;;
}
return result;
}
void setResourceLimits() {
storm::settings::modules::ResourceSettings const& resources = storm::settings::getModule<storm::settings::modules::ResourceSettings>();
// If we were given a time limit, we put it in place now.
if (resources.isTimeoutSet()) {
storm::utility::resources::setCPULimit(resources.getTimeoutInSeconds());
}
}
void setLogLevel() {
storm::settings::modules::GeneralSettings const& general = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
storm::settings::modules::DebugSettings const& debug = storm::settings::getModule<storm::settings::modules::DebugSettings>();
if (general.isVerboseSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::INFO);
}
if (debug.isDebugSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::DEBUG);
}
if (debug.isTraceSet()) {
storm::utility::setLogLevel(l3pp::LogLevel::TRACE);
}
if (debug.isLogfileSet()) {
storm::utility::initializeFileLogging();
}
}
void setFileLogging() {
storm::settings::modules::DebugSettings const& debug = storm::settings::getModule<storm::settings::modules::DebugSettings>();
if (debug.isLogfileSet()) {
storm::utility::initializeFileLogging();
}
}
void setUrgentOptions() {
setResourceLimits();
setLogLevel();
setFileLogging();
}
struct SymbolicInput {
// The symbolic model description.
boost::optional<storm::storage::SymbolicModelDescription> model;
// The properties to check.
std::vector<storm::jani::Property> properties;
};
void parseSymbolicModelDescription(storm::settings::modules::IOSettings const& ioSettings, SymbolicInput& input) {
if (ioSettings.isPrismOrJaniInputSet()) {
if (ioSettings.isPrismInputSet()) {
@ -262,7 +55,7 @@ namespace storm {
auto janiInput = storm::api::parseJaniModel(ioSettings.getJaniInputFilename());
input.model = janiInput.first;
auto const& janiPropertyInput = janiInput.second;
if (ioSettings.isJaniPropertiesSet()) {
for (auto const& propName : ioSettings.getJaniProperties()) {
auto propertyIt = janiPropertyInput.find(propName);
@ -273,7 +66,7 @@ namespace storm {
}
}
}
void parseProperties(storm::settings::modules::IOSettings const& ioSettings, SymbolicInput& input, boost::optional<std::set<std::string>> const& propertyFilter) {
if (ioSettings.isPropertySet()) {
std::vector<storm::jani::Property> newProperties;
@ -282,30 +75,30 @@ namespace storm {
} else {
newProperties = storm::api::parseProperties(ioSettings.getProperty(), propertyFilter);
}
input.properties.insert(input.properties.end(), newProperties.begin(), newProperties.end());
}
}
SymbolicInput parseSymbolicInput() {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
// Parse the property filter, if any is given.
boost::optional<std::set<std::string>> propertyFilter = storm::api::parsePropertyFilter(ioSettings.getPropertyFilter());
SymbolicInput input;
parseSymbolicModelDescription(ioSettings, input);
parseProperties(ioSettings, input, propertyFilter);
return input;
}
SymbolicInput preprocessSymbolicInput(SymbolicInput const& input) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>();
SymbolicInput output = input;
// Substitute constant definitions in symbolic input.
std::string constantDefinitionString = ioSettings.getConstantDefinitionString();
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
@ -316,19 +109,19 @@ namespace storm {
if (!output.properties.empty()) {
output.properties = storm::api::substituteConstantsInProperties(output.properties, constantDefinitions);
}
// Check whether conversion for PRISM to JANI is requested or necessary.
if (input.model && input.model.get().isPrismProgram()) {
bool transformToJani = ioSettings.isPrismToJaniSet();
bool transformToJaniForJit = coreSettings.getEngine() == storm::settings::modules::CoreSettings::Engine::Sparse && ioSettings.isJitSet();
STORM_LOG_WARN_COND(transformToJani || !transformToJaniForJit, "The JIT-based model builder is only available for JANI models, automatically converting the PRISM input model.");
transformToJani |= transformToJaniForJit;
if (transformToJani) {
storm::prism::Program const& model = output.model.get().asPrismProgram();
auto modelAndRenaming = model.toJaniWithLabelRenaming(true);
output.model = modelAndRenaming.first;
if (!modelAndRenaming.second.empty()) {
std::map<std::string, std::string> const& labelRenaming = modelAndRenaming.second;
std::vector<storm::jani::Property> amendedProperties;
@ -339,10 +132,10 @@ namespace storm {
}
}
}
return output;
}
void exportSymbolicInput(SymbolicInput const& input) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
if (input.model && input.model.get().isJaniModel()) {
@ -350,23 +143,23 @@ namespace storm {
if (ioSettings.isExportJaniDotSet()) {
storm::api::exportJaniModelAsDot(model.asJaniModel(), ioSettings.getExportJaniDotFilename());
}
if (model.isJaniModel() && storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) {
storm::api::exportJaniModel(model.asJaniModel(), input.properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename());
}
}
}
SymbolicInput parseAndPreprocessSymbolicInput() {
SymbolicInput input = parseSymbolicInput();
input = preprocessSymbolicInput(input);
exportSymbolicInput(input);
return input;
}
std::vector<std::shared_ptr<storm::logic::Formula const>> createFormulasToRespect(std::vector<storm::jani::Property> const& properties) {
std::vector<std::shared_ptr<storm::logic::Formula const>> result = storm::api::extractFormulasFromProperties(properties);
for (auto const& property : properties) {
if (!property.getFilter().getStatesFormula()->isInitialFormula()) {
result.push_back(property.getFilter().getStatesFormula());
@ -375,16 +168,24 @@ namespace storm {
return result;
}
template <storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildModelDd(SymbolicInput const& input) {
return storm::api::buildSymbolicModel<DdType, ValueType>(input.model.get(), createFormulasToRespect(input.properties));
return storm::api::buildSymbolicModel<DdType, ValueType>(input.model.get(), createFormulasToRespect(input.properties), storm::settings::getModule<storm::settings::modules::IOSettings>().isBuildFullModelSet());
}
template <typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::settings::modules::IOSettings const& ioSettings) {
auto counterexampleGeneratorSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
return storm::api::buildSparseModel<ValueType>(input.model.get(), createFormulasToRespect(input.properties), ioSettings.isBuildChoiceLabelsSet(), counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
storm::builder::BuilderOptions options(createFormulasToRespect(input.properties));
options.setBuildChoiceLabels(ioSettings.isBuildChoiceLabelsSet());
options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
options.setBuildAllLabels(ioSettings.isBuildFullModelSet());
options.setBuildAllRewardModels(ioSettings.isBuildFullModelSet());
if (ioSettings.isBuildFullModelSet()) {
options.clearTerminalStates();
}
return storm::api::buildSparseModel<ValueType>(input.model.get(), options, ioSettings.isJitSet(), storm::settings::getModule<storm::settings::modules::JitBuilderSettings>().isDoctorSet());
}
template <typename ValueType>
@ -416,7 +217,7 @@ namespace storm {
STORM_LOG_THROW(engine == storm::settings::modules::CoreSettings::Engine::Sparse, storm::exceptions::InvalidSettingsException, "Can only use sparse engine with explicit input.");
result = buildModelExplicit<ValueType>(ioSettings);
}
modelBuildingWatch.stop();
if (result) {
STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl << std::endl);
@ -424,7 +225,7 @@ namespace storm {
return result;
}
template <typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> preprocessSparseMarkovAutomaton(std::shared_ptr<storm::models::sparse::MarkovAutomaton<ValueType>> const& model) {
std::shared_ptr<storm::models::sparse::Model<ValueType>> result = model;
@ -441,40 +242,40 @@ namespace storm {
if (bisimulationSettings.isWeakBisimulationSet()) {
bisimType = storm::storage::BisimulationType::Weak;
}
STORM_LOG_INFO("Performing bisimulation minimization...");
return storm::api::performBisimulationMinimization<ValueType>(model, createFormulasToRespect(input.properties), bisimType);
}
template <typename ValueType>
std::pair<std::shared_ptr<storm::models::sparse::Model<ValueType>>, bool> preprocessSparseModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
std::pair<std::shared_ptr<storm::models::sparse::Model<ValueType>>, bool> result = std::make_pair(model, false);
if (result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) {
result.first = preprocessSparseMarkovAutomaton(result.first->template as<storm::models::sparse::MarkovAutomaton<ValueType>>());
result.second = true;
}
if (generalSettings.isBisimulationSet()) {
result.first = preprocessSparseModelBisimulation(result.first, input, bisimulationSettings);
result.second = true;
}
return result;
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
std::pair<std::shared_ptr<storm::models::sparse::Model<ValueType>>, bool> result = std::make_pair(model, false);
if (result.first->isOfType(storm::models::ModelType::MarkovAutomaton)) {
result.first = preprocessSparseMarkovAutomaton(result.first->template as<storm::models::sparse::MarkovAutomaton<ValueType>>());
result.second = true;
}
if (generalSettings.isBisimulationSet()) {
result.first = preprocessSparseModelBisimulation(result.first, input, bisimulationSettings);
result.second = true;
}
return result;
}
template <typename ValueType>
void exportSparseModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, SymbolicInput const& input) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
if (ioSettings.isExportExplicitSet()) {
storm::api::exportSparseModelAsDrn(model, ioSettings.getExportExplicitFilename(), input.model ? input.model.get().getParameterNames() : std::vector<std::string>());
}
if (ioSettings.isExportDotSet()) {
storm::api::exportSparseModelAsDot(model, ioSettings.getExportDotFilename());
}
@ -484,7 +285,7 @@ namespace storm {
void exportDdModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input) {
// Intentionally left empty.
}
template <storm::dd::DdType DdType, typename ValueType>
void exportModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
if (model->isSparseModel()) {
@ -493,7 +294,7 @@ namespace storm {
exportDdModel<DdType, ValueType>(model->as<storm::models::symbolic::Model<DdType, ValueType>>(), input);
}
}
template <storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::Model<ValueType>> preprocessDdModelBisimulation(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input, storm::settings::modules::BisimulationSettings const& bisimulationSettings) {
STORM_LOG_WARN_COND(!bisimulationSettings.isWeakBisimulationSet(), "Weak bisimulation is currently not supported on DDs. Falling back to strong bisimulation.");
@ -519,7 +320,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
std::pair<std::shared_ptr<storm::models::ModelBase>, bool> preprocessModel(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
storm::utility::Stopwatch preprocessingWatch(true);
std::pair<std::shared_ptr<storm::models::ModelBase>, bool> result = std::make_pair(model, false);
if (model->isSparseModel()) {
result = preprocessSparseModel<ValueType>(result.first->as<storm::models::sparse::Model<ValueType>>(), input);
@ -529,16 +330,17 @@ namespace storm {
}
preprocessingWatch.stop();
if (result.second) {
STORM_PRINT_AND_LOG(std::endl << "Time for model preprocessing: " << preprocessingWatch << "." << std::endl << std::endl);
}
return result;
}
void printComputingCounterexample(storm::jani::Property const& property) {
STORM_PRINT_AND_LOG("Computing counterexample for property " << *property.getRawFormula() << " ..." << std::endl);
}
void printCounterexample(std::shared_ptr<storm::counterexamples::Counterexample> const& counterexample, storm::utility::Stopwatch* watch = nullptr) {
if (counterexample) {
STORM_PRINT_AND_LOG(*counterexample << std::endl);
@ -554,17 +356,17 @@ namespace storm {
void generateCounterexamples(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Counterexample generation is not supported for this data-type.");
}
template <>
void generateCounterexamples<double>(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
typedef double ValueType;
STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::NotSupportedException, "Counterexample generation is currently only supported for sparse models.");
auto sparseModel = model->as<storm::models::sparse::Model<ValueType>>();
STORM_LOG_THROW(sparseModel->isOfType(storm::models::ModelType::Mdp), storm::exceptions::NotSupportedException, "Counterexample is currently only supported for MDPs.");
auto mdp = sparseModel->template as<storm::models::sparse::Mdp<ValueType>>();
auto counterexampleSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
if (counterexampleSettings.isMinimalCommandSetGenerationSet()) {
STORM_LOG_THROW(input.model && input.model.get().isPrismProgram(), storm::exceptions::NotSupportedException, "Minimal command set counterexamples are only supported for PRISM model input.");
@ -587,7 +389,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The selected counterexample formalism is unsupported.");
}
}
template<typename ValueType>
void printFilteredResult(std::unique_ptr<storm::modelchecker::CheckResult> const& result, storm::modelchecker::FilterType ft) {
if (result->isQuantitative()) {
@ -641,7 +443,7 @@ namespace storm {
}
STORM_PRINT_AND_LOG(std::endl);
}
void printModelCheckingProperty(storm::jani::Property const& property) {
STORM_PRINT_AND_LOG(std::endl << "Model checking property " << *property.getRawFormula() << " ..." << std::endl);
}
@ -660,25 +462,25 @@ namespace storm {
STORM_PRINT_AND_LOG(" failed, property is unsupported by selected engine/settings." << std::endl);
}
}
struct PostprocessingIdentity {
void operator()(std::unique_ptr<storm::modelchecker::CheckResult> const&) {
// Intentionally left empty.
}
};
template<typename ValueType>
void verifyProperties(std::vector<storm::jani::Property> const& properties, std::function<std::unique_ptr<storm::modelchecker::CheckResult>(std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states)> const& verificationCallback, std::function<void(std::unique_ptr<storm::modelchecker::CheckResult> const&)> const& postprocessingCallback = PostprocessingIdentity()) {
for (auto const& property : properties) {
printModelCheckingProperty(property);
storm::utility::Stopwatch watch(true);
std::unique_ptr<storm::modelchecker::CheckResult> result = verificationCallback(property.getRawFormula(), property.getFilter().getStatesFormula());
watch.stop();
postprocessingCallback(result);
printResult<ValueType>(result, property, &watch);
}
for (auto const& property : properties) {
printModelCheckingProperty(property);
storm::utility::Stopwatch watch(true);
std::unique_ptr<storm::modelchecker::CheckResult> result = verificationCallback(property.getRawFormula(), property.getFilter().getStatesFormula());
watch.stop();
postprocessingCallback(result);
printResult<ValueType>(result, property, &watch);
}
}
template <storm::dd::DdType DdType, typename ValueType>
void verifyWithAbstractionRefinementEngine(SymbolicInput const& input) {
STORM_LOG_ASSERT(input.model, "Expected symbolic model description.");
@ -697,7 +499,7 @@ namespace storm {
return storm::api::verifyWithExplorationEngine<ValueType>(input.model.get(), storm::api::createTask<ValueType>(formula, true));
});
}
template <typename ValueType>
void verifyWithSparseEngine(std::shared_ptr<storm::models::ModelBase> const& model, SymbolicInput const& input) {
auto sparseModel = model->as<storm::models::sparse::Model<ValueType>>();
@ -706,7 +508,7 @@ namespace storm {
bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithSparseEngine<ValueType>(sparseModel, task);
std::unique_ptr<storm::modelchecker::CheckResult> filter;
if (filterForInitialStates) {
filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(sparseModel->getInitialStates());
@ -725,10 +527,10 @@ namespace storm {
verifyProperties<ValueType>(input.properties, [&model] (std::shared_ptr<storm::logic::Formula const> const& formula, std::shared_ptr<storm::logic::Formula const> const& states) {
bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
auto symbolicModel = model->as<storm::models::symbolic::Model<DdType, ValueType>>();
std::unique_ptr<storm::modelchecker::CheckResult> result = storm::api::verifyWithHybridEngine<DdType, ValueType>(symbolicModel, task);
std::unique_ptr<storm::modelchecker::CheckResult> filter;
if (filterForInitialStates) {
filter = std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<DdType>>(symbolicModel->getReachableStates(), symbolicModel->getInitialStates());
@ -788,11 +590,36 @@ namespace storm {
verifySymbolicModel<DdType, ValueType>(model, input, coreSettings);
}
}
template <storm::dd::DdType DdType, typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildPreprocessExportModelWithValueTypeAndDdlib(SymbolicInput const& input, storm::settings::modules::CoreSettings::Engine engine) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
std::shared_ptr<storm::models::ModelBase> model;
if (!ioSettings.isNoBuildModelSet()) {
model = buildModel<DdType, ValueType>(engine, input, ioSettings);
}
if (model) {
model->printModelInformationToStream(std::cout);
}
STORM_LOG_THROW(model || input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model.");
if (model) {
auto preprocessingResult = preprocessModel<DdType, ValueType>(model, input);
if (preprocessingResult.second) {
model = preprocessingResult.first;
model->printModelInformationToStream(std::cout);
}
exportModel<DdType, ValueType>(model, input);
}
return model;
}
template <storm::dd::DdType DdType, typename ValueType>
void processInputWithValueTypeAndDdlib(SymbolicInput const& input) {
auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>();
// For several engines, no model building step is performed, but the verification is started right away.
storm::settings::modules::CoreSettings::Engine engine = coreSettings.getEngine();
if (engine == storm::settings::modules::CoreSettings::Engine::AbstractionRefinement) {
@ -800,43 +627,24 @@ namespace storm {
} else if (engine == storm::settings::modules::CoreSettings::Engine::Exploration) {
verifyWithExplorationEngine<ValueType>(input);
} else {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
std::shared_ptr<storm::models::ModelBase> model;
if (!ioSettings.isNoBuildModelSet()) {
model = buildModel<DdType, ValueType>(engine, input, ioSettings);
}
if (model) {
model->printModelInformationToStream(std::cout);
}
STORM_LOG_THROW(model || input.properties.empty(), storm::exceptions::InvalidSettingsException, "No input model.");
if (model) {
auto preprocessingResult = preprocessModel<DdType, ValueType>(model, input);
if (preprocessingResult.second) {
model = preprocessingResult.first;
model->printModelInformationToStream(std::cout);
}
}
std::shared_ptr<storm::models::ModelBase> model = buildPreprocessExportModelWithValueTypeAndDdlib<DdType, ValueType>(input, engine);
if (model) {
exportModel<DdType, ValueType>(model, input);
if (coreSettings.isCounterexampleSet()) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
generateCounterexamples<ValueType>(model, input);
} else {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
verifyModel<DdType, ValueType>(model, input, coreSettings);
}
}
}
}
template <typename ValueType>
void processInputWithValueType(SymbolicInput const& input) {
auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>();
if (coreSettings.getDdLibraryType() == storm::dd::DdType::CUDD) {
processInputWithValueTypeAndDdlib<storm::dd::DdType::CUDD, ValueType>(input);
} else {
@ -844,53 +652,6 @@ namespace storm {
processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, ValueType>(input);
}
}
void processOptions() {
// Start by setting some urgent options (log levels, resources, etc.)
setUrgentOptions();
// Parse and preprocess symbolic input (PRISM, JANI, properties, etc.)
SymbolicInput symbolicInput = parseAndPreprocessSymbolicInput();
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
if (generalSettings.isParametricSet()) {
#ifdef STORM_HAVE_CARL
processInputWithValueType<storm::RationalFunction>(symbolicInput);
#else
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "No parameters are supported in this build.");
#endif
} else if (generalSettings.isExactSet()) {
#ifdef STORM_HAVE_CARL
processInputWithValueType<storm::RationalNumber>(symbolicInput);
#else
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "No exact numbers are supported in this build.");
#endif
} else {
processInputWithValueType<double>(symbolicInput);
}
}
void printTimeAndMemoryStatistics(uint64_t wallclockMilliseconds) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
std::cout << std::endl << "Performance statistics:" << std::endl;
#ifdef MACOS
// For Mac OS, this is returned in bytes.
uint64_t maximumResidentSizeInMegabytes = ru.ru_maxrss / 1024 / 1024;
#endif
#ifdef LINUX
// For Linux, this is returned in kilobytes.
uint64_t maximumResidentSizeInMegabytes = ru.ru_maxrss / 1024;
#endif
std::cout << " * peak memory usage: " << maximumResidentSizeInMegabytes << "MB" << std::endl;
char oldFillChar = std::cout.fill('0');
std::cout << " * CPU time: " << ru.ru_utime.tv_sec << "." << std::setw(3) << ru.ru_utime.tv_usec/1000 << "s" << std::endl;
if (wallclockMilliseconds != 0) {
std::cout << " * wallclock time: " << (wallclockMilliseconds/1000) << "." << std::setw(3) << (wallclockMilliseconds % 1000) << "s" << std::endl;
}
std::cout.fill(oldFillChar);
}
}
}
}

2
src/storm-dft-cli/CMakeLists.txt

@ -1,6 +1,6 @@
# Create storm-dft.
add_executable(storm-dft-cli ${PROJECT_SOURCE_DIR}/src/storm-dft-cli/storm-dyftee.cpp)
target_link_libraries(storm-dft-cli storm-dft) # Adding headers for xcode
target_link_libraries(storm-dft-cli storm-dft storm-cli-utilities) # Adding headers for xcode
set_target_properties(storm-dft-cli PROPERTIES OUTPUT_NAME "storm-dft")
add_dependencies(binaries storm-dft-cli)

4
src/storm-dft-cli/storm-dyftee.cpp

@ -1,12 +1,12 @@
#include "storm/logic/Formula.h"
#include "storm/utility/initialize.h"
#include "storm/api/storm.h"
#include "storm/cli/cli.h"
#include "storm-cli-utilities/cli.h"
#include "storm/exceptions/BaseException.h"
#include "storm/logic/Formula.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/settings/modules/DebugSettings.h"
#include "storm/settings/modules/GmmxxEquationSolverSettings.h"

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

@ -1,5 +1,6 @@
#include "DFTModelChecker.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/builder/ParallelCompositionBuilder.h"
#include "storm/utility/bitoperations.h"
#include "storm/utility/DirectEncodingExporter.h"
@ -357,6 +358,7 @@ namespace storm {
explorationTimer.stop();
// Export the model if required
// TODO move this outside of the model checker?
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isExportExplicitSet()) {
std::ofstream stream;
storm::utility::openFile(storm::settings::getModule<storm::settings::modules::IOSettings>().getExportExplicitFilename(), stream);

8
src/storm-dft/storage/dft/OrderDFTElementsById.cpp

@ -22,12 +22,12 @@ namespace storm {
// Explicitly instantiate the class.
template class OrderElementsById<double>;
template class OrderElementsByRank<double>;
template struct OrderElementsById<double>;
template struct OrderElementsByRank<double>;
#ifdef STORM_HAVE_CARL
template class OrderElementsById<RationalFunction>;
template class OrderElementsByRank<RationalFunction>;
template struct OrderElementsById<RationalFunction>;
template struct OrderElementsByRank<RationalFunction>;
#endif
}
}

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

@ -1,5 +1,5 @@
add_executable(storm-gspn-cli ${PROJECT_SOURCE_DIR}/src/storm-gspn-cli/storm-gspn.cpp)
target_link_libraries(storm-gspn-cli storm-gspn) # Adding headers for xcode
target_link_libraries(storm-gspn-cli storm-gspn storm-cli-utilities) # Adding headers for xcode
set_target_properties(storm-gspn-cli PROPERTIES OUTPUT_NAME "storm-gspn")
add_dependencies(binaries storm-gspn-cli)

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

@ -12,7 +12,7 @@
#include "storm/utility/initialize.h"
#include "api/storm.h"
#include "storm/cli/cli.h"
#include "storm-cli-utilities/cli.h"
#include "storm/parser/FormulaParser.h"
@ -27,7 +27,7 @@
#include "storm/exceptions/FileIoException.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/GSPNSettings.h"
#include "storm/settings/modules/GSPNExportSettings.h"
#include "storm/settings/modules/CoreSettings.h"

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

@ -6,7 +6,7 @@
#include "storm/settings/SettingsManager.h"
#include "storm/api/storm.h"
#include "storm/cli/cli.h"
#include "storm-cli-utilities/cli.h"
#include "storm/models/ModelBase.h"
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/utility/file.h"
@ -23,13 +23,13 @@
#include "storm/exceptions/InvalidSettingsException.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/cli/cli.cpp"
#include "storm-cli-utilities/cli.cpp"
namespace storm {
namespace pars {
typedef typename storm::cli::SymbolicInput SymbolicInput;
template <typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::settings::modules::IOSettings const& ioSettings) {
return storm::api::buildSparseModel<ValueType>(input.model.get(), storm::api::extractFormulasFromProperties(input.properties), ioSettings.isBuildChoiceLabelsSet());
@ -50,7 +50,7 @@ namespace storm {
STORM_LOG_THROW(engine == storm::settings::modules::CoreSettings::Engine::Sparse, storm::exceptions::InvalidSettingsException, "Can only use sparse engine with explicit input.");
result = storm::cli::buildModelExplicit<ValueType>(ioSettings);
}
modelBuildingWatch.stop();
if (result) {
STORM_PRINT_AND_LOG("Time for model construction: " << modelBuildingWatch << "." << std::endl << std::endl);
@ -306,15 +306,8 @@ namespace storm {
if (parSettings.onlyObtainConstraints()) {
STORM_LOG_THROW(parSettings.exportResultToFile(), storm::exceptions::InvalidSettingsException, "When computing constraints, export path has to be specified.");
if (model->isOfType(storm::models::ModelType::Dtmc)) {
auto dtmc = model->template as<storm::models::sparse::Dtmc<ValueType>>();
storm::api::exportParametricResultToFile<ValueType>(boost::none, storm::analysis::ConstraintCollector<ValueType>(*dtmc),parSettings.exportResultPath());
return;
} else {
STORM_LOG_THROW(parSettings.exportResultToFile(), storm::exceptions::NotImplementedException, "Constraints for MDPs and CTMCs not implemented.");
}
storm::api::exportParametricResultToFile<ValueType>(boost::none, storm::analysis::ConstraintCollector<ValueType>(*(model->as<storm::models::sparse::Model<ValueType>>())), parSettings.exportResultPath());
return;
}
if (model) {
@ -335,27 +328,7 @@ namespace storm {
processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalFunction>(symbolicInput);
}
int64_t process(const int argc, const char** argv) {
storm::utility::setUp();
storm::cli::printHeader("Storm-pars", argc, argv);
storm::settings::initializeParsSettings("Storm-pars", "storm-pars");
storm::utility::Stopwatch totalTimer(true);
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
}
processOptions();
totalTimer.stop();
if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) {
storm::cli::printTimeAndMemoryStatistics(totalTimer.getTimeInMilliseconds());
}
storm::utility::cleanUp();
return 0;
}
}
}
@ -366,7 +339,24 @@ namespace storm {
int main(const int argc, const char** argv) {
try {
return storm::pars::process(argc, argv);
storm::utility::setUp();
storm::cli::printHeader("Storm-pars", argc, argv);
storm::settings::initializeParsSettings("Storm-pars", "storm-pars");
storm::utility::Stopwatch totalTimer(true);
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
}
storm::pars::processOptions();
totalTimer.stop();
if (storm::settings::getModule<storm::settings::modules::ResourceSettings>().isPrintTimeAndMemorySet()) {
storm::cli::printTimeAndMemoryStatistics(totalTimer.getTimeInMilliseconds());
}
storm::utility::cleanUp();
return 0;
} catch (storm::exceptions::BaseException const& exception) {
STORM_LOG_ERROR("An exception caused Storm-pars to terminate. The message of the exception is: " << exception.what());
return 1;

13
src/storm-pars/transformer/SparseParametricModelSimplifier.cpp

@ -45,7 +45,7 @@ namespace storm {
}
}
// reaching this point means that the provided formula is not supported. Thus, no simplification is possible.
STORM_LOG_DEBUG("Simplification not possible because the formula is not suppoerted. Formula: " << formula);
STORM_LOG_DEBUG("Simplification not possible because the formula is not supported. Formula: " << formula);
return false;
}
@ -63,8 +63,8 @@ namespace storm {
template<typename SparseModelType>
bool SparseParametricModelSimplifier<SparseModelType>::simplifyForUntilProbabilities(storm::logic::ProbabilityOperatorFormula const& formula) {
// If this method was not overriden by any subclass, simplification is not possible
STORM_LOG_DEBUG("Simplification not possible because the formula is not suppoerted. Formula: " << formula);
// If this method was not overridden by any subclass, simplification is not possible
STORM_LOG_DEBUG("Simplification not possible because the formula is not supported. Formula: " << formula);
return false;
}
@ -77,21 +77,21 @@ namespace storm {
template<typename SparseModelType>
bool SparseParametricModelSimplifier<SparseModelType>::simplifyForBoundedUntilProbabilities(storm::logic::ProbabilityOperatorFormula const& formula) {
// If this method was not overriden by any subclass, simplification is not possible
// If this method was not overridden by any subclass, simplification is not possible
STORM_LOG_DEBUG("Simplification not possible because the formula is not supported. Formula: " << formula);
return false;
}
template<typename SparseModelType>
bool SparseParametricModelSimplifier<SparseModelType>::simplifyForReachabilityRewards(storm::logic::RewardOperatorFormula const& formula) {
// If this method was not overriden by any subclass, simplification is not possible
// If this method was not overridden by any subclass, simplification is not possible
STORM_LOG_DEBUG("Simplification not possible because the formula is not supported. Formula: " << formula);
return false;
}
template<typename SparseModelType>
bool SparseParametricModelSimplifier<SparseModelType>::simplifyForCumulativeRewards(storm::logic::RewardOperatorFormula const& formula) {
// If this method was not overriden by any subclass, simplification is not possible
// If this method was not overridden by any subclass, simplification is not possible
STORM_LOG_DEBUG("Simplification not possible because the formula is not supported. Formula: " << formula);
return false;
}
@ -100,7 +100,6 @@ namespace storm {
std::shared_ptr<SparseModelType> SparseParametricModelSimplifier<SparseModelType>::eliminateConstantDeterministicStates(SparseModelType const& model, storm::storage::BitVector const& consideredStates, boost::optional<std::string> const& rewardModelName) {
storm::storage::SparseMatrix<typename SparseModelType::ValueType> const& sparseMatrix = model.getTransitionMatrix();
// get the action-based reward values
std::vector<typename SparseModelType::ValueType> actionRewards;
if(rewardModelName) {

2
src/storm-pgcl-cli/CMakeLists.txt

@ -1,5 +1,5 @@
add_executable(storm-pgcl-cli ${PROJECT_SOURCE_DIR}/src/storm-pgcl-cli/storm-pgcl.cpp)
target_link_libraries(storm-pgcl-cli storm-pgcl)
target_link_libraries(storm-pgcl-cli storm-pgcl storm-cli-utilities)
set_target_properties(storm-pgcl-cli PROPERTIES OUTPUT_NAME "storm-pgcl")
# installation

2
src/storm-pgcl-cli/storm-pgcl.cpp

@ -2,7 +2,7 @@
#include "logic/Formula.h"
#include "utility/initialize.h"
#include "storm/cli/cli.h"
#include "storm-cli-utilities/cli.h"
#include "storm/exceptions/BaseException.h"
#include "storm/utility/macros.h"
#include <boost/lexical_cast.hpp>

2
src/storm/CMakeLists.txt

@ -49,7 +49,7 @@ 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)
target_link_libraries(storm-main PUBLIC storm storm-cli-utilities)
set_target_properties(storm-main PROPERTIES OUTPUT_NAME "storm")
# Install storm headers to include directory.

3
src/storm/adapters/RationalFunctionAdapter.h

@ -7,7 +7,6 @@
#include <carl/core/VariablePool.h>
#include <carl/core/FactorizedPolynomial.h>
#include <carl/core/Relation.h>
#include <carl/core/SimpleConstraint.h>
#include <carl/util/stringparser.h>
namespace carl {
@ -58,5 +57,5 @@ namespace storm {
typedef carl::RationalFunction<Polynomial, true> RationalFunction;
typedef carl::Interval<double> Interval;
template<typename T> using ArithConstraint = carl::SimpleConstraint<T>;
}

30
src/storm/adapters/Smt2ExpressionAdapter.h

@ -38,8 +38,7 @@ namespace storm {
std::string translateExpression(storm::expressions::Expression const& ) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented");
}
#ifdef STORM_HAVE_CARL
/*!
* Translates the given constraint "leftHandSide relation rightHandSide" to an equivalent expression for Smt2.
@ -60,6 +59,7 @@ namespace storm {
") " +
")";
}
/*!
* Translates the given constraint "leftHandSide relation 0" to an equivalent expression for Smt2.
@ -67,31 +67,16 @@ namespace storm {
* @param constraint
* @return An equivalent expression for Smt2.
*/
std::string translateExpression(storm::ArithConstraint<storm::RawPolynomial> const& constraint) {
std::stringstream ss;
ss << "(" << constraint.rel() << " " <<
constraint.lhs().toString(false, useReadableVarNames) << " " <<
"0 " <<
")";
return ss.str();
}
/*!
* Translates the given constraint "leftHandSide relation 0" to an equivalent expression for Smt2.
* @param constraint
* @return An equivalent expression for Smt2.
*/
std::string translateExpression(storm::ArithConstraint<storm::Polynomial> const& constraint) {
std::string translateExpression(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation) {
std::stringstream ss;
ss << "(" << constraint.rel() << " " <<
constraint.lhs().toString(false, useReadableVarNames) << " " <<
ss << "(" << relation << " " <<
leftHandSide.toString(false, useReadableVarNames) << " " <<
"0 " <<
")";
return ss.str();
}
#endif
/*!
* Translates the given variable to an equivalent expression for Smt2.
*
@ -126,7 +111,7 @@ namespace storm {
}
#ifdef STORM_HAVE_CARL
/*! Checks whether the variables in the given set are already declared and creates them if necessary
* @param variables the set of variables to check
*/
@ -167,7 +152,6 @@ namespace storm {
}
return result;
}
#endif
private:
// The manager that can be used to build expressions.

30
src/storm/analysis/GraphConditions.cpp

@ -1,4 +1,6 @@
#include "storm/models/sparse/MarkovAutomaton.h"
#include "storm/models/sparse/Ctmc.h"
#include "GraphConditions.h"
#include "storm/utility/constants.h"
#include "storm/exceptions/NotImplementedException.h"
@ -9,8 +11,8 @@ namespace storm {
template <typename ValueType>
ConstraintCollector<ValueType>::ConstraintCollector(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
process(dtmc);
ConstraintCollector<ValueType>::ConstraintCollector(storm::models::sparse::Model<ValueType> const& model) {
process(model);
}
template <typename ValueType>
@ -50,10 +52,12 @@ namespace storm {
}
template <typename ValueType>
void ConstraintCollector<ValueType>::process(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
for(uint_fast64_t state = 0; state < dtmc.getNumberOfStates(); ++state) {
void ConstraintCollector<ValueType>::process(storm::models::sparse::Model<ValueType> const& model) {
for(uint_fast64_t action = 0; action < model.getTransitionMatrix().getRowCount(); ++action) {
ValueType sum = storm::utility::zero<ValueType>();
for (auto const& transition : dtmc.getRows(state)) {
for (auto transitionIt = model.getTransitionMatrix().begin(action); transitionIt != model.getTransitionMatrix().end(action); ++transitionIt) {
auto const& transition = *transitionIt;
sum += transition.getValue();
if (!storm::utility::isConstant(transition.getValue())) {
auto const& transitionVars = transition.getValue().gatherVariables();
@ -90,9 +94,17 @@ namespace storm {
// Assert: sum == 1
wellformedConstraintSet.emplace((sum.nominator() - sum.denominator()).polynomialWithCoefficient(), storm::CompareRelation::EQ);
}
}
if (model.getType() == storm::models::ModelType::Ctmc) {
auto const& exitRateVector = static_cast<storm::models::sparse::Ctmc<ValueType> const&>(model).getExitRateVector();
wellformedRequiresNonNegativeEntries(exitRateVector);
} else if (model.getType() == storm::models::ModelType::MarkovAutomaton) {
auto const& exitRateVector = static_cast<storm::models::sparse::MarkovAutomaton<ValueType> const&>(model).getExitRates();
wellformedRequiresNonNegativeEntries(exitRateVector);
}
for(auto const& rewModelEntry : dtmc.getRewardModels()) {
for(auto const& rewModelEntry : model.getRewardModels()) {
if (rewModelEntry.second.hasStateRewards()) {
wellformedRequiresNonNegativeEntries(rewModelEntry.second.getStateRewardVector());
}
@ -117,13 +129,13 @@ namespace storm {
}
}
}
}
}
template <typename ValueType>
void ConstraintCollector<ValueType>::operator()(storm::models::sparse::Dtmc<ValueType> const& dtmc) {
process(dtmc);
void ConstraintCollector<ValueType>::operator()(storm::models::sparse::Model<ValueType> const& model) {
process(model);
}
template class ConstraintCollector<storm::RationalFunction>;

24
src/storm/analysis/GraphConditions.h

@ -8,12 +8,12 @@
namespace storm {
namespace analysis {
template <typename ValueType, typename Enable=void>
struct ConstraintType {
typedef storm::ArithConstraint<ValueType> val;
typedef void* val;
};
template<typename ValueType>
struct ConstraintType<ValueType, typename std::enable_if<std::is_same<storm::RationalFunction, ValueType>::value>::type> {
typedef carl::Formula<typename ValueType::PolyType::PolyType> val;
@ -38,12 +38,12 @@ namespace storm {
void wellformedRequiresNonNegativeEntries(std::vector<ValueType> const&);
public:
/*!
* Constructs a constraint collector for the given DTMC. The constraints are built and ready for
* Constructs a constraint collector for the given Model. The constraints are built and ready for
* retrieval after the construction.
*
* @param dtmc The DTMC for which to create the constraints.
* @param model The Model for which to create the constraints.
*/
ConstraintCollector(storm::models::sparse::Dtmc<ValueType> const& dtmc);
ConstraintCollector(storm::models::sparse::Model<ValueType> const& model);
/*!
* Returns the set of wellformed-ness constraints.
@ -66,18 +66,18 @@ namespace storm {
std::set<storm::RationalFunctionVariable> const& getVariables() const;
/*!
* Constructs the constraints for the given DTMC.
* Constructs the constraints for the given Model.
*
* @param dtmc The DTMC for which to create the constraints.
* @param model The DTMC for which to create the constraints.
*/
void process(storm::models::sparse::Dtmc<ValueType> const& dtmc);
void process(storm::models::sparse::Model<ValueType> const& model);
/*!
* Constructs the constraints for the given DTMC by calling the process method.
* Constructs the constraints for the given Model by calling the process method.
*
* @param dtmc The DTMC for which to create the constraints.
* @param model The Model for which to create the constraints.
*/
void operator()(storm::models::sparse::Dtmc<ValueType> const& dtmc);
void operator()(storm::models::sparse::Model<ValueType> const& model);
};

44
src/storm/api/builder.h

@ -23,10 +23,6 @@
#include "storm/builder/ExplicitModelBuilder.h"
#include "storm/builder/jit/ExplicitJitJaniModelBuilder.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/settings/modules/JitBuilderSettings.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/NotSupportedException.h"
@ -34,12 +30,12 @@ namespace storm {
namespace api {
template<storm::dd::DdType LibraryType, typename ValueType>
std::shared_ptr<storm::models::symbolic::Model<LibraryType, ValueType>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
std::shared_ptr<storm::models::symbolic::Model<LibraryType, ValueType>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool buildFullModel = false) {
if (model.isPrismProgram()) {
typename storm::builder::DdPrismModelBuilder<LibraryType, ValueType>::Options options;
options = typename storm::builder::DdPrismModelBuilder<LibraryType, ValueType>::Options(formulas);
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isBuildFullModelSet()) {
if (buildFullModel) {
options.buildAllLabels = true;
options.buildAllRewardModels = true;
}
@ -51,7 +47,7 @@ namespace storm {
typename storm::builder::DdJaniModelBuilder<LibraryType, ValueType>::Options options;
options = typename storm::builder::DdJaniModelBuilder<LibraryType, ValueType>::Options(formulas);
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isBuildFullModelSet()) {
if (buildFullModel) {
options.buildAllLabels = true;
options.buildAllRewardModels = true;
}
@ -62,39 +58,28 @@ namespace storm {
}
template<>
inline std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, storm::RationalNumber>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
inline std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, storm::RationalNumber>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool buildFullModel) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "CUDD does not support rational numbers.");
}
template<>
inline std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, storm::RationalFunction>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) {
inline std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, storm::RationalFunction>> buildSymbolicModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool buildFullModel) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "CUDD does not support rational functions.");
}
template<typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildSparseModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool buildChoiceLabels = false, bool buildChoiceOrigins = false, bool buildStateValuations = false) {
storm::builder::BuilderOptions options(formulas);
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isBuildFullModelSet()) {
options.setBuildAllLabels();
options.setBuildAllRewardModels();
options.clearTerminalStates();
}
options.setBuildChoiceLabels(buildChoiceLabels);
options.setBuildChoiceOrigins(buildChoiceOrigins);
options.setBuildStateValuations(buildStateValuations);
if (storm::settings::getModule<storm::settings::modules::IOSettings>().isJitSet()) {
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildSparseModel(storm::storage::SymbolicModelDescription const& model, storm::builder::BuilderOptions const& options, bool jit = false, bool doctor = false) {
if (jit) {
STORM_LOG_THROW(model.isJaniModel(), storm::exceptions::NotSupportedException, "Cannot use JIT-based model builder for non-JANI model.");
storm::builder::jit::ExplicitJitJaniModelBuilder<ValueType> builder(model.asJaniModel(), options);
if (storm::settings::getModule<storm::settings::modules::JitBuilderSettings>().isDoctorSet()) {
if (doctor) {
bool result = builder.doctor();
STORM_LOG_THROW(result, storm::exceptions::NotSupportedException, "The JIT-based model builder cannot be used on your system.");
STORM_LOG_INFO("The JIT-based model builder seems to be working.");
}
return builder.build();
} else {
std::shared_ptr<storm::generator::NextStateGenerator<ValueType, uint32_t>> generator;
@ -109,6 +94,12 @@ namespace storm {
return builder.build();
}
}
template<typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildSparseModel(storm::storage::SymbolicModelDescription const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, bool jit = false, bool doctor = false) {
storm::builder::BuilderOptions options(formulas);
return buildSparseModel<ValueType>(model, options, jit, doctor);
}
template<typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> buildSparseModel(storm::models::ModelType modelType, storm::storage::sparse::ModelComponents<ValueType, RewardModelType>&& components) {
@ -157,6 +148,5 @@ namespace storm {
return storm::parser::ImcaMarkovAutomatonParser<double>::parseImcaFile(imcaFile);
}
}
}

8
src/storm/builder/BuilderOptions.cpp

@ -157,8 +157,8 @@ namespace storm {
return buildAllLabels;
}
BuilderOptions& BuilderOptions::setBuildAllRewardModels() {
buildAllRewardModels = true;
BuilderOptions& BuilderOptions::setBuildAllRewardModels(bool newValue) {
buildAllRewardModels = newValue;
return *this;
}
@ -185,8 +185,8 @@ namespace storm {
return *this;
}
BuilderOptions& BuilderOptions::setBuildAllLabels() {
buildAllLabels = true;
BuilderOptions& BuilderOptions::setBuildAllLabels(bool newValue) {
buildAllLabels = newValue;
return *this;
}

63
src/storm/builder/BuilderOptions.h

@ -81,9 +81,21 @@ namespace storm {
* model.
*/
void setTerminalStatesFromFormula(storm::logic::Formula const& formula);
/*!
* Which reward models are built
* @return
*/
std::vector<std::string> const& getRewardModelNames() const;
/*!
* Which labels are built
* @return
*/
std::set<std::string> const& getLabelNames() const;
/*!
* Which expression labels are built
* @return
*/
std::vector<storm::expressions::Expression> const& getExpressionLabels() const;
std::vector<std::pair<LabelOrExpression, bool>> const& getTerminalStates() const;
bool hasTerminalStates() const;
@ -96,18 +108,53 @@ namespace storm {
bool isExplorationChecksSet() const;
bool isExplorationShowProgressSet() const;
uint64_t getExplorationShowProgressDelay() const;
BuilderOptions& setBuildAllRewardModels();
/**
* Should all reward models be built? If not set, only required reward models are build.
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setBuildAllRewardModels(bool newValue = true);
/**
* Add an additional reward model to build
* @param newValue The name of the extra reward model
* @return this
*/
BuilderOptions& addRewardModel(std::string const& rewardModelName);
BuilderOptions& setBuildAllLabels();
/**
* Should all reward models be built? If not set, only required reward models are build.
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setBuildAllLabels(bool newValue = true);
BuilderOptions& addLabel(storm::expressions::Expression const& expression);
BuilderOptions& addLabel(std::string const& labelName);
BuilderOptions& addTerminalExpression(storm::expressions::Expression const& expression, bool value);
BuilderOptions& addTerminalLabel(std::string const& label, bool value);
BuilderOptions& setBuildChoiceLabels(bool newValue);
BuilderOptions& setBuildStateValuations(bool newValue);
BuilderOptions& setBuildChoiceOrigins(bool newValue);
BuilderOptions& setExplorationChecks(bool newValue);
/**
* Should the choice labels be built?
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setBuildChoiceLabels(bool newValue = true);
/**
* Should the state valuation mapping be built?
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setBuildStateValuations(bool newValue = true);
/**
* Should the origins the different choices be built?
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setBuildChoiceOrigins(bool newValue = true);
/**
* Should extra checks be performed during exploration
* @param newValue The new value (default true)
* @return this
*/
BuilderOptions& setExplorationChecks(bool newValue = true);
private:
/// A flag that indicates whether all reward models are to be built. In this case, the reward model names are

20
src/storm/models/sparse/Mdp.cpp

@ -37,27 +37,7 @@ namespace storm {
// Intentionally left empty
}
template <typename ValueType, typename RewardModelType>
Mdp<ValueType, RewardModelType> Mdp<ValueType, RewardModelType>::restrictChoices(storm::storage::BitVector const& enabledChoices) const {
storm::storage::sparse::ModelComponents<ValueType, RewardModelType> newComponents(this->getTransitionMatrix().restrictRows(enabledChoices));
newComponents.stateLabeling = this->getStateLabeling();
for (auto const& rewardModel : this->getRewardModels()) {
newComponents.rewardModels.emplace(rewardModel.first, rewardModel.second.restrictActions(enabledChoices));
}
if (this->hasChoiceLabeling()) {
newComponents.choiceLabeling = this->getChoiceLabeling().getSubLabeling(enabledChoices);
}
newComponents.stateValuations = this->getOptionalStateValuations();
if (this->hasChoiceOrigins()) {
newComponents.choiceOrigins = this->getChoiceOrigins()->selectChoices(enabledChoices);
}
return Mdp<ValueType, RewardModelType>(std::move(newComponents));
}
template<typename ValueType, typename RewardModelType>
uint_least64_t Mdp<ValueType, RewardModelType>::getChoiceIndex(storm::storage::StateActionPair const& stateactPair) const {
return this->getNondeterministicChoiceIndices()[stateactPair.getState()]+stateactPair.getAction();
}
template class Mdp<double>;

15
src/storm/models/sparse/Mdp.h

@ -1,9 +1,7 @@
#ifndef STORM_MODELS_SPARSE_MDP_H_
#define STORM_MODELS_SPARSE_MDP_H_
#include "storm/storage/StateActionPair.h"
#include "storm/models/sparse/NondeterministicModel.h"
#include "storm/utility/OsDetection.h"
namespace storm {
namespace models {
@ -50,19 +48,6 @@ namespace storm {
Mdp(Mdp<ValueType, RewardModelType>&& other) = default;
Mdp& operator=(Mdp<ValueType, RewardModelType>&& other) = default;
/*!
* Constructs an MDP by copying the current MDP and restricting the choices of each state to the ones given by the bitvector.
*
* @param enabledActions A BitVector of lenght numberOfChoices(), which is one iff the action should be kept.
* @return A subMDP.
*/
Mdp<ValueType, RewardModelType> restrictChoices(storm::storage::BitVector const& enabledActions) const;
/*!
* For a state/action pair, get the choice index referring to the state-action pair.
*/
uint_fast64_t getChoiceIndex(storm::storage::StateActionPair const& stateactPair) const;
};
} // namespace sparse

7
src/storm/models/sparse/NondeterministicModel.cpp

@ -185,7 +185,12 @@ namespace storm {
outStream << "}" << std::endl;
}
}
template<typename ValueType, typename RewardModelType>
uint_least64_t NondeterministicModel<ValueType, RewardModelType>::getChoiceIndex(storm::storage::StateActionPair const& stateactPair) const {
return this->getNondeterministicChoiceIndices()[stateactPair.getState()]+stateactPair.getAction();
}
template class NondeterministicModel<double>;
#ifdef STORM_HAVE_CARL

8
src/storm/models/sparse/NondeterministicModel.h

@ -2,7 +2,7 @@
#define STORM_MODELS_SPARSE_NONDETERMINISTICMODEL_H_
#include "storm/models/sparse/Model.h"
#include "storm/utility/OsDetection.h"
#include "storm/storage/StateActionPair.h"
namespace storm {
@ -54,7 +54,11 @@ namespace storm {
uint_fast64_t getNumberOfChoices(uint_fast64_t state) const;
virtual void reduceToStateBasedRewards() override;
/*!
* For a state/action pair, get the choice index referring to the state-action pair.
*/
uint_fast64_t getChoiceIndex(storm::storage::StateActionPair const& stateactPair) const;
/*!
* Applies the given scheduler to this model.
* @param scheduler the considered scheduler.

4
src/storm/permissivesched/PermissiveSchedulers.h

@ -2,6 +2,7 @@
#ifndef PERMISSIVESCHEDULERS_H
#define PERMISSIVESCHEDULERS_H
#include <storm/transformer/ChoiceSelector.h>
#include "../logic/ProbabilityOperatorFormula.h"
#include "../models/sparse/Mdp.h"
#include "../models/sparse/StandardRewardModel.h"
@ -38,7 +39,8 @@ namespace storm {
storm::models::sparse::Mdp<double, RM> apply() const {
return mdp.restrictChoices(enabledChoices);
storm::transformer::ChoiceSelector<double, RM> cs(mdp);
return *(cs.transform(enabledChoices)->template as<storm::models::sparse::Mdp<double, RM>>());
}
template<typename T>

10
src/storm/settings/Argument.cpp

@ -12,12 +12,12 @@ namespace storm {
namespace settings {
template<typename T>
Argument<T>::Argument(std::string const& name, std::string const& description, std::vector<std::shared_ptr<ArgumentValidator<T>>> const& validators): ArgumentBase(name, description), argumentValue(), argumentType(inferToEnumType<T>()), validators(validators), isOptional(false), defaultValue(), hasDefaultValue(false) {
Argument<T>::Argument(std::string const& name, std::string const& description, std::vector<std::shared_ptr<ArgumentValidator<T>>> const& validators): ArgumentBase(name, description), argumentValue(), argumentType(inferToEnumType<T>()), validators(validators), isOptional(false), defaultValue(), hasDefaultValue(false), wasSetFromDefaultValueFlag(false) {
// Intentionally left empty.
}
template<typename T>
Argument<T>::Argument(std::string const& name, std::string const& description, std::vector<std::shared_ptr<ArgumentValidator<T>>> const& validators, bool isOptional, T defaultValue): ArgumentBase(name, description), argumentValue(), argumentType(inferToEnumType<T>()), validators(validators), isOptional(isOptional), defaultValue(), hasDefaultValue(true) {
Argument<T>::Argument(std::string const& name, std::string const& description, std::vector<std::shared_ptr<ArgumentValidator<T>>> const& validators, bool isOptional, T defaultValue): ArgumentBase(name, description), argumentValue(), argumentType(inferToEnumType<T>()), validators(validators), isOptional(isOptional), defaultValue(), hasDefaultValue(true), wasSetFromDefaultValueFlag(false) {
this->setDefaultValue(defaultValue);
}
@ -71,6 +71,12 @@ namespace storm {
STORM_LOG_THROW(this->hasDefaultValue, storm::exceptions::IllegalFunctionCallException, "Unable to set value from default value, because the argument " << name << " has none.");
bool result = this->setFromTypeValue(this->defaultValue, false);
STORM_LOG_THROW(result, storm::exceptions::IllegalArgumentValueException, "Unable to assign default value to argument " << name << ", because it was rejected.");
this->wasSetFromDefaultValueFlag = true;
}
template<typename T>
bool Argument<T>::wasSetFromDefaultValue() const {
return wasSetFromDefaultValueFlag;
}
template<typename T>

5
src/storm/settings/Argument.h

@ -85,6 +85,8 @@ namespace storm {
void setFromDefaultValue() override;
virtual bool wasSetFromDefaultValue() const override;
virtual std::string getValueAsString() const override;
virtual int_fast64_t getValueAsInteger() const override;
@ -116,6 +118,9 @@ namespace storm {
// A flag indicating whether a default value has been provided.
bool hasDefaultValue;
// A flag indicating whether the argument was set from the default value.
bool wasSetFromDefaultValueFlag;
/*!
* Sets the default value of the argument to the provided value.
*

4
src/storm/settings/ArgumentBase.h

@ -80,6 +80,8 @@ namespace storm {
*/
virtual void setFromDefaultValue() = 0;
virtual bool wasSetFromDefaultValue() const = 0;
/*!
* Tries to set the value of the argument from the given string.
*
@ -134,7 +136,7 @@ namespace storm {
friend std::ostream& operator<<(std::ostream& out, ArgumentBase const& argument);
protected:
protected:
// A flag indicating whether the argument has been set.
bool hasBeenSet;

15
src/storm/settings/SettingsManager.cpp

@ -271,7 +271,7 @@ namespace storm {
return moduleIterator->second->getPrintLengthOfLongestOption();
}
void SettingsManager::addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings) {
void SettingsManager::addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings, bool doRegister) {
auto moduleIterator = this->modules.find(moduleSettings->getModuleName());
STORM_LOG_THROW(moduleIterator == this->modules.end(), storm::exceptions::IllegalFunctionCallException, "Unable to register module '" << moduleSettings->getModuleName() << "' because a module with the same name already exists.");
@ -281,12 +281,15 @@ namespace storm {
this->modules.emplace(moduleSettings->getModuleName(), std::move(moduleSettings));
auto iterator = this->modules.find(moduleName);
std::unique_ptr<modules::ModuleSettings> const& settings = iterator->second;
// Now register the options of the module.
this->moduleOptions.emplace(moduleName, std::vector<std::shared_ptr<Option>>());
for (auto const& option : settings->getOptions()) {
this->addOption(option);
if (doRegister) {
// Now register the options of the module.
this->moduleOptions.emplace(moduleName, std::vector<std::shared_ptr<Option>>());
for (auto const& option : settings->getOptions()) {
this->addOption(option);
}
}
}
void SettingsManager::addOption(std::shared_ptr<Option> const& option) {

6
src/storm/settings/SettingsManager.h

@ -101,7 +101,7 @@ namespace storm {
*
* @param moduleSettings The settings of the module to add.
*/
void addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings);
void addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings, bool doRegister = true);
/*!
* Retrieves the settings of the module with the given name.
@ -238,9 +238,9 @@ namespace storm {
* Add new module to use for the settings. The new module is given as a template argument.
*/
template<typename SettingsType>
void addModule() {
void addModule(bool doRegister = true) {
static_assert(std::is_base_of<storm::settings::modules::ModuleSettings, SettingsType>::value, "Template argument must be derived from ModuleSettings");
mutableManager().addModule(std::unique_ptr<modules::ModuleSettings>(new SettingsType()));
mutableManager().addModule(std::unique_ptr<modules::ModuleSettings>(new SettingsType()), doRegister);
}
/*!

4
src/storm/settings/modules/CoreSettings.cpp

@ -89,6 +89,10 @@ namespace storm {
return this->getOption(eqSolverOptionName).getHasOptionBeenSet();
}
bool CoreSettings::isEquationSolverSetFromDefaultValue() const {
return !this->getOption(eqSolverOptionName).getHasOptionBeenSet() || this->getOption(eqSolverOptionName).getArgumentByName("name").wasSetFromDefaultValue();
}
storm::solver::LpSolverType CoreSettings::getLpSolver() const {
std::string lpSolverName = this->getOption(lpSolverOptionName).getArgumentByName("name").getValueAsString();
if (lpSolverName == "gurobi") {

7
src/storm/settings/modules/CoreSettings.h

@ -81,6 +81,13 @@ namespace storm {
*/
bool isEquationSolverSet() const;
/*!
* Retrieves whether the equation solver has been set from its default value.
*
* @return True iff it has been set from its default value.
*/
bool isEquationSolverSetFromDefaultValue() const;
/*!
* Retrieves the selected LP solver.
*

4
src/storm/settings/modules/MinMaxEquationSolverSettings.cpp

@ -50,6 +50,10 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown min/max equation solving technique '" << minMaxEquationSolvingTechnique << "'.");
}
bool MinMaxEquationSolverSettings::isMinMaxEquationSolvingMethodSetFromDefaultValue() const {
return !this->getOption(solvingMethodOptionName).getArgumentByName("name").getHasBeenSet() || this->getOption(solvingMethodOptionName).getArgumentByName("name").wasSetFromDefaultValue();
}
bool MinMaxEquationSolverSettings::isMinMaxEquationSolvingMethodSet() const {
return this->getOption(solvingMethodOptionName).getHasOptionBeenSet();
}

11
src/storm/settings/modules/MinMaxEquationSolverSettings.h

@ -27,12 +27,19 @@ namespace storm {
bool isMinMaxEquationSolvingMethodSet() const;
/*!
* Retrieves the selected min/max equation solving technique.
* Retrieves the selected min/max equation solving method.
*
* @return The selected min/max equation solving technique.
* @return The selected min/max equation solving method.
*/
storm::solver::MinMaxMethod getMinMaxEquationSolvingMethod() const;
/*!
* Retrieves whether the min/max equation solving method is set from its default value.
*
* @return True iff if it is set from its default value.
*/
bool isMinMaxEquationSolvingMethodSetFromDefaultValue() const;
/*!
* Retrieves whether the maximal iteration count has been set.
*

4
src/storm/settings/modules/NativeEquationSolverSettings.cpp

@ -40,6 +40,10 @@ namespace storm {
return this->getOption(techniqueOptionName).getHasOptionBeenSet();
}
bool NativeEquationSolverSettings::isLinearEquationSystemTechniqueSetFromDefaultValue() const {
return !this->getOption(techniqueOptionName).getHasOptionBeenSet() || this->getOption(techniqueOptionName).getArgumentByName("name").wasSetFromDefaultValue();
}
NativeEquationSolverSettings::LinearEquationMethod NativeEquationSolverSettings::getLinearEquationSystemMethod() const {
std::string linearEquationSystemTechniqueAsString = this->getOption(techniqueOptionName).getArgumentByName("name").getValueAsString();
if (linearEquationSystemTechniqueAsString == "jacobi") {

7
src/storm/settings/modules/NativeEquationSolverSettings.h

@ -30,6 +30,13 @@ namespace storm {
*/
bool isLinearEquationSystemTechniqueSet() const;
/*!
* Retrieves whether the linear equation system technique is set from its default value.
*
* @return True iff it was set from its default value.
*/
bool isLinearEquationSystemTechniqueSetFromDefaultValue() const;
/*!
* Retrieves the method that is to be used for solving systems of linear equations.
*

2
src/storm/solver/IterativeMinMaxLinearEquationSolver.h

@ -73,7 +73,7 @@ namespace storm {
IterativeMinMaxLinearEquationSolverSettings<ValueType> settings;
};
template<typename ValueType>
template<typename ValueType>
class IterativeMinMaxLinearEquationSolverFactory : public StandardMinMaxLinearEquationSolverFactory<ValueType> {
public:
IterativeMinMaxLinearEquationSolverFactory(MinMaxMethodSelection const& method = MinMaxMethodSelection::FROMSETTINGS, bool trackScheduler = false);

15
src/storm/solver/MinMaxLinearEquationSolver.cpp

@ -154,7 +154,19 @@ namespace storm {
template<typename ValueType>
void MinMaxLinearEquationSolverFactory<ValueType>::setMinMaxMethod(MinMaxMethodSelection const& newMethod) {
if (newMethod == MinMaxMethodSelection::FROMSETTINGS) {
setMinMaxMethod(storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>().getMinMaxEquationSolvingMethod());
bool wasSet = false;
auto const& minMaxSettings = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>();
if (std::is_same<ValueType, storm::RationalNumber>::value) {
if (minMaxSettings.isMinMaxEquationSolvingMethodSetFromDefaultValue() && minMaxSettings.getMinMaxEquationSolvingMethod() != MinMaxMethod::PolicyIteration) {
STORM_LOG_WARN("Selecting policy iteration as the solution method to guarantee exact results. If you want to override this, please explicitly specify a different method.");
this->setMinMaxMethod(MinMaxMethod::PolicyIteration);
wasSet = true;
}
}
if (!wasSet) {
setMinMaxMethod(minMaxSettings.getMinMaxEquationSolvingMethod());
}
} else {
setMinMaxMethod(convert(newMethod));
}
@ -162,6 +174,7 @@ namespace storm {
template<typename ValueType>
void MinMaxLinearEquationSolverFactory<ValueType>::setMinMaxMethod(MinMaxMethod const& newMethod) {
STORM_LOG_WARN_COND(!(std::is_same<ValueType, storm::RationalNumber>::value) || newMethod == MinMaxMethod::PolicyIteration, "The selected solution method does not guarantee exact result. Consider using policy iteration.");
method = newMethod;
}

27
src/storm/solver/SmtlibSmtSolver.cpp

@ -102,33 +102,6 @@ namespace storm {
writeCommand("( assert " + expressionAdapter->translateExpression(leftHandSide, relation, rightHandSide) + " )", true);
}
void SmtlibSmtSolver::add(storm::ArithConstraint<storm::RationalFunction> const& constraint) {
add(constraint.lhs(), constraint.rel());
}
void SmtlibSmtSolver::add(storm::ArithConstraint<storm::RawPolynomial> const& constraint) {
//if some of the occurring variables are not declared yet, we will have to.
std::set<storm::RationalFunctionVariable> variables = constraint.lhs().gatherVariables();
std::vector<std::string> const varDeclarations = expressionAdapter->checkForUndeclaredVariables(variables);
for (auto declaration : varDeclarations){
writeCommand(declaration, true);
}
writeCommand("( assert " + expressionAdapter->translateExpression(constraint) + " )", true);
}
void SmtlibSmtSolver::add(storm::RationalFunctionVariable const& guard, typename storm::ArithConstraint<storm::Polynomial> const& constraint){
STORM_LOG_THROW((guard.getType()==carl::VariableType::VT_BOOL), storm::exceptions::IllegalArgumentException, "Tried to add a guarded constraint, but the guard is not of type bool.");
//if some of the occurring variables are not declared yet, we will have to (including the guard!).
std::set<storm::RationalFunctionVariable> variables = constraint.lhs().gatherVariables();
variables.insert(guard);
std::vector<std::string> const varDeclarations = expressionAdapter->checkForUndeclaredVariables(variables);
for (auto declaration : varDeclarations){
writeCommand(declaration, true);
}
std::string guardName= carl::VariablePool::getInstance().getName(guard, this->useReadableVarNames);
writeCommand("( assert (=> " + guardName + " " + expressionAdapter->translateExpression(constraint) + " ) )", true);
}
void SmtlibSmtSolver::add(const storm::RationalFunctionVariable& variable, bool value){
STORM_LOG_THROW((variable.getType()==carl::VariableType::VT_BOOL), storm::exceptions::IllegalArgumentException, "Tried to add a constraint that consists of a non-boolean variable.");
std::set<storm::RationalFunctionVariable> variableSet;

12
src/storm/solver/SmtlibSmtSolver.h

@ -51,12 +51,7 @@ namespace storm {
//adds the constraint "leftHandSide relation rightHandSide"
virtual void add(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation, storm::RationalFunction const& rightHandSide=storm::RationalFunction(0));
//adds the given carl constraint
void add(typename storm::ArithConstraint<storm::RationalFunction> const& constraint);
void add(typename storm::ArithConstraint<storm::RawPolynomial> const& constraint);
// adds the given carl constraint that is guarded by the given guard. The guard should have type 'bool'
void add(storm::RationalFunctionVariable const& guard, typename storm::ArithConstraint<storm::Polynomial> const& constraint);
// asserts that the given variable has the given value. The variable should have type 'bool'
void add(storm::RationalFunctionVariable const& variable, bool value);
@ -65,10 +60,9 @@ namespace storm {
virtual CheckResult check() override;
virtual CheckResult checkWithAssumptions(std::set<storm::expressions::Expression> const& assumptions) override;
#ifndef WINDOWS
virtual CheckResult checkWithAssumptions(std::initializer_list<storm::expressions::Expression> const& assumptions) override;
#endif
bool isNeedsRestart() const;
//Todo: some of these might be added in the future

28
src/storm/solver/SymbolicLinearEquationSolver.cpp

@ -59,6 +59,34 @@ namespace storm {
}
}
template<storm::dd::DdType DdType>
std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, storm::RationalNumber>> GeneralSymbolicLinearEquationSolverFactory<DdType, storm::RationalNumber>::create(storm::dd::Add<DdType, storm::RationalNumber> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) const {
auto const& coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>();
storm::solver::EquationSolverType equationSolver;
if (coreSettings.isEquationSolverSetFromDefaultValue()) {
STORM_LOG_WARN("Selecting the elimination solver to guarantee exact results. If you want to override this, please explicitly specify a different equation solver.");
equationSolver = storm::solver::EquationSolverType::Elimination;
} else {
equationSolver = coreSettings.getEquationSolver();
}
if (equationSolver != storm::solver::EquationSolverType::Elimination) {
STORM_LOG_WARN("The chosen equation solver does not guarantee precise results despite using exact arithmetic. Consider using the elimination solver instead.");
}
switch (equationSolver) {
case storm::solver::EquationSolverType::Elimination: return std::make_unique<storm::solver::SymbolicEliminationLinearEquationSolver<DdType, storm::RationalNumber>>(A, allRows, rowMetaVariables, columnMetaVariables, rowColumnMetaVariablePairs);
break;
case storm::solver::EquationSolverType::Native:
return std::make_unique<storm::solver::SymbolicNativeLinearEquationSolver<DdType, storm::RationalNumber>>(A, allRows, rowMetaVariables, columnMetaVariables, rowColumnMetaVariablePairs);
break;
default:
STORM_LOG_WARN("The selected equation solver is not available in the dd engine. Falling back to elimination solver.");
return std::make_unique<storm::solver::SymbolicEliminationLinearEquationSolver<DdType, storm::RationalNumber>>(A, allRows, rowMetaVariables, columnMetaVariables, rowColumnMetaVariablePairs);
}
}
template<storm::dd::DdType DdType>
std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, storm::RationalFunction>> GeneralSymbolicLinearEquationSolverFactory<DdType, storm::RationalFunction>::create(storm::dd::Add<DdType, storm::RationalFunction> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) const {

6
src/storm/solver/SymbolicLinearEquationSolver.h

@ -101,6 +101,12 @@ namespace storm {
public:
virtual std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, ValueType>> create(storm::dd::Add<DdType, ValueType> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) const;
};
template<storm::dd::DdType DdType>
class GeneralSymbolicLinearEquationSolverFactory<DdType, storm::RationalNumber> : public SymbolicLinearEquationSolverFactory<DdType, storm::RationalNumber> {
public:
virtual std::unique_ptr<storm::solver::SymbolicLinearEquationSolver<DdType, storm::RationalNumber>> create(storm::dd::Add<DdType, storm::RationalNumber> const& A, storm::dd::Bdd<DdType> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) const;
};
template<storm::dd::DdType DdType>
class GeneralSymbolicLinearEquationSolverFactory<DdType, storm::RationalFunction> : public SymbolicLinearEquationSolverFactory<DdType, storm::RationalFunction> {

4
src/storm/storage/expressions/Variable.h

@ -130,9 +130,9 @@ namespace storm {
bool hasRationalType() const;
/*!
* Checks whether the variable is of boolean type.
* Checks whether the variable is of numerical type.
*
* @return True iff the variable if of boolean type.
* @return True iff the variable if of numerical type.
*/
bool hasNumericalType() const;

2
src/storm/storm.cpp

@ -1,7 +1,7 @@
#include "storm/utility/macros.h"
#include "storm/exceptions/BaseException.h"
#include "storm/cli/cli.h"
#include "storm-cli-utilities/cli.h"
/*!
* Main entry point of the executable storm.

26
src/storm/transformer/ChoiceSelector.cpp

@ -0,0 +1,26 @@
#include "storm/transformer/ChoiceSelector.h"
#include "storm/models/sparse/Mdp.h"
namespace storm {
namespace transformer {
template <typename ValueType, typename RewardModelType>
std::shared_ptr<storm::models::sparse::NondeterministicModel<ValueType, RewardModelType>> ChoiceSelector<ValueType, RewardModelType>::transform(storm::storage::BitVector const& enabledActions) const
{
storm::storage::sparse::ModelComponents<ValueType, RewardModelType> newComponents(inputModel.getTransitionMatrix().restrictRows(enabledActions));
newComponents.stateLabeling = inputModel.getStateLabeling();
for (auto const& rewardModel : inputModel.getRewardModels()) {
newComponents.rewardModels.emplace(rewardModel.first, rewardModel.second.restrictActions(enabledActions));
}
if (inputModel.hasChoiceLabeling()) {
newComponents.choiceLabeling = inputModel.getChoiceLabeling().getSubLabeling(enabledActions);
}
newComponents.stateValuations = inputModel.getOptionalStateValuations();
if (inputModel.hasChoiceOrigins()) {
newComponents.choiceOrigins = inputModel.getChoiceOrigins()->selectChoices(enabledActions);
}
return std::make_shared<storm::models::sparse::Mdp<ValueType, RewardModelType>>(std::move(newComponents));
}
template class ChoiceSelector<double>;
}
}

30
src/storm/transformer/ChoiceSelector.h

@ -0,0 +1,30 @@
#pragma once
#include "storm/models/sparse/StandardRewardModel.h"
#include "storm/models/sparse/NondeterministicModel.h"
namespace storm {
namespace transformer {
template<typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
class ChoiceSelector {
public:
ChoiceSelector(storm::models::sparse::NondeterministicModel<ValueType, RewardModelType> const& inputModel) : inputModel(inputModel) {
}
/*!
* Constructs an MDP by copying the current MDP and restricting the choices of each state to the ones given by the bitvector.
*
* @param enabledActions A BitVector of lenght numberOfChoices(), which is one iff the action should be kept.
* @return A subMDP.
*/
std::shared_ptr<storm::models::sparse::NondeterministicModel<ValueType, RewardModelType>> transform(storm::storage::BitVector const& enabledActions) const;
private:
storm::models::sparse::NondeterministicModel<ValueType, RewardModelType> const& inputModel;
};
}
}

164
travis/build-helper.sh

@ -0,0 +1,164 @@
#!/bin/bash
# Inspired by https://github.com/google/fruit
set -e
# Helper for travis folding
travis_fold() {
local action=$1
local name=$2
echo -en "travis_fold:${action}:${name}\r"
}
# Helper for distinguishing between different runs
run() {
case "$1" in
Build1 | Build2 | Build3 | Build4)
if [[ "$1" == "Build1" ]]
then
# CMake
travis_fold start cmake
mkdir build
cd build
cmake .. "${CMAKE_ARGS[@]}"
echo
if [ -f "CMakeFiles/CMakeError.log" ]
then
echo "Content of CMakeFiles/CMakeError.log:"
cat CMakeFiles/CMakeError.log
fi
echo
cd ..
travis_fold end cmake
fi
# Make
travis_fold start make
cd build
make -j$N_JOBS
travis_fold end make
# Set skip-file
if [[ "$1" != "Build4" ]]
then
touch skip.txt
else
rm -rf skip.txt
fi
;;
TestAll)
# Test all
travis_fold start test_all
cd build
ctest test --output-on-failure
travis_fold end test_all
;;
*)
echo "Unrecognized value of run: $1"
exit 1
esac
}
# This only exists in OS X, but it doesn't cause issues in Linux (the dir doesn't exist, so it's
# ignored).
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
case $COMPILER in
gcc-4.8)
export CC=gcc-4.8
export CXX=g++-4.8
;;
gcc-4.9)
export CC=gcc-4.9
export CXX=g++-4.9
;;
gcc-5)
export CC=gcc-5
export CXX=g++-5
;;
gcc-6)
export CC=gcc-6
export CXX=g++-6
;;
gcc-default)
export CC=gcc
export CXX=g++
;;
clang-3.5)
export CC=clang-3.5
export CXX=clang++-3.5
;;
clang-3.6)
export CC=clang-3.6
export CXX=clang++-3.6
;;
clang-3.7)
export CC=clang-3.7
export CXX=clang++-3.7
;;
clang-3.8)
export CC=clang-3.8
export CXX=clang++-3.8
;;
clang-3.9)
export CC=clang-3.9
export CXX=clang++-3.9
;;
clang-4.0)
case "$OS" in
linux)
export CC=clang-4.0
export CXX=clang++-4.0
;;
osx)
export CC=/usr/local/opt/llvm/bin/clang-4.0
export CXX=/usr/local/opt/llvm/bin/clang++
;;
*) echo "Error: unexpected OS: $OS"; exit 1 ;;
esac
;;
clang-default)
export CC=clang
export CXX=clang++
;;
*)
echo "Unrecognized value of COMPILER: $COMPILER"
exit 1
esac
# Build
echo CXX version: $($CXX --version)
echo C++ Standard library location: $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1)
echo Normalized C++ Standard library location: $(readlink -f $(echo '#include <vector>' | $CXX -x c++ -E - | grep 'vector\"' | awk '{print $3}' | sed 's@/vector@@;s@\"@@g' | head -n 1))
case "$CONFIG" in
DefaultDebug) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$STLARG") ;;
DefaultRelease) CMAKE_ARGS=(-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="$STLARG") ;;
*) echo "Unrecognized value of CONFIG: $CONFIG"; exit 1 ;;
esac
# Restore timestamps of files
travis_fold start mtime
if [[ "$1" == "Build1" ]]
then
# Remove old mtime cache
rm -rf travis/mtime_cache/cache.json
fi
ruby travis/mtime_cache/mtime_cache.rb -g travis/mtime_cache/globs.txt -c travis/mtime_cache/cache.json
travis_fold end mtime
run "$1"

71
travis/build.sh

@ -0,0 +1,71 @@
#!/bin/bash -x
# Inspired by https://github.com/google/fruit
N_JOBS=2
TIMEOUT_MAC=1600
TIMEOUT_LINUX=2300
OS=$TRAVIS_OS_NAME
EXITCODE=42
# Skip this run?
if [ -f build/skip.txt ]
then
# Remove flag s.t. tests will be executed
if [[ "$1" == "Build4" ]]
then
rm build/skip.txt
fi
exit 0
fi
case $OS in
linux)
# Execute docker image on Linux
# Stop previous session
docker rm -f storm &>/dev/null
# Run container
set -e
docker run -d -it --name storm --privileged mvolk/storm-basesystem:$LINUX
# Copy local content into container
docker exec storm mkdir storm
docker cp . storm:/storm
set +e
# Execute main process
timeout $TIMEOUT_LINUX docker exec storm bash -c "
export CONFIG=$CONFIG;
export COMPILER=$COMPILER;
export N_JOBS=$N_JOBS;
export STLARG=;
export OS=$OS;
cd storm;
travis/build-helper.sh $1"
EXITCODE=$?
;;
osx)
# Mac OSX
STLARG="-stdlib=libc++"
export CONFIG=$CONFIG
export COMPILER
export N_JOBS
export STLARG
export OS
gtimeout $TIMEOUT_MAC travis/build-helper.sh "$1"
EXITCODE=$?
;;
*)
# Unknown OS
echo "Unsupported OS: $OS"
exit 1
esac
if [[ $EXITCODE == 124 ]] && [[ "$1" == Build* ]] && [[ "$1" != "Build4" ]]
then
exit 0
else
exit $EXITCODE
fi

16
travis/dockerfiles/Dockerfile.debian-9

@ -0,0 +1,16 @@
FROM debian:9
MAINTAINER Matthias Volk <matthias.volk@cs.rwth-aachen.de>
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
build-essential \
ruby \
git \
cmake \
libboost-all-dev \
libcln-dev \
libeigen3-dev \
libgmp-dev \
libginac-dev \
automake \
libglpk-dev \
libz3-dev

8
travis/dockerfiles/Dockerfile.storm

@ -0,0 +1,8 @@
FROM mvolk/storm-basesystem:ubuntu-16.10
MAINTAINER Matthias Volk <matthias.volk@cs.rwth-aachen.de>
COPY build_carl.sh /opt
RUN cd opt && ./build_carl.sh
COPY build_storm.sh /opt
RUN cd opt && ./build_storm.sh

17
travis/dockerfiles/Dockerfile.ubuntu-16.10

@ -0,0 +1,17 @@
FROM ubuntu:16.10
MAINTAINER Matthias Volk <matthias.volk@cs.rwth-aachen.de>
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
build-essential \
ruby \
git \
cmake \
libboost-all-dev \
libcln-dev \
libeigen3-dev \
libgmp-dev \
libginac-dev \
automake \
libglpk-dev \
libhwloc-dev \
libz3-dev

9
travis/dockerfiles/build_carl.sh

@ -0,0 +1,9 @@
#!/bin/bash
echo "Building Carl..."
git clone https://github.com/smtrat/carl.git
cd carl
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_CLN_NUMBERS=ON -DUSE_GINAC=ON
make lib_carl -j2
echo "Building Carl finished"

9
travis/dockerfiles/build_docker.sh

@ -0,0 +1,9 @@
#!/bin/bash
# Build Ubuntu 16.10 "Yakkety Yak"
docker build -t mvolk/storm-basesystem:ubuntu-16.10 -f Dockerfile.ubuntu-16.10 .
docker push mvolk/storm-basesystem:ubuntu-16.10
# Build Debian 9 "Stretch"
docker build -t mvolk/storm-basesystem:debian-9 -f Dockerfile.debian-9 .
docker push mvolk/storm-basesystem:debian-9

9
travis/dockerfiles/build_storm.sh

@ -0,0 +1,9 @@
#!/bin/bash
echo "Building Storm..."
git clone https://github.com/moves-rwth/storm.git
cd storm
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make storm storm-dft storm-pars -j1
echo "Building Storm finished"

123
travis/generate_travis.py

@ -0,0 +1,123 @@
# Configuration for Linux
configs_linux = [
# OS, compiler
("ubuntu-16.10", "gcc", "-6"),
#("debian-9", "gcc", "-6"),
]
# Configurations for Mac
configs_mac = [
# OS, compiler
("osx", "clang", "-4.0"),
]
# Build types
build_types = [
"DefaultDebug",
"DefaultRelease",
]
# Stages in travis
stages = [
("Build (1st run)", "Build1"),
("Build (2nd run)", "Build2"),
("Build (3rd run)", "Build3"),
("Build (4th run)", "Build4"),
("Test all", "TestAll"),
]
if __name__ == "__main__":
s = ""
# Initial config
s += "# This file was inspired from https://github.com/google/fruit\n"
s += "\n"
s += "#\n"
s += "# General config\n"
s += "#\n"
s += "branches:\n"
s += " only:\n"
s += " - master\n"
s += " - stable\n"
s += "dist: trusty\n"
s += "language: cpp\n"
s += "\n"
s += "# Enable caching\n"
s += "cache:\n"
s += " timeout: 1000\n"
s += " directories:\n"
s += " - build\n"
s += " - travis/mtime_cache\n"
s += "\n"
s += "# Enable docker support\n"
s += "services:\n"
s += "- docker\n"
s += "sudo: required\n"
s += "\n"
s += "notifications:\n"
s += " email:\n"
s += " on_failure: always\n"
s += " on_success: change\n"
s += " recipients:\n"
s += ' secure: "Q9CW/PtyWkZwExDrfFFb9n1STGYsRfI6awv1bZHcGwfrDvhpXoMCuF8CwviIfilm7fFJJEoKizTtdRpY0HrOnY/8KY111xrtcFYosxdndv7xbESodIxQOUoIEFCO0mCNHwWYisoi3dAA7H3Yn661EsxluwHjzX5vY0xSbw0n229hlsFz092HwGLSU33zHl7eXpQk+BOFmBTRGlOq9obtDZ17zbHz1oXFZntHK/JDUIYP0b0uq8NvE2jM6CIVdcuSwmIkOhZJoO2L3Py3rBbPci+L2PSK4Smv2UjCPF8KusnOaFIyDB3LcNM9Jqq5ssJMrK/KaO6BiuYrOZXYWZ7KEg3Y/naC8HjOH1dzty+P7oW46sb9F03pTsufqD4R7wcK+9wROTztO6aJPDG/IPH7EWgrBTxqlOkVRwi2eYuQouZpZUW6EMClKbMHMIxCH2S8aOk/r1w2cNwmPEcunnP0nl413x/ByHr4fTPFykPj8pQxIsllYjpdWBRQfDOauKWGzk6LcrFW0qpWP+/aJ2vYu/IoZQMG5lMHbp6Y1Lg09pYm7Q983v3b7D+JvXhOXMyGq91HyPahA2wwKoG1GA4uoZ2I95/IFYNiKkelDd3WTBoFLNF9YFoEJNdCywm1fO2WY4WkyEFBuQcgDA+YpFMJJMxjTbivYk9jvHk2gji//2w="\n'
s += "\n"
s += "#\n"
s += "# Configurations\n"
s += "#\n"
s += "jobs:\n"
s += " include:\n"
# Generate all configurations
for stage in stages:
s += "\n"
s += " ###\n"
s += " # Stage: {}\n".format(stage[0])
s += " ###\n"
s += "\n"
# Mac OS X
for config in configs_mac:
osx = config[0]
compiler = "{}{}".format(config[1], config[2])
s += " # {}\n".format(osx)
buildConfig = ""
for build in build_types:
buildConfig += " - stage: {}\n".format(stage[0])
buildConfig += " os: osx\n"
buildConfig += " compiler: {}\n".format(config[1])
buildConfig += " env: CONFIG={} COMPILER={} STL=libc++\n".format(build, compiler)
buildConfig += " install:\n"
if stage[1] == "Build1":
buildConfig += " - rm -rf build\n"
buildConfig += " - travis/install_osx.sh\n"
buildConfig += " script:\n"
buildConfig += " - travis/build.sh {}\n".format(stage[1])
buildConfig += " after_failure:\n"
buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n"
s += buildConfig
# Linux via Docker
for config in configs_linux:
linux = config[0]
compiler = "{}{}".format(config[1], config[2])
s += " # {}\n".format(linux)
buildConfig = ""
for build in build_types:
buildConfig += " - stage: {}\n".format(stage[0])
buildConfig += " os: linux\n"
buildConfig += " compiler: {}\n".format(config[1])
buildConfig += " env: CONFIG={} LINUX={} COMPILER={}\n".format(build, linux, compiler)
buildConfig += " install:\n"
if stage[1] == "Build1":
buildConfig += " - rm -rf build\n"
buildConfig += " - travis/install_linux.sh\n"
buildConfig += " script:\n"
buildConfig += " - travis/build.sh {}\n".format(stage[1])
buildConfig += " before_cache:\n"
buildConfig += " - docker cp storm:/storm/. .\n"
buildConfig += " after_failure:\n"
buildConfig += " - find build -iname '*err*.log' -type f -print -exec cat {} \;\n"
s += buildConfig
print(s)

11
travis/install_linux.sh

@ -0,0 +1,11 @@
#!/bin/bash
set -e
# Skip this run?
if [ -f build/skip.txt ]
then
exit 0
fi
sudo apt-get install -qq -y docker

73
travis/install_osx.sh

@ -0,0 +1,73 @@
#!/bin/bash
# Script installing dependencies
# Inspired by https://github.com/google/fruit
set -e
# Helper for travis folding
travis_fold() {
local action=$1
local name=$2
echo -en "travis_fold:${action}:${name}\r"
}
# Helper for installing packages via homebrew
install_brew_package() {
if brew list -1 | grep -q "^$1\$"; then
# Package is installed, upgrade if needed
brew outdated "$1" || brew upgrade "$@"
else
# Package not installed yet, install.
# If there are conflicts, try overwriting the files (these are in /usr/local anyway so it should be ok).
brew install "$@" || brew link --overwrite gcc49
fi
}
# Skip this run?
if [ -f build/skip.txt ]
then
exit 0
fi
# Update packages
travis_fold start brew_update
brew update
travis_fold end brew_update
travis_fold start brew_install_util
# For md5sum
install_brew_package md5sha1sum
# For `timeout'
install_brew_package coreutils
which cmake &>/dev/null || install_brew_package cmake
# Install compiler
case "${COMPILER}" in
gcc-4.8) install_brew_package gcc@4.8 ;;
gcc-4.9) install_brew_package gcc@4.9 ;;
gcc-5) install_brew_package gcc@5 ;;
gcc-6) install_brew_package gcc@6 ;;
clang-default) ;;
clang-3.7) install_brew_package llvm@3.7 --with-clang --with-libcxx;;
clang-3.8) install_brew_package llvm@3.8 --with-clang --with-libcxx;;
clang-3.9) install_brew_package llvm@3.9 --with-clang --with-libcxx;;
clang-4.0) install_brew_package llvm --with-clang --with-libcxx;;
*) echo "Compiler not supported: ${COMPILER}. See travis/install_osx.sh"; exit 1 ;;
esac
travis_fold end brew_install_util
# Install dependencies
travis_fold start brew_install_dependencies
install_brew_package gmp --c++11
install_brew_package cln
install_brew_package ginac
install_brew_package doxygen
install_brew_package boost --c++11
install_brew_package z3 # optional
brew tap homebrew/science
install_brew_package homebrew/science/glpk
install_brew_package homebrew/science/hwloc
install_brew_package eigen
travis_fold end brew_install_dependencies

5
travis/mtime_cache/globs.txt

@ -0,0 +1,5 @@
src/**/*.{%{cpp}}
src/**/CMakeLists.txt
CMakeLists.txt
resources/3rdparty/**/*.{%{cpp}}
resources/3rdparty/eigen-3.3-beta1/StormEigen/**/*

178
travis/mtime_cache/mtime_cache.rb

@ -0,0 +1,178 @@
#!/usr/bin/env ruby
#
# mtime_cache
# Copyright (c) 2016 Borislav Stanimirov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
require 'digest/md5'
require 'json'
require 'fileutils'
VERSION = "1.0.2"
VERSION_TEXT = "mtime_cache v#{VERSION}"
USAGE = <<ENDUSAGE
Usage:
mtime_cache [<globs>] [-g globfile] [-d] [-q|V] [-c cache]
ENDUSAGE
HELP = <<ENDHELP
Traverse through globbed files, making a json cache based on their mtime.
If a cache exists, changes the mtime of existing unchanged (based on MD5
hash) files to the one in the cache.
Options:
globs Ruby-compatible glob strings (ex some/path/**/*.java)
A extension pattern is allowd in the form %{pattern}
(ex some/path/*.{%{pattern1},%{pattern2}})
The globs support the following patterns:
%{cpp} - common C++ extensions
-g, --globfile A file with list of globs to perform (one per line)
-?, -h, --help Show this help message.
-v, --version Show the version number (#{VERSION})
-q, --quiet Don't log anything to stdout
-V, --verbose Show extra logging
-d, --dryrun Don't change any files on the filesystem
-c, --cache Specify the cache file for input and output.
[Default is .mtime_cache.json]
ENDHELP
param_arg = nil
ARGS = { :cache => '.mtime_cache.json', :globs => [] }
ARGV.each do |arg|
case arg
when '-g', '--globfile' then param_arg = :globfile
when '-h', '-?', '--help' then ARGS[:help] = true
when '-v', '--version' then ARGS[:ver] = true
when '-q', '--quiet' then ARGS[:quiet] = true
when '-V', '--verbose' then ARGS[:verbose] = true
when '-d', '--dryrun' then ARGS[:dry] = true
when '-c', '--cache' then param_arg = :cache
else
if param_arg
ARGS[param_arg] = arg
param_arg = nil
else
ARGS[:globs] << arg
end
end
end
def log(text, level = 0)
return if ARGS[:quiet]
return if level > 0 && !ARGS[:verbose]
puts text
end
if ARGS[:ver] || ARGS[:help]
log VERSION_TEXT
exit if ARGS[:ver]
log USAGE
log HELP
exit
end
if ARGS[:globs].empty? && !ARGS[:globfile]
log 'Error: Missing globs'
log USAGE
exit 1
end
EXTENSION_PATTERNS = {
:cpp => "c,cc,cpp,cxx,h,hpp,hxx,inl,ipp,inc,ixx"
}
cache_file = ARGS[:cache]
cache = {}
if File.file?(cache_file)
log "Found #{cache_file}"
cache = JSON.parse(File.read(cache_file))
log "Read #{cache.length} entries"
else
log "#{cache_file} not found. A new one will be created"
end
globs = ARGS[:globs].map { |g| g % EXTENSION_PATTERNS }
globfile = ARGS[:globfile]
if globfile
File.open(globfile, 'r').each_line do |line|
line.strip!
next if line.empty?
globs << line % EXTENSION_PATTERNS
end
end
if globs.empty?
log 'Error: No globs in globfile'
log USAGE
exit 1
end
files = {}
num_changed = 0
globs.each do |glob|
Dir[glob].each do |file|
next if !File.file?(file)
mtime = File.mtime(file).to_i
hash = Digest::MD5.hexdigest(File.read(file))
cached = cache[file]
if cached && cached['hash'] == hash && cached['mtime'] < mtime
mtime = cached['mtime']
log "mtime_cache: changing mtime of #{file} to #{mtime}", 1
File.utime(File.atime(file), Time.at(mtime), file) if !ARGS[:dry]
num_changed += 1
else
log "mtime_cache: NOT changing mtime of #{file}", 1
end
files[file] = { 'mtime' => mtime, 'hash' => hash }
end
end
log "Changed mtime of #{num_changed} of #{files.length} files"
log "Writing #{cache_file}"
if !ARGS[:dry]
dirname = File.dirname(cache_file)
unless File.directory?(dirname)
FileUtils.mkdir_p(dirname)
end
File.open(cache_file, 'w').write(JSON.pretty_generate(files))
end
Loading…
Cancel
Save