Browse Source

Merge branch 'monolithic-dft' of https://sselab.de/lab9/private/git/storm into monolithic-dft

Former-commit-id: 3176ffa15c
main
sjunges 9 years ago
parent
commit
27b57f055e
  1. 52
      CMakeLists.txt
  2. 9
      examples/dft/spare_symmetry.dft
  3. 21
      resources/3rdparty/CMakeLists.txt
  4. 9
      src/adapters/GmmxxAdapter.h
  5. 6
      src/builder/DdPrismModelBuilder.cpp
  6. 2
      src/builder/ExplicitDFTModelBuilder.h
  7. 6
      src/builder/ExplicitPrismModelBuilder.cpp
  8. 12
      src/cli/cli.cpp
  9. 28
      src/counterexamples/GenerateCounterexample.h
  10. 44
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  11. 42
      src/counterexamples/PathBasedSubsystemGenerator.h
  12. 84
      src/counterexamples/SMTMinimalCommandSetGenerator.h
  13. 14
      src/logic/AtomicExpressionFormula.cpp
  14. 4
      src/logic/AtomicExpressionFormula.h
  15. 14
      src/logic/AtomicLabelFormula.cpp
  16. 4
      src/logic/AtomicLabelFormula.h
  17. 6
      src/logic/BinaryBooleanStateFormula.cpp
  18. 2
      src/logic/BinaryBooleanStateFormula.h
  19. 38
      src/logic/BinaryPathFormula.cpp
  20. 10
      src/logic/BinaryPathFormula.h
  21. 38
      src/logic/BinaryStateFormula.cpp
  22. 10
      src/logic/BinaryStateFormula.h
  23. 22
      src/logic/BooleanLiteralFormula.cpp
  24. 6
      src/logic/BooleanLiteralFormula.h
  25. 18
      src/logic/BoundedUntilFormula.cpp
  26. 7
      src/logic/BoundedUntilFormula.h
  27. 59
      src/logic/ConditionalFormula.cpp
  28. 43
      src/logic/ConditionalFormula.h
  29. 24
      src/logic/ConditionalPathFormula.cpp
  30. 25
      src/logic/ConditionalPathFormula.h
  31. 10
      src/logic/CumulativeRewardFormula.cpp
  32. 9
      src/logic/CumulativeRewardFormula.h
  33. 36
      src/logic/EventuallyFormula.cpp
  34. 14
      src/logic/EventuallyFormula.h
  35. 14
      src/logic/ExpectedTimeOperatorFormula.cpp
  36. 8
      src/logic/ExpectedTimeOperatorFormula.h
  37. 107
      src/logic/Formula.cpp
  38. 122
      src/logic/Formula.h
  39. 12
      src/logic/FormulaContext.h
  40. 46
      src/logic/FormulaInformation.cpp
  41. 34
      src/logic/FormulaInformation.h
  42. 85
      src/logic/FormulaInformationVisitor.cpp
  43. 38
      src/logic/FormulaInformationVisitor.h
  44. 36
      src/logic/FormulaVisitor.h
  45. 4
      src/logic/Formulas.h
  46. 36
      src/logic/FormulasForwardDeclarations.h
  47. 207
      src/logic/FragmentChecker.cpp
  48. 39
      src/logic/FragmentChecker.h
  49. 359
      src/logic/FragmentSpecification.cpp
  50. 153
      src/logic/FragmentSpecification.h
  51. 10
      src/logic/GloballyFormula.cpp
  52. 5
      src/logic/GloballyFormula.h
  53. 10
      src/logic/InstantaneousRewardFormula.cpp
  54. 8
      src/logic/InstantaneousRewardFormula.h
  55. 14
      src/logic/LongRunAverageOperatorFormula.cpp
  56. 4
      src/logic/LongRunAverageOperatorFormula.h
  57. 10
      src/logic/LongRunAverageRewardFormula.cpp
  58. 12
      src/logic/LongRunAverageRewardFormula.h
  59. 8
      src/logic/NextFormula.cpp
  60. 5
      src/logic/NextFormula.h
  61. 24
      src/logic/ProbabilityOperatorFormula.cpp
  62. 8
      src/logic/ProbabilityOperatorFormula.h
  63. 35
      src/logic/ReachabilityRewardFormula.cpp
  64. 36
      src/logic/ReachabilityRewardFormula.h
  65. 20
      src/logic/RewardOperatorFormula.cpp
  66. 6
      src/logic/RewardOperatorFormula.h
  67. 9
      src/logic/RewardPathFormula.cpp
  68. 19
      src/logic/RewardPathFormula.h
  69. 6
      src/logic/UnaryBooleanStateFormula.cpp
  70. 2
      src/logic/UnaryBooleanStateFormula.h
  71. 34
      src/logic/UnaryPathFormula.cpp
  72. 9
      src/logic/UnaryPathFormula.h
  73. 38
      src/logic/UnaryStateFormula.cpp
  74. 10
      src/logic/UnaryStateFormula.h
  75. 10
      src/logic/UntilFormula.cpp
  76. 3
      src/logic/UntilFormula.h
  77. 122
      src/modelchecker/AbstractModelChecker.cpp
  78. 9
      src/modelchecker/AbstractModelChecker.h
  79. 6
      src/modelchecker/CheckTask.h
  80. 10
      src/modelchecker/csl/HybridCtmcCslModelChecker.cpp
  81. 2
      src/modelchecker/csl/HybridCtmcCslModelChecker.h
  82. 10
      src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
  83. 2
      src/modelchecker/csl/SparseCtmcCslModelChecker.h
  84. 14
      src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
  85. 2
      src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
  86. 10
      src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
  87. 2
      src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h
  88. 19
      src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
  89. 2
      src/modelchecker/prctl/HybridMdpPrctlModelChecker.h
  90. 52
      src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
  91. 10
      src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
  92. 37
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
  93. 4
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
  94. 20
      src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
  95. 2
      src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h
  96. 19
      src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
  97. 2
      src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h
  98. 120
      src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
  99. 12
      src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h
  100. 14
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

52
CMakeLists.txt

@ -28,6 +28,8 @@ option(USE_LIBCXX "Sets whether the standard library is libc++." OFF)
option(USE_CARL "Sets whether carl should be included." ON) option(USE_CARL "Sets whether carl should be included." ON)
option(FORCE_COLOR "Force color output" OFF) option(FORCE_COLOR "Force color output" OFF)
option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON) option(STORM_COMPILE_WITH_CCACHE "Compile using CCache" ON)
option(STORM_LOGGING_FRAMEWORK "Use a framework for logging" OFF)
option(STORM_LOG_DISABLE_DEBUG "Disable log and trace message support" OFF)
set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).") set(GUROBI_ROOT "" CACHE STRING "A hint to the root directory of Gurobi (optional).")
set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).") set(Z3_ROOT "" CACHE STRING "A hint to the root directory of Z3 (optional).")
set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.") set(CUDA_ROOT "" CACHE STRING "The root directory of CUDA.")
@ -259,8 +261,6 @@ endif(STORM_HAVE_Z3)
set(STORM_HAVE_GLPK 1) set(STORM_HAVE_GLPK 1)
message (STATUS "StoRM - Linking with glpk") message (STATUS "StoRM - Linking with glpk")
set(GLPK_LIBRARIES ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT})
set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include)
include_directories(${GLPK_INCLUDE_DIR}) include_directories(${GLPK_INCLUDE_DIR})
list(APPEND STORM_LINK_LIBRARIES ${GLPK_LIBRARIES}) list(APPEND STORM_LINK_LIBRARIES ${GLPK_LIBRARIES})
@ -537,28 +537,15 @@ endif()
## ##
############################################################# #############################################################
set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan")
ExternalProject_Add(
sylvan
DOWNLOAD_COMMAND ""
PREFIX "sylvan"
SOURCE_DIR "${STORM_SYLVAN_ROOT}"
CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release
BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan"
INSTALL_COMMAND ""
INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan"
)
ExternalProject_Get_Property(sylvan binary_dir)
set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src")
message(STATUS "Linking with shipped version of sylvan (in directory ${STORM_SYLVAN_ROOT}).") message(STATUS "Linking with shipped version of sylvan (in directory ${STORM_SYLVAN_ROOT}).")
include_directories("${Sylvan_INCLUDE_DIR}") include_directories("${Sylvan_INCLUDE_DIR}")
list(APPEND STORM_LINK_LIBRARIES "${binary_dir}/src/libsylvan.a") list(APPEND STORM_LINK_LIBRARIES ${Sylvan_LIBRARY})
if(${OPERATING_SYSTEM} MATCHES "Linux") if(${OPERATING_SYSTEM} MATCHES "Linux")
find_package(Hwloc QUIET) find_package(Hwloc QUIET)
if(NOT Hwloc_FOUND) if(NOT Hwloc_FOUND)
message(SEND_ERROR "HWLOC is required but was not found.") message(SEND_ERROR "HWLOC is required but was not found.")
else() else()
list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES}) list(APPEND STORM_LINK_LIBRARIES ${Hwloc_LIBRARIES})
endif() endif()
endif() endif()
@ -573,20 +560,21 @@ endif()
## Log4CPlus ## Log4CPlus
## ##
############################################################# #############################################################
set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library") if(STORM_LOGGING_FRAMEWORK)
set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF) set(BUILD_SHARED_LIBS OFF CACHE BOOL "If TRUE, log4cplus is built as a shared library, otherwise as a static library")
set(LOG4CPLUS_BUILD_TESTING OFF) set(LOG4CPLUS_BUILD_LOGGINGSERVER OFF)
set(LOG4CPLUS_USE_UNICODE OFF) set(LOG4CPLUS_BUILD_TESTING OFF)
set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF) set(LOG4CPLUS_USE_UNICODE OFF)
add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1") set(LOG4CPLUS_DEFINE_INSTALL_TARGET OFF)
include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") add_subdirectory("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1")
include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file include_directories("${PROJECT_SOURCE_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include")
include_directories("${PROJECT_BINARY_DIR}/resources/3rdparty/log4cplus-1.1.3-rc1/include") # This adds the defines.hxx file
list(APPEND STORM_LINK_LIBRARIES log4cplusS) list(APPEND STORM_LINK_LIBRARIES log4cplusS)
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
list(APPEND STORM_LINK_LIBRARIES rt) list(APPEND STORM_LINK_LIBRARIES rt)
endif(UNIX AND NOT APPLE) endif(UNIX AND NOT APPLE)
endif()
############################################################# #############################################################
## ##
## Intel Threading Building Blocks (optional) ## Intel Threading Building Blocks (optional)

9
examples/dft/spare_symmetry.dft

@ -0,0 +1,9 @@
toplevel "A";
"A" and "B" "C";
"B" wsp "I" "J";
"C" wsp "K" "L";
"I" lambda=0.5 dorm=0.3;
"J" lambda=0.5 dorm=0.3;
"K" lambda=0.5 dorm=0.3;
"L" lambda=0.5 dorm=0.3;

21
resources/3rdparty/CMakeLists.txt

@ -32,6 +32,8 @@ ExternalProject_Add(
) )
add_dependencies(resources glpk) add_dependencies(resources glpk)
set(GLPK_LIBRARIES ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/lib/libglpk${DYNAMIC_EXT} PARENT_SCOPE)
set(GLPK_INCLUDE_DIR ${CMAKE_BINARY_DIR}/resources/3rdparty/glpk-4.57/include PARENT_SCOPE)
ExternalProject_Add( ExternalProject_Add(
cudd3 cudd3
@ -42,6 +44,9 @@ ExternalProject_Add(
BUILD_COMMAND make "CFLAGS=-O2 -w" BUILD_COMMAND make "CFLAGS=-O2 -w"
INSTALL_COMMAND make install INSTALL_COMMAND make install
BUILD_IN_SOURCE 0 BUILD_IN_SOURCE 0
LOG_CONFIGURE ON
LOG_BUILD ON
LOG_INSTALL ON
) )
add_dependencies(resources cudd3) add_dependencies(resources cudd3)
@ -51,6 +56,22 @@ set(CUDD3_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/include PARENT_SCOP
set(CUDD3_SHARED_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/lib/libcudd${DYNAMIC_EXT} PARENT_SCOPE) set(CUDD3_SHARED_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/lib/libcudd${DYNAMIC_EXT} PARENT_SCOPE)
set(CUDD3_STATIC_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/liblibcudd${STATIC_EXT} PARENT_SCOPE) set(CUDD3_STATIC_LIBRARIES ${CMAKE_CURRENT_BINARY_DIR}/cudd-3.0.0/liblibcudd${STATIC_EXT} PARENT_SCOPE)
set(STORM_SYLVAN_ROOT "${PROJECT_SOURCE_DIR}/resources/3rdparty/sylvan")
ExternalProject_Add(
sylvan
DOWNLOAD_COMMAND ""
PREFIX "sylvan"
SOURCE_DIR "${STORM_SYLVAN_ROOT}"
CMAKE_ARGS -DSYLVAN_BUILD_TEST=Off -DSYLVAN_BUILD_EXAMPLES=Off -DCMAKE_BUILD_TYPE=Release
BINARY_DIR "${PROJECT_BINARY_DIR}/sylvan"
INSTALL_COMMAND ""
INSTALL_DIR "${PROJECT_BINARY_DIR}/sylvan"
)
ExternalProject_Get_Property(sylvan binary_dir)
set(Sylvan_INCLUDE_DIR "${STORM_SYLVAN_ROOT}/src" PARENT_SCOPE)
set(Sylvan_LIBRARY "${binary_dir}/src/libsylvan.a" PARENT_SCOPE)
ExternalProject_Add( ExternalProject_Add(
googletest googletest
#For downloads (may be useful later!) #For downloads (may be useful later!)

9
src/adapters/GmmxxAdapter.h

@ -16,10 +16,7 @@
#include "src/storage/SparseMatrix.h" #include "src/storage/SparseMatrix.h"
#include "src/utility/ConversionHelper.h" #include "src/utility/ConversionHelper.h"
#include "log4cplus/logger.h" #include "src/utility/macros.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace storm { namespace storm {
@ -34,7 +31,7 @@ public:
template<class T> template<class T>
static std::unique_ptr<gmm::csr_matrix<T>> toGmmxxSparseMatrix(storm::storage::SparseMatrix<T> const& matrix) { static std::unique_ptr<gmm::csr_matrix<T>> toGmmxxSparseMatrix(storm::storage::SparseMatrix<T> const& matrix) {
uint_fast64_t realNonZeros = matrix.getEntryCount(); uint_fast64_t realNonZeros = matrix.getEntryCount();
LOG4CPLUS_DEBUG(logger, "Converting matrix with " << realNonZeros << " non-zeros to gmm++ format."); STORM_LOG_DEBUG("Converting matrix with " << realNonZeros << " non-zeros to gmm++ format.");
// Prepare the resulting matrix. // Prepare the resulting matrix.
std::unique_ptr<gmm::csr_matrix<T>> result(new gmm::csr_matrix<T>(matrix.getRowCount(), matrix.getColumnCount())); std::unique_ptr<gmm::csr_matrix<T>> result(new gmm::csr_matrix<T>(matrix.getRowCount(), matrix.getColumnCount()));
@ -58,7 +55,7 @@ public:
std::swap(result->ir, columns); std::swap(result->ir, columns);
std::swap(result->pr, values); std::swap(result->pr, values);
LOG4CPLUS_DEBUG(logger, "Done converting matrix to gmm++ format."); STORM_LOG_DEBUG("Done converting matrix to gmm++ format.");
return result; return result;
} }

6
src/builder/DdPrismModelBuilder.cpp

@ -227,10 +227,8 @@ namespace storm {
// If we are not required to build all reward models, we determine the reward models we need to build. // If we are not required to build all reward models, we determine the reward models we need to build.
if (!buildAllRewardModels) { if (!buildAllRewardModels) {
if (formula.containsRewardOperator()) { std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
}
} }
// Extract all the labels used in the formula. // Extract all the labels used in the formula.

2
src/builder/ExplicitDFTModelBuilder.h

@ -76,4 +76,4 @@ namespace storm {
} }
} }
#endif /* EXPLICITDFTMODELBUILDER_H */ #endif /* EXPLICITDFTMODELBUILDER_H */

6
src/builder/ExplicitPrismModelBuilder.cpp

@ -185,10 +185,8 @@ namespace storm {
// If we are not required to build all reward models, we determine the reward models we need to build. // If we are not required to build all reward models, we determine the reward models we need to build.
if (!buildAllRewardModels) { if (!buildAllRewardModels) {
if (formula.containsRewardOperator()) { std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels();
std::set<std::string> referencedRewardModels = formula.getReferencedRewardModels(); rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
rewardModelsToBuild.insert(referencedRewardModels.begin(), referencedRewardModels.end());
}
} }
// Extract all the labels used in the formula. // Extract all the labels used in the formula.

12
src/cli/cli.cpp

@ -186,18 +186,14 @@ namespace storm {
} }
if (storm::settings::generalSettings().isVerboseSet()) { if (storm::settings::generalSettings().isVerboseSet()) {
logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); STORM_GLOBAL_LOGLEVEL_INFO();
LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console.");
} }
if (storm::settings::debugSettings().isDebugSet()) { if (storm::settings::debugSettings().isDebugSet()) {
logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); STORM_GLOBAL_LOGLEVEL_DEBUG();
logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL);
LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console.");
} }
if (storm::settings::debugSettings().isTraceSet()) { if (storm::settings::debugSettings().isTraceSet()) {
logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); STORM_GLOBAL_LOGLEVEL_TRACE();
logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL);
LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console.");
} }
if (storm::settings::debugSettings().isLogfileSet()) { if (storm::settings::debugSettings().isLogfileSet()) {
storm::utility::initializeFileLogging(); storm::utility::initializeFileLogging();

28
src/counterexamples/GenerateCounterexample.h

@ -24,20 +24,20 @@
* @param parser An AutoParser to get the model from. * @param parser An AutoParser to get the model from.
*/ */
void generateCounterExample(std::shared_ptr<storm::models::sparse::Model<double>> model) { void generateCounterExample(std::shared_ptr<storm::models::sparse::Model<double>> model) {
LOG4CPLUS_INFO(logger, "Starting counterexample generation."); STORM_LOG_INFO("Starting counterexample generation.");
LOG4CPLUS_INFO(logger, "Testing inputs..."); STORM_LOG_INFO("Testing inputs...");
storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance();
// First test output directory. // First test output directory.
std::string outPath = s->getOptionByLongName("counterExample").getArgument(0).getValueAsString(); std::string outPath = s->getOptionByLongName("counterExample").getArgument(0).getValueAsString();
if(outPath.back() != '/' && outPath.back() != '\\') { if(outPath.back() != '/' && outPath.back() != '\\') {
LOG4CPLUS_ERROR(logger, "The output path is not valid."); STORM_LOG_ERROR("The output path is not valid.");
return; return;
} }
std::ofstream testFile(outPath + "test.dot"); std::ofstream testFile(outPath + "test.dot");
if(testFile.fail()) { if(testFile.fail()) {
LOG4CPLUS_ERROR(logger, "The output path is not valid."); STORM_LOG_ERROR("The output path is not valid.");
return; return;
} }
testFile.close(); testFile.close();
@ -45,7 +45,7 @@
// Differentiate between model types. // Differentiate between model types.
if(model->getType() != storm::models::DTMC) { if(model->getType() != storm::models::DTMC) {
LOG4CPLUS_ERROR(logger, "Counterexample generation for the selected model type is not supported."); STORM_LOG_ERROR("Counterexample generation for the selected model type is not supported.");
return; return;
} }
@ -53,21 +53,21 @@
// Note that the ownership of the object referenced by dtmc lies at the main function. // Note that the ownership of the object referenced by dtmc lies at the main function.
// Thus, it must not be deleted. // Thus, it must not be deleted.
storm::models::Dtmc<double> dtmc = *(model->as<storm::models::Dtmc<double>>()); storm::models::Dtmc<double> dtmc = *(model->as<storm::models::Dtmc<double>>());
LOG4CPLUS_INFO(logger, "Model is a DTMC."); STORM_LOG_INFO("Model is a DTMC.");
// Get specified PRCTL formulas. // Get specified PRCTL formulas.
if(!s->isSet("prctl")) { if(!s->isSet("prctl")) {
LOG4CPLUS_ERROR(logger, "No PRCTL formula file specified."); STORM_LOG_ERROR("No PRCTL formula file specified.");
return; return;
} }
std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString();
LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); STORM_LOG_INFO("Parsing prctl file: " << chosenPrctlFile << ".");
std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile);
// Test for each formula if a counterexample can be generated for it. // Test for each formula if a counterexample can be generated for it.
if(formulaList.size() == 0) { if(formulaList.size() == 0) {
LOG4CPLUS_ERROR(logger, "No PRCTL formula found."); STORM_LOG_ERROR("No PRCTL formula found.");
return; return;
} }
@ -94,7 +94,7 @@
// First check if it is a formula type for which a counterexample can be generated. // First check if it is a formula type for which a counterexample can be generated.
if (std::dynamic_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) { if (std::dynamic_pointer_cast<storm::properties::prctl::AbstractStateFormula<double>>(formula->getChild()).get() == nullptr) {
LOG4CPLUS_ERROR(logger, "Unexpected kind of formula. Expected a state formula."); STORM_LOG_ERROR("Unexpected kind of formula. Expected a state formula.");
continue; continue;
} }
@ -102,9 +102,9 @@
// Do some output // Do some output
std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl; std::cout << "Generating counterexample for formula " << fIndex << ":" << std::endl;
LOG4CPLUS_INFO(logger, "Generating counterexample for formula " + std::to_string(fIndex) + ": "); STORM_LOG_INFO("Generating counterexample for formula " + std::to_string(fIndex) + ": ");
std::cout << "\t" << formula->toString() << "\n" << std::endl; std::cout << "\t" << formula->toString() << "\n" << std::endl;
LOG4CPLUS_INFO(logger, formula->toString()); STORM_LOG_INFO(formula->toString());
// Now check if the model does not satisfy the formula. // Now check if the model does not satisfy the formula.
// That is if there is at least one initial state of the model that does not. // That is if there is at least one initial state of the model that does not.
@ -117,14 +117,14 @@
if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) { if((result & dtmc.getInitialStates()).getNumberOfSetBits() == dtmc.getInitialStates().getNumberOfSetBits()) {
std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl; std::cout << "Formula is satisfied. Can not generate counterexample.\n\n" << std::endl;
LOG4CPLUS_INFO(logger, "Formula is satisfied. Can not generate counterexample."); STORM_LOG_INFO("Formula is satisfied. Can not generate counterexample.");
continue; continue;
} }
// Generate counterexample // Generate counterexample
storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(dtmc, stateForm); storm::models::Dtmc<double> counterExample = storm::counterexamples::PathBasedSubsystemGenerator<double>::computeCriticalSubsystem(dtmc, stateForm);
LOG4CPLUS_INFO(logger, "Found counterexample."); STORM_LOG_INFO("Found counterexample.");
// Output counterexample // Output counterexample
// Do standard output // Do standard output

44
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -98,10 +98,10 @@ namespace storm {
result.relevantStates &= ~psiStates; result.relevantStates &= ~psiStates;
result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates); result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates &= result.relevantStates; result.problematicStates &= result.relevantStates;
LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states."); STORM_LOG_DEBUG("Found " << phiStates.getNumberOfSetBits() << " filter states.");
LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states."); STORM_LOG_DEBUG("Found " << psiStates.getNumberOfSetBits() << " target states.");
LOG4CPLUS_DEBUG(logger, "Found " << result.relevantStates.getNumberOfSetBits() << " relevant states."); STORM_LOG_DEBUG("Found " << result.relevantStates.getNumberOfSetBits() << " relevant states.");
LOG4CPLUS_DEBUG(logger, "Found " << result.problematicStates.getNumberOfSetBits() << " problematic states."); STORM_LOG_DEBUG("Found " << result.problematicStates.getNumberOfSetBits() << " problematic states.");
return result; return result;
} }
@ -158,7 +158,7 @@ namespace storm {
// Finally, determine the set of labels that are known to be taken. // Finally, determine the set of labels that are known to be taken.
result.knownLabels = storm::utility::counterexamples::getGuaranteedLabelSet(labeledMdp, psiStates, result.allRelevantLabels); result.knownLabels = storm::utility::counterexamples::getGuaranteedLabelSet(labeledMdp, psiStates, result.allRelevantLabels);
LOG4CPLUS_DEBUG(logger, "Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels."); STORM_LOG_DEBUG("Found " << result.allRelevantLabels.size() << " relevant labels and " << result.knownLabels.size() << " known labels.");
return result; return result;
} }
@ -364,47 +364,47 @@ namespace storm {
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels); std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
result.labelToVariableMap = std::move(labelVariableResult.first); result.labelToVariableMap = std::move(labelVariableResult.first);
result.numberOfVariables += labelVariableResult.second; result.numberOfVariables += labelVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for labels."); STORM_LOG_DEBUG("Created variables for labels.");
// Create scheduler variables for relevant states and their actions. // Create scheduler variables for relevant states and their actions.
std::pair<std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation); std::pair<std::unordered_map<uint_fast64_t, std::list<storm::expressions::Variable>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first); result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first);
result.numberOfVariables += schedulerVariableResult.second; result.numberOfVariables += schedulerVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for nondeterministic choices."); STORM_LOG_DEBUG("Created variables for nondeterministic choices.");
// Create scheduler variables for nondeterministically choosing an initial state. // Create scheduler variables for nondeterministically choosing an initial state.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation); std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first); result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first);
result.numberOfVariables += initialChoiceVariableResult.second; result.numberOfVariables += initialChoiceVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the nondeterministic choice of the initial state."); STORM_LOG_DEBUG("Created variables for the nondeterministic choice of the initial state.");
// Create variables for probabilities for all relevant states. // Create variables for probabilities for all relevant states.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation); std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first); result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first);
result.numberOfVariables += probabilityVariableResult.second; result.numberOfVariables += probabilityVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities."); STORM_LOG_DEBUG("Created variables for the reachability probabilities.");
// Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state. // Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state.
std::pair<storm::expressions::Variable, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver); std::pair<storm::expressions::Variable, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
result.virtualInitialStateVariable = virtualInitialStateVariableResult.first; result.virtualInitialStateVariable = virtualInitialStateVariableResult.first;
result.numberOfVariables += virtualInitialStateVariableResult.second; result.numberOfVariables += virtualInitialStateVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state."); STORM_LOG_DEBUG("Created variables for the virtual initial state.");
// Create variables for problematic states. // Create variables for problematic states.
std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation); std::pair<std::unordered_map<uint_fast64_t, storm::expressions::Variable>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first); result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first);
result.numberOfVariables += problematicStateVariableResult.second; result.numberOfVariables += problematicStateVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the problematic states."); STORM_LOG_DEBUG("Created variables for the problematic states.");
// Create variables for problematic choices. // Create variables for problematic choices.
std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation); std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, storm::expressions::Variable, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first; result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first;
result.numberOfVariables += problematicTransitionVariableResult.second; result.numberOfVariables += problematicTransitionVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the problematic choices."); STORM_LOG_DEBUG("Created variables for the problematic choices.");
// Finally, we need to update the model to make the new variables usable. // Finally, we need to update the model to make the new variables usable.
solver.update(); solver.update();
LOG4CPLUS_INFO(logger, "Successfully created " << result.numberOfVariables << " MILP variables."); STORM_LOG_INFO("Successfully created " << result.numberOfVariables << " MILP variables.");
// Finally, return variable information struct. // Finally, return variable information struct.
return result; return result;
@ -816,43 +816,43 @@ namespace storm {
static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) { static void buildConstraintSystem(storm::solver::LpSolver& solver, storm::models::sparse::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound, bool includeSchedulerCuts = false) {
// Assert that the reachability probability in the subsystem exceeds the given threshold. // Assert that the reachability probability in the subsystem exceeds the given threshold.
uint_fast64_t numberOfConstraints = assertProbabilityGreaterThanThreshold(solver, labeledMdp, variableInformation, probabilityThreshold, strictBound); uint_fast64_t numberOfConstraints = assertProbabilityGreaterThanThreshold(solver, labeledMdp, variableInformation, probabilityThreshold, strictBound);
LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability exceeds threshold."); STORM_LOG_DEBUG("Asserted that reachability probability exceeds threshold.");
// Add constraints that assert the policy takes at most one action in each state. // Add constraints that assert the policy takes at most one action in each state.
numberOfConstraints += assertValidPolicy(solver, stateInformation, variableInformation); numberOfConstraints += assertValidPolicy(solver, stateInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted that policy is valid."); STORM_LOG_DEBUG("Asserted that policy is valid.");
// Add constraints that assert the labels that belong to some taken choices are taken as well. // Add constraints that assert the labels that belong to some taken choices are taken as well.
numberOfConstraints += assertChoicesImplyLabels(solver, labeledMdp, stateInformation, choiceInformation, variableInformation); numberOfConstraints += assertChoicesImplyLabels(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted that labels implied by choices are taken."); STORM_LOG_DEBUG("Asserted that labels implied by choices are taken.");
// Add constraints that encode that the reachability probability from states which do not pick any action // Add constraints that encode that the reachability probability from states which do not pick any action
// is zero. // is zero.
numberOfConstraints += assertZeroProbabilityWithoutChoice(solver, stateInformation, choiceInformation, variableInformation); numberOfConstraints += assertZeroProbabilityWithoutChoice(solver, stateInformation, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted that reachability probability is zero if no choice is taken."); STORM_LOG_DEBUG("Asserted that reachability probability is zero if no choice is taken.");
// Add constraints that encode the reachability probabilities for states. // Add constraints that encode the reachability probabilities for states.
numberOfConstraints += assertReachabilityProbabilities(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation); numberOfConstraints += assertReachabilityProbabilities(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted constraints for reachability probabilities."); STORM_LOG_DEBUG("Asserted constraints for reachability probabilities.");
// Add constraints that ensure the reachability of an unproblematic state from each problematic state. // Add constraints that ensure the reachability of an unproblematic state from each problematic state.
numberOfConstraints += assertUnproblematicStateReachable(solver, labeledMdp, stateInformation, choiceInformation, variableInformation); numberOfConstraints += assertUnproblematicStateReachable(solver, labeledMdp, stateInformation, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted that unproblematic state reachable from problematic states."); STORM_LOG_DEBUG("Asserted that unproblematic state reachable from problematic states.");
// Add constraints that express that certain labels are already known to be taken. // Add constraints that express that certain labels are already known to be taken.
numberOfConstraints += assertKnownLabels(solver, labeledMdp, psiStates, choiceInformation, variableInformation); numberOfConstraints += assertKnownLabels(solver, labeledMdp, psiStates, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted known labels are taken."); STORM_LOG_DEBUG("Asserted known labels are taken.");
// If required, assert additional constraints that reduce the number of possible policies. // If required, assert additional constraints that reduce the number of possible policies.
if (includeSchedulerCuts) { if (includeSchedulerCuts) {
numberOfConstraints += assertSchedulerCuts(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation); numberOfConstraints += assertSchedulerCuts(solver, labeledMdp, psiStates, stateInformation, choiceInformation, variableInformation);
LOG4CPLUS_DEBUG(logger, "Asserted scheduler cuts."); STORM_LOG_DEBUG("Asserted scheduler cuts.");
} }
// Finally, we can tell the solver to incorporate the latest changes. // Finally, we can tell the solver to incorporate the latest changes.
solver.update(); solver.update();
LOG4CPLUS_INFO(logger, "Successfully created " << numberOfConstraints << " MILP constraints."); STORM_LOG_INFO("Successfully created " << numberOfConstraints << " MILP constraints.");
} }
/*! /*!

42
src/counterexamples/PathBasedSubsystemGenerator.h

@ -100,7 +100,7 @@ public:
} }
} }
LOG4CPLUS_DEBUG(logger, "Initialized."); STORM_LOG_DEBUG("Initialized.");
//Now find the shortest distances to all states //Now find the shortest distances to all states
while(!activeSet.empty()) { while(!activeSet.empty()) {
@ -151,7 +151,7 @@ public:
} }
} }
LOG4CPLUS_DEBUG(logger, "Discovery done."); STORM_LOG_DEBUG("Discovery done.");
} }
/*! /*!
@ -215,7 +215,7 @@ public:
} }
} }
LOG4CPLUS_DEBUG(logger, "Initialized."); STORM_LOG_DEBUG("Initialized.");
//Now find the shortest distances to all states //Now find the shortest distances to all states
while(!activeSet.empty()) { while(!activeSet.empty()) {
@ -269,7 +269,7 @@ public:
} }
} }
LOG4CPLUS_DEBUG(logger, "Discovery done."); STORM_LOG_DEBUG("Discovery done.");
} }
/*! /*!
@ -324,7 +324,7 @@ public:
if(distances[bestIndex].second == (T) -1){ if(distances[bestIndex].second == (T) -1){
shortestPath.push_back(bestIndex); shortestPath.push_back(bestIndex);
probability = (T) 0; probability = (T) 0;
LOG4CPLUS_DEBUG(logger, "Terminal state not viable!"); STORM_LOG_DEBUG("Terminal state not viable!");
return; return;
} }
@ -338,8 +338,8 @@ public:
bestIndex = distances[bestIndex].first; bestIndex = distances[bestIndex].first;
} }
LOG4CPLUS_DEBUG(logger, "Found best state: " << bestIndex); STORM_LOG_DEBUG("Found best state: " << bestIndex);
LOG4CPLUS_DEBUG(logger, "Value: " << bestValue); STORM_LOG_DEBUG("Value: " << bestValue);
shortestPath.push_back(bestIndex); shortestPath.push_back(bestIndex);
bestIndex = distances[bestIndex].first; bestIndex = distances[bestIndex].first;
@ -382,9 +382,9 @@ public:
//------------------------------------------------------------- //-------------------------------------------------------------
#ifdef BENCHMARK #ifdef BENCHMARK
LOG4CPLUS_INFO(logger, "Formula: " << stateFormula.toString()); STORM_LOG_INFO("Formula: " << stateFormula.toString());
#endif #endif
LOG4CPLUS_INFO(logger, "Start finding critical subsystem."); STORM_LOG_INFO("Start finding critical subsystem.");
// make model checker // make model checker
// TODO: Implement and use generic Model Checker factory. // TODO: Implement and use generic Model Checker factory.
@ -397,7 +397,7 @@ public:
std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<T>>(stateFormula); std::shared_ptr<storm::properties::prctl::ProbabilisticBoundOperator<T>> boundOperator = std::dynamic_pointer_cast<storm::properties::prctl::ProbabilisticBoundOperator<T>>(stateFormula);
if(boundOperator == nullptr){ if(boundOperator == nullptr){
LOG4CPLUS_ERROR(logger, "No path bound operator at formula root."); STORM_LOG_ERROR("No path bound operator at formula root.");
return model.getSubDtmc(subSys); return model.getSubDtmc(subSys);
} }
T bound = boundOperator->getBound(); T bound = boundOperator->getBound();
@ -440,7 +440,7 @@ public:
targetStates = until->getRight()->check(modelCheck); targetStates = until->getRight()->check(modelCheck);
} }
else { else {
LOG4CPLUS_ERROR(logger, "Strange path formula. Can't decipher."); STORM_LOG_ERROR("Strange path formula. Can't decipher.");
return model.getSubDtmc(subSys); return model.getSubDtmc(subSys);
} }
@ -476,11 +476,11 @@ public:
if((initStates & targetStates).getNumberOfSetBits() != 0) { if((initStates & targetStates).getNumberOfSetBits() != 0) {
subSys.set(*(initStates & targetStates).begin()); subSys.set(*(initStates & targetStates).begin());
LOG4CPLUS_INFO(logger, "Critical subsystem found."); STORM_LOG_INFO("Critical subsystem found.");
LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount); STORM_LOG_INFO("Paths needed: " << pathCount);
LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits()); STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits());
LOG4CPLUS_INFO(logger, "Prob: " << 1); STORM_LOG_INFO("Prob: " << 1);
LOG4CPLUS_INFO(logger, "Model checks: " << mcCount); STORM_LOG_INFO("Model checks: " << mcCount);
return model.getSubDtmc(subSys); return model.getSubDtmc(subSys);
} }
@ -555,11 +555,11 @@ public:
} }
} }
LOG4CPLUS_INFO(logger, "Critical subsystem found."); STORM_LOG_INFO("Critical subsystem found.");
LOG4CPLUS_INFO(logger, "Paths needed: " << pathCount); STORM_LOG_INFO("Paths needed: " << pathCount);
LOG4CPLUS_INFO(logger, "State count of critical subsystem: " << subSys.getNumberOfSetBits()); STORM_LOG_INFO("State count of critical subsystem: " << subSys.getNumberOfSetBits());
LOG4CPLUS_INFO(logger, "Prob: " << subSysProb); STORM_LOG_INFO("Prob: " << subSysProb);
LOG4CPLUS_INFO(logger, "Model checks: " << mcCount); STORM_LOG_INFO("Model checks: " << mcCount);
return model.getSubDtmc(subSys); return model.getSubDtmc(subSys);
} }

84
src/counterexamples/SMTMinimalCommandSetGenerator.h

@ -99,8 +99,8 @@ namespace storm {
relevancyInformation.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates); relevancyInformation.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
relevancyInformation.relevantStates &= ~psiStates; relevancyInformation.relevantStates &= ~psiStates;
LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states."); STORM_LOG_DEBUG("Found " << relevancyInformation.relevantStates.getNumberOfSetBits() << " relevant states.");
LOG4CPLUS_DEBUG(logger, relevancyInformation.relevantStates); STORM_LOG_DEBUG(relevancyInformation.relevantStates);
// Retrieve some references for convenient access. // Retrieve some references for convenient access.
storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix(); storm::storage::SparseMatrix<T> const& transitionMatrix = labeledMdp.getTransitionMatrix();
@ -141,7 +141,7 @@ namespace storm {
std::cout << "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels." << std::endl; std::cout << "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels." << std::endl;
LOG4CPLUS_DEBUG(logger, "Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels."); STORM_LOG_DEBUG("Found " << relevancyInformation.relevantLabels.size() << " relevant and " << relevancyInformation.knownLabels.size() << " known labels.");
return relevancyInformation; return relevancyInformation;
} }
@ -350,9 +350,9 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Successfully gathered data for explicit cuts."); STORM_LOG_DEBUG("Successfully gathered data for explicit cuts.");
LOG4CPLUS_DEBUG(logger, "Asserting initial combination is taken."); STORM_LOG_DEBUG("Asserting initial combination is taken.");
{ {
std::vector<storm::expressions::Expression> formulae; std::vector<storm::expressions::Expression> formulae;
@ -378,7 +378,7 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Asserting target combination is taken."); STORM_LOG_DEBUG("Asserting target combination is taken.");
{ {
std::vector<storm::expressions::Expression> formulae; std::vector<storm::expressions::Expression> formulae;
@ -414,7 +414,7 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Asserting taken labels are followed by another label if they are not a target label."); STORM_LOG_DEBUG("Asserting taken labels are followed by another label if they are not a target label.");
// Now assert that for each non-target label, we take a following label. // Now assert that for each non-target label, we take a following label.
for (auto const& labelSetFollowingSetsPair : followingLabels) { for (auto const& labelSetFollowingSetsPair : followingLabels) {
std::vector<storm::expressions::Expression> formulae; std::vector<storm::expressions::Expression> formulae;
@ -502,7 +502,7 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Asserting synchronization cuts."); STORM_LOG_DEBUG("Asserting synchronization cuts.");
// Finally, assert that if we take one of the synchronizing labels, we also take one of the combinations // Finally, assert that if we take one of the synchronizing labels, we also take one of the combinations
// the label appears in. // the label appears in.
for (auto const& labelSynchronizingSetsPair : synchronizingLabels) { for (auto const& labelSynchronizingSetsPair : synchronizingLabels) {
@ -667,7 +667,7 @@ namespace storm {
// If the solver reports unsat, then we know that the current selection is not enabled in the initial state. // If the solver reports unsat, then we know that the current selection is not enabled in the initial state.
if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) { if (checkResult == storm::solver::SmtSolver::CheckResult::Unsat) {
LOG4CPLUS_DEBUG(logger, "Selection not enabled in initial state."); STORM_LOG_DEBUG("Selection not enabled in initial state.");
storm::expressions::Expression guardConjunction; storm::expressions::Expression guardConjunction;
if (currentCommandVector.size() == 1) { if (currentCommandVector.size() == 1) {
guardConjunction = currentCommandVector.begin()->get().getGuardExpression(); guardConjunction = currentCommandVector.begin()->get().getGuardExpression();
@ -685,10 +685,10 @@ namespace storm {
} }
} else { } else {
throw storm::exceptions::InvalidStateException() << "Choice label set is empty."; throw storm::exceptions::InvalidStateException() << "Choice label set is empty.";
LOG4CPLUS_DEBUG(logger, "Choice label set is empty."); STORM_LOG_DEBUG("Choice label set is empty.");
} }
LOG4CPLUS_DEBUG(logger, "About to assert disjunction of negated guards."); STORM_LOG_DEBUG("About to assert disjunction of negated guards.");
storm::expressions::Expression guardExpression = localManager.boolean(false); storm::expressions::Expression guardExpression = localManager.boolean(false);
bool firstAssignment = true; bool firstAssignment = true;
for (auto const& command : currentCommandVector) { for (auto const& command : currentCommandVector) {
@ -699,7 +699,7 @@ namespace storm {
} }
} }
localSolver->add(guardExpression); localSolver->add(guardExpression);
LOG4CPLUS_DEBUG(logger, "Asserted disjunction of negated guards."); STORM_LOG_DEBUG("Asserted disjunction of negated guards.");
// Now check the possible preceding label sets for the essential ones. // Now check the possible preceding label sets for the essential ones.
for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) { for (auto const& precedingLabelSet : labelSetAndPrecedingLabelSetsPair.second) {
@ -742,10 +742,10 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "About to assert a weakest precondition."); STORM_LOG_DEBUG("About to assert a weakest precondition.");
storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap); storm::expressions::Expression wp = guardConjunction.substitute(currentUpdateCombinationMap);
formulae.push_back(wp); formulae.push_back(wp);
LOG4CPLUS_DEBUG(logger, "Asserted weakest precondition."); STORM_LOG_DEBUG("Asserted weakest precondition.");
// Now try to move iterators to the next position if possible. If we could properly move it, we can directly // Now try to move iterators to the next position if possible. If we could properly move it, we can directly
// move on to the next combination of updates. If we have to reset it to the start, we // move on to the next combination of updates. If we have to reset it to the start, we
@ -768,7 +768,7 @@ namespace storm {
// Now assert the disjunction of all weakest preconditions of all considered update combinations. // Now assert the disjunction of all weakest preconditions of all considered update combinations.
assertDisjunction(*localSolver, formulae, localManager); assertDisjunction(*localSolver, formulae, localManager);
LOG4CPLUS_DEBUG(logger, "Asserted disjunction of all weakest preconditions."); STORM_LOG_DEBUG("Asserted disjunction of all weakest preconditions.");
if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) { if (localSolver->check() == storm::solver::SmtSolver::CheckResult::Sat) {
backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet); backwardImplications[labelSetAndPrecedingLabelSetsPair.first].insert(precedingLabelSet);
@ -793,7 +793,7 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Asserting taken labels are preceded by another label if they are not an initial label."); STORM_LOG_DEBUG("Asserting taken labels are preceded by another label if they are not an initial label.");
// Now assert that for each non-target label, we take a following label. // Now assert that for each non-target label, we take a following label.
for (auto const& labelSetImplicationsPair : backwardImplications) { for (auto const& labelSetImplicationsPair : backwardImplications) {
std::vector<storm::expressions::Expression> formulae; std::vector<storm::expressions::Expression> formulae;
@ -1042,7 +1042,7 @@ namespace storm {
static std::vector<storm::expressions::Expression> createAdder(VariableInformation const& variableInformation, std::vector<storm::expressions::Expression> const& in1, std::vector<storm::expressions::Expression> const& in2) { static std::vector<storm::expressions::Expression> createAdder(VariableInformation const& variableInformation, std::vector<storm::expressions::Expression> const& in1, std::vector<storm::expressions::Expression> const& in2) {
// Sanity check for sizes of input. // Sanity check for sizes of input.
if (in1.size() != in2.size() || in1.size() == 0) { if (in1.size() != in2.size() || in1.size() == 0) {
LOG4CPLUS_ERROR(logger, "Illegal input to adder (" << in1.size() << ", " << in2.size() << ")."); STORM_LOG_ERROR("Illegal input to adder (" << in1.size() << ", " << in2.size() << ").");
throw storm::exceptions::InvalidArgumentException() << "Illegal input to adder."; throw storm::exceptions::InvalidArgumentException() << "Illegal input to adder.";
} }
@ -1097,7 +1097,7 @@ namespace storm {
* @return A bit vector representing the number of literals that are set to true. * @return A bit vector representing the number of literals that are set to true.
*/ */
static std::vector<storm::expressions::Expression> createCounterCircuit(VariableInformation const& variableInformation, std::vector<storm::expressions::Variable> const& literals) { static std::vector<storm::expressions::Expression> createCounterCircuit(VariableInformation const& variableInformation, std::vector<storm::expressions::Variable> const& literals) {
LOG4CPLUS_DEBUG(logger, "Creating counter circuit for " << literals.size() << " literals."); STORM_LOG_DEBUG("Creating counter circuit for " << literals.size() << " literals.");
// Create the auxiliary vector. // Create the auxiliary vector.
std::vector<std::vector<storm::expressions::Expression>> aux; std::vector<std::vector<storm::expressions::Expression>> aux;
@ -1136,7 +1136,7 @@ namespace storm {
* @return The relaxation variable associated with the constraint. * @return The relaxation variable associated with the constraint.
*/ */
static storm::expressions::Variable assertLessOrEqualKRelaxed(storm::solver::SmtSolver& solver, VariableInformation const& variableInformation, uint64_t k) { static storm::expressions::Variable assertLessOrEqualKRelaxed(storm::solver::SmtSolver& solver, VariableInformation const& variableInformation, uint64_t k) {
LOG4CPLUS_DEBUG(logger, "Asserting solution has size less or equal " << k << "."); STORM_LOG_DEBUG("Asserting solution has size less or equal " << k << ".");
std::vector<storm::expressions::Variable> const& input = variableInformation.adderVariables; std::vector<storm::expressions::Variable> const& input = variableInformation.adderVariables;
@ -1209,16 +1209,16 @@ namespace storm {
} }
// Check whether the assumptions are satisfiable. // Check whether the assumptions are satisfiable.
LOG4CPLUS_DEBUG(logger, "Invoking satisfiability checking."); STORM_LOG_DEBUG("Invoking satisfiability checking.");
z3::check_result result = solver.check(assumptions); z3::check_result result = solver.check(assumptions);
LOG4CPLUS_DEBUG(logger, "Done invoking satisfiability checking."); STORM_LOG_DEBUG("Done invoking satisfiability checking.");
if (result == z3::sat) { if (result == z3::sat) {
return true; return true;
} else { } else {
LOG4CPLUS_DEBUG(logger, "Computing unsat core."); STORM_LOG_DEBUG("Computing unsat core.");
z3::expr_vector unsatCore = solver.unsat_core(); z3::expr_vector unsatCore = solver.unsat_core();
LOG4CPLUS_DEBUG(logger, "Computed unsat core."); STORM_LOG_DEBUG("Computed unsat core.");
std::vector<z3::expr> blockingVariables; std::vector<z3::expr> blockingVariables;
blockingVariables.reserve(unsatCore.size()); blockingVariables.reserve(unsatCore.size());
@ -1334,7 +1334,7 @@ namespace storm {
// As long as the constraints are unsatisfiable, we need to relax the last at-most-k constraint and // As long as the constraints are unsatisfiable, we need to relax the last at-most-k constraint and
// try with an increased bound. // try with an increased bound.
while (solver.checkWithAssumptions({assumption}) == storm::solver::SmtSolver::CheckResult::Unsat) { while (solver.checkWithAssumptions({assumption}) == storm::solver::SmtSolver::CheckResult::Unsat) {
LOG4CPLUS_DEBUG(logger, "Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound."); STORM_LOG_DEBUG("Constraint system is unsatisfiable with at most " << currentBound << " taken commands; increasing bound.");
solver.add(variableInformation.auxiliaryVariables.back()); solver.add(variableInformation.auxiliaryVariables.back());
variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(solver, variableInformation, ++currentBound)); variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(solver, variableInformation, ++currentBound));
assumption = !variableInformation.auxiliaryVariables.back(); assumption = !variableInformation.auxiliaryVariables.back();
@ -1359,7 +1359,7 @@ namespace storm {
static void analyzeZeroProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { static void analyzeZeroProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) {
storm::storage::BitVector reachableStates(subMdp.getNumberOfStates()); storm::storage::BitVector reachableStates(subMdp.getNumberOfStates());
LOG4CPLUS_DEBUG(logger, "Analyzing solution with zero probability."); STORM_LOG_DEBUG("Analyzing solution with zero probability.");
// Initialize the stack for the DFS. // Initialize the stack for the DFS.
bool targetStateIsReachable = false; bool targetStateIsReachable = false;
@ -1403,10 +1403,10 @@ namespace storm {
} }
} }
LOG4CPLUS_DEBUG(logger, "Successfully performed reachability analysis."); STORM_LOG_DEBUG("Successfully performed reachability analysis.");
if (targetStateIsReachable) { if (targetStateIsReachable) {
LOG4CPLUS_ERROR(logger, "Target must be unreachable for this analysis."); STORM_LOG_ERROR("Target must be unreachable for this analysis.");
throw storm::exceptions::InvalidStateException() << "Target must be unreachable for this analysis."; throw storm::exceptions::InvalidStateException() << "Target must be unreachable for this analysis.";
} }
@ -1417,7 +1417,7 @@ namespace storm {
std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), commandSet.begin(), commandSet.end(), std::inserter(locallyRelevantLabels, locallyRelevantLabels.begin())); std::set_difference(relevancyInformation.relevantLabels.begin(), relevancyInformation.relevantLabels.end(), commandSet.begin(), commandSet.end(), std::inserter(locallyRelevantLabels, locallyRelevantLabels.begin()));
std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedLabelSets = storm::utility::counterexamples::getGuaranteedLabelSets(originalMdp, statesThatCanReachTargetStates, locallyRelevantLabels); std::vector<boost::container::flat_set<uint_fast64_t>> guaranteedLabelSets = storm::utility::counterexamples::getGuaranteedLabelSets(originalMdp, statesThatCanReachTargetStates, locallyRelevantLabels);
LOG4CPLUS_DEBUG(logger, "Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states."); STORM_LOG_DEBUG("Found " << reachableLabels.size() << " reachable labels and " << reachableStates.getNumberOfSetBits() << " reachable states.");
// Search for states on the border of the reachable state space, i.e. states that are still reachable // Search for states on the border of the reachable state space, i.e. states that are still reachable
// and possess a (disabled) option to leave the reachable part of the state space. // and possess a (disabled) option to leave the reachable part of the state space.
@ -1466,7 +1466,7 @@ namespace storm {
formulae.push_back(cube); formulae.push_back(cube);
} }
LOG4CPLUS_DEBUG(logger, "Asserting reachability implications."); STORM_LOG_DEBUG("Asserting reachability implications.");
assertDisjunction(solver, formulae, *variableInformation.manager); assertDisjunction(solver, formulae, *variableInformation.manager);
} }
@ -1484,7 +1484,7 @@ namespace storm {
*/ */
static void analyzeInsufficientProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) { static void analyzeInsufficientProbabilitySolution(storm::solver::SmtSolver& solver, storm::models::sparse::Mdp<T> const& subMdp, storm::models::sparse::Mdp<T> const& originalMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, boost::container::flat_set<uint_fast64_t> const& commandSet, VariableInformation& variableInformation, RelevancyInformation const& relevancyInformation) {
LOG4CPLUS_DEBUG(logger, "Analyzing solution with insufficient probability."); STORM_LOG_DEBUG("Analyzing solution with insufficient probability.");
storm::storage::BitVector reachableStates(subMdp.getNumberOfStates()); storm::storage::BitVector reachableStates(subMdp.getNumberOfStates());
@ -1529,7 +1529,7 @@ namespace storm {
} }
} }
} }
LOG4CPLUS_DEBUG(logger, "Successfully determined reachable state space."); STORM_LOG_DEBUG("Successfully determined reachable state space.");
storm::storage::BitVector unreachableRelevantStates = ~reachableStates & relevancyInformation.relevantStates; storm::storage::BitVector unreachableRelevantStates = ~reachableStates & relevancyInformation.relevantStates;
storm::storage::BitVector statesThatCanReachTargetStates = storm::utility::graph::performProbGreater0E(subMdp.getTransitionMatrix(), subMdp.getNondeterministicChoiceIndices(), subMdp.getBackwardTransitions(), phiStates, psiStates); storm::storage::BitVector statesThatCanReachTargetStates = storm::utility::graph::performProbGreater0E(subMdp.getTransitionMatrix(), subMdp.getNondeterministicChoiceIndices(), subMdp.getBackwardTransitions(), phiStates, psiStates);
@ -1574,7 +1574,7 @@ namespace storm {
formulae.push_back(cube); formulae.push_back(cube);
} }
LOG4CPLUS_DEBUG(logger, "Asserting reachability implications."); STORM_LOG_DEBUG("Asserting reachability implications.");
assertDisjunction(solver, formulae, *variableInformation.manager); assertDisjunction(solver, formulae, *variableInformation.manager);
} }
#endif #endif
@ -1627,7 +1627,7 @@ namespace storm {
double maximalReachabilityProbability = 0; double maximalReachabilityProbability = 0;
if (checkThresholdFeasible) { if (checkThresholdFeasible) {
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
LOG4CPLUS_DEBUG(logger, "Invoking model checker."); STORM_LOG_DEBUG("Invoking model checker.");
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values); std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, labeledMdp.getTransitionMatrix(), labeledMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
for (auto state : labeledMdp.getInitialStates()) { for (auto state : labeledMdp.getInitialStates()) {
maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]); maximalReachabilityProbability = std::max(maximalReachabilityProbability, result[state]);
@ -1645,7 +1645,7 @@ namespace storm {
// (4) Create the variables for the relevant commands. // (4) Create the variables for the relevant commands.
VariableInformation variableInformation = createVariables(manager, labeledMdp, psiStates, relevancyInformation, includeReachabilityEncoding); VariableInformation variableInformation = createVariables(manager, labeledMdp, psiStates, relevancyInformation, includeReachabilityEncoding);
LOG4CPLUS_DEBUG(logger, "Created variables."); STORM_LOG_DEBUG("Created variables.");
// (5) Now assert an adder whose result variables can later be used to constrain the nummber of label // (5) Now assert an adder whose result variables can later be used to constrain the nummber of label
// variables that were set to true. Initially, we are looking for a solution that has no label enabled // variables that were set to true. Initially, we are looking for a solution that has no label enabled
@ -1654,14 +1654,14 @@ namespace storm {
variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(*solver, variableInformation, 0)); variableInformation.auxiliaryVariables.push_back(assertLessOrEqualKRelaxed(*solver, variableInformation, 0));
// (6) Add constraints that cut off a lot of suboptimal solutions. // (6) Add constraints that cut off a lot of suboptimal solutions.
LOG4CPLUS_DEBUG(logger, "Asserting cuts."); STORM_LOG_DEBUG("Asserting cuts.");
assertExplicitCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver); assertExplicitCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver);
LOG4CPLUS_DEBUG(logger, "Asserted explicit cuts."); STORM_LOG_DEBUG("Asserted explicit cuts.");
assertSymbolicCuts(preparedProgram, labeledMdp, variableInformation, relevancyInformation, *solver); assertSymbolicCuts(preparedProgram, labeledMdp, variableInformation, relevancyInformation, *solver);
LOG4CPLUS_DEBUG(logger, "Asserted symbolic cuts."); STORM_LOG_DEBUG("Asserted symbolic cuts.");
if (includeReachabilityEncoding) { if (includeReachabilityEncoding) {
assertReachabilityCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver); assertReachabilityCuts(labeledMdp, psiStates, variableInformation, relevancyInformation, *solver);
LOG4CPLUS_DEBUG(logger, "Asserted reachability cuts."); STORM_LOG_DEBUG("Asserted reachability cuts.");
} }
// As we are done with the setup at this point, stop the clock for the setup time. // As we are done with the setup at this point, stop the clock for the setup time.
@ -1680,20 +1680,20 @@ namespace storm {
maximalReachabilityProbability = 0; maximalReachabilityProbability = 0;
uint_fast64_t zeroProbabilityCount = 0; uint_fast64_t zeroProbabilityCount = 0;
do { do {
LOG4CPLUS_DEBUG(logger, "Computing minimal command set."); STORM_LOG_DEBUG("Computing minimal command set.");
solverClock = std::chrono::high_resolution_clock::now(); solverClock = std::chrono::high_resolution_clock::now();
commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound); commandSet = findSmallestCommandSet(*solver, variableInformation, currentBound);
totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock; totalSolverTime += std::chrono::high_resolution_clock::now() - solverClock;
LOG4CPLUS_DEBUG(logger, "Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << "."); STORM_LOG_DEBUG("Computed minimal command set of size " << (commandSet.size() + relevancyInformation.knownLabels.size()) << ".");
// Restrict the given MDP to the current set of labels and compute the reachability probability. // Restrict the given MDP to the current set of labels and compute the reachability probability.
modelCheckingClock = std::chrono::high_resolution_clock::now(); modelCheckingClock = std::chrono::high_resolution_clock::now();
commandSet.insert(relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end()); commandSet.insert(relevancyInformation.knownLabels.begin(), relevancyInformation.knownLabels.end());
storm::models::sparse::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet); storm::models::sparse::Mdp<T> subMdp = labeledMdp.restrictChoiceLabels(commandSet);
storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper; storm::modelchecker::helper::SparseMdpPrctlHelper<T> modelCheckerHelper;
LOG4CPLUS_DEBUG(logger, "Invoking model checker."); STORM_LOG_DEBUG("Invoking model checker.");
std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values); std::vector<T> result = std::move(modelCheckerHelper.computeUntilProbabilities(false, subMdp.getTransitionMatrix(), subMdp.getBackwardTransitions(), phiStates, psiStates, false, false, storm::utility::solver::MinMaxLinearEquationSolverFactory<T>()).values);
LOG4CPLUS_DEBUG(logger, "Computed model checking results."); STORM_LOG_DEBUG("Computed model checking results.");
totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock; totalModelCheckingTime += std::chrono::high_resolution_clock::now() - modelCheckingClock;
// Now determine the maximal reachability probability by checking all initial states. // Now determine the maximal reachability probability by checking all initial states.

14
src/logic/AtomicExpressionFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/AtomicExpressionFormula.h" #include "src/logic/AtomicExpressionFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
AtomicExpressionFormula::AtomicExpressionFormula(storm::expressions::Expression const& expression) : expression(expression) { AtomicExpressionFormula::AtomicExpressionFormula(storm::expressions::Expression const& expression) : expression(expression) {
@ -10,18 +12,10 @@ namespace storm {
return true; return true;
} }
bool AtomicExpressionFormula::isPctlStateFormula() const { boost::any AtomicExpressionFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return true; return visitor.visit(*this, data);
}
bool AtomicExpressionFormula::isLtlFormula() const {
return true;
} }
bool AtomicExpressionFormula::isPropositionalFormula() const {
return true;
}
storm::expressions::Expression const& AtomicExpressionFormula::getExpression() const { storm::expressions::Expression const& AtomicExpressionFormula::getExpression() const {
return expression; return expression;
} }

4
src/logic/AtomicExpressionFormula.h

@ -15,9 +15,7 @@ namespace storm {
virtual bool isAtomicExpressionFormula() const override; virtual bool isAtomicExpressionFormula() const override;
virtual bool isPctlStateFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool isLtlFormula() const override;
virtual bool isPropositionalFormula() const override;
storm::expressions::Expression const& getExpression() const; storm::expressions::Expression const& getExpression() const;

14
src/logic/AtomicLabelFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/AtomicLabelFormula.h" #include "src/logic/AtomicLabelFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
AtomicLabelFormula::AtomicLabelFormula(std::string const& label) : label(label) { AtomicLabelFormula::AtomicLabelFormula(std::string const& label) : label(label) {
@ -10,16 +12,8 @@ namespace storm {
return true; return true;
} }
bool AtomicLabelFormula::isPctlStateFormula() const { boost::any AtomicLabelFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return true; return visitor.visit(*this, data);
}
bool AtomicLabelFormula::isLtlFormula() const {
return true;
}
bool AtomicLabelFormula::isPropositionalFormula() const {
return true;
} }
std::string const& AtomicLabelFormula::getLabel() const { std::string const& AtomicLabelFormula::getLabel() const {

4
src/logic/AtomicLabelFormula.h

@ -17,9 +17,7 @@ namespace storm {
virtual bool isAtomicLabelFormula() const override; virtual bool isAtomicLabelFormula() const override;
virtual bool isPctlStateFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool isLtlFormula() const override;
virtual bool isPropositionalFormula() const override;
std::string const& getLabel() const; std::string const& getLabel() const;

6
src/logic/BinaryBooleanStateFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/BinaryBooleanStateFormula.h" #include "src/logic/BinaryBooleanStateFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
BinaryBooleanStateFormula::BinaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryStateFormula(leftSubformula, rightSubformula), operatorType(operatorType) { BinaryBooleanStateFormula::BinaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryStateFormula(leftSubformula, rightSubformula), operatorType(operatorType) {
@ -10,8 +12,8 @@ namespace storm {
return true; return true;
} }
bool BinaryBooleanStateFormula::isPropositionalFormula() const { boost::any BinaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return this->getLeftSubformula().isPropositionalFormula() && this->getRightSubformula().isPropositionalFormula(); return visitor.visit(*this, data);
} }
BinaryBooleanStateFormula::OperatorType BinaryBooleanStateFormula::getOperator() const { BinaryBooleanStateFormula::OperatorType BinaryBooleanStateFormula::getOperator() const {

2
src/logic/BinaryBooleanStateFormula.h

@ -19,7 +19,7 @@ namespace storm {
virtual bool isBinaryBooleanStateFormula() const override; virtual bool isBinaryBooleanStateFormula() const override;
virtual bool isPropositionalFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
OperatorType getOperator() const; OperatorType getOperator() const;

38
src/logic/BinaryPathFormula.cpp

@ -9,43 +9,7 @@ namespace storm {
bool BinaryPathFormula::isBinaryPathFormula() const { bool BinaryPathFormula::isBinaryPathFormula() const {
return true; return true;
} }
bool BinaryPathFormula::isPctlPathFormula() const {
return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
}
bool BinaryPathFormula::isCslPathFormula() const {
return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
}
bool BinaryPathFormula::isLtlFormula() const {
return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula();
}
bool BinaryPathFormula::containsBoundedUntilFormula() const {
return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula();
}
bool BinaryPathFormula::containsNextFormula() const {
return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula();
}
bool BinaryPathFormula::containsProbabilityOperator() const {
return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator();
}
bool BinaryPathFormula::containsNestedProbabilityOperators() const {
return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators();
}
bool BinaryPathFormula::containsRewardOperator() const {
return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator();
}
bool BinaryPathFormula::containsNestedRewardOperators() const {
return this->getLeftSubformula().containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators();
}
Formula const& BinaryPathFormula::getLeftSubformula() const { Formula const& BinaryPathFormula::getLeftSubformula() const {
return *leftSubformula; return *leftSubformula;
} }

10
src/logic/BinaryPathFormula.h

@ -17,16 +17,6 @@ namespace storm {
virtual bool isBinaryPathFormula() const override; virtual bool isBinaryPathFormula() const override;
virtual bool isPctlPathFormula() const override;
virtual bool isCslPathFormula() const override;
virtual bool isLtlFormula() const override;
virtual bool containsBoundedUntilFormula() const override;
virtual bool containsNextFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual bool containsRewardOperator() const override;
virtual bool containsNestedRewardOperators() const override;
Formula const& getLeftSubformula() const; Formula const& getLeftSubformula() const;
Formula const& getRightSubformula() const; Formula const& getRightSubformula() const;

38
src/logic/BinaryStateFormula.cpp

@ -9,43 +9,7 @@ namespace storm {
bool BinaryStateFormula::isBinaryStateFormula() const { bool BinaryStateFormula::isBinaryStateFormula() const {
return true; return true;
} }
bool BinaryStateFormula::isPctlStateFormula() const {
return this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
}
bool BinaryStateFormula::isCslStateFormula() const {
return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
}
bool BinaryStateFormula::isLtlFormula() const {
return this->getLeftSubformula().isLtlFormula() && this->getRightSubformula().isLtlFormula();
}
bool BinaryStateFormula::containsBoundedUntilFormula() const {
return this->getLeftSubformula().containsBoundedUntilFormula() || this->getRightSubformula().containsBoundedUntilFormula();
}
bool BinaryStateFormula::containsNextFormula() const {
return this->getLeftSubformula().containsNextFormula() || this->getRightSubformula().containsNextFormula();
}
bool BinaryStateFormula::containsProbabilityOperator() const {
return this->getLeftSubformula().containsProbabilityOperator() || this->getRightSubformula().containsProbabilityOperator();
}
bool BinaryStateFormula::containsNestedProbabilityOperators() const {
return this->getLeftSubformula().containsNestedProbabilityOperators() || this->getRightSubformula().containsNestedProbabilityOperators();
}
bool BinaryStateFormula::containsRewardOperator() const {
return this->getLeftSubformula().containsRewardOperator() || this->getRightSubformula().containsRewardOperator();
}
bool BinaryStateFormula::containsNestedRewardOperators() const {
return this->containsNestedRewardOperators() || this->getRightSubformula().containsNestedRewardOperators();
}
Formula const& BinaryStateFormula::getLeftSubformula() const { Formula const& BinaryStateFormula::getLeftSubformula() const {
return *leftSubformula; return *leftSubformula;
} }

10
src/logic/BinaryStateFormula.h

@ -15,16 +15,6 @@ namespace storm {
virtual bool isBinaryStateFormula() const override; virtual bool isBinaryStateFormula() const override;
virtual bool isPctlStateFormula() const override;
virtual bool isCslStateFormula() const override;
virtual bool isLtlFormula() const override;
virtual bool containsBoundedUntilFormula() const override;
virtual bool containsNextFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual bool containsRewardOperator() const override;
virtual bool containsNestedRewardOperators() const override;
Formula const& getLeftSubformula() const; Formula const& getLeftSubformula() const;
Formula const& getRightSubformula() const; Formula const& getRightSubformula() const;

22
src/logic/BooleanLiteralFormula.cpp

@ -1,11 +1,17 @@
#include "src/logic/BooleanLiteralFormula.h" #include "src/logic/BooleanLiteralFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
BooleanLiteralFormula::BooleanLiteralFormula(bool value) : value(value) { BooleanLiteralFormula::BooleanLiteralFormula(bool value) : value(value) {
// Intenionally left empty. // Intenionally left empty.
} }
bool BooleanLiteralFormula::isBooleanLiteralFormula() const {
return true;
}
bool BooleanLiteralFormula::isTrueFormula() const { bool BooleanLiteralFormula::isTrueFormula() const {
return value; return value;
} }
@ -14,20 +20,8 @@ namespace storm {
return !value; return !value;
} }
bool BooleanLiteralFormula::isPctlStateFormula() const { boost::any BooleanLiteralFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return true; return visitor.visit(*this, data);
}
bool BooleanLiteralFormula::isLtlFormula() const {
return true;
}
bool BooleanLiteralFormula::isPropositionalFormula() const {
return true;
}
bool BooleanLiteralFormula::isBooleanLiteralFormula() const {
return true;
} }
std::shared_ptr<Formula> BooleanLiteralFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> BooleanLiteralFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {

6
src/logic/BooleanLiteralFormula.h

@ -16,10 +16,8 @@ namespace storm {
virtual bool isBooleanLiteralFormula() const override; virtual bool isBooleanLiteralFormula() const override;
virtual bool isTrueFormula() const override; virtual bool isTrueFormula() const override;
virtual bool isFalseFormula() const override; virtual bool isFalseFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool isPctlStateFormula() const override;
virtual bool isLtlFormula() const override;
virtual bool isPropositionalFormula() const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

18
src/logic/BoundedUntilFormula.cpp

@ -3,6 +3,8 @@
#include "src/utility/macros.h" #include "src/utility/macros.h"
#include "src/exceptions/InvalidArgumentException.h" #include "src/exceptions/InvalidArgumentException.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, double lowerBound, double upperBound) : BinaryPathFormula(leftSubformula, rightSubformula), bounds(std::make_pair(lowerBound, upperBound)) { BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, double lowerBound, double upperBound) : BinaryPathFormula(leftSubformula, rightSubformula), bounds(std::make_pair(lowerBound, upperBound)) {
@ -22,22 +24,18 @@ namespace storm {
return true; return true;
} }
bool BoundedUntilFormula::containsBoundedUntilFormula() const { bool BoundedUntilFormula::isProbabilityPathFormula() const {
return true; return true;
} }
boost::any BoundedUntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
bool BoundedUntilFormula::hasDiscreteTimeBound() const { bool BoundedUntilFormula::hasDiscreteTimeBound() const {
return bounds.which() == 0; return bounds.which() == 0;
} }
bool BoundedUntilFormula::isPctlPathFormula() const {
return this->hasDiscreteTimeBound() && this->getLeftSubformula().isPctlStateFormula() && this->getRightSubformula().isPctlStateFormula();
}
bool BoundedUntilFormula::isCslPathFormula() const {
return this->getLeftSubformula().isCslStateFormula() && this->getRightSubformula().isCslStateFormula();
}
std::pair<double, double> const& BoundedUntilFormula::getIntervalBounds() const { std::pair<double, double> const& BoundedUntilFormula::getIntervalBounds() const {
return boost::get<std::pair<double, double>>(bounds); return boost::get<std::pair<double, double>>(bounds);
} }

7
src/logic/BoundedUntilFormula.h

@ -15,15 +15,14 @@ namespace storm {
virtual bool isBoundedUntilFormula() const override; virtual bool isBoundedUntilFormula() const override;
virtual bool containsBoundedUntilFormula() const override; virtual bool isProbabilityPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
bool hasDiscreteTimeBound() const; bool hasDiscreteTimeBound() const;
std::pair<double, double> const& getIntervalBounds() const; std::pair<double, double> const& getIntervalBounds() const;
uint_fast64_t getDiscreteTimeBound() const; uint_fast64_t getDiscreteTimeBound() const;
virtual bool isPctlPathFormula() const override;
virtual bool isCslPathFormula() const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;

59
src/logic/ConditionalFormula.cpp

@ -0,0 +1,59 @@
#include "src/logic/ConditionalFormula.h"
#include "src/logic/FormulaVisitor.h"
#include "src/utility/macros.h"
#include "src/exceptions/InvalidPropertyException.h"
namespace storm {
namespace logic {
ConditionalFormula::ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context) : subformula(subformula), conditionFormula(conditionFormula), context(context) {
STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward, storm::exceptions::InvalidPropertyException, "Invalid context for formula.");
}
Formula const& ConditionalFormula::getSubformula() const {
return *subformula;
}
Formula const& ConditionalFormula::getConditionFormula() const {
return *conditionFormula;
}
bool ConditionalFormula::isConditionalProbabilityFormula() const {
return context == FormulaContext::Probability;
}
bool ConditionalFormula::isConditionalRewardFormula() const {
return context == FormulaContext::Reward;
}
boost::any ConditionalFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
std::shared_ptr<Formula> ConditionalFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<ConditionalFormula>(this->getSubformula().substitute(substitution), this->getConditionFormula().substitute(substitution), context);
}
void ConditionalFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const {
this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
this->getConditionFormula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
}
void ConditionalFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas);
this->getConditionFormula().gatherAtomicLabelFormulas(atomicLabelFormulas);
}
void ConditionalFormula::gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const {
this->getSubformula().gatherReferencedRewardModels(referencedRewardModels);
this->getConditionFormula().gatherReferencedRewardModels(referencedRewardModels);
}
std::ostream& ConditionalFormula::writeToStream(std::ostream& out) const {
this->getSubformula().writeToStream(out);
out << " || ";
this->getConditionFormula().writeToStream(out);
return out;
}
}
}

43
src/logic/ConditionalFormula.h

@ -0,0 +1,43 @@
#ifndef STORM_LOGIC_CONDITIONALFORMULA_H_
#define STORM_LOGIC_CONDITIONALFORMULA_H_
#include "src/logic/BinaryPathFormula.h"
#include "src/logic/FormulaContext.h"
namespace storm {
namespace logic {
class ConditionalFormula : public Formula {
public:
enum class Context { Probability, Reward };
ConditionalFormula(std::shared_ptr<Formula const> const& subformula, std::shared_ptr<Formula const> const& conditionFormula, FormulaContext context = FormulaContext::Probability);
virtual ~ConditionalFormula() {
// Intentionally left empty.
}
Formula const& getSubformula() const;
Formula const& getConditionFormula() const;
virtual bool isConditionalProbabilityFormula() const override;
virtual bool isConditionalRewardFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;
virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override;
virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override;
private:
std::shared_ptr<Formula const> subformula;
std::shared_ptr<Formula const> conditionFormula;
FormulaContext context;
};
}
}
#endif /* STORM_LOGIC_CONDITIONALFORMULA_H_ */

24
src/logic/ConditionalPathFormula.cpp

@ -1,24 +0,0 @@
#include "src/logic/ConditionalPathFormula.h"
namespace storm {
namespace logic {
ConditionalPathFormula::ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) {
// Intentionally left empty.
}
bool ConditionalPathFormula::isConditionalPathFormula() const {
return true;
}
std::shared_ptr<Formula> ConditionalPathFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<ConditionalPathFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
}
std::ostream& ConditionalPathFormula::writeToStream(std::ostream& out) const {
this->getLeftSubformula().writeToStream(out);
out << " || ";
this->getRightSubformula().writeToStream(out);
return out;
}
}
}

25
src/logic/ConditionalPathFormula.h

@ -1,25 +0,0 @@
#ifndef STORM_LOGIC_CONDITIONALPATHFORMULA_H_
#define STORM_LOGIC_CONDITIONALPATHFORMULA_H_
#include "src/logic/BinaryPathFormula.h"
namespace storm {
namespace logic {
class ConditionalPathFormula : public BinaryPathFormula {
public:
ConditionalPathFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula);
virtual ~ConditionalPathFormula() {
// Intentionally left empty.
}
virtual bool isConditionalPathFormula() const override;
virtual std::ostream& writeToStream(std::ostream& out) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
};
}
}
#endif /* STORM_LOGIC_CONDITIONALPATHFORMULA_H_ */

10
src/logic/CumulativeRewardFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/CumulativeRewardFormula.h" #include "src/logic/CumulativeRewardFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
CumulativeRewardFormula::CumulativeRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) { CumulativeRewardFormula::CumulativeRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
@ -14,6 +16,14 @@ namespace storm {
return true; return true;
} }
bool CumulativeRewardFormula::isRewardPathFormula() const {
return true;
}
boost::any CumulativeRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
bool CumulativeRewardFormula::hasDiscreteTimeBound() const { bool CumulativeRewardFormula::hasDiscreteTimeBound() const {
return timeBound.which() == 0; return timeBound.which() == 0;
} }

9
src/logic/CumulativeRewardFormula.h

@ -3,11 +3,11 @@
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include "src/logic/RewardPathFormula.h" #include "src/logic/PathFormula.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
class CumulativeRewardFormula : public RewardPathFormula { class CumulativeRewardFormula : public PathFormula {
public: public:
CumulativeRewardFormula(uint_fast64_t timeBound); CumulativeRewardFormula(uint_fast64_t timeBound);
@ -16,9 +16,12 @@ namespace storm {
virtual ~CumulativeRewardFormula() { virtual ~CumulativeRewardFormula() {
// Intentionally left empty. // Intentionally left empty.
} }
virtual bool isCumulativeRewardFormula() const override; virtual bool isCumulativeRewardFormula() const override;
virtual bool isRewardPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;
bool hasDiscreteTimeBound() const; bool hasDiscreteTimeBound() const;

36
src/logic/EventuallyFormula.cpp

@ -1,17 +1,45 @@
#include "src/logic/EventuallyFormula.h" #include "src/logic/EventuallyFormula.h"
#include "src/logic/FormulaVisitor.h"
#include "src/utility/macros.h"
#include "src/exceptions/InvalidPropertyException.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { EventuallyFormula::EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context) : UnaryPathFormula(subformula), context(context) {
// Intentionally left empty. STORM_LOG_THROW(context == FormulaContext::Probability || context == FormulaContext::Reward || context == FormulaContext::ExpectedTime, storm::exceptions::InvalidPropertyException, "Invalid context for formula.");
} }
bool EventuallyFormula::isEventuallyFormula() const { bool EventuallyFormula::isEventuallyFormula() const {
return true; return context == FormulaContext::Probability;
}
bool EventuallyFormula::isReachabilityRewardFormula() const {
return context == FormulaContext::Reward;
}
bool EventuallyFormula::isReachbilityExpectedTimeFormula() const {
return context == FormulaContext::ExpectedTime;
}
bool EventuallyFormula::isProbabilityPathFormula() const {
return this->isEventuallyFormula();
}
bool EventuallyFormula::isRewardPathFormula() const {
return this->isReachabilityRewardFormula();
}
bool EventuallyFormula::isExpectedTimePathFormula() const {
return this->isReachbilityExpectedTimeFormula();
}
boost::any EventuallyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
} }
std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> EventuallyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution)); return std::make_shared<EventuallyFormula>(this->getSubformula().substitute(substitution), context);
} }
std::ostream& EventuallyFormula::writeToStream(std::ostream& out) const { std::ostream& EventuallyFormula::writeToStream(std::ostream& out) const {

14
src/logic/EventuallyFormula.h

@ -2,23 +2,33 @@
#define STORM_LOGIC_EVENTUALLYFORMULA_H_ #define STORM_LOGIC_EVENTUALLYFORMULA_H_
#include "src/logic/UnaryPathFormula.h" #include "src/logic/UnaryPathFormula.h"
#include "src/logic/FormulaContext.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
class EventuallyFormula : public UnaryPathFormula { class EventuallyFormula : public UnaryPathFormula {
public: public:
EventuallyFormula(std::shared_ptr<Formula const> const& subformula); EventuallyFormula(std::shared_ptr<Formula const> const& subformula, FormulaContext context = FormulaContext::Probability);
virtual ~EventuallyFormula() { virtual ~EventuallyFormula() {
// Intentionally left empty. // Intentionally left empty.
} }
virtual bool isEventuallyFormula() const override; virtual bool isEventuallyFormula() const override;
virtual bool isReachabilityRewardFormula() const override;
virtual bool isReachbilityExpectedTimeFormula() const override;
virtual bool isProbabilityPathFormula() const override;
virtual bool isRewardPathFormula() const override;
virtual bool isExpectedTimePathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
private:
FormulaContext context;
}; };
} }
} }

14
src/logic/ExpectedTimeOperatorFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/ExpectedTimeOperatorFormula.h" #include "src/logic/ExpectedTimeOperatorFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ExpectedTimeOperatorFormula(boost::none, boost::none, subformula) { ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ExpectedTimeOperatorFormula(boost::none, boost::none, subformula) {
@ -22,16 +24,8 @@ namespace storm {
return true; return true;
} }
bool ExpectedTimeOperatorFormula::isPctlStateFormula() const { boost::any ExpectedTimeOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return this->getSubformula().isPctlStateFormula(); return visitor.visit(*this, data);
}
bool ExpectedTimeOperatorFormula::containsProbabilityOperator() const {
return this->getSubformula().containsProbabilityOperator();
}
bool ExpectedTimeOperatorFormula::containsNestedProbabilityOperators() const {
return this->getSubformula().containsNestedProbabilityOperators();
} }
ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { ExpectedTimeOperatorFormula::ExpectedTimeOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {

8
src/logic/ExpectedTimeOperatorFormula.h

@ -3,6 +3,8 @@
#include "src/logic/OperatorFormula.h" #include "src/logic/OperatorFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
class ExpectedTimeOperatorFormula : public OperatorFormula { class ExpectedTimeOperatorFormula : public OperatorFormula {
@ -18,10 +20,8 @@ namespace storm {
} }
virtual bool isExpectedTimeOperatorFormula() const override; virtual bool isExpectedTimeOperatorFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool isPctlStateFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

107
src/logic/Formula.cpp

@ -1,6 +1,9 @@
#include "src/logic/Formulas.h" #include "src/logic/Formulas.h"
#include <sstream> #include <sstream>
#include "src/logic/FragmentChecker.h"
#include "src/logic/FormulaInformationVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
bool Formula::isPathFormula() const { bool Formula::isPathFormula() const {
@ -71,19 +74,15 @@ namespace storm {
return false; return false;
} }
bool Formula::isConditionalPathFormula() const { bool Formula::isConditionalProbabilityFormula() const {
return false;
}
bool Formula::isNextFormula() const {
return false; return false;
} }
bool Formula::isLongRunAverageOperatorFormula() const { bool Formula::isConditionalRewardFormula() const {
return false; return false;
} }
bool Formula::isExpectedTimeOperatorFormula() const { bool Formula::isProbabilityPathFormula() const {
return false; return false;
} }
@ -91,84 +90,62 @@ namespace storm {
return false; return false;
} }
bool Formula::isCumulativeRewardFormula() const { bool Formula::isExpectedTimePathFormula() const {
return false; return false;
} }
bool Formula::isInstantaneousRewardFormula() const { bool Formula::isNextFormula() const {
return false;
}
bool Formula::isReachabilityRewardFormula() const {
return false;
}
bool Formula::isLongRunAverageRewardFormula() const {
return false;
}
bool Formula::isProbabilityOperatorFormula() const {
return false;
}
bool Formula::isRewardOperatorFormula() const {
return false; return false;
} }
bool Formula::isOperatorFormula() const { bool Formula::isLongRunAverageOperatorFormula() const {
return false; return false;
} }
bool Formula::isPctlPathFormula() const { bool Formula::isExpectedTimeOperatorFormula() const {
return false; return false;
} }
bool Formula::isPctlStateFormula() const { bool Formula::isCumulativeRewardFormula() const {
return false; return false;
} }
bool Formula::isCslPathFormula() const { bool Formula::isInstantaneousRewardFormula() const {
return this->isPctlPathFormula();
}
bool Formula::isCslStateFormula() const {
return this->isPctlStateFormula();
}
bool Formula::isPltlFormula() const {
return false; return false;
} }
bool Formula::isLtlFormula() const { bool Formula::isReachabilityRewardFormula() const {
return false; return false;
} }
bool Formula::isPropositionalFormula() const { bool Formula::isLongRunAverageRewardFormula() const {
return false; return false;
} }
bool Formula::containsBoundedUntilFormula() const { bool Formula::isReachbilityExpectedTimeFormula() const {
return false; return false;
} }
bool Formula::containsNextFormula() const { bool Formula::isProbabilityOperatorFormula() const {
return false; return false;
} }
bool Formula::containsProbabilityOperator() const { bool Formula::isRewardOperatorFormula() const {
return false; return false;
} }
bool Formula::containsNestedProbabilityOperators() const { bool Formula::isOperatorFormula() const {
return false; return false;
} }
bool Formula::containsRewardOperator() const { bool Formula::isInFragment(FragmentSpecification const& fragment) const {
return false; FragmentChecker checker;
return checker.conformsToSpecification(*this, fragment);
} }
bool Formula::containsNestedRewardOperators() const { FormulaInformation Formula::info() const {
return false; FormulaInformationVisitor visitor;
return visitor.getInformation(*this);
} }
std::shared_ptr<Formula const> Formula::getTrueFormula() { std::shared_ptr<Formula const> Formula::getTrueFormula() {
@ -207,12 +184,12 @@ namespace storm {
return dynamic_cast<UnaryStateFormula const&>(*this); return dynamic_cast<UnaryStateFormula const&>(*this);
} }
ConditionalPathFormula& Formula::asConditionalPathFormula() { ConditionalFormula& Formula::asConditionalFormula() {
return dynamic_cast<ConditionalPathFormula&>(*this); return dynamic_cast<ConditionalFormula&>(*this);
} }
ConditionalPathFormula const& Formula::asConditionalPathFormula() const { ConditionalFormula const& Formula::asConditionalFormula() const {
return dynamic_cast<ConditionalPathFormula const&>(*this); return dynamic_cast<ConditionalFormula const&>(*this);
} }
BinaryBooleanStateFormula& Formula::asBinaryBooleanStateFormula() { BinaryBooleanStateFormula& Formula::asBinaryBooleanStateFormula() {
@ -279,6 +256,14 @@ namespace storm {
return dynamic_cast<EventuallyFormula const&>(*this); return dynamic_cast<EventuallyFormula const&>(*this);
} }
EventuallyFormula& Formula::asReachabilityRewardFormula() {
return dynamic_cast<EventuallyFormula&>(*this);
}
EventuallyFormula const& Formula::asReachabilityRewardFormula() const {
return dynamic_cast<EventuallyFormula const&>(*this);
}
GloballyFormula& Formula::asGloballyFormula() { GloballyFormula& Formula::asGloballyFormula() {
return dynamic_cast<GloballyFormula&>(*this); return dynamic_cast<GloballyFormula&>(*this);
} }
@ -327,14 +312,6 @@ namespace storm {
return dynamic_cast<ExpectedTimeOperatorFormula const&>(*this); return dynamic_cast<ExpectedTimeOperatorFormula const&>(*this);
} }
RewardPathFormula& Formula::asRewardPathFormula() {
return dynamic_cast<RewardPathFormula&>(*this);
}
RewardPathFormula const& Formula::asRewardPathFormula() const {
return dynamic_cast<RewardPathFormula const&>(*this);
}
CumulativeRewardFormula& Formula::asCumulativeRewardFormula() { CumulativeRewardFormula& Formula::asCumulativeRewardFormula() {
return dynamic_cast<CumulativeRewardFormula&>(*this); return dynamic_cast<CumulativeRewardFormula&>(*this);
} }
@ -350,15 +327,7 @@ namespace storm {
InstantaneousRewardFormula const& Formula::asInstantaneousRewardFormula() const { InstantaneousRewardFormula const& Formula::asInstantaneousRewardFormula() const {
return dynamic_cast<InstantaneousRewardFormula const&>(*this); return dynamic_cast<InstantaneousRewardFormula const&>(*this);
} }
ReachabilityRewardFormula& Formula::asReachabilityRewardFormula() {
return dynamic_cast<ReachabilityRewardFormula&>(*this);
}
ReachabilityRewardFormula const& Formula::asReachabilityRewardFormula() const {
return dynamic_cast<ReachabilityRewardFormula const&>(*this);
}
LongRunAverageRewardFormula& Formula::asLongRunAverageRewardFormula() { LongRunAverageRewardFormula& Formula::asLongRunAverageRewardFormula() {
return dynamic_cast<LongRunAverageRewardFormula&>(*this); return dynamic_cast<LongRunAverageRewardFormula&>(*this);
} }
@ -421,7 +390,7 @@ namespace storm {
return; return;
} }
void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const { void Formula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
return; return;
} }

122
src/logic/Formula.h

@ -6,42 +6,24 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <boost/any.hpp>
#include "src/storage/expressions/Variable.h" #include "src/storage/expressions/Variable.h"
#include "src/storage/expressions/Expression.h" #include "src/storage/expressions/Expression.h"
#include "src/logic/FormulasForwardDeclarations.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
// Forward-declare all formula classes. // Forward-declare visitor for accept() method.
class PathFormula; class FormulaVisitor;
class StateFormula; // Forward-declare fragment specification for isInFragment() method.
class BinaryStateFormula; class FragmentSpecification;
class UnaryStateFormula; // Forward-declare formula information class for info() method.
class BinaryBooleanStateFormula; class FormulaInformation;
class UnaryBooleanStateFormula;
class BooleanLiteralFormula;
class AtomicExpressionFormula;
class AtomicLabelFormula;
class UntilFormula;
class BoundedUntilFormula;
class EventuallyFormula;
class GloballyFormula;
class BinaryPathFormula;
class UnaryPathFormula;
class ConditionalPathFormula;
class NextFormula;
class LongRunAverageOperatorFormula;
class ExpectedTimeOperatorFormula;
class RewardPathFormula;
class CumulativeRewardFormula;
class InstantaneousRewardFormula;
class ReachabilityRewardFormula;
class LongRunAverageRewardFormula;
class ProbabilityOperatorFormula;
class RewardOperatorFormula;
class OperatorFormula;
// Also foward-declare base model checker class.
class ModelChecker;
class Formula : public std::enable_shared_from_this<Formula const> { class Formula : public std::enable_shared_from_this<Formula const> {
public: public:
@ -51,51 +33,60 @@ namespace storm {
}; };
friend std::ostream& operator<<(std::ostream& out, Formula const& formula); friend std::ostream& operator<<(std::ostream& out, Formula const& formula);
// Basic formula types.
// Methods for querying the exact formula type.
virtual bool isPathFormula() const; virtual bool isPathFormula() const;
virtual bool isStateFormula() const; virtual bool isStateFormula() const;
virtual bool isBinaryStateFormula() const; virtual bool isConditionalProbabilityFormula() const;
virtual bool isUnaryStateFormula() const; virtual bool isConditionalRewardFormula() const;
virtual bool isProbabilityPathFormula() const;
virtual bool isRewardPathFormula() const;
virtual bool isExpectedTimePathFormula() const;
virtual bool isBinaryBooleanStateFormula() const; virtual bool isBinaryBooleanStateFormula() const;
virtual bool isUnaryBooleanStateFormula() const; virtual bool isUnaryBooleanStateFormula() const;
// Operator formulas.
virtual bool isOperatorFormula() const;
virtual bool isLongRunAverageOperatorFormula() const;
virtual bool isExpectedTimeOperatorFormula() const;
virtual bool isProbabilityOperatorFormula() const;
virtual bool isRewardOperatorFormula() const;
// Atomic state formulas.
virtual bool isBooleanLiteralFormula() const; virtual bool isBooleanLiteralFormula() const;
virtual bool isTrueFormula() const; virtual bool isTrueFormula() const;
virtual bool isFalseFormula() const; virtual bool isFalseFormula() const;
virtual bool isAtomicExpressionFormula() const; virtual bool isAtomicExpressionFormula() const;
virtual bool isAtomicLabelFormula() const; virtual bool isAtomicLabelFormula() const;
// Probability path formulas.
virtual bool isNextFormula() const;
virtual bool isUntilFormula() const; virtual bool isUntilFormula() const;
virtual bool isBoundedUntilFormula() const; virtual bool isBoundedUntilFormula() const;
virtual bool isEventuallyFormula() const; virtual bool isEventuallyFormula() const;
virtual bool isGloballyFormula() const; virtual bool isGloballyFormula() const;
virtual bool isBinaryPathFormula() const; // Reward formulas.
virtual bool isUnaryPathFormula() const;
virtual bool isConditionalPathFormula() const;
virtual bool isNextFormula() const;
virtual bool isLongRunAverageOperatorFormula() const;
virtual bool isExpectedTimeOperatorFormula() const;
virtual bool isRewardPathFormula() const;
virtual bool isCumulativeRewardFormula() const; virtual bool isCumulativeRewardFormula() const;
virtual bool isInstantaneousRewardFormula() const; virtual bool isInstantaneousRewardFormula() const;
virtual bool isReachabilityRewardFormula() const; virtual bool isReachabilityRewardFormula() const;
virtual bool isLongRunAverageRewardFormula() const; virtual bool isLongRunAverageRewardFormula() const;
virtual bool isProbabilityOperatorFormula() const; // Expected time formulas.
virtual bool isRewardOperatorFormula() const; virtual bool isReachbilityExpectedTimeFormula() const;
virtual bool isOperatorFormula() const; // Type checks for abstract intermediate classes.
virtual bool isBinaryPathFormula() const;
virtual bool isBinaryStateFormula() const;
virtual bool isUnaryPathFormula() const;
virtual bool isUnaryStateFormula() const;
virtual bool isPctlPathFormula() const; bool isInFragment(FragmentSpecification const& fragment) const;
virtual bool isPctlStateFormula() const; FormulaInformation info() const;
virtual bool isCslPathFormula() const; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data = boost::any()) const = 0;
virtual bool isCslStateFormula() const;
virtual bool isPltlFormula() const;
virtual bool isLtlFormula() const;
virtual bool isPropositionalFormula() const;
virtual bool containsBoundedUntilFormula() const;
virtual bool containsNextFormula() const;
virtual bool containsProbabilityOperator() const;
virtual bool containsNestedProbabilityOperators() const;
virtual bool containsRewardOperator() const;
virtual bool containsNestedRewardOperators() const;
static std::shared_ptr<Formula const> getTrueFormula(); static std::shared_ptr<Formula const> getTrueFormula();
@ -135,6 +126,9 @@ namespace storm {
EventuallyFormula& asEventuallyFormula(); EventuallyFormula& asEventuallyFormula();
EventuallyFormula const& asEventuallyFormula() const; EventuallyFormula const& asEventuallyFormula() const;
EventuallyFormula& asReachabilityRewardFormula();
EventuallyFormula const& asReachabilityRewardFormula() const;
GloballyFormula& asGloballyFormula(); GloballyFormula& asGloballyFormula();
GloballyFormula const& asGloballyFormula() const; GloballyFormula const& asGloballyFormula() const;
@ -144,8 +138,8 @@ namespace storm {
UnaryPathFormula& asUnaryPathFormula(); UnaryPathFormula& asUnaryPathFormula();
UnaryPathFormula const& asUnaryPathFormula() const; UnaryPathFormula const& asUnaryPathFormula() const;
ConditionalPathFormula& asConditionalPathFormula(); ConditionalFormula& asConditionalFormula();
ConditionalPathFormula const& asConditionalPathFormula() const; ConditionalFormula const& asConditionalFormula() const;
NextFormula& asNextFormula(); NextFormula& asNextFormula();
NextFormula const& asNextFormula() const; NextFormula const& asNextFormula() const;
@ -156,18 +150,12 @@ namespace storm {
ExpectedTimeOperatorFormula& asExpectedTimeOperatorFormula(); ExpectedTimeOperatorFormula& asExpectedTimeOperatorFormula();
ExpectedTimeOperatorFormula const& asExpectedTimeOperatorFormula() const; ExpectedTimeOperatorFormula const& asExpectedTimeOperatorFormula() const;
RewardPathFormula& asRewardPathFormula();
RewardPathFormula const& asRewardPathFormula() const;
CumulativeRewardFormula& asCumulativeRewardFormula(); CumulativeRewardFormula& asCumulativeRewardFormula();
CumulativeRewardFormula const& asCumulativeRewardFormula() const; CumulativeRewardFormula const& asCumulativeRewardFormula() const;
InstantaneousRewardFormula& asInstantaneousRewardFormula(); InstantaneousRewardFormula& asInstantaneousRewardFormula();
InstantaneousRewardFormula const& asInstantaneousRewardFormula() const; InstantaneousRewardFormula const& asInstantaneousRewardFormula() const;
ReachabilityRewardFormula& asReachabilityRewardFormula();
ReachabilityRewardFormula const& asReachabilityRewardFormula() const;
LongRunAverageRewardFormula& asLongRunAverageRewardFormula(); LongRunAverageRewardFormula& asLongRunAverageRewardFormula();
LongRunAverageRewardFormula const& asLongRunAverageRewardFormula() const; LongRunAverageRewardFormula const& asLongRunAverageRewardFormula() const;
@ -193,7 +181,7 @@ namespace storm {
virtual std::ostream& writeToStream(std::ostream& out) const = 0; virtual std::ostream& writeToStream(std::ostream& out) const = 0;
virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const; virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const;
virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicExpressionFormulas) const; virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const;
virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const; virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const;
private: private:

12
src/logic/FormulaContext.h

@ -0,0 +1,12 @@
#ifndef STORM_LOGIC_FORMULACONTEXT_H_
#define STORM_LOGIC_FORMULACONTEXT_H_
namespace storm {
namespace logic {
enum class FormulaContext { Undefined, Probability, Reward, LongRunAverage, ExpectedTime };
}
}
#endif /* STORM_LOGIC_FORMULACONTEXT_H_ */

46
src/logic/FormulaInformation.cpp

@ -0,0 +1,46 @@
#include "src/logic/FormulaInformation.h"
namespace storm {
namespace logic {
FormulaInformation::FormulaInformation() {
this->mContainsRewardOperator = false;
this->mContainsNextFormula = false;
this->mContainsBoundedUntilFormula = false;
}
bool FormulaInformation::containsRewardOperator() const {
return this->mContainsRewardOperator;
}
bool FormulaInformation::containsNextFormula() const {
return this->mContainsNextFormula;
}
bool FormulaInformation::containsBoundedUntilFormula() const {
return this->mContainsBoundedUntilFormula;
}
FormulaInformation FormulaInformation::join(FormulaInformation const& other) {
FormulaInformation result;
result.mContainsRewardOperator = this->containsRewardOperator() || other.containsRewardOperator();
result.mContainsNextFormula = this->containsNextFormula() || other.containsNextFormula();
result.mContainsBoundedUntilFormula = this->containsBoundedUntilFormula() || other.containsBoundedUntilFormula();
return result;
}
FormulaInformation& FormulaInformation::setContainsRewardOperator(bool newValue) {
this->mContainsRewardOperator = newValue;
return *this;
}
FormulaInformation& FormulaInformation::setContainsNextFormula(bool newValue) {
this->mContainsNextFormula = newValue;
return *this;
}
FormulaInformation& FormulaInformation::setContainsBoundedUntilFormula(bool newValue) {
this->mContainsBoundedUntilFormula = newValue;
return *this;
}
}
}

34
src/logic/FormulaInformation.h

@ -0,0 +1,34 @@
#ifndef STORM_LOGIC_FORMULAINFORMATION_H_
#define STORM_LOGIC_FORMULAINFORMATION_H_
namespace storm {
namespace logic {
class FormulaInformation {
public:
FormulaInformation();
FormulaInformation(FormulaInformation const& other) = default;
FormulaInformation(FormulaInformation&& other) = default;
FormulaInformation& operator=(FormulaInformation const& other) = default;
FormulaInformation& operator=(FormulaInformation&& other) = default;
bool containsRewardOperator() const;
bool containsNextFormula() const;
bool containsBoundedUntilFormula() const;
FormulaInformation join(FormulaInformation const& other);
FormulaInformation& setContainsRewardOperator(bool newValue = true);
FormulaInformation& setContainsNextFormula(bool newValue = true);
FormulaInformation& setContainsBoundedUntilFormula(bool newValue = true);
private:
bool mContainsRewardOperator;
bool mContainsNextFormula;
bool mContainsBoundedUntilFormula;
};
}
}
#endif /* STORM_LOGIC_FORMULAINFORMATION_H_ */

85
src/logic/FormulaInformationVisitor.cpp

@ -0,0 +1,85 @@
#include "src/logic/FormulaInformationVisitor.h"
#include "src/logic/Formulas.h"
namespace storm {
namespace logic {
FormulaInformation FormulaInformationVisitor::getInformation(Formula const& f) const {
boost::any result = f.accept(*this, boost::any());
return boost::any_cast<FormulaInformation>(result);
}
boost::any FormulaInformationVisitor::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(AtomicLabelFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this))).setContainsBoundedUntilFormula();
}
boost::any FormulaInformationVisitor::visit(ConditionalFormula const& f, boost::any const& data) const {
return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getConditionFormula().accept(*this)));
}
boost::any FormulaInformationVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(EventuallyFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(GloballyFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
return FormulaInformation();
}
boost::any FormulaInformationVisitor::visit(NextFormula const& f, boost::any const& data) const {
return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsNextFormula();
}
boost::any FormulaInformationVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
return boost::any_cast<FormulaInformation>(f.getSubformula().accept(*this)).setContainsRewardOperator();
}
boost::any FormulaInformationVisitor::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
return f.getSubformula().accept(*this);
}
boost::any FormulaInformationVisitor::visit(UntilFormula const& f, boost::any const& data) const {
return boost::any_cast<FormulaInformation>(f.getLeftSubformula().accept(*this)).join(boost::any_cast<FormulaInformation>(f.getRightSubformula().accept(*this)));
}
}
}

38
src/logic/FormulaInformationVisitor.h

@ -0,0 +1,38 @@
#ifndef STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_
#define STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_
#include "src/logic/FormulaVisitor.h"
#include "src/logic/FormulaInformation.h"
namespace storm {
namespace logic {
class FormulaInformationVisitor : public FormulaVisitor {
public:
FormulaInformation getInformation(Formula const& f) const;
virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override;
virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override;
virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override;
virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(NextFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override;
virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override;
};
}
}
#endif /* STORM_LOGIC_FORMULAINFORMATIONVISITOR_H_ */

36
src/logic/FormulaVisitor.h

@ -0,0 +1,36 @@
#ifndef STORM_LOGIC_FORMULAVISITOR_H_
#define STORM_LOGIC_FORMULAVISITOR_H_
#include <boost/any.hpp>
#include "src/logic/FormulasForwardDeclarations.h"
namespace storm {
namespace logic {
class FormulaVisitor {
public:
virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(NextFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const = 0;
virtual boost::any visit(UntilFormula const& f, boost::any const& data) const = 0;
};
}
}
#endif /* STORM_LOGIC_FORMULAVISITOR_H_ */

4
src/logic/Formulas.h

@ -12,10 +12,8 @@
#include "src/logic/InstantaneousRewardFormula.h" #include "src/logic/InstantaneousRewardFormula.h"
#include "src/logic/NextFormula.h" #include "src/logic/NextFormula.h"
#include "src/logic/PathFormula.h" #include "src/logic/PathFormula.h"
#include "src/logic/RewardPathFormula.h"
#include "src/logic/OperatorFormula.h" #include "src/logic/OperatorFormula.h"
#include "src/logic/ProbabilityOperatorFormula.h" #include "src/logic/ProbabilityOperatorFormula.h"
#include "src/logic/ReachabilityRewardFormula.h"
#include "src/logic/LongRunAverageRewardFormula.h" #include "src/logic/LongRunAverageRewardFormula.h"
#include "src/logic/RewardOperatorFormula.h" #include "src/logic/RewardOperatorFormula.h"
#include "src/logic/StateFormula.h" #include "src/logic/StateFormula.h"
@ -25,7 +23,7 @@
#include "src/logic/UnaryPathFormula.h" #include "src/logic/UnaryPathFormula.h"
#include "src/logic/UnaryStateFormula.h" #include "src/logic/UnaryStateFormula.h"
#include "src/logic/UntilFormula.h" #include "src/logic/UntilFormula.h"
#include "src/logic/ConditionalPathFormula.h" #include "src/logic/ConditionalFormula.h"
#include "src/logic/ProbabilityOperatorFormula.h" #include "src/logic/ProbabilityOperatorFormula.h"
#include "src/logic/RewardOperatorFormula.h" #include "src/logic/RewardOperatorFormula.h"
#include "src/logic/ComparisonType.h" #include "src/logic/ComparisonType.h"

36
src/logic/FormulasForwardDeclarations.h

@ -0,0 +1,36 @@
#ifndef STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_
#define STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_
namespace storm {
namespace logic {
// Forward-declare all formula classes.
class Formula;
class AtomicExpressionFormula;
class AtomicLabelFormula;
class BinaryBooleanStateFormula;
class BinaryPathFormula;
class BinaryStateFormula;
class BooleanLiteralFormula;
class BoundedUntilFormula;
class ConditionalFormula;
class CumulativeRewardFormula;
class EventuallyFormula;
class ExpectedTimeOperatorFormula;
class GloballyFormula;
class InstantaneousRewardFormula;
class LongRunAverageOperatorFormula;
class LongRunAverageRewardFormula;
class NextFormula;
class OperatorFormula;
class PathFormula;
class ProbabilityOperatorFormula;
class RewardOperatorFormula;
class StateFormula;
class UnaryBooleanStateFormula;
class UnaryPathFormula;
class UnaryStateFormula;
class UntilFormula;
}
}
#endif /* STORM_LOGIC_FORMULASFORWARDDECLARATIONS_H_ */

207
src/logic/FragmentChecker.cpp

@ -0,0 +1,207 @@
#include "src/logic/FragmentChecker.h"
#include "src/logic/Formulas.h"
namespace storm {
namespace logic {
class InheritedInformation {
public:
InheritedInformation(FragmentSpecification const& fragmentSpecification) : fragmentSpecification(fragmentSpecification) {
// Intentionally left empty.
}
FragmentSpecification const& getSpecification() const {
return fragmentSpecification;
}
private:
FragmentSpecification const& fragmentSpecification;
};
bool FragmentChecker::conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const {
boost::any result = f.accept(*this, InheritedInformation(specification));
return boost::any_cast<bool>(result);
}
boost::any FragmentChecker::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areAtomicExpressionFormulasAllowed();
}
boost::any FragmentChecker::visit(AtomicLabelFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areAtomicLabelFormulasAllowed();
}
boost::any FragmentChecker::visit(BinaryBooleanStateFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areBinaryBooleanStateFormulasAllowed();
result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(BooleanLiteralFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areBooleanLiteralFormulasAllowed();
}
boost::any FragmentChecker::visit(BoundedUntilFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areBoundedUntilFormulasAllowed();
if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
result = result && !f.getLeftSubformula().isPathFormula();
result = result && !f.getRightSubformula().isPathFormula();
}
if (f.hasDiscreteTimeBound()) {
result = result && inherited.getSpecification().areStepBoundedUntilFormulasAllowed();
} else {
result = result && inherited.getSpecification().areTimeBoundedUntilFormulasAllowed();
}
result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(ConditionalFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = true;
if (f.isConditionalProbabilityFormula()) {
result = result && inherited.getSpecification().areConditionalProbabilityFormulasAllowed();
} else if (f.isConditionalRewardFormula()) {
result = result && inherited.getSpecification().areConditionalRewardFormulasFormulasAllowed();
}
if (inherited.getSpecification().areOnlyEventuallyFormuluasInConditionalFormulasAllowed()) {
if (f.isConditionalProbabilityFormula()) {
result = result && f.getSubformula().isEventuallyFormula() && f.getConditionFormula().isEventuallyFormula();
} else if (f.isConditionalRewardFormula()) {
result = result && f.getSubformula().isReachabilityRewardFormula() && f.getConditionFormula().isEventuallyFormula();
}
}
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
result = result && boost::any_cast<bool>(f.getConditionFormula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areCumulativeRewardFormulasAllowed();
}
boost::any FragmentChecker::visit(EventuallyFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = true;
if (f.isEventuallyFormula()) {
result = inherited.getSpecification().areEventuallyFormulasAllowed();
if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
result = result && !f.getSubformula().isPathFormula();
}
} else if (f.isReachabilityRewardFormula()) {
result = result && inherited.getSpecification().areReachabilityRewardFormulasAllowed();
result = result && f.getSubformula().isStateFormula();
} else if (f.isReachbilityExpectedTimeFormula()) {
result = result && inherited.getSpecification().areReachbilityExpectedTimeFormulasAllowed();
result = result && f.getSubformula().isStateFormula();
}
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areExpectedTimeOperatorsAllowed();
result = result && f.getSubformula().isExpectedTimePathFormula();
if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
} else {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
}
return result;
}
boost::any FragmentChecker::visit(GloballyFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areGloballyFormulasAllowed();
if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
result = result && !f.getSubformula().isPathFormula();
}
result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areInstantaneousRewardFormulasAllowed();
}
boost::any FragmentChecker::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areLongRunAverageOperatorsAllowed();
result = result && f.getSubformula().isStateFormula();
if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
} else {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
}
return result;
}
boost::any FragmentChecker::visit(LongRunAverageRewardFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
return inherited.getSpecification().areLongRunAverageRewardFormulasAllowed();
}
boost::any FragmentChecker::visit(NextFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areNextFormulasAllowed();
if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
result = result && !f.getSubformula().isPathFormula();
}
result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areProbabilityOperatorsAllowed();
result = result && (f.getSubformula().isProbabilityPathFormula() || f.getSubformula().isConditionalProbabilityFormula());
if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
} else {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
}
return result;
}
boost::any FragmentChecker::visit(RewardOperatorFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areRewardOperatorsAllowed();
result = result && (f.getSubformula().isRewardPathFormula() || f.getSubformula().isConditionalRewardFormula());
if (!inherited.getSpecification().areNestedOperatorsAllowed()) {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, InheritedInformation(inherited.getSpecification().copy().setOperatorsAllowed(false))));
} else {
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
}
return result;
}
boost::any FragmentChecker::visit(UnaryBooleanStateFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areUnaryBooleanStateFormulasAllowed();
result = result && boost::any_cast<bool>(f.getSubformula().accept(*this, data));
return result;
}
boost::any FragmentChecker::visit(UntilFormula const& f, boost::any const& data) const {
InheritedInformation const& inherited = boost::any_cast<InheritedInformation const&>(data);
bool result = inherited.getSpecification().areUntilFormulasAllowed();
if (!inherited.getSpecification().areNestedPathFormulasAllowed()) {
result = result && !f.getLeftSubformula().isPathFormula();
result = result && !f.getRightSubformula().isPathFormula();
}
result = result && boost::any_cast<bool>(f.getLeftSubformula().accept(*this, data));
result = result && boost::any_cast<bool>(f.getRightSubformula().accept(*this, data));
return result;
}
}
}

39
src/logic/FragmentChecker.h

@ -0,0 +1,39 @@
#ifndef STORM_LOGIC_FRAGMENTCHECKER_H_
#define STORM_LOGIC_FRAGMENTCHECKER_H_
#include "src/logic/FormulaVisitor.h"
#include "src/logic/FragmentSpecification.h"
namespace storm {
namespace logic {
class FragmentChecker : public FormulaVisitor {
public:
bool conformsToSpecification(Formula const& f, FragmentSpecification const& specification) const;
virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override;
virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override;
virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override;
virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(EventuallyFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ExpectedTimeOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(GloballyFormula const& f, boost::any const& data) const override;
virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(LongRunAverageRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(NextFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(RewardOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(UnaryBooleanStateFormula const& f, boost::any const& data) const override;
virtual boost::any visit(UntilFormula const& f, boost::any const& data) const override;
};
}
}
#endif /* STORM_LOGIC_FRAGMENTCHECKER_H_ */

359
src/logic/FragmentSpecification.cpp

@ -0,0 +1,359 @@
#include "src/logic/FragmentSpecification.h"
#include <iostream>
namespace storm {
namespace logic {
FragmentSpecification propositional() {
FragmentSpecification propositional;
propositional.setBooleanLiteralFormulasAllowed(true);
propositional.setBinaryBooleanStateFormulasAllowed(true);
propositional.setUnaryBooleanStateFormulasAllowed(true);
propositional.setAtomicExpressionFormulasAllowed(true);
propositional.setAtomicLabelFormulasAllowed(true);
return propositional;
}
FragmentSpecification pctl() {
FragmentSpecification pctl = propositional();
pctl.setProbabilityOperatorsAllowed(true);
pctl.setGloballyFormulasAllowed(true);
pctl.setEventuallyFormulasAllowed(true);
pctl.setNextFormulasAllowed(true);
pctl.setUntilFormulasAllowed(true);
pctl.setBoundedUntilFormulasAllowed(true);
pctl.setStepBoundedUntilFormulasAllowed(true);
return pctl;
}
FragmentSpecification prctl() {
FragmentSpecification prctl = pctl();
prctl.setRewardOperatorsAllowed(true);
prctl.setCumulativeRewardFormulasAllowed(true);
prctl.setInstantaneousFormulasAllowed(true);
prctl.setReachabilityRewardFormulasAllowed(true);
prctl.setLongRunAverageOperatorsAllowed(true);
return prctl;
}
FragmentSpecification csl() {
FragmentSpecification csl = pctl();
csl.setTimeBoundedUntilFormulasAllowed(true);
return csl;
}
FragmentSpecification csrl() {
FragmentSpecification csrl = csl();
csrl.setRewardOperatorsAllowed(true);
csrl.setCumulativeRewardFormulasAllowed(true);
csrl.setInstantaneousFormulasAllowed(true);
csrl.setReachabilityRewardFormulasAllowed(true);
csrl.setLongRunAverageOperatorsAllowed(true);
return csrl;
}
FragmentSpecification::FragmentSpecification() {
probabilityOperator = false;
rewardOperator = false;
expectedTimeOperator = false;
longRunAverageOperator = false;
globallyFormula = false;
eventuallyFormula = false;
nextFormula = false;
untilFormula = false;
boundedUntilFormula = false;
atomicExpressionFormula = false;
atomicLabelFormula = false;
booleanLiteralFormula = false;
unaryBooleanStateFormula = false;
binaryBooleanStateFormula = false;
cumulativeRewardFormula = false;
instantaneousRewardFormula = false;
reachabilityRewardFormula = false;
longRunAverageRewardFormula = false;
conditionalProbabilityFormula = false;
conditionalRewardFormula = false;
reachabilityExpectedTimeFormula = false;
nestedOperators = true;
nestedPathFormulas = false;
onlyEventuallyFormuluasInConditionalFormulas = true;
stepBoundedUntilFormulas = false;
timeBoundedUntilFormulas = false;
}
FragmentSpecification FragmentSpecification::copy() const {
return FragmentSpecification(*this);
}
bool FragmentSpecification::areProbabilityOperatorsAllowed() const {
return probabilityOperator;
}
FragmentSpecification& FragmentSpecification::setProbabilityOperatorsAllowed(bool newValue) {
this->probabilityOperator = newValue;
return *this;
}
bool FragmentSpecification::areRewardOperatorsAllowed() const {
return rewardOperator;
}
FragmentSpecification& FragmentSpecification::setRewardOperatorsAllowed(bool newValue) {
this->rewardOperator = newValue;
return *this;
}
bool FragmentSpecification::areExpectedTimeOperatorsAllowed() const {
return expectedTimeOperator;
}
FragmentSpecification& FragmentSpecification::setExpectedTimeOperatorsAllowed(bool newValue) {
this->expectedTimeOperator = newValue;
return *this;
}
bool FragmentSpecification::areLongRunAverageOperatorsAllowed() const {
return longRunAverageOperator;
}
FragmentSpecification& FragmentSpecification::setLongRunAverageOperatorsAllowed(bool newValue) {
this->longRunAverageOperator = newValue;
return *this;
}
bool FragmentSpecification::areGloballyFormulasAllowed() const {
return globallyFormula;
}
FragmentSpecification& FragmentSpecification::setGloballyFormulasAllowed(bool newValue) {
this->globallyFormula = newValue;
return *this;
}
bool FragmentSpecification::areEventuallyFormulasAllowed() const {
return eventuallyFormula;
}
FragmentSpecification& FragmentSpecification::setEventuallyFormulasAllowed(bool newValue) {
this->eventuallyFormula = newValue;
return *this;
}
bool FragmentSpecification::areNextFormulasAllowed() const {
return nextFormula;
}
FragmentSpecification& FragmentSpecification::setNextFormulasAllowed(bool newValue) {
this->nextFormula = newValue;
return *this;
}
bool FragmentSpecification::areUntilFormulasAllowed() const {
return untilFormula;
}
FragmentSpecification& FragmentSpecification::setUntilFormulasAllowed(bool newValue) {
this->untilFormula = newValue;
return *this;
}
bool FragmentSpecification::areBoundedUntilFormulasAllowed() const {
return boundedUntilFormula;
}
FragmentSpecification& FragmentSpecification::setBoundedUntilFormulasAllowed(bool newValue) {
this->boundedUntilFormula = newValue;
return *this;
}
bool FragmentSpecification::areAtomicExpressionFormulasAllowed() const {
return atomicExpressionFormula;
}
FragmentSpecification& FragmentSpecification::setAtomicExpressionFormulasAllowed(bool newValue) {
this->atomicExpressionFormula = newValue;
return *this;
}
bool FragmentSpecification::areAtomicLabelFormulasAllowed() const {
return atomicLabelFormula;
}
FragmentSpecification& FragmentSpecification::setAtomicLabelFormulasAllowed(bool newValue) {
this->atomicLabelFormula = newValue;
return *this;
}
bool FragmentSpecification::areBooleanLiteralFormulasAllowed() const {
return booleanLiteralFormula;
}
FragmentSpecification& FragmentSpecification::setBooleanLiteralFormulasAllowed(bool newValue) {
this->booleanLiteralFormula = newValue;
return *this;
}
bool FragmentSpecification::areUnaryBooleanStateFormulasAllowed() const {
return unaryBooleanStateFormula;
}
FragmentSpecification& FragmentSpecification::setUnaryBooleanStateFormulasAllowed(bool newValue) {
this->unaryBooleanStateFormula = newValue;
return *this;
}
bool FragmentSpecification::areBinaryBooleanStateFormulasAllowed() const {
return binaryBooleanStateFormula;
}
FragmentSpecification& FragmentSpecification::setBinaryBooleanStateFormulasAllowed(bool newValue) {
this->binaryBooleanStateFormula = newValue;
return *this;
}
bool FragmentSpecification::areCumulativeRewardFormulasAllowed() const {
return cumulativeRewardFormula;
}
FragmentSpecification& FragmentSpecification::setCumulativeRewardFormulasAllowed(bool newValue) {
this->cumulativeRewardFormula = newValue;
return *this;
}
bool FragmentSpecification::areInstantaneousRewardFormulasAllowed() const {
return instantaneousRewardFormula;
}
FragmentSpecification& FragmentSpecification::setInstantaneousFormulasAllowed(bool newValue) {
this->instantaneousRewardFormula = newValue;
return *this;
}
bool FragmentSpecification::areReachabilityRewardFormulasAllowed() const {
return reachabilityRewardFormula;
}
FragmentSpecification& FragmentSpecification::setReachabilityRewardFormulasAllowed(bool newValue) {
this->reachabilityRewardFormula = newValue;
return *this;
}
bool FragmentSpecification::areLongRunAverageRewardFormulasAllowed() const {
return longRunAverageRewardFormula;
}
FragmentSpecification& FragmentSpecification::setLongRunAverageRewardFormulasAllowed(bool newValue) {
this->longRunAverageRewardFormula = newValue;
return *this;
}
bool FragmentSpecification::areConditionalProbabilityFormulasAllowed() const {
return conditionalProbabilityFormula;
}
FragmentSpecification& FragmentSpecification::setConditionalProbabilityFormulasAllowed(bool newValue) {
this->conditionalProbabilityFormula = newValue;
return *this;
}
bool FragmentSpecification::areConditionalRewardFormulasFormulasAllowed() const {
return conditionalRewardFormula;
}
FragmentSpecification& FragmentSpecification::setConditionalRewardFormulasAllowed(bool newValue) {
this->conditionalRewardFormula = newValue;
return *this;
}
bool FragmentSpecification::areReachbilityExpectedTimeFormulasAllowed() const {
return reachabilityExpectedTimeFormula;
}
FragmentSpecification& FragmentSpecification::setReachbilityExpectedTimeFormulasAllowed(bool newValue) {
this->reachabilityExpectedTimeFormula = newValue;
return *this;
}
bool FragmentSpecification::areNestedOperatorsAllowed() const {
return this->nestedOperators;
}
FragmentSpecification& FragmentSpecification::setNestedOperatorsAllowed(bool newValue) {
this->nestedOperators = newValue;
return *this;
}
bool FragmentSpecification::areNestedPathFormulasAllowed() const {
return this->nestedPathFormulas;
}
FragmentSpecification& FragmentSpecification::setNestedPathFormulasAllowed(bool newValue) {
this->nestedPathFormulas = newValue;
return *this;
}
bool FragmentSpecification::areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const {
return this->onlyEventuallyFormuluasInConditionalFormulas;
}
FragmentSpecification& FragmentSpecification::setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue) {
this->onlyEventuallyFormuluasInConditionalFormulas = newValue;
return *this;
}
bool FragmentSpecification::areStepBoundedUntilFormulasAllowed() const {
return this->stepBoundedUntilFormulas;
}
FragmentSpecification& FragmentSpecification::setStepBoundedUntilFormulasAllowed(bool newValue) {
this->stepBoundedUntilFormulas = newValue;
return *this;
}
bool FragmentSpecification::areTimeBoundedUntilFormulasAllowed() const {
return this->timeBoundedUntilFormulas;
}
FragmentSpecification& FragmentSpecification::setTimeBoundedUntilFormulasAllowed(bool newValue) {
this->timeBoundedUntilFormulas = newValue;
return *this;
}
FragmentSpecification& FragmentSpecification::setOperatorsAllowed(bool newValue) {
this->setProbabilityOperatorsAllowed(newValue);
this->setRewardOperatorsAllowed(newValue);
this->setLongRunAverageOperatorsAllowed(newValue);
this->setExpectedTimeOperatorsAllowed(newValue);
return *this;
}
FragmentSpecification& FragmentSpecification::setExpectedTimeAllowed(bool newValue) {
this->setExpectedTimeOperatorsAllowed(newValue);
this->setReachbilityExpectedTimeFormulasAllowed(newValue);
return *this;
}
FragmentSpecification& FragmentSpecification::setLongRunAverageProbabilitiesAllowed(bool newValue) {
this->setLongRunAverageOperatorsAllowed(newValue);
return *this;
}
}
}

153
src/logic/FragmentSpecification.h

@ -0,0 +1,153 @@
#ifndef STORM_LOGIC_FRAGMENTSPECIFICATION_H_
#define STORM_LOGIC_FRAGMENTSPECIFICATION_H_
namespace storm {
namespace logic {
class FragmentSpecification {
public:
FragmentSpecification();
FragmentSpecification(FragmentSpecification const& other) = default;
FragmentSpecification(FragmentSpecification&& other) = default;
FragmentSpecification& operator=(FragmentSpecification const& other) = default;
FragmentSpecification& operator=(FragmentSpecification&& other) = default;
FragmentSpecification copy() const;
bool areProbabilityOperatorsAllowed() const;
FragmentSpecification& setProbabilityOperatorsAllowed(bool newValue);
bool areRewardOperatorsAllowed() const;
FragmentSpecification& setRewardOperatorsAllowed(bool newValue);
bool areExpectedTimeOperatorsAllowed() const;
FragmentSpecification& setExpectedTimeOperatorsAllowed(bool newValue);
bool areLongRunAverageOperatorsAllowed() const;
FragmentSpecification& setLongRunAverageOperatorsAllowed(bool newValue);
bool areGloballyFormulasAllowed() const;
FragmentSpecification& setGloballyFormulasAllowed(bool newValue);
bool areEventuallyFormulasAllowed() const;
FragmentSpecification& setEventuallyFormulasAllowed(bool newValue);
bool areNextFormulasAllowed() const;
FragmentSpecification& setNextFormulasAllowed(bool newValue);
bool areUntilFormulasAllowed() const;
FragmentSpecification& setUntilFormulasAllowed(bool newValue);
bool areBoundedUntilFormulasAllowed() const;
FragmentSpecification& setBoundedUntilFormulasAllowed(bool newValue);
bool areAtomicExpressionFormulasAllowed() const;
FragmentSpecification& setAtomicExpressionFormulasAllowed(bool newValue);
bool areAtomicLabelFormulasAllowed() const;
FragmentSpecification& setAtomicLabelFormulasAllowed(bool newValue);
bool areBooleanLiteralFormulasAllowed() const;
FragmentSpecification& setBooleanLiteralFormulasAllowed(bool newValue);
bool areUnaryBooleanStateFormulasAllowed() const;
FragmentSpecification& setUnaryBooleanStateFormulasAllowed(bool newValue);
bool areBinaryBooleanStateFormulasAllowed() const;
FragmentSpecification& setBinaryBooleanStateFormulasAllowed(bool newValue);
bool areCumulativeRewardFormulasAllowed() const;
FragmentSpecification& setCumulativeRewardFormulasAllowed(bool newValue);
bool areInstantaneousRewardFormulasAllowed() const;
FragmentSpecification& setInstantaneousFormulasAllowed(bool newValue);
bool areReachabilityRewardFormulasAllowed() const;
FragmentSpecification& setReachabilityRewardFormulasAllowed(bool newValue);
bool areLongRunAverageRewardFormulasAllowed() const;
FragmentSpecification& setLongRunAverageRewardFormulasAllowed(bool newValue);
bool areConditionalProbabilityFormulasAllowed() const;
FragmentSpecification& setConditionalProbabilityFormulasAllowed(bool newValue);
bool areConditionalRewardFormulasFormulasAllowed() const;
FragmentSpecification& setConditionalRewardFormulasAllowed(bool newValue);
bool areReachbilityExpectedTimeFormulasAllowed() const;
FragmentSpecification& setReachbilityExpectedTimeFormulasAllowed(bool newValue);
bool areNestedOperatorsAllowed() const;
FragmentSpecification& setNestedOperatorsAllowed(bool newValue);
bool areNestedPathFormulasAllowed() const;
FragmentSpecification& setNestedPathFormulasAllowed(bool newValue);
bool areOnlyEventuallyFormuluasInConditionalFormulasAllowed() const;
FragmentSpecification& setOnlyEventuallyFormuluasInConditionalFormulasAllowed(bool newValue);
bool areStepBoundedUntilFormulasAllowed() const;
FragmentSpecification& setStepBoundedUntilFormulasAllowed(bool newValue);
bool areTimeBoundedUntilFormulasAllowed() const;
FragmentSpecification& setTimeBoundedUntilFormulasAllowed(bool newValue);
FragmentSpecification& setOperatorsAllowed(bool newValue);
FragmentSpecification& setExpectedTimeAllowed(bool newValue);
FragmentSpecification& setLongRunAverageProbabilitiesAllowed(bool newValue);
private:
// Flags that indicate whether it is legal to see such a formula.
bool probabilityOperator;
bool rewardOperator;
bool expectedTimeOperator;
bool longRunAverageOperator;
bool globallyFormula;
bool eventuallyFormula;
bool nextFormula;
bool untilFormula;
bool boundedUntilFormula;
bool atomicExpressionFormula;
bool atomicLabelFormula;
bool booleanLiteralFormula;
bool unaryBooleanStateFormula;
bool binaryBooleanStateFormula;
bool cumulativeRewardFormula;
bool instantaneousRewardFormula;
bool reachabilityRewardFormula;
bool longRunAverageRewardFormula;
bool conditionalProbabilityFormula;
bool conditionalRewardFormula;
bool reachabilityExpectedTimeFormula;
// Members that indicate certain restrictions.
bool nestedOperators;
bool nestedPathFormulas;
bool onlyEventuallyFormuluasInConditionalFormulas;
bool stepBoundedUntilFormulas;
bool timeBoundedUntilFormulas;
};
// Propositional.
FragmentSpecification propositional();
// Regular PCTL.
FragmentSpecification pctl();
// PCTL + cumulative, instantaneous, reachability and long-run rewards.
FragmentSpecification prctl();
// Regular CSL.
FragmentSpecification csl();
// CSL + cumulative, instantaneous, reachability and long-run rewards.
FragmentSpecification csrl();
}
}
#endif /* STORM_LOGIC_FRAGMENTSPECIFICATION_H_ */

10
src/logic/GloballyFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/GloballyFormula.h" #include "src/logic/GloballyFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
GloballyFormula::GloballyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { GloballyFormula::GloballyFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) {
@ -9,7 +11,15 @@ namespace storm {
bool GloballyFormula::isGloballyFormula() const { bool GloballyFormula::isGloballyFormula() const {
return true; return true;
} }
bool GloballyFormula::isProbabilityPathFormula() const {
return true;
}
boost::any GloballyFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> GloballyFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution)); return std::make_shared<GloballyFormula>(this->getSubformula().substitute(substitution));
} }

5
src/logic/GloballyFormula.h

@ -14,7 +14,10 @@ namespace storm {
} }
virtual bool isGloballyFormula() const override; virtual bool isGloballyFormula() const override;
virtual bool isProbabilityPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;

10
src/logic/InstantaneousRewardFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/InstantaneousRewardFormula.h" #include "src/logic/InstantaneousRewardFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
InstantaneousRewardFormula::InstantaneousRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) { InstantaneousRewardFormula::InstantaneousRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
@ -14,6 +16,14 @@ namespace storm {
return true; return true;
} }
bool InstantaneousRewardFormula::isRewardPathFormula() const {
return true;
}
boost::any InstantaneousRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
bool InstantaneousRewardFormula::hasDiscreteTimeBound() const { bool InstantaneousRewardFormula::hasDiscreteTimeBound() const {
return timeBound.which() == 0; return timeBound.which() == 0;
} }

8
src/logic/InstantaneousRewardFormula.h

@ -3,11 +3,11 @@
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include "src/logic/RewardPathFormula.h" #include "src/logic/PathFormula.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
class InstantaneousRewardFormula : public RewardPathFormula { class InstantaneousRewardFormula : public PathFormula {
public: public:
InstantaneousRewardFormula(uint_fast64_t timeBound); InstantaneousRewardFormula(uint_fast64_t timeBound);
@ -18,6 +18,10 @@ namespace storm {
} }
virtual bool isInstantaneousRewardFormula() const override; virtual bool isInstantaneousRewardFormula() const override;
virtual bool isRewardPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;

14
src/logic/LongRunAverageOperatorFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/LongRunAverageOperatorFormula.h" #include "src/logic/LongRunAverageOperatorFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(std::shared_ptr<Formula const> const& subformula) : LongRunAverageOperatorFormula(boost::none, boost::none, subformula) { LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(std::shared_ptr<Formula const> const& subformula) : LongRunAverageOperatorFormula(boost::none, boost::none, subformula) {
@ -22,16 +24,8 @@ namespace storm {
return true; return true;
} }
bool LongRunAverageOperatorFormula::isPctlStateFormula() const { boost::any LongRunAverageOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return this->getSubformula().isPctlStateFormula(); return visitor.visit(*this, data);
}
bool LongRunAverageOperatorFormula::containsProbabilityOperator() const {
return this->getSubformula().containsProbabilityOperator();
}
bool LongRunAverageOperatorFormula::containsNestedProbabilityOperators() const {
return this->getSubformula().containsNestedProbabilityOperators();
} }
LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { LongRunAverageOperatorFormula::LongRunAverageOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {

4
src/logic/LongRunAverageOperatorFormula.h

@ -19,9 +19,7 @@ namespace storm {
virtual bool isLongRunAverageOperatorFormula() const override; virtual bool isLongRunAverageOperatorFormula() const override;
virtual bool isPctlStateFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

10
src/logic/LongRunAverageRewardFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/LongRunAverageRewardFormula.h" #include "src/logic/LongRunAverageRewardFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
LongRunAverageRewardFormula::LongRunAverageRewardFormula() { LongRunAverageRewardFormula::LongRunAverageRewardFormula() {
@ -10,6 +12,14 @@ namespace storm {
return true; return true;
} }
bool LongRunAverageRewardFormula::isRewardPathFormula() const {
return true;
}
boost::any LongRunAverageRewardFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> LongRunAverageRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::shared_ptr<Formula>(new LongRunAverageRewardFormula()); return std::shared_ptr<Formula>(new LongRunAverageRewardFormula());
} }

12
src/logic/LongRunAverageRewardFormula.h

@ -1,14 +1,11 @@
#ifndef STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_ #ifndef STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_
#define STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_ #define STORM_LOGIC_LONGRUNAVERAGEREWARDFORMULA_H_
#include <memory> #include "src/logic/PathFormula.h"
#include "src/logic/RewardPathFormula.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
class LongRunAverageRewardFormula : public RewardPathFormula { class LongRunAverageRewardFormula : public PathFormula {
public: public:
LongRunAverageRewardFormula(); LongRunAverageRewardFormula();
@ -17,7 +14,10 @@ namespace storm {
} }
virtual bool isLongRunAverageRewardFormula() const override; virtual bool isLongRunAverageRewardFormula() const override;
virtual bool isRewardPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;

8
src/logic/NextFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/NextFormula.h" #include "src/logic/NextFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
NextFormula::NextFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) { NextFormula::NextFormula(std::shared_ptr<Formula const> const& subformula) : UnaryPathFormula(subformula) {
@ -10,10 +12,14 @@ namespace storm {
return true; return true;
} }
bool NextFormula::containsNextFormula() const { bool NextFormula::isProbabilityPathFormula() const {
return true; return true;
} }
boost::any NextFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
std::shared_ptr<Formula> NextFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> NextFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<NextFormula>(this->getSubformula().substitute(substitution)); return std::make_shared<NextFormula>(this->getSubformula().substitute(substitution));
} }

5
src/logic/NextFormula.h

@ -14,8 +14,9 @@ namespace storm {
} }
virtual bool isNextFormula() const override; virtual bool isNextFormula() const override;
virtual bool isProbabilityPathFormula() const override;
virtual bool containsNextFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

24
src/logic/ProbabilityOperatorFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/ProbabilityOperatorFormula.h" #include "src/logic/ProbabilityOperatorFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
ProbabilityOperatorFormula::ProbabilityOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ProbabilityOperatorFormula(boost::none, boost::none, subformula) { ProbabilityOperatorFormula::ProbabilityOperatorFormula(std::shared_ptr<Formula const> const& subformula) : ProbabilityOperatorFormula(boost::none, boost::none, subformula) {
@ -22,26 +24,10 @@ namespace storm {
return true; return true;
} }
bool ProbabilityOperatorFormula::isPctlStateFormula() const { boost::any ProbabilityOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return this->getSubformula().isPctlPathFormula(); return visitor.visit(*this, data);
}
bool ProbabilityOperatorFormula::isCslStateFormula() const {
return this->getSubformula().isCslPathFormula();
} }
bool ProbabilityOperatorFormula::isPltlFormula() const {
return this->getSubformula().isLtlFormula();
}
bool ProbabilityOperatorFormula::containsProbabilityOperator() const {
return true;
}
bool ProbabilityOperatorFormula::containsNestedProbabilityOperators() const {
return this->getSubformula().containsProbabilityOperator();
}
ProbabilityOperatorFormula::ProbabilityOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) { ProbabilityOperatorFormula::ProbabilityOperatorFormula(boost::optional<OptimizationDirection> optimalityType, boost::optional<Bound<double>> bound, std::shared_ptr<Formula const> const& subformula) : OperatorFormula(optimalityType, bound, subformula) {
// Intentionally left empty. // Intentionally left empty.
} }

8
src/logic/ProbabilityOperatorFormula.h

@ -17,13 +17,9 @@ namespace storm {
// Intentionally left empty. // Intentionally left empty.
} }
virtual bool isPctlStateFormula() const override;
virtual bool isCslStateFormula() const override;
virtual bool isPltlFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual bool isProbabilityOperatorFormula() const override; virtual bool isProbabilityOperatorFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

35
src/logic/ReachabilityRewardFormula.cpp

@ -1,35 +0,0 @@
#include "src/logic/ReachabilityRewardFormula.h"
namespace storm {
namespace logic {
ReachabilityRewardFormula::ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula) : subformula(subformula) {
// Intentionally left empty.
}
bool ReachabilityRewardFormula::isReachabilityRewardFormula() const {
return true;
}
Formula const& ReachabilityRewardFormula::getSubformula() const {
return *subformula;
}
void ReachabilityRewardFormula::gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const {
this->getSubformula().gatherAtomicExpressionFormulas(atomicExpressionFormulas);
}
void ReachabilityRewardFormula::gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const {
this->getSubformula().gatherAtomicLabelFormulas(atomicLabelFormulas);
}
std::shared_ptr<Formula> ReachabilityRewardFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<ReachabilityRewardFormula>(this->getSubformula().substitute(substitution));
}
std::ostream& ReachabilityRewardFormula::writeToStream(std::ostream& out) const {
out << "F ";
this->getSubformula().writeToStream(out);
return out;
}
}
}

36
src/logic/ReachabilityRewardFormula.h

@ -1,36 +0,0 @@
#ifndef STORM_LOGIC_REACHABILITYREWARDFORMULA_H_
#define STORM_LOGIC_REACHABILITYREWARDFORMULA_H_
#include <memory>
#include "src/logic/RewardPathFormula.h"
namespace storm {
namespace logic {
class ReachabilityRewardFormula : public RewardPathFormula {
public:
ReachabilityRewardFormula(std::shared_ptr<Formula const> const& subformula);
virtual ~ReachabilityRewardFormula() {
// Intentionally left empty.
}
virtual bool isReachabilityRewardFormula() const override;
Formula const& getSubformula() const;
virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;
virtual void gatherAtomicLabelFormulas(std::vector<std::shared_ptr<AtomicLabelFormula const>>& atomicLabelFormulas) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;
private:
std::shared_ptr<Formula const> subformula;
};
}
}
#endif /* STORM_LOGIC_REACHABILITYREWARDFORMULA_H_ */

20
src/logic/RewardOperatorFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/RewardOperatorFormula.h" #include "src/logic/RewardOperatorFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::none, boost::none, subformula) { RewardOperatorFormula::RewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::shared_ptr<Formula const> const& subformula) : RewardOperatorFormula(rewardModelName, boost::none, boost::none, subformula) {
@ -22,24 +24,16 @@ namespace storm {
return true; return true;
} }
bool RewardOperatorFormula::isPctlStateFormula() const { boost::any RewardOperatorFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return this->getSubformula().isRewardPathFormula(); return visitor.visit(*this, data);
} }
bool RewardOperatorFormula::containsRewardOperator() const { std::string const& RewardOperatorFormula::getRewardModelName() const {
return true; return this->rewardModelName.get();
}
bool RewardOperatorFormula::containsNestedRewardOperators() const {
return this->getSubformula().containsRewardOperator();
} }
bool RewardOperatorFormula::hasRewardModelName() const { bool RewardOperatorFormula::hasRewardModelName() const {
return static_cast<bool>(this->rewardModelName); return static_cast<bool>(rewardModelName);
}
std::string const& RewardOperatorFormula::getRewardModelName() const {
return this->rewardModelName.get();
} }
boost::optional<std::string> const& RewardOperatorFormula::getOptionalRewardModelName() const { boost::optional<std::string> const& RewardOperatorFormula::getOptionalRewardModelName() const {

6
src/logic/RewardOperatorFormula.h

@ -20,10 +20,8 @@ namespace storm {
virtual bool isRewardOperatorFormula() const override; virtual bool isRewardOperatorFormula() const override;
virtual bool isPctlStateFormula() const override; virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual bool containsRewardOperator() const override;
virtual bool containsNestedRewardOperators() const override;
virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override; virtual void gatherReferencedRewardModels(std::set<std::string>& referencedRewardModels) const override;
virtual std::ostream& writeToStream(std::ostream& out) const override; virtual std::ostream& writeToStream(std::ostream& out) const override;

9
src/logic/RewardPathFormula.cpp

@ -1,9 +0,0 @@
#include "src/logic/RewardPathFormula.h"
namespace storm {
namespace logic {
bool RewardPathFormula::isRewardPathFormula() const {
return true;
}
}
}

19
src/logic/RewardPathFormula.h

@ -1,19 +0,0 @@
#ifndef STORM_LOGIC_PATHREWARDFORMULA_H_
#define STORM_LOGIC_PATHREWARDFORMULA_H_
#include "src/logic/PathFormula.h"
namespace storm {
namespace logic {
class RewardPathFormula : public Formula {
public:
virtual ~RewardPathFormula() {
// Intentionally left empty.
}
virtual bool isRewardPathFormula() const override;
};
}
}
#endif /* STORM_LOGIC_PATHREWARDFORMULA_H_ */

6
src/logic/UnaryBooleanStateFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/UnaryBooleanStateFormula.h" #include "src/logic/UnaryBooleanStateFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
UnaryBooleanStateFormula::UnaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& subformula) : UnaryStateFormula(subformula), operatorType(operatorType) { UnaryBooleanStateFormula::UnaryBooleanStateFormula(OperatorType operatorType, std::shared_ptr<Formula const> const& subformula) : UnaryStateFormula(subformula), operatorType(operatorType) {
@ -9,6 +11,10 @@ namespace storm {
bool UnaryBooleanStateFormula::isUnaryBooleanStateFormula() const { bool UnaryBooleanStateFormula::isUnaryBooleanStateFormula() const {
return true; return true;
} }
boost::any UnaryBooleanStateFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
UnaryBooleanStateFormula::OperatorType UnaryBooleanStateFormula::getOperator() const { UnaryBooleanStateFormula::OperatorType UnaryBooleanStateFormula::getOperator() const {
return operatorType; return operatorType;

2
src/logic/UnaryBooleanStateFormula.h

@ -17,6 +17,8 @@ namespace storm {
virtual bool isUnaryBooleanStateFormula() const override; virtual bool isUnaryBooleanStateFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
OperatorType getOperator() const; OperatorType getOperator() const;
virtual bool isNot() const; virtual bool isNot() const;

34
src/logic/UnaryPathFormula.cpp

@ -9,39 +9,7 @@ namespace storm {
bool UnaryPathFormula::isUnaryPathFormula() const { bool UnaryPathFormula::isUnaryPathFormula() const {
return true; return true;
} }
bool UnaryPathFormula::isPctlPathFormula() const {
return this->getSubformula().isPctlStateFormula();
}
bool UnaryPathFormula::isLtlFormula() const {
return this->getSubformula().isLtlFormula();
}
bool UnaryPathFormula::containsBoundedUntilFormula() const {
return this->getSubformula().containsBoundedUntilFormula();
}
bool UnaryPathFormula::containsNextFormula() const {
return this->getSubformula().containsNextFormula();
}
bool UnaryPathFormula::containsProbabilityOperator() const {
return this->getSubformula().containsProbabilityOperator();
}
bool UnaryPathFormula::containsNestedProbabilityOperators() const {
return this->getSubformula().containsNestedProbabilityOperators();
}
bool UnaryPathFormula::containsRewardOperator() const {
return this->getSubformula().containsRewardOperator();
}
bool UnaryPathFormula::containsNestedRewardOperators() const {
return this->getSubformula().containsNestedRewardOperators();
}
Formula const& UnaryPathFormula::getSubformula() const { Formula const& UnaryPathFormula::getSubformula() const {
return *subformula; return *subformula;
} }

9
src/logic/UnaryPathFormula.h

@ -17,15 +17,6 @@ namespace storm {
virtual bool isUnaryPathFormula() const override; virtual bool isUnaryPathFormula() const override;
virtual bool isPctlPathFormula() const override;
virtual bool isLtlFormula() const override;
virtual bool containsBoundedUntilFormula() const override;
virtual bool containsNextFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual bool containsRewardOperator() const override;
virtual bool containsNestedRewardOperators() const override;
Formula const& getSubformula() const; Formula const& getSubformula() const;
virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override; virtual void gatherAtomicExpressionFormulas(std::vector<std::shared_ptr<AtomicExpressionFormula const>>& atomicExpressionFormulas) const override;

38
src/logic/UnaryStateFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/UnaryStateFormula.h" #include "src/logic/UnaryStateFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
UnaryStateFormula::UnaryStateFormula(std::shared_ptr<Formula const> subformula) : subformula(subformula) { UnaryStateFormula::UnaryStateFormula(std::shared_ptr<Formula const> subformula) : subformula(subformula) {
@ -10,42 +12,6 @@ namespace storm {
return true; return true;
} }
bool UnaryStateFormula::isPropositionalFormula() const {
return this->getSubformula().isPropositionalFormula();
}
bool UnaryStateFormula::isPctlStateFormula() const {
return this->getSubformula().isPctlStateFormula();
}
bool UnaryStateFormula::isLtlFormula() const {
return this->getSubformula().isLtlFormula();
}
bool UnaryStateFormula::containsBoundedUntilFormula() const {
return this->getSubformula().containsBoundedUntilFormula();
}
bool UnaryStateFormula::containsNextFormula() const {
return this->getSubformula().containsNextFormula();
}
bool UnaryStateFormula::containsProbabilityOperator() const {
return getSubformula().containsProbabilityOperator();
}
bool UnaryStateFormula::containsNestedProbabilityOperators() const {
return getSubformula().containsNestedProbabilityOperators();
}
bool UnaryStateFormula::containsRewardOperator() const {
return this->getSubformula().containsRewardOperator();
}
bool UnaryStateFormula::containsNestedRewardOperators() const {
return this->getSubformula().containsNestedRewardOperators();
}
Formula const& UnaryStateFormula::getSubformula() const { Formula const& UnaryStateFormula::getSubformula() const {
return *subformula; return *subformula;
} }

10
src/logic/UnaryStateFormula.h

@ -14,16 +14,6 @@ namespace storm {
} }
virtual bool isUnaryStateFormula() const override; virtual bool isUnaryStateFormula() const override;
virtual bool isPropositionalFormula() const override;
virtual bool isPctlStateFormula() const override;
virtual bool isLtlFormula() const override;
virtual bool containsBoundedUntilFormula() const override;
virtual bool containsNextFormula() const override;
virtual bool containsProbabilityOperator() const override;
virtual bool containsNestedProbabilityOperators() const override;
virtual bool containsRewardOperator() const override;
virtual bool containsNestedRewardOperators() const override;
Formula const& getSubformula() const; Formula const& getSubformula() const;

10
src/logic/UntilFormula.cpp

@ -1,5 +1,7 @@
#include "src/logic/UntilFormula.h" #include "src/logic/UntilFormula.h"
#include "src/logic/FormulaVisitor.h"
namespace storm { namespace storm {
namespace logic { namespace logic {
UntilFormula::UntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) { UntilFormula::UntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula) : BinaryPathFormula(leftSubformula, rightSubformula) {
@ -10,6 +12,14 @@ namespace storm {
return true; return true;
} }
bool UntilFormula::isProbabilityPathFormula() const {
return true;
}
boost::any UntilFormula::accept(FormulaVisitor const& visitor, boost::any const& data) const {
return visitor.visit(*this, data);
}
std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const { std::shared_ptr<Formula> UntilFormula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution)); return std::make_shared<UntilFormula>(this->getLeftSubformula().substitute(substitution), this->getRightSubformula().substitute(substitution));
} }

3
src/logic/UntilFormula.h

@ -14,6 +14,9 @@ namespace storm {
} }
virtual bool isUntilFormula() const override; virtual bool isUntilFormula() const override;
virtual bool isProbabilityPathFormula() const override;
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override; virtual std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const override;

122
src/modelchecker/AbstractModelChecker.cpp

@ -15,45 +15,51 @@ namespace storm {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
STORM_LOG_THROW(this->canHandle(formula), storm::exceptions::InvalidArgumentException, "The model checker is not able to check the formula '" << formula << "'."); STORM_LOG_THROW(this->canHandle(formula), storm::exceptions::InvalidArgumentException, "The model checker is not able to check the formula '" << formula << "'.");
if (formula.isStateFormula()) { if (formula.isStateFormula()) {
return this->checkStateFormula(checkTask.replaceFormula(formula.asStateFormula())); return this->checkStateFormula(checkTask.substituteFormula(formula.asStateFormula()));
} else if (formula.isPathFormula()) { } else if (formula.isPathFormula()) {
return this->computeProbabilities(checkTask.replaceFormula(formula.asPathFormula())); if (formula.isProbabilityPathFormula()) {
} else if (formula.isRewardPathFormula()) { return this->computeProbabilities(checkTask);
return this->computeRewards(checkTask.replaceFormula(formula.asRewardPathFormula())); } else if (formula.isRewardPathFormula()) {
return this->computeRewards(checkTask);
}
} else if (formula.isConditionalProbabilityFormula()) {
return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula()));
} else if (formula.isConditionalRewardFormula()) {
return this->computeConditionalRewards(checkTask.substituteFormula(formula.asConditionalFormula()));
} }
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid."); STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask) {
storm::logic::PathFormula const& pathFormula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (pathFormula.isBoundedUntilFormula()) { if (formula.isBoundedUntilFormula()) {
return this->computeBoundedUntilProbabilities(checkTask.replaceFormula(pathFormula.asBoundedUntilFormula())); return this->computeBoundedUntilProbabilities(checkTask.substituteFormula(formula.asBoundedUntilFormula()));
} else if (pathFormula.isConditionalPathFormula()) { } else if (formula.isEventuallyFormula()) {
return this->computeConditionalProbabilities(checkTask.replaceFormula(pathFormula.asConditionalPathFormula())); return this->computeEventuallyProbabilities(checkTask.substituteFormula(formula.asEventuallyFormula()));
} else if (pathFormula.isEventuallyFormula()) { } else if (formula.isGloballyFormula()) {
return this->computeEventuallyProbabilities(checkTask.replaceFormula(pathFormula.asEventuallyFormula())); return this->computeGloballyProbabilities(checkTask.substituteFormula(formula.asGloballyFormula()));
} else if (pathFormula.isGloballyFormula()) { } else if (formula.isUntilFormula()) {
return this->computeGloballyProbabilities(checkTask.replaceFormula(pathFormula.asGloballyFormula())); return this->computeUntilProbabilities(checkTask.substituteFormula(formula.asUntilFormula()));
} else if (pathFormula.isUntilFormula()) { } else if (formula.isNextFormula()) {
return this->computeUntilProbabilities(checkTask.replaceFormula(pathFormula.asUntilFormula())); return this->computeNextProbabilities(checkTask.substituteFormula(formula.asNextFormula()));
} else if (pathFormula.isNextFormula()) { } else if (formula.isConditionalProbabilityFormula()) {
return this->computeNextProbabilities(checkTask.replaceFormula(pathFormula.asNextFormula())); return this->computeConditionalProbabilities(checkTask.substituteFormula(formula.asConditionalFormula()));
} }
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << pathFormula << "' is invalid."); STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << formula << "' is invalid.");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::EventuallyFormula const& pathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& pathFormula = checkTask.getFormula();
storm::logic::UntilFormula newFormula(storm::logic::Formula::getTrueFormula(), pathFormula.getSubformula().asSharedPointer()); storm::logic::UntilFormula newFormula(storm::logic::Formula::getTrueFormula(), pathFormula.getSubformula().asSharedPointer());
return this->computeUntilProbabilities(checkTask.replaceFormula(newFormula)); return this->computeUntilProbabilities(checkTask.substituteFormula(newFormula));
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) {
@ -68,18 +74,24 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeRewards(CheckTask<storm::logic::Formula> const& checkTask) {
storm::logic::RewardPathFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::Formula const& rewardFormula = checkTask.getFormula();
if (rewardPathFormula.isCumulativeRewardFormula()) { if (rewardFormula.isCumulativeRewardFormula()) {
return this->computeCumulativeRewards(checkTask.replaceFormula(rewardPathFormula.asCumulativeRewardFormula())); return this->computeCumulativeRewards(checkTask.substituteFormula(rewardFormula.asCumulativeRewardFormula()));
} else if (rewardPathFormula.isInstantaneousRewardFormula()) { } else if (rewardFormula.isInstantaneousRewardFormula()) {
return this->computeInstantaneousRewards(checkTask.replaceFormula(rewardPathFormula.asInstantaneousRewardFormula())); return this->computeInstantaneousRewards(checkTask.substituteFormula(rewardFormula.asInstantaneousRewardFormula()));
} else if (rewardPathFormula.isReachabilityRewardFormula()) { } else if (rewardFormula.isReachabilityRewardFormula()) {
return this->computeReachabilityRewards(checkTask.replaceFormula(rewardPathFormula.asReachabilityRewardFormula())); return this->computeReachabilityRewards(checkTask.substituteFormula(rewardFormula.asEventuallyFormula()));
} else if (rewardPathFormula.isLongRunAverageRewardFormula()) { } else if (rewardFormula.isLongRunAverageRewardFormula()) {
return this->computeLongRunAverageRewards(checkTask.replaceFormula(rewardPathFormula.asLongRunAverageRewardFormula())); return this->computeLongRunAverageRewards(checkTask.substituteFormula(rewardFormula.asLongRunAverageRewardFormula()));
} else if (rewardFormula.isConditionalRewardFormula()) {
return this->computeConditionalRewards(checkTask.substituteFormula(rewardFormula.asConditionalFormula()));
} }
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardPathFormula << "' is invalid."); STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << rewardFormula << "' is invalid.");
}
std::unique_ptr<CheckResult> AbstractModelChecker::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) {
@ -90,7 +102,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << "."); STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "This model checker does not support the formula: " << checkTask.getFormula() << ".");
} }
@ -109,25 +121,25 @@ namespace storm {
std::unique_ptr<CheckResult> AbstractModelChecker::checkStateFormula(CheckTask<storm::logic::StateFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkStateFormula(CheckTask<storm::logic::StateFormula> const& checkTask) {
storm::logic::StateFormula const& stateFormula = checkTask.getFormula(); storm::logic::StateFormula const& stateFormula = checkTask.getFormula();
if (stateFormula.isBinaryBooleanStateFormula()) { if (stateFormula.isBinaryBooleanStateFormula()) {
return this->checkBinaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asBinaryBooleanStateFormula())); return this->checkBinaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asBinaryBooleanStateFormula()));
} else if (stateFormula.isUnaryBooleanStateFormula()) { } else if (stateFormula.isUnaryBooleanStateFormula()) {
return this->checkUnaryBooleanStateFormula(checkTask.replaceFormula(stateFormula.asUnaryBooleanStateFormula())); return this->checkUnaryBooleanStateFormula(checkTask.substituteFormula(stateFormula.asUnaryBooleanStateFormula()));
} else if (stateFormula.isBooleanLiteralFormula()) { } else if (stateFormula.isBooleanLiteralFormula()) {
return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula())); return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula()));
} else if (stateFormula.isProbabilityOperatorFormula()) { } else if (stateFormula.isProbabilityOperatorFormula()) {
return this->checkProbabilityOperatorFormula(checkTask.replaceFormula(stateFormula.asProbabilityOperatorFormula())); return this->checkProbabilityOperatorFormula(checkTask.substituteFormula(stateFormula.asProbabilityOperatorFormula()));
} else if (stateFormula.isRewardOperatorFormula()) { } else if (stateFormula.isRewardOperatorFormula()) {
return this->checkRewardOperatorFormula(checkTask.replaceFormula(stateFormula.asRewardOperatorFormula())); return this->checkRewardOperatorFormula(checkTask.substituteFormula(stateFormula.asRewardOperatorFormula()));
} else if (stateFormula.isExpectedTimeOperatorFormula()) { } else if (stateFormula.isExpectedTimeOperatorFormula()) {
return this->checkExpectedTimeOperatorFormula(checkTask.replaceFormula(stateFormula.asExpectedTimeOperatorFormula())); return this->checkExpectedTimeOperatorFormula(checkTask.substituteFormula(stateFormula.asExpectedTimeOperatorFormula()));
} else if (stateFormula.isLongRunAverageOperatorFormula()) { } else if (stateFormula.isLongRunAverageOperatorFormula()) {
return this->checkLongRunAverageOperatorFormula(checkTask.replaceFormula(stateFormula.asLongRunAverageOperatorFormula())); return this->checkLongRunAverageOperatorFormula(checkTask.substituteFormula(stateFormula.asLongRunAverageOperatorFormula()));
} else if (stateFormula.isAtomicExpressionFormula()) { } else if (stateFormula.isAtomicExpressionFormula()) {
return this->checkAtomicExpressionFormula(checkTask.replaceFormula(stateFormula.asAtomicExpressionFormula())); return this->checkAtomicExpressionFormula(checkTask.substituteFormula(stateFormula.asAtomicExpressionFormula()));
} else if (stateFormula.isAtomicLabelFormula()) { } else if (stateFormula.isAtomicLabelFormula()) {
return this->checkAtomicLabelFormula(checkTask.replaceFormula(stateFormula.asAtomicLabelFormula())); return this->checkAtomicLabelFormula(checkTask.substituteFormula(stateFormula.asAtomicLabelFormula()));
} else if (stateFormula.isBooleanLiteralFormula()) { } else if (stateFormula.isBooleanLiteralFormula()) {
return this->checkBooleanLiteralFormula(checkTask.replaceFormula(stateFormula.asBooleanLiteralFormula())); return this->checkBooleanLiteralFormula(checkTask.substituteFormula(stateFormula.asBooleanLiteralFormula()));
} }
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << stateFormula << "' is invalid."); STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The given formula '" << stateFormula << "' is invalid.");
} }
@ -136,7 +148,7 @@ namespace storm {
storm::logic::AtomicExpressionFormula const& stateFormula = checkTask.getFormula(); storm::logic::AtomicExpressionFormula const& stateFormula = checkTask.getFormula();
std::stringstream stream; std::stringstream stream;
stream << stateFormula.getExpression(); stream << stateFormula.getExpression();
return this->checkAtomicLabelFormula(checkTask.replaceFormula(storm::logic::AtomicLabelFormula(stream.str()))); return this->checkAtomicLabelFormula(checkTask.substituteFormula(storm::logic::AtomicLabelFormula(stream.str())));
} }
std::unique_ptr<CheckResult> AbstractModelChecker::checkAtomicLabelFormula(CheckTask<storm::logic::AtomicLabelFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkAtomicLabelFormula(CheckTask<storm::logic::AtomicLabelFormula> const& checkTask) {
@ -147,8 +159,8 @@ namespace storm {
storm::logic::BinaryBooleanStateFormula const& stateFormula = checkTask.getFormula(); storm::logic::BinaryBooleanStateFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(stateFormula.getLeftSubformula().isStateFormula() && stateFormula.getRightSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); STORM_LOG_THROW(stateFormula.getLeftSubformula().isStateFormula() && stateFormula.getRightSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
std::unique_ptr<CheckResult> leftResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula())); std::unique_ptr<CheckResult> leftResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getLeftSubformula().asStateFormula()));
std::unique_ptr<CheckResult> rightResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula())); std::unique_ptr<CheckResult> rightResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getRightSubformula().asStateFormula()));
STORM_LOG_THROW(leftResult->isQualitative() && rightResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative results."); STORM_LOG_THROW(leftResult->isQualitative() && rightResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative results.");
@ -169,9 +181,7 @@ namespace storm {
std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkProbabilityOperatorFormula(CheckTask<storm::logic::ProbabilityOperatorFormula> const& checkTask) {
storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula(); storm::logic::ProbabilityOperatorFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(stateFormula.getSubformula().isPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.substituteFormula(stateFormula.getSubformula()));
std::unique_ptr<CheckResult> result = this->computeProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asPathFormula()));
if (stateFormula.hasBound()) { if (stateFormula.hasBound()) {
STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@ -183,9 +193,7 @@ namespace storm {
std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkRewardOperatorFormula(CheckTask<storm::logic::RewardOperatorFormula> const& checkTask) {
storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula(); storm::logic::RewardOperatorFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(stateFormula.getSubformula().isRewardPathFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.substituteFormula(stateFormula.getSubformula()));
std::unique_ptr<CheckResult> result = this->computeRewards(checkTask.replaceFormula(stateFormula.getSubformula().asRewardPathFormula()));
if (checkTask.isBoundSet()) { if (checkTask.isBoundSet()) {
STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@ -197,9 +205,9 @@ namespace storm {
std::unique_ptr<CheckResult> AbstractModelChecker::checkExpectedTimeOperatorFormula(CheckTask<storm::logic::ExpectedTimeOperatorFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkExpectedTimeOperatorFormula(CheckTask<storm::logic::ExpectedTimeOperatorFormula> const& checkTask) {
storm::logic::ExpectedTimeOperatorFormula const& stateFormula = checkTask.getFormula(); storm::logic::ExpectedTimeOperatorFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(stateFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); STORM_LOG_THROW(stateFormula.getSubformula().isReachbilityExpectedTimeFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.replaceFormula(stateFormula.getSubformula().asEventuallyFormula())); std::unique_ptr<CheckResult> result = this->computeExpectedTimes(checkTask.substituteFormula(stateFormula.getSubformula().asEventuallyFormula()));
if (checkTask.isBoundSet()) { if (checkTask.isBoundSet()) {
STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@ -213,7 +221,7 @@ namespace storm {
storm::logic::LongRunAverageOperatorFormula const& stateFormula = checkTask.getFormula(); storm::logic::LongRunAverageOperatorFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(stateFormula.getSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid."); STORM_LOG_THROW(stateFormula.getSubformula().isStateFormula(), storm::exceptions::InvalidArgumentException, "The given formula is invalid.");
std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.replaceFormula(stateFormula.getSubformula().asStateFormula())); std::unique_ptr<CheckResult> result = this->computeLongRunAverageProbabilities(checkTask.substituteFormula(stateFormula.getSubformula().asStateFormula()));
if (checkTask.isBoundSet()) { if (checkTask.isBoundSet()) {
STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result."); STORM_LOG_THROW(result->isQuantitative(), storm::exceptions::InvalidOperationException, "Unable to perform comparison operation on non-quantitative result.");
@ -225,7 +233,7 @@ namespace storm {
std::unique_ptr<CheckResult> AbstractModelChecker::checkUnaryBooleanStateFormula(CheckTask<storm::logic::UnaryBooleanStateFormula> const& checkTask) { std::unique_ptr<CheckResult> AbstractModelChecker::checkUnaryBooleanStateFormula(CheckTask<storm::logic::UnaryBooleanStateFormula> const& checkTask) {
storm::logic::UnaryBooleanStateFormula const& stateFormula = checkTask.getFormula(); storm::logic::UnaryBooleanStateFormula const& stateFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResult = this->check(checkTask.replaceFormula<storm::logic::Formula>(stateFormula.getSubformula())); std::unique_ptr<CheckResult> subResult = this->check(checkTask.substituteFormula<storm::logic::Formula>(stateFormula.getSubformula()));
STORM_LOG_THROW(subResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative result."); STORM_LOG_THROW(subResult->isQualitative(), storm::exceptions::InternalTypeErrorException, "Expected qualitative result.");
if (stateFormula.isNot()) { if (stateFormula.isNot()) {
subResult->asQualitativeCheckResult().complement(); subResult->asQualitativeCheckResult().complement();
@ -235,4 +243,4 @@ namespace storm {
return subResult; return subResult;
} }
} }
} }

9
src/modelchecker/AbstractModelChecker.h

@ -35,19 +35,20 @@ namespace storm {
virtual std::unique_ptr<CheckResult> check(CheckTask<storm::logic::Formula> const& checkTask); virtual std::unique_ptr<CheckResult> check(CheckTask<storm::logic::Formula> const& checkTask);
// The methods to compute probabilities for path formulas. // The methods to compute probabilities for path formulas.
virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::PathFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeProbabilities(CheckTask<storm::logic::Formula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeEventuallyProbabilities(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask);
// The methods to compute the rewards for path formulas. // The methods to compute the rewards for path formulas.
virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::RewardPathFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeRewards(CheckTask<storm::logic::Formula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask);
virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask); virtual std::unique_ptr<CheckResult> computeLongRunAverageRewards(CheckTask<storm::logic::LongRunAverageRewardFormula> const& checkTask);
// The methods to compute the long-run average and expected time. // The methods to compute the long-run average and expected time.

6
src/modelchecker/CheckTask.h

@ -16,6 +16,10 @@ namespace storm {
namespace modelchecker { namespace modelchecker {
enum class CheckType {
Probabilities, Rewards
};
/* /*
* This class is used to customize the checking process of a formula. * This class is used to customize the checking process of a formula.
*/ */
@ -75,7 +79,7 @@ namespace storm {
* changes the formula type of the check task object. * changes the formula type of the check task object.
*/ */
template<typename NewFormulaType> template<typename NewFormulaType>
CheckTask<NewFormulaType, ValueType> replaceFormula(NewFormulaType const& newFormula) const { CheckTask<NewFormulaType, ValueType> substituteFormula(NewFormulaType const& newFormula) const {
return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers); return CheckTask<NewFormulaType, ValueType>(newFormula, this->optimizationDirection, this->rewardModel, this->onlyInitialStatesRelevant, this->bound, this->qualitative, this->produceSchedulers);
} }

10
src/modelchecker/csl/HybridCtmcCslModelChecker.cpp

@ -10,6 +10,8 @@
#include "src/storage/dd/Add.h" #include "src/storage/dd/Add.h"
#include "src/storage/dd/Bdd.h" #include "src/storage/dd/Bdd.h"
#include "src/logic/FragmentSpecification.h"
namespace storm { namespace storm {
namespace modelchecker { namespace modelchecker {
template<storm::dd::DdType DdType, class ValueType> template<storm::dd::DdType DdType, class ValueType>
@ -25,7 +27,7 @@ namespace storm {
template<storm::dd::DdType DdType, class ValueType> template<storm::dd::DdType DdType, class ValueType>
bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool HybridCtmcCslModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula(); return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true));
} }
template<storm::dd::DdType DdType, class ValueType> template<storm::dd::DdType DdType, class ValueType>
@ -54,9 +56,9 @@ namespace storm {
} }
template<storm::dd::DdType DdType, class ValueType> template<storm::dd::DdType DdType, class ValueType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);

2
src/modelchecker/csl/HybridCtmcCslModelChecker.h

@ -23,7 +23,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
protected: protected:

10
src/modelchecker/csl/SparseCtmcCslModelChecker.cpp

@ -13,6 +13,8 @@
#include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/NotImplementedException.h" #include "src/exceptions/NotImplementedException.h"
@ -32,7 +34,7 @@ namespace storm {
template <typename SparseCtmcModelType> template <typename SparseCtmcModelType>
bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isCslStateFormula() || formula.isCslPathFormula() || formula.isRewardPathFormula() || formula.isExpectedTimeOperatorFormula(); return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setExpectedTimeAllowed(true));
} }
template <typename SparseCtmcModelType> template <typename SparseCtmcModelType>
@ -91,9 +93,9 @@ namespace storm {
} }
template <typename SparseCtmcModelType> template <typename SparseCtmcModelType>
std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);

2
src/modelchecker/csl/SparseCtmcCslModelChecker.h

@ -26,7 +26,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;

14
src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp

@ -12,6 +12,8 @@
#include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/NotImplementedException.h" #include "src/exceptions/NotImplementedException.h"
@ -30,7 +32,9 @@ namespace storm {
template<typename SparseMarkovAutomatonModelType> template<typename SparseMarkovAutomatonModelType>
bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isCslStateFormula() || formula.isCslPathFormula() || (formula.isRewardPathFormula() && formula.isReachabilityRewardFormula()) || formula.isExpectedTimeOperatorFormula(); storm::logic::FragmentSpecification fragment = storm::logic::csl().setGloballyFormulasAllowed(false).setNextFormulasAllowed(false).setReachabilityRewardFormulasAllowed(true);
fragment.setExpectedTimeAllowed(true).setLongRunAverageProbabilitiesAllowed(true);
return formula.isInFragment(fragment);
} }
template<typename SparseMarkovAutomatonModelType> template<typename SparseMarkovAutomatonModelType>
@ -59,11 +63,11 @@ namespace storm {
} }
template<typename SparseMarkovAutomatonModelType> template<typename SparseMarkovAutomatonModelType>
std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseMarkovAutomatonCslModelChecker<SparseMarkovAutomatonModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute reachability rewards in non-closed Markov automaton."); STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute reachability rewards in non-closed Markov automaton.");
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
@ -97,4 +101,4 @@ namespace storm {
template class SparseMarkovAutomatonCslModelChecker<storm::models::sparse::MarkovAutomaton<double>>; template class SparseMarkovAutomatonCslModelChecker<storm::models::sparse::MarkovAutomaton<double>>;
} }
} }

2
src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h

@ -23,7 +23,7 @@ namespace storm {
virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override; virtual bool canHandle(CheckTask<storm::logic::Formula> const& checkTask) const override;
virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeExpectedTimes(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;

10
src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp

@ -17,6 +17,8 @@
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/modelchecker/results/HybridQuantitativeCheckResult.h" #include "src/modelchecker/results/HybridQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/exceptions/InvalidStateException.h" #include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h" #include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/InvalidArgumentException.h" #include "src/exceptions/InvalidArgumentException.h"
@ -36,7 +38,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool HybridDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula(); return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true));
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
@ -91,9 +93,9 @@ namespace storm {
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
} }

2
src/modelchecker/prctl/HybridDtmcPrctlModelChecker.h

@ -24,7 +24,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
protected: protected:

19
src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp

@ -8,6 +8,8 @@
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/solver/MinMaxLinearEquationSolver.h" #include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/settings/modules/GeneralSettings.h" #include "src/settings/modules/GeneralSettings.h"
@ -30,16 +32,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool HybridMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
return true;
}
if (formula.isProbabilityOperatorFormula()) {
return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
}
if (formula.isGloballyFormula()) {
return true;
}
return false;
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
@ -100,10 +93,10 @@ namespace storm {
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
} }

2
src/modelchecker/prctl/HybridMdpPrctlModelChecker.h

@ -31,7 +31,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
protected: protected:
storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override; storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override;

52
src/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp

@ -11,6 +11,8 @@
#include "src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h" #include "src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h"
#include "src/modelchecker/csl/helper/SparseCtmcCslHelper.h" #include "src/modelchecker/csl/helper/SparseCtmcCslHelper.h"
#include "src/logic/FragmentSpecification.h"
#include "src/models/sparse/StandardRewardModel.h" #include "src/models/sparse/StandardRewardModel.h"
#include "src/settings/modules/GeneralSettings.h" #include "src/settings/modules/GeneralSettings.h"
@ -34,22 +36,7 @@ namespace storm {
template<typename SparseDtmcModelType> template<typename SparseDtmcModelType>
bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SparseDtmcPrctlModelChecker<SparseDtmcModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setConditionalRewardFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
return true;
}
if (formula.isGloballyFormula()) {
return true;
}
if (formula.isProbabilityOperatorFormula()) {
return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
}
if (formula.isConditionalPathFormula()) {
storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula());
}
}
return false;
} }
template<typename SparseDtmcModelType> template<typename SparseDtmcModelType>
@ -111,9 +98,9 @@ namespace storm {
} }
template<typename SparseDtmcModelType> template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
@ -129,13 +116,13 @@ namespace storm {
} }
template<typename SparseDtmcModelType> template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula(); storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula()); std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula()); std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
@ -143,6 +130,21 @@ namespace storm {
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
} }
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
STORM_LOG_THROW(conditionalFormula.getSubformula().isReachabilityRewardFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asReachabilityRewardFormula().getSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeConditionalRewards(this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>; template class SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>;
} }
} }

10
src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h

@ -24,12 +24,14 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeConditionalRewards(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
private: private:
// An object that is used for retrieving linear equation solvers. // An object that is used for retrieving linear equation solvers.
std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory; std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<ValueType>> linearEquationSolverFactory;

37
src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp

@ -8,6 +8,8 @@
#include "src/modelchecker/results/ExplicitQualitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQualitativeCheckResult.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h" #include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/models/sparse/StandardRewardModel.h" #include "src/models/sparse/StandardRewardModel.h"
#include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h" #include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h"
@ -39,22 +41,7 @@ namespace storm {
template<typename SparseMdpModelType> template<typename SparseMdpModelType>
bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SparseMdpPrctlModelChecker<SparseMdpModelType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false).setLongRunAverageProbabilitiesAllowed(true).setConditionalProbabilityFormulasAllowed(true).setOnlyEventuallyFormuluasInConditionalFormulasAllowed(true));
return true;
}
if (formula.isProbabilityOperatorFormula()) {
return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
}
if (formula.isGloballyFormula()) {
return true;
}
if (formula.isConditionalPathFormula()) {
storm::logic::ConditionalPathFormula const& conditionalPathFormula = formula.asConditionalPathFormula();
if (conditionalPathFormula.getLeftSubformula().isEventuallyFormula() && conditionalPathFormula.getRightSubformula().isEventuallyFormula()) {
return this->canHandle(conditionalPathFormula.getLeftSubformula()) && this->canHandle(conditionalPathFormula.getRightSubformula());
}
}
return false;
} }
template<typename SparseMdpModelType> template<typename SparseMdpModelType>
@ -106,15 +93,15 @@ namespace storm {
} }
template<typename SparseMdpModelType> template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) {
storm::logic::ConditionalPathFormula const& pathFormula = checkTask.getFormula(); storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(this->getModel().getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::InvalidPropertyException, "Cannot compute conditional probabilities on MDPs with more than one initial state."); STORM_LOG_THROW(this->getModel().getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::InvalidPropertyException, "Cannot compute conditional probabilities on MDPs with more than one initial state.");
STORM_LOG_THROW(pathFormula.getLeftSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
STORM_LOG_THROW(pathFormula.getRightSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula."); STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula().asEventuallyFormula().getSubformula()); std::unique_ptr<CheckResult> leftResultPointer = this->check(conditionalFormula.getSubformula().asEventuallyFormula().getSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula().asEventuallyFormula().getSubformula()); std::unique_ptr<CheckResult> rightResultPointer = this->check(conditionalFormula.getConditionFormula().asEventuallyFormula().getSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
@ -140,10 +127,10 @@ namespace storm {
} }
template<typename SparseMdpModelType> template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult(); ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory); std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult))); return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));

4
src/modelchecker/prctl/SparseMdpPrctlModelChecker.h

@ -22,10 +22,10 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeNextProbabilities(CheckTask<storm::logic::NextFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeUntilProbabilities(CheckTask<storm::logic::UntilFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalPathFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula> const& checkTask) override;
private: private:

20
src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp

@ -10,6 +10,9 @@
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/solver/SymbolicLinearEquationSolver.h" #include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/settings/modules/GeneralSettings.h" #include "src/settings/modules/GeneralSettings.h"
@ -32,16 +35,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SymbolicDtmcPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
return true;
}
if (formula.isProbabilityOperatorFormula()) {
return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
}
if (formula.isGloballyFormula()) {
return true;
}
return false;
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
@ -102,9 +96,9 @@ namespace storm {
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeReachabilityRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult)); return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult));

2
src/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.h

@ -21,7 +21,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
protected: protected:
storm::models::symbolic::Dtmc<DdType, ValueType> const& getModel() const override; storm::models::symbolic::Dtmc<DdType, ValueType> const& getModel() const override;

19
src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp

@ -5,6 +5,8 @@
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h" #include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/logic/FragmentSpecification.h"
#include "src/models/symbolic/StandardRewardModel.h" #include "src/models/symbolic/StandardRewardModel.h"
#include "src/utility/macros.h" #include "src/utility/macros.h"
@ -32,16 +34,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const { bool SymbolicMdpPrctlModelChecker<DdType, ValueType>::canHandle(CheckTask<storm::logic::Formula> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula(); storm::logic::Formula const& formula = checkTask.getFormula();
if (formula.isPctlStateFormula() || formula.isPctlPathFormula() || formula.isRewardPathFormula()) { return formula.isInFragment(storm::logic::prctl().setLongRunAverageRewardFormulasAllowed(false));
return true;
}
if (formula.isProbabilityOperatorFormula()) {
return this->canHandle(checkTask.replaceFormula(formula.asProbabilityOperatorFormula().getSubformula()));
}
if (formula.isGloballyFormula()) {
return true;
}
return false;
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
@ -102,10 +95,10 @@ namespace storm {
} }
template<storm::dd::DdType DdType, typename ValueType> template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) { std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<DdType, ValueType>::computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) {
storm::logic::ReachabilityRewardFormula const& rewardPathFormula = checkTask.getFormula(); storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model."); STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(rewardPathFormula.getSubformula()); std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>(); SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory); return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *this->linearEquationSolverFactory);
} }

2
src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.h

@ -23,7 +23,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeCumulativeRewards(CheckTask<storm::logic::CumulativeRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(CheckTask<storm::logic::InstantaneousRewardFormula> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::ReachabilityRewardFormula> const& checkTask) override; virtual std::unique_ptr<CheckResult> computeReachabilityRewards(CheckTask<storm::logic::EventuallyFormula> const& checkTask) override;
protected: protected:
storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override; storm::models::symbolic::Mdp<DdType, ValueType> const& getModel() const override;

120
src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp

@ -46,7 +46,7 @@ namespace storm {
return result; return result;
} }
template<typename ValueType, typename RewardModelType> template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// We need to identify the states which have to be taken out of the matrix, i.e. // We need to identify the states which have to be taken out of the matrix, i.e.
@ -154,7 +154,7 @@ namespace storm {
return result; return result;
} }
template<typename ValueType, typename RewardModelType> template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return computeReachabilityRewards(transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory); return computeReachabilityRewards(transitionMatrix, backwardTransitions, [&] (uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) { return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates); }, targetStates, qualitative, linearEquationSolverFactory);
@ -170,7 +170,7 @@ namespace storm {
}, },
targetStates, qualitative, linearEquationSolverFactory); targetStates, qualitative, linearEquationSolverFactory);
} }
template<typename ValueType, typename RewardModelType> template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
@ -222,23 +222,26 @@ namespace storm {
return result; return result;
} }
template<typename ValueType, typename RewardModelType> template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverageProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseCtmcCslHelper<ValueType>::computeLongRunAverageProbabilities(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory); return SparseCtmcCslHelper<ValueType>::computeLongRunAverageProbabilities(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory);
} }
template<typename ValueType, typename RewardModelType> template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) { typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory); BaierTransformedModel result;
// Start by computing all 'before' states, i.e. the states for which the conditional probability is defined. // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
storm::storage::BitVector beforeStates(targetStates.size(), true); std::vector<ValueType> probabilitiesToReachConditionStates = computeUntilProbabilities(transitionMatrix, backwardTransitions, storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false, linearEquationSolverFactory);
result.beforeStates = storm::storage::BitVector(targetStates.size(), true);
uint_fast64_t state = 0; uint_fast64_t state = 0;
uint_fast64_t beforeStateIndex = 0; uint_fast64_t beforeStateIndex = 0;
for (auto const& value : probabilitiesToReachConditionStates) { for (auto const& value : probabilitiesToReachConditionStates) {
if (value == storm::utility::zero<ValueType>()) { if (value == storm::utility::zero<ValueType>()) {
beforeStates.set(state, false); result.beforeStates.set(state, false);
} else { } else {
probabilitiesToReachConditionStates[beforeStateIndex] = value; probabilitiesToReachConditionStates[beforeStateIndex] = value;
++beforeStateIndex; ++beforeStateIndex;
@ -246,35 +249,33 @@ namespace storm {
++state; ++state;
} }
probabilitiesToReachConditionStates.resize(beforeStateIndex); probabilitiesToReachConditionStates.resize(beforeStateIndex);
// If there were any before states, we can compute their conditional probabilities. If not, the result
// is undefined for all states.
std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
if (targetStates.empty()) { if (targetStates.empty()) {
storm::utility::vector::setVectorValues(result, beforeStates, storm::utility::zero<ValueType>()); result.noTargetStates = true;
} else if (!beforeStates.empty()) { return result;
} else if (!result.beforeStates.empty()) {
// If there are some states for which the conditional probability is defined and there are some // If there are some states for which the conditional probability is defined and there are some
// states that can reach the target states without visiting condition states first, we need to // states that can reach the target states without visiting condition states first, we need to
// do more work. // do more work.
// First, compute the relevant states and some offsets. // First, compute the relevant states and some offsets.
storm::storage::BitVector allStates(targetStates.size(), true); storm::storage::BitVector allStates(targetStates.size(), true);
std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = beforeStates.getNumberOfSetBitsBeforeIndices(); std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices();
storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates); storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates);
statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates); statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates);
uint_fast64_t normalStatesOffset = beforeStates.getNumberOfSetBits(); uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits();
std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices(); std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices();
// All transitions going to states with probability zero, need to be redirected to a deadlock state. // All transitions going to states with probability zero, need to be redirected to a deadlock state.
bool addDeadlockState = false; bool addDeadlockState = false;
uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits(); uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits();
// Now, we create the matrix of 'before' and 'normal' states. // Now, we create the matrix of 'before' and 'normal' states.
storm::storage::SparseMatrixBuilder<ValueType> builder; storm::storage::SparseMatrixBuilder<ValueType> builder;
// Start by creating the transitions of the 'before' states. // Start by creating the transitions of the 'before' states.
uint_fast64_t currentRow = 0; uint_fast64_t currentRow = 0;
for (auto beforeState : beforeStates) { for (auto beforeState : result.beforeStates) {
if (conditionStates.get(beforeState)) { if (conditionStates.get(beforeState)) {
// For condition states, we move to the 'normal' states. // For condition states, we move to the 'normal' states.
ValueType zeroProbability = storm::utility::zero<ValueType>(); ValueType zeroProbability = storm::utility::zero<ValueType>();
@ -291,7 +292,7 @@ namespace storm {
} else { } else {
// For non-condition states, we scale the probabilities going to other before states. // For non-condition states, we scale the probabilities going to other before states.
for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) { for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
if (beforeStates.get(successorEntry.getColumn())) { if (result.beforeStates.get(successorEntry.getColumn())) {
builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()], successorEntry.getValue() * probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] / probabilitiesToReachConditionStates[currentRow]); builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()], successorEntry.getValue() * probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] / probabilitiesToReachConditionStates[currentRow]);
} }
} }
@ -320,21 +321,84 @@ namespace storm {
} }
// Build the new transition matrix and the new targets. // Build the new transition matrix and the new targets.
storm::storage::SparseMatrix<ValueType> newTransitionMatrix = builder.build(); result.transitionMatrix = builder.build();
storm::storage::BitVector newTargetStates = targetStates % beforeStates; storm::storage::BitVector newTargetStates = targetStates % result.beforeStates;
newTargetStates.resize(newTransitionMatrix.getRowCount()); newTargetStates.resize(result.transitionMatrix.get().getRowCount());
for (auto state : targetStates % statesWithProbabilityGreater0) { for (auto state : targetStates % statesWithProbabilityGreater0) {
newTargetStates.set(normalStatesOffset + state, true); newTargetStates.set(normalStatesOffset + state, true);
} }
result.targetStates = std::move(newTargetStates);
// If a reward model was given, we need to compute the rewards for the transformed model.
if (stateRewards) {
std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits());
storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get());
newStateRewards.reserve(newStateRewards.size() + statesWithProbabilityGreater0.getNumberOfSetBits() + 1);
for (auto state : statesWithProbabilityGreater0) {
newStateRewards.push_back(stateRewards.get()[state]);
}
// Add a zero reward to the deadlock state.
newStateRewards.push_back(storm::utility::zero<ValueType>());
result.stateRewards = std::move(newStateRewards);
}
// Finally, compute the conditional probabiltities by a reachability query.
std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), newTargetStates, qualitative, linearEquationSolverFactory);
storm::utility::vector::setVectorValues(result, beforeStates, conditionalProbabilities);
} }
return result; return result;
} }
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// Prepare result vector.
std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
if (!conditionStates.empty()) {
BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none, linearEquationSolverFactory);
if (transformedModel.noTargetStates) {
storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
} else {
// At this point, we do not need to check whether there are 'before' states, since the condition
// states were non-empty so there is at least one state with a positive probability of satisfying
// the condition.
// Now compute reachability probabilities in the transformed model.
storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
std::vector<ValueType> conditionalProbabilities = computeUntilProbabilities(newTransitionMatrix, newTransitionMatrix.transpose(), storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
}
}
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// Prepare result vector.
std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
if (!conditionStates.empty()) {
BaierTransformedModel transformedModel = computeBaierTransformation(transitionMatrix, backwardTransitions, targetStates, conditionStates, rewardModel.getTotalRewardVector(transitionMatrix), linearEquationSolverFactory);
if (transformedModel.noTargetStates) {
storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
} else {
// At this point, we do not need to check whether there are 'before' states, since the condition
// states were non-empty so there is at least one state with a positive probability of satisfying
// the condition.
// Now compute reachability probabilities in the transformed model.
storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
std::vector<ValueType> conditionalRewards = computeReachabilityRewards(newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(), transformedModel.targetStates.get(), qualitative, linearEquationSolverFactory);
storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards);
}
}
return result;
}
template class SparseDtmcPrctlHelper<double>; template class SparseDtmcPrctlHelper<double>;
} }
} }

12
src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h

@ -39,8 +39,20 @@ namespace storm {
static std::vector<ValueType> computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); static std::vector<ValueType> computeConditionalProbabilities(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
static std::vector<ValueType> computeConditionalRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
private: private:
static std::vector<ValueType> computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory); static std::vector<ValueType> computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const& totalStateRewardVectorGetter, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
struct BaierTransformedModel {
storm::storage::BitVector beforeStates;
boost::optional<storm::storage::SparseMatrix<ValueType>> transitionMatrix;
boost::optional<storm::storage::BitVector> targetStates;
boost::optional<std::vector<ValueType>> stateRewards;
bool noTargetStates;
};
static BaierTransformedModel computeBaierTransformation(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates, boost::optional<std::vector<ValueType>> const& stateRewards, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
}; };
} }

14
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

@ -87,9 +87,9 @@ namespace storm {
storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first); storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first);
storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second); storm::storage::BitVector statesWithProbability1 = std::move(statesWithProbability01.second);
storm::storage::BitVector maybeStates = ~(statesWithProbability0 | statesWithProbability1); storm::storage::BitVector maybeStates = ~(statesWithProbability0 | statesWithProbability1);
LOG4CPLUS_INFO(logger, "Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states."); STORM_LOG_INFO("Found " << statesWithProbability0.getNumberOfSetBits() << " 'no' states.");
LOG4CPLUS_INFO(logger, "Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states."); STORM_LOG_INFO("Found " << statesWithProbability1.getNumberOfSetBits() << " 'yes' states.");
LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
// Create resulting vector. // Create resulting vector.
std::vector<ValueType> result(transitionMatrix.getRowGroupCount()); std::vector<ValueType> result(transitionMatrix.getRowGroupCount());
@ -287,16 +287,16 @@ namespace storm {
} }
infinityStates.complement(); infinityStates.complement();
storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates; storm::storage::BitVector maybeStates = ~targetStates & ~infinityStates;
LOG4CPLUS_INFO(logger, "Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states."); STORM_LOG_INFO("Found " << infinityStates.getNumberOfSetBits() << " 'infinity' states.");
LOG4CPLUS_INFO(logger, "Found " << targetStates.getNumberOfSetBits() << " 'target' states."); STORM_LOG_INFO("Found " << targetStates.getNumberOfSetBits() << " 'target' states.");
LOG4CPLUS_INFO(logger, "Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states."); STORM_LOG_INFO("Found " << maybeStates.getNumberOfSetBits() << " 'maybe' states.");
// Create resulting vector. // Create resulting vector.
std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>()); std::vector<ValueType> result(transitionMatrix.getRowGroupCount(), storm::utility::zero<ValueType>());
// Check whether we need to compute exact rewards for some states. // Check whether we need to compute exact rewards for some states.
if (qualitative) { if (qualitative) {
LOG4CPLUS_INFO(logger, "The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed."); STORM_LOG_INFO("The rewards for the initial states were determined in a preprocessing step. No exact rewards were computed.");
// Set the values for all maybe-states to 1 to indicate that their reward values // Set the values for all maybe-states to 1 to indicate that their reward values
// are neither 0 nor infinity. // are neither 0 nor infinity.
storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>()); storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>());

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

|||||||
100:0
Loading…
Cancel
Save