Browse Source

Merge branch 'master' into menu_games

Former-commit-id: 6994060bb6
main
dehnert 10 years ago
parent
commit
e67e057e98
  1. 20
      CMakeLists.txt
  2. 67
      src/builder/DdPrismModelBuilder.cpp
  3. 14
      src/builder/DdPrismModelBuilder.h
  4. 71
      src/builder/ExplicitPrismModelBuilder.cpp
  5. 17
      src/builder/ExplicitPrismModelBuilder.h
  6. 13
      src/cli/cli.cpp
  7. 29
      src/cli/cli.h
  8. 1
      src/modelchecker/csl/SparseCtmcCslModelChecker.cpp
  9. 10
      src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
  10. 1
      src/modelchecker/csl/helper/HybridCtmcCslHelper.cpp
  11. 60
      src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp
  12. 7
      src/modelchecker/csl/helper/SparseCtmcCslHelper.h
  13. 41
      src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp
  14. 5
      src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h
  15. 1
      src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
  16. 1
      src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
  17. 10
      src/modelchecker/prctl/HybridMdpPrctlModelChecker.h
  18. 3
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
  19. 2
      src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
  20. 4
      src/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp
  21. 1
      src/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp
  22. 5
      src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.cpp
  23. 77
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
  24. 20
      src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h
  25. 3
      src/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp
  26. 5
      src/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp
  27. 1
      src/modelchecker/propositional/SparsePropositionalModelChecker.h
  28. 10
      src/modelchecker/propositional/SymbolicPropositionalModelChecker.h
  29. 1
      src/models/ModelBase.h
  30. 1
      src/models/sparse/Dtmc.h
  31. 5
      src/models/sparse/Model.h
  32. 2
      src/models/sparse/NondeterministicModel.cpp
  33. 15
      src/models/sparse/StandardRewardModel.cpp
  34. 2
      src/models/sparse/StandardRewardModel.h
  35. 1
      src/models/symbolic/Model.cpp
  36. 36
      src/parser/ExpressionParser.cpp
  37. 5
      src/parser/ExpressionParser.h
  38. 354
      src/parser/FormulaParser.cpp
  39. 164
      src/parser/FormulaParser.h
  40. 54
      src/solver/AllowEarlyTerminationCondition.cpp
  41. 54
      src/solver/AllowEarlyTerminationCondition.h
  42. 4
      src/solver/GmmxxMinMaxLinearEquationSolver.cpp
  43. 4
      src/solver/MinMaxLinearEquationSolver.cpp
  44. 9
      src/solver/MinMaxLinearEquationSolver.h
  45. 14
      src/solver/NativeLinearEquationSolver.cpp
  46. 15
      src/solver/NativeLinearEquationSolver.h
  47. 4
      src/solver/NativeMinMaxLinearEquationSolver.cpp
  48. 2
      src/solver/SolverSelectionOptions.h
  49. 1
      src/storage/DeterministicModelBisimulationDecomposition.h
  50. 25
      src/storage/SparseMatrix.cpp
  51. 3
      src/storage/SparseMatrix.h
  52. 23
      src/storage/expressions/SimpleValuation.cpp
  53. 10
      src/storage/expressions/SimpleValuation.h
  54. 11
      src/storage/prism/Program.cpp
  55. 10
      src/storage/prism/Program.h
  56. 10
      src/storm.cpp
  57. 1025
      src/utility/graph.cpp
  58. 794
      src/utility/graph.h
  59. 72
      src/utility/solver.cpp
  60. 57
      src/utility/solver.h
  61. 37
      src/utility/storm.h
  62. 36
      src/utility/vector.h
  63. 5
      test/functional/modelchecker/GmmxxHybridMdpPrctlModelCheckerTest.cpp
  64. 8
      test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp
  65. 10
      test/functional/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp
  66. 5
      test/functional/modelchecker/NativeHybridMdpPrctlModelCheckerTest.cpp
  67. 18
      test/functional/modelchecker/NativeMdpPrctlModelCheckerTest.cpp
  68. 8
      test/functional/modelchecker/TopologicalValueIterationMdpPrctlModelCheckerTest.cpp
  69. 29
      test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp
  70. 4
      test/performance/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp
  71. 4
      test/performance/modelchecker/NativeMdpPrctlModelCheckerTest.cpp
  72. 4
      test/performance/modelchecker/TopologicalValueIterationMdpPrctlModelCheckerTest.cpp

20
CMakeLists.txt

@ -164,7 +164,7 @@ else(CLANG)
endif()
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=${CLANG_STDLIB} -Wall -pedantic -Wno-newline-eof -Wno-mismatched-tags -ftemplate-depth=1024")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -stdlib=${CLANG_STDLIB} -Wall -pedantic -Wno-newline-eof -Wno-mismatched-tags -ftemplate-depth=1024")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic")
# Turn on popcnt instruction if desired (yes by default)
@ -370,11 +370,13 @@ endif()
##
#############################################################
file(GLOB_RECURSE STORM_HEADERS ${PROJECT_SOURCE_DIR}/src/*.h)
file(GLOB_RECURSE STORM_HEADERS_CLI ${PROJECT_SOURCE_DIR}/src/cli/*.h)
file(GLOB_RECURSE STORM_SOURCES_WITHOUT_MAIN ${PROJECT_SOURCE_DIR}/src/*/*.cpp)
file(GLOB_RECURSE STORM_SOURCES_CLI ${PROJECT_SOURCE_DIR}/src/cli/*.cpp)
file(GLOB_RECURSE STORM_MAIN_FILE ${PROJECT_SOURCE_DIR}/src/storm.cpp)
set(STORM_SOURCES "${STORM_SOURCES_WITHOUT_MAIN};${STORM_MAIN_FILE};")
file(GLOB_RECURSE STORM_ADAPTERS_FILES ${PROJECT_SOURCE_DIR}/src/adapters/*.h ${PROJECT_SOURCE_DIR}/src/adapters/*.cpp)
file(GLOB_RECURSE STORM_BUILDER_FILES ${PROJECT_SOURCE_DIR}/src/builder/*.h ${PROJECT_SOURCE_DIR}/src/builder/*.cpp)
file(GLOB_RECURSE STORM_CLI_FILES ${PROJECT_SOURCE_DIR}/src/cli/*.h ${PROJECT_SOURCE_DIR}/src/cli/*.cpp)
file(GLOB_RECURSE STORM_EXCEPTIONS_FILES ${PROJECT_SOURCE_DIR}/src/exceptions/*.h ${PROJECT_SOURCE_DIR}/src/exceptions/*.cpp)
file(GLOB_RECURSE STORM_LOGIC_FILES ${PROJECT_SOURCE_DIR}/src/logic/*.h ${PROJECT_SOURCE_DIR}/src/logic/*.cpp)
file(GLOB STORM_MODELCHECKER_FILES ${PROJECT_SOURCE_DIR}/src/modelchecker/*.h ${PROJECT_SOURCE_DIR}/src/modelchecker/*.cpp)
@ -410,10 +412,18 @@ file(GLOB_RECURSE STORM_PERFORMANCE_TEST_FILES ${STORM_CPP_TESTS_BASE_PATH}/perf
# Additional include files like the storm-config.h
file(GLOB_RECURSE STORM_BUILD_HEADERS ${PROJECT_BINARY_DIR}/include/*.h)
set(STORM_LIB_SOURCES ${STORM_SOURCES_WITHOUT_MAIN})
list(REMOVE_ITEM STORM_LIB_SOURCES ${STORM_SOURCES_CLI})
set(STORM_LIB_HEADERS ${STORM_HEADERS})
list(REMOVE_ITEM STORM_LIB_HEADERS ${STORM_HEADERS_CLI})
set(STORM_MAIN_SOURCES ${STORM_SOURCES_CLI} ${STORM_MAIN_FILE})
set(STORM_MAIN_HEADERS ${STORM_HEADERS_CLI})
# Group the headers and sources
source_group(main FILES ${STORM_MAIN_FILE})
source_group(adapters FILES ${STORM_ADAPTERS_FILES})
source_group(builder FILES ${STORM_BUILDER_FILES})
source_group(cli FILES ${STORM_CLI_FILES})
source_group(exceptions FILES ${STORM_EXCEPTIONS_FILES})
source_group(logic FILES ${STORM_LOGIC_FILES})
source_group(generated FILES ${STORM_BUILD_HEADERS} ${STORM_BUILD_SOURCES})
@ -492,9 +502,9 @@ endif()
## All link_directories() calls MUST be made before this point #
## #
###############################################################################
add_library(storm ${STORM_SOURCES_WITHOUT_MAIN} ${STORM_HEADERS})
add_executable(storm-main ${STORM_MAIN_FILE})
target_link_libraries(storm-main storm)
add_library(storm ${STORM_LIB_SOURCES} ${STORM_LIB_HEADERS}) # Adding headers for xcode
add_executable(storm-main ${STORM_MAIN_SOURCES} ${STORM_MAIN_HEADERS})
target_link_libraries(storm-main storm) # Adding headers for xcode
set_target_properties(storm-main PROPERTIES OUTPUT_NAME "storm")
add_executable(storm-functional-tests ${STORM_FUNCTIONAL_TEST_MAIN_FILE} ${STORM_FUNCTIONAL_TEST_FILES})
target_link_libraries(storm-functional-tests storm)

67
src/builder/DdPrismModelBuilder.cpp

@ -118,7 +118,7 @@ namespace storm {
columnMetaVariables.insert(variablePair.second);
variableToColumnMetaVariableMap.emplace(integerVariable.getExpressionVariable(), variablePair.second);
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first).toAdd();
storm::dd::Add<Type> variableIdentity = manager->getIdentity(variablePair.first).equals(manager->getIdentity(variablePair.second)) * manager->getRange(variablePair.first).toAdd() * manager->getRange(variablePair.second).toAdd();
variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity);
rowColumnMetaVariablePairs.push_back(variablePair);
@ -190,17 +190,18 @@ namespace storm {
};
template <storm::dd::DdType Type>
DdPrismModelBuilder<Type>::Options::Options() : buildAllRewardModels(true), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(true), labelsToBuild(), expressionLabels() {
DdPrismModelBuilder<Type>::Options::Options() : buildAllRewardModels(true), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(true), labelsToBuild(), expressionLabels(), terminalStates() {
// Intentionally left empty.
}
template <storm::dd::DdType Type>
DdPrismModelBuilder<Type>::Options::Options(storm::logic::Formula const& formula) : buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), expressionLabels(std::vector<storm::expressions::Expression>()) {
DdPrismModelBuilder<Type>::Options::Options(storm::logic::Formula const& formula) : buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), expressionLabels(std::vector<storm::expressions::Expression>()), terminalStates() {
this->preserveFormula(formula);
this->setTerminalStatesFromFormula(formula);
}
template <storm::dd::DdType Type>
DdPrismModelBuilder<Type>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula>> const& formulas) : buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(), expressionLabels() {
DdPrismModelBuilder<Type>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula>> const& formulas) : buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(), expressionLabels(), terminalStates() {
if (formulas.empty()) {
this->buildAllRewardModels = true;
this->buildAllLabels = true;
@ -208,11 +209,19 @@ namespace storm {
for (auto const& formula : formulas) {
this->preserveFormula(*formula);
}
if (formulas.size() == 1) {
this->setTerminalStatesFromFormula(*formulas.front());
}
}
}
template <storm::dd::DdType Type>
void DdPrismModelBuilder<Type>::Options::preserveFormula(storm::logic::Formula const& formula) {
// If we already had terminal states, we need to erase them.
if (terminalStates) {
terminalStates.reset();
}
// If we are not required to build all reward models, we determine the reward models we need to build.
if (!buildAllRewardModels) {
if (formula.containsRewardOperator()) {
@ -240,6 +249,30 @@ namespace storm {
}
}
template <storm::dd::DdType Type>
void DdPrismModelBuilder<Type>::Options::setTerminalStatesFromFormula(storm::logic::Formula const& formula) {
if (formula.isAtomicExpressionFormula()) {
terminalStates = formula.asAtomicExpressionFormula().getExpression();
} else if (formula.isAtomicLabelFormula()) {
terminalStates = formula.asAtomicLabelFormula().getLabel();
} else if (formula.isEventuallyFormula()) {
storm::logic::Formula const& sub = formula.asEventuallyFormula().getSubformula();
if (sub.isAtomicExpressionFormula() || sub.isAtomicLabelFormula()) {
this->setTerminalStatesFromFormula(sub);
}
} else if (formula.isUntilFormula()) {
storm::logic::Formula const& right = formula.asUntilFormula().getLeftSubformula();
if (right.isAtomicExpressionFormula() || right.isAtomicLabelFormula()) {
this->setTerminalStatesFromFormula(right);
}
} else if (formula.isProbabilityOperatorFormula()) {
storm::logic::Formula const& sub = formula.asProbabilityOperatorFormula().getSubformula();
if (sub.isEventuallyFormula() || sub.isUntilFormula()) {
this->setTerminalStatesFromFormula(sub);
}
}
}
template <storm::dd::DdType Type>
void DdPrismModelBuilder<Type>::Options::addConstantDefinitionsFromString(storm::prism::Program const& program, std::string const& constantDefinitionString) {
std::map<storm::expressions::Variable, storm::expressions::Expression> newConstantDefinitions = storm::utility::prism::parseConstantDefinitionString(program, constantDefinitionString);
@ -989,12 +1022,27 @@ namespace storm {
ModuleDecisionDiagram const& globalModule = system.globalModule;
storm::dd::Add<Type> stateActionDd = system.stateActionDd;
// If we were asked to treat some states as terminal states, we cut away their transitions now.
if (options.terminalStates) {
storm::expressions::Expression terminalExpression;
if (options.terminalStates.get().type() == typeid(storm::expressions::Expression)) {
terminalExpression = boost::get<storm::expressions::Expression>(options.terminalStates.get());
} else {
std::string const& labelName = boost::get<std::string>(options.terminalStates.get());
terminalExpression = preparedProgram.getLabelExpression(labelName);
}
STORM_LOG_TRACE("Making the states satisfying " << terminalExpression << " terminal.");
storm::dd::Add<Type> terminalStatesAdd = generationInfo.rowExpressionAdapter->translateExpression(terminalExpression);
transitionMatrix *= !terminalStatesAdd;
}
// Cut the transitions and rewards to the reachable fragment of the state space.
storm::dd::Bdd<Type> initialStates = createInitialStatesDecisionDiagram(generationInfo);
storm::dd::Bdd<Type> transitionMatrixBdd = transitionMatrix.notZero();
if (program.getModelType() == storm::prism::Program::ModelType::MDP) {
transitionMatrixBdd = transitionMatrixBdd.existsAbstract(generationInfo.allNondeterminismVariables);
}
storm::dd::Bdd<Type> reachableStates = computeReachableStates(generationInfo, initialStates, transitionMatrixBdd);
storm::dd::Add<Type> reachableStatesAdd = reachableStates.toAdd();
transitionMatrix *= reachableStatesAdd;
@ -1007,7 +1055,12 @@ namespace storm {
if (!deadlockStates.isZero()) {
// If we need to fix deadlocks, we do so now.
if (!storm::settings::generalSettings().isDontFixDeadlocksSet()) {
STORM_LOG_WARN("Fixing deadlocks in " << deadlockStates.getNonZeroCount() << " states.");
STORM_LOG_INFO("Fixing deadlocks in " << deadlockStates.getNonZeroCount() << " states. The first three of these states are: ");
uint_fast64_t count = 0;
for (auto it = deadlockStates.begin(), ite = deadlockStates.end(); it != ite && count < 3; ++it, ++count) {
STORM_LOG_INFO((*it).first.toPrettyString(generationInfo.rowMetaVariables) << std::endl);
}
if (program.getModelType() == storm::prism::Program::ModelType::DTMC) {
// For DTMCs, we can simply add the identity of the global module for all deadlock states.
@ -1017,6 +1070,10 @@ namespace storm {
// want to attach a lot of self-loops to the deadlock states.
storm::dd::Add<Type> action = generationInfo.manager->getAddOne();
std::for_each(generationInfo.allNondeterminismVariables.begin(), generationInfo.allNondeterminismVariables.end(), [&action,&generationInfo] (storm::expressions::Variable const& metaVariable) { action *= !generationInfo.manager->getIdentity(metaVariable); } );
// Make sure that global variables do not change along the introduced self-loops.
for (auto const& var : generationInfo.allGlobalVariables) {
action *= generationInfo.variableToIdentityMap.at(var);
}
transitionMatrix += deadlockStates * globalModule.identity * action;
}
} else {

14
src/builder/DdPrismModelBuilder.h

@ -71,6 +71,16 @@ namespace storm {
*/
void preserveFormula(storm::logic::Formula const& formula);
/*!
* Analyzes the given formula and sets an expression for the states states of the model that can be
* treated as terminal states. Note that this may interfere with checking properties different than the
* one provided.
*
* @param formula The formula used to (possibly) derive an expression for the terminal states of the
* model.
*/
void setTerminalStatesFromFormula(storm::logic::Formula const& formula);
// A flag that indicates whether or not all reward models are to be build.
bool buildAllRewardModels;
@ -88,6 +98,10 @@ namespace storm {
// An optional set of expressions for which labels need to be built.
boost::optional<std::vector<storm::expressions::Expression>> expressionLabels;
// An optional expression or label that characterizes the terminal states of the model. If this is set,
// the outgoing transitions of these states are replaced with a self-loop.
boost::optional<boost::variant<storm::expressions::Expression, std::string>> terminalStates;
};
/*!

71
src/builder/ExplicitPrismModelBuilder.cpp

@ -106,17 +106,17 @@ namespace storm {
}
template <typename ValueType, typename IndexType>
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options() : buildCommandLabels(false), buildAllRewardModels(true), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(true), labelsToBuild(), expressionLabels() {
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options() : buildCommandLabels(false), buildAllRewardModels(true), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(true), labelsToBuild(), expressionLabels(), terminalStates() {
// Intentionally left empty.
}
template <typename ValueType, typename IndexType>
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options(storm::logic::Formula const& formula) : buildCommandLabels(false), buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), expressionLabels(std::vector<storm::expressions::Expression>()) {
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options(storm::logic::Formula const& formula) : buildCommandLabels(false), buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(std::set<std::string>()), expressionLabels(std::vector<storm::expressions::Expression>()), terminalStates() {
this->preserveFormula(formula);
}
template <typename ValueType, typename IndexType>
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula>> const& formulas) : buildCommandLabels(false), buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(), expressionLabels() {
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options(std::vector<std::shared_ptr<storm::logic::Formula>> const& formulas) : buildCommandLabels(false), buildAllRewardModels(false), rewardModelsToBuild(), constantDefinitions(), buildAllLabels(false), labelsToBuild(), expressionLabels(), terminalStates() {
if (formulas.empty()) {
this->buildAllRewardModels = true;
this->buildAllLabels = true;
@ -124,11 +124,43 @@ namespace storm {
for (auto const& formula : formulas) {
this->preserveFormula(*formula);
}
if (formulas.size() == 1) {
this->setTerminalStatesFromFormula(*formulas.front());
}
}
}
template <typename ValueType, typename IndexType>
void ExplicitPrismModelBuilder<ValueType, IndexType>::Options::setTerminalStatesFromFormula(storm::logic::Formula const& formula) {
if (formula.isAtomicExpressionFormula()) {
terminalStates = formula.asAtomicExpressionFormula().getExpression();
} else if (formula.isAtomicLabelFormula()) {
terminalStates = formula.asAtomicLabelFormula().getLabel();
} else if (formula.isEventuallyFormula()) {
storm::logic::Formula const& sub = formula.asEventuallyFormula().getSubformula();
if (sub.isAtomicExpressionFormula() || sub.isAtomicLabelFormula()) {
this->setTerminalStatesFromFormula(sub);
}
} else if (formula.isUntilFormula()) {
storm::logic::Formula const& right = formula.asUntilFormula().getLeftSubformula();
if (right.isAtomicExpressionFormula() || right.isAtomicLabelFormula()) {
this->setTerminalStatesFromFormula(right);
}
} else if (formula.isProbabilityOperatorFormula()) {
storm::logic::Formula const& sub = formula.asProbabilityOperatorFormula().getSubformula();
if (sub.isEventuallyFormula() || sub.isUntilFormula()) {
this->setTerminalStatesFromFormula(sub);
}
}
}
template <typename ValueType, typename IndexType>
void ExplicitPrismModelBuilder<ValueType, IndexType>::Options::preserveFormula(storm::logic::Formula const& formula) {
// If we already had terminal states, we need to erase them.
if (terminalStates) {
terminalStates.reset();
}
// If we are not required to build all reward models, we determine the reward models we need to build.
if (!buildAllRewardModels) {
if (formula.containsRewardOperator()) {
@ -152,6 +184,9 @@ namespace storm {
// Extract all the expressions used in the formula.
std::vector<std::shared_ptr<storm::logic::AtomicExpressionFormula const>> atomicExpressionFormulas = formula.getAtomicExpressionFormulas();
for (auto const& formula : atomicExpressionFormulas) {
if (!expressionLabels) {
expressionLabels = std::vector<storm::expressions::Expression>();
}
expressionLabels.get().push_back(formula.get()->getExpression());
}
}
@ -181,7 +216,7 @@ namespace storm {
} else {
preparedProgram = program;
}
// If the program still contains undefined constants and we are not in a parametric setting, assemble an appropriate error message.
#ifdef STORM_HAVE_CARL
// If the program either has undefined constants or we are building a parametric model, but the parameters
@ -528,7 +563,7 @@ namespace storm {
}
template <typename ValueType, typename IndexType>
boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> ExplicitPrismModelBuilder<ValueType, IndexType>::buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<std::reference_wrapper<storm::prism::RewardModel const>> const& selectedRewardModels, StateInformation& stateInformation, bool commandLabels, bool deterministicModel, bool discreteTimeModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, std::vector<RewardModelBuilder<ValueType>>& rewardModelBuilders) {
boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> ExplicitPrismModelBuilder<ValueType, IndexType>::buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<std::reference_wrapper<storm::prism::RewardModel const>> const& selectedRewardModels, StateInformation& stateInformation, bool commandLabels, bool deterministicModel, bool discreteTimeModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, std::vector<RewardModelBuilder<ValueType>>& rewardModelBuilders, boost::optional<storm::expressions::Expression> const& terminalExpression) {
// Create choice labels, if requested,
boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> choiceLabels;
if (commandLabels) {
@ -579,9 +614,16 @@ namespace storm {
STORM_LOG_TRACE("Exploring state with id " << stateIndex << ".");
unpackStateIntoEvaluator(currentState, variableInformation, evaluator);
// Retrieve all choices for the current state.
std::vector<Choice<ValueType>> allUnlabeledChoices = getUnlabeledTransitions(program, discreteTimeModel, stateInformation, variableInformation, currentState, commandLabels, evaluator, stateQueue, comparator);
std::vector<Choice<ValueType>> allLabeledChoices = getLabeledTransitions(program, discreteTimeModel, stateInformation, variableInformation, currentState, commandLabels, evaluator, stateQueue, comparator);
// If a terminal expression was given, we check whether the current state needs to be explored further.
std::vector<Choice<ValueType>> allUnlabeledChoices;
std::vector<Choice<ValueType>> allLabeledChoices;
if (terminalExpression && evaluator.asBool(terminalExpression.get())) {
// Nothing to do in this case.
} else {
// Retrieve all choices for the current state.
allUnlabeledChoices = getUnlabeledTransitions(program, discreteTimeModel, stateInformation, variableInformation, currentState, commandLabels, evaluator, stateQueue, comparator);
allLabeledChoices = getLabeledTransitions(program, discreteTimeModel, stateInformation, variableInformation, currentState, commandLabels, evaluator, stateQueue, comparator);
}
uint_fast64_t totalNumberOfChoices = allUnlabeledChoices.size() + allLabeledChoices.size();
@ -890,7 +932,18 @@ namespace storm {
rewardModelBuilders.emplace_back(deterministicModel, rewardModel.get().hasStateRewards(), rewardModel.get().hasStateActionRewards(), rewardModel.get().hasTransitionRewards());
}
modelComponents.choiceLabeling = buildMatrices(program, variableInformation, selectedRewardModels, stateInformation, options.buildCommandLabels, deterministicModel, discreteTimeModel, transitionMatrixBuilder, rewardModelBuilders);
// If we were asked to treat some states as terminal states, we cut away their transitions now.
boost::optional<storm::expressions::Expression> terminalExpression;
if (options.terminalStates) {
if (options.terminalStates.get().type() == typeid(storm::expressions::Expression)) {
terminalExpression = boost::get<storm::expressions::Expression>(options.terminalStates.get());
} else {
std::string const& labelName = boost::get<std::string>(options.terminalStates.get());
terminalExpression = program.getLabelExpression(labelName);
}
}
modelComponents.choiceLabeling = buildMatrices(program, variableInformation, selectedRewardModels, stateInformation, options.buildCommandLabels, deterministicModel, discreteTimeModel, transitionMatrixBuilder, rewardModelBuilders, terminalExpression);
modelComponents.transitionMatrix = transitionMatrixBuilder.build();

17
src/builder/ExplicitPrismModelBuilder.h

@ -162,6 +162,16 @@ namespace storm {
*/
void preserveFormula(storm::logic::Formula const& formula);
/*!
* Analyzes the given formula and sets an expression for the states states of the model that can be
* treated as terminal states. Note that this may interfere with checking properties different than the
* one provided.
*
* @param formula The formula used to (possibly) derive an expression for the terminal states of the
* model.
*/
void setTerminalStatesFromFormula(storm::logic::Formula const& formula);
// A flag that indicates whether or not command labels are to be built.
bool buildCommandLabels;
@ -182,6 +192,10 @@ namespace storm {
// An optional set of expressions for which labels need to be built.
boost::optional<std::vector<storm::expressions::Expression>> expressionLabels;
// An optional expression or label that characterizes the terminal states of the model. If this is set,
// the outgoing transitions of these states are replaced with a self-loop.
boost::optional<boost::variant<storm::expressions::Expression, std::string>> terminalStates;
};
/*!
@ -267,10 +281,11 @@ namespace storm {
* function.
* @param rewardModelBuilders A vector of reward model builders that is used to build the vector of selected
* reward models.
* @param terminalExpression If given, terminal states are not explored further.
* @return A tuple containing a vector with all rows at which the nondeterministic choices of each state begin
* and a vector containing the labels associated with each choice.
*/
static boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<std::reference_wrapper<storm::prism::RewardModel const>> const& selectedRewardModels, StateInformation& stateInformation, bool commandLabels, bool deterministicModel, bool discreteTimeModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, std::vector<RewardModelBuilder<ValueType>>& rewardModelBuilders);
static boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>> buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<std::reference_wrapper<storm::prism::RewardModel const>> const& selectedRewardModels, StateInformation& stateInformation, bool commandLabels, bool deterministicModel, bool discreteTimeModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, std::vector<RewardModelBuilder<ValueType>>& rewardModelBuilders, boost::optional<storm::expressions::Expression> const& terminalExpression);
/*!
* Explores the state space of the given program and returns the components of the model as a result.

13
src/utility/cli.cpp → src/cli/cli.cpp

@ -1,9 +1,12 @@
#include "cli.h"
#include "../utility/storm.h"
#include "src/settings/modules/DebugSettings.h"
#include "src/exceptions/OptionParserException.h"
#include "src/utility/storm-version.h"
// Includes for the linked libraries and versions header.
#ifdef STORM_HAVE_INTELTBB
# include "tbb/tbb_stddef.h"
@ -30,7 +33,6 @@
#endif
namespace storm {
namespace utility {
namespace cli {
std::string getCurrentWorkingDirectory() {
char temp[512];
@ -196,14 +198,14 @@ namespace storm {
LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console.");
}
if (storm::settings::debugSettings().isLogfileSet()) {
initializeFileLogging();
storm::utility::initializeFileLogging();
}
return true;
}
void processOptions() {
if (storm::settings::debugSettings().isLogfileSet()) {
initializeFileLogging();
storm::utility::initializeFileLogging();
}
storm::settings::modules::GeneralSettings const& settings = storm::settings::generalSettings();
@ -222,7 +224,7 @@ namespace storm {
if (settings.isPropertySet()) {
storm::parser::FormulaParser formulaParser;
if (program) {
storm::parser::FormulaParser formulaParser(program.get().getManager().getSharedPointer());
formulaParser = storm::parser::FormulaParser(program.get().getManager().getSharedPointer());
}
// If the given property looks like a file (containing a dot and there exists a file with that name),
@ -253,5 +255,4 @@ namespace storm {
}
}
}
}
}

29
src/cli/cli.h

@ -0,0 +1,29 @@
#ifndef STORM_UTILITY_CLI_H_
#define STORM_UTILITY_CLI_H_
#include <string>
namespace storm {
namespace cli {
std::string getCurrentWorkingDirectory();
void printHeader(const int argc, const char* argv[]);
void printUsage();
/*!
* Parses the given command line arguments.
*
* @param argc The argc argument of main().
* @param argv The argv argument of main().
* @return True iff the program should continue to run after parsing the options.
*/
bool parseOptions(const int argc, const char* argv[]);
void processOptions();
}
}
#endif

1
src/modelchecker/csl/SparseCtmcCslModelChecker.cpp

@ -15,6 +15,7 @@
#include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/NotImplementedException.h"
namespace storm {
namespace modelchecker {
template <typename SparseCtmcModelType>

10
src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp

@ -37,7 +37,7 @@ namespace storm {
STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute time-bounded reachability probabilities in non-closed Markov automaton.");
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult const& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeBoundedUntilProbabilities(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), pathFormula.getIntervalBounds(), *minMaxLinearEquationSolverFactory);
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeBoundedUntilProbabilities(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rightResult.getTruthValuesVector(), pathFormula.getIntervalBounds(), *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
}
@ -48,7 +48,7 @@ namespace storm {
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
ExplicitQualitativeCheckResult& rightResult = rightResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeUntilProbabilities(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeUntilProbabilities(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
}
@ -58,7 +58,7 @@ namespace storm {
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());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeReachabilityRewards(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModelName ? this->getModel().getRewardModel(rewardModelName.get()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
}
@ -68,7 +68,7 @@ namespace storm {
STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute long-run average in non-closed Markov automaton.");
std::unique_ptr<CheckResult> subResultPointer = this->check(stateFormula);
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeLongRunAverage(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeLongRunAverage(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
}
@ -78,7 +78,7 @@ namespace storm {
STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException, "Unable to compute expected times in non-closed Markov automaton.");
std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeExpectedTimes(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
std::vector<ValueType> result = storm::modelchecker::helper::SparseMarkovAutomatonCslHelper<ValueType>::computeExpectedTimes(optimalityType.get() == storm::logic::OptimalityType::Minimize, this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), qualitative, *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
}

1
src/modelchecker/csl/helper/HybridCtmcCslHelper.cpp

@ -10,6 +10,7 @@
#include "src/utility/macros.h"
#include "src/utility/graph.h"
#include "src/utility/constants.h"
#include "src/models/symbolic/StandardRewardModel.h"

60
src/modelchecker/csl/helper/SparseCtmcCslHelper.cpp

@ -2,15 +2,18 @@
#include "src/modelchecker/prctl/helper/SparseDtmcPrctlHelper.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/storage/StronglyConnectedComponentDecomposition.h"
#include "src/utility/macros.h"
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/utility/numerical.h"
#include "src/exceptions/InvalidStateException.h"
@ -19,8 +22,8 @@
namespace storm {
namespace modelchecker {
namespace helper {
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeBoundedUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeBoundedUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
uint_fast64_t numberOfStates = rateMatrix.getRowCount();
@ -184,18 +187,18 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative, linearEquationSolverFactory);
template <typename ValueType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseDtmcPrctlHelper<ValueType>::computeUntilProbabilities(computeProbabilityMatrix(rateMatrix, exitRateVector), backwardTransitions, phiStates, psiStates, qualitative, linearEquationSolverFactory);
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeNextProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates, linearEquationSolverFactory);
template <typename ValueType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeNextProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& nextStates, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseDtmcPrctlHelper<ValueType>::computeNextProbabilities(computeProbabilityMatrix(rateMatrix, exitRateVector), nextStates, linearEquationSolverFactory);
}
template <typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeUniformizedMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::BitVector const& maybeStates, ValueType uniformizationRate, std::vector<ValueType> const& exitRates) {
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType>::computeUniformizedMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::BitVector const& maybeStates, ValueType uniformizationRate, std::vector<ValueType> const& exitRates) {
STORM_LOG_DEBUG("Computing uniformized matrix using uniformization rate " << uniformizationRate << ".");
STORM_LOG_DEBUG("Keeping " << maybeStates.getNumberOfSetBits() << " rows.");
@ -221,9 +224,9 @@ namespace storm {
return uniformizedMatrix;
}
template <typename ValueType, typename RewardModelType>
template <typename ValueType>
template<bool computeCumulativeReward>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeTransientProbabilities(storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeTransientProbabilities(storm::storage::SparseMatrix<ValueType> const& uniformizedMatrix, std::vector<ValueType> const* addVector, ValueType timeBound, ValueType uniformizationRate, std::vector<ValueType> values, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
ValueType lambda = timeBound * uniformizationRate;
@ -304,8 +307,9 @@ namespace storm {
return result;
}
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeInstantaneousRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template <typename ValueType>
template <typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeInstantaneousRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// Only compute the result if the model has a state-based reward this->getModel().
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -330,8 +334,9 @@ namespace storm {
return result;
}
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeCumulativeRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template <typename ValueType>
template <typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeCumulativeRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// Only compute the result if the model has a state-based reward this->getModel().
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -361,8 +366,9 @@ namespace storm {
return computeTransientProbabilities<true>(uniformizedMatrix, nullptr, timeBound, uniformizationRate, totalRewardVector, linearEquationSolverFactory);
}
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template <typename ValueType>
template <typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
storm::storage::SparseMatrix<ValueType> probabilityMatrix = computeProbabilityMatrix(rateMatrix, exitRateVector);
@ -392,8 +398,8 @@ namespace storm {
return storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(probabilityMatrix, backwardTransitions, totalRewardVector, targetStates, qualitative, linearEquationSolverFactory);
}
template <typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeProbabilityMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates) {
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType>::computeProbabilityMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates) {
// Turn the rates into probabilities by scaling each row with the exit rate of the state.
storm::storage::SparseMatrix<ValueType> result(rateMatrix);
for (uint_fast64_t row = 0; row < result.getRowCount(); ++row) {
@ -404,8 +410,8 @@ namespace storm {
return result;
}
template <typename ValueType, typename RewardModelType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeGeneratorMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates) {
template <typename ValueType>
storm::storage::SparseMatrix<ValueType> SparseCtmcCslHelper<ValueType>::computeGeneratorMatrix(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRates) {
storm::storage::SparseMatrix<ValueType> generatorMatrix(rateMatrix, true);
// Place the negative exit rate on the diagonal.
@ -420,8 +426,8 @@ namespace storm {
return generatorMatrix;
}
template <typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType, RewardModelType>::computeLongRunAverage(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseCtmcCslHelper<ValueType>::computeLongRunAverage(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
// If there are no goal states, we avoid the computation and directly return zero.
uint_fast64_t numberOfStates = probabilityMatrix.getRowCount();
if (psiStates.empty()) {
@ -645,6 +651,10 @@ namespace storm {
}
template class SparseCtmcCslHelper<double>;
template std::vector<double> SparseCtmcCslHelper<double>::computeInstantaneousRewards(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory);
template std::vector<double> SparseCtmcCslHelper<double>::computeCumulativeRewards(storm::storage::SparseMatrix<double> const& rateMatrix, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory);
template std::vector<double> SparseCtmcCslHelper<double>::computeReachabilityRewards(storm::storage::SparseMatrix<double> const& rateMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<double> const& linearEquationSolverFactory);
}
}
}

7
src/modelchecker/csl/helper/SparseCtmcCslHelper.h

@ -1,8 +1,6 @@
#ifndef STORM_MODELCHECKER_SPARSE_CTMC_CSL_MODELCHECKER_HELPER_H_
#define STORM_MODELCHECKER_SPARSE_CTMC_CSL_MODELCHECKER_HELPER_H_
#include "src/models/sparse/StandardRewardModel.h"
#include "src/storage/BitVector.h"
#include "src/utility/solver.h"
@ -10,7 +8,7 @@
namespace storm {
namespace modelchecker {
namespace helper {
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
template <typename ValueType>
class SparseCtmcCslHelper {
public:
static std::vector<ValueType> computeBoundedUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, std::vector<ValueType> const& exitRates, bool qualitative, double lowerBound, double upperBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
@ -19,10 +17,13 @@ namespace storm {
static std::vector<ValueType> computeUntilProbabilities(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeInstantaneousRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeCumulativeRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, double timeBound, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeReachabilityRewards(storm::storage::SparseMatrix<ValueType> const& rateMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);
static std::vector<ValueType> computeLongRunAverage(storm::storage::SparseMatrix<ValueType> const& probabilityMatrix, storm::storage::BitVector const& psiStates, std::vector<ValueType> const* exitRateVector, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory);

41
src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp

@ -2,6 +2,8 @@
#include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/storage/StronglyConnectedComponentDecomposition.h"
#include "src/storage/MaximalEndComponentDecomposition.h"
@ -12,6 +14,9 @@
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/storage/expressions/Variable.h"
#include "src/storage/expressions/Expression.h"
#include "src/utility/numerical.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
@ -23,8 +28,8 @@
namespace storm {
namespace modelchecker {
namespace helper {
template<typename ValueType, typename RewardModelType>
void SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
void SparseMarkovAutomatonCslHelper<ValueType>::computeBoundedReachabilityProbabilities(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::BitVector const& markovianNonGoalStates, storm::storage::BitVector const& probabilisticNonGoalStates, std::vector<ValueType>& markovianNonGoalValues, std::vector<ValueType>& probabilisticNonGoalValues, ValueType delta, uint_fast64_t numberOfSteps, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Start by computing four sparse matrices:
// * a matrix aMarkovian with all (discretized) transitions from Markovian non-goal states to all Markovian non-goal states.
// * a matrix aMarkovianToProbabilistic with all (discretized) transitions from Markovian non-goal states to all probabilistic non-goal states.
@ -110,8 +115,8 @@ namespace storm {
solver->solveEquationSystem(min, probabilisticNonGoalValues, bProbabilistic, &multiplicationResultScratchMemory, &aProbabilisticScratchMemory);
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
// 'Unpack' the bounds to make them more easily accessible.
@ -173,19 +178,20 @@ namespace storm {
}
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(minimize, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, minMaxLinearEquationSolverFactory);
template <typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
return storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(minimize, transitionMatrix, backwardTransitions, phiStates, psiStates, qualitative, minMaxLinearEquationSolverFactory);
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
template <typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix.getRowCount(), transitionMatrix, storm::storage::BitVector(transitionMatrix.getRowGroupCount(), true));
return computeExpectedRewards(minimize, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, psiStates, totalRewardVector, minMaxLinearEquationSolverFactory);
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
// If there are no goal states, we avoid the computation and directly return zero.
@ -339,16 +345,16 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeExpectedTimes(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeExpectedTimes(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
std::vector<ValueType> rewardValues(numberOfStates, storm::utility::zero<ValueType>());
storm::utility::vector::setVectorValues(rewardValues, markovianStates, storm::utility::one<ValueType>());
return computeExpectedRewards(minimize, transitionMatrix, backwardTransitions, exitRateVector, markovianStates, psiStates, rewardValues, minMaxLinearEquationSolverFactory);
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeExpectedRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, std::vector<ValueType> const& stateRewards, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template <typename ValueType>
std::vector<ValueType> SparseMarkovAutomatonCslHelper<ValueType>::computeExpectedRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, std::vector<ValueType> const& stateRewards, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
// First, we need to check which states have infinite expected time (by definition).
@ -430,8 +436,8 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
ValueType SparseMarkovAutomatonCslHelper<ValueType, RewardModelType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec) {
template <typename ValueType>
ValueType SparseMarkovAutomatonCslHelper<ValueType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec) {
std::unique_ptr<storm::utility::solver::LpSolverFactory> lpSolverFactory(new storm::utility::solver::LpSolverFactory());
std::unique_ptr<storm::solver::LpSolver> solver = lpSolverFactory->create("LRA for MEC");
solver->setModelSense(minimize ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
@ -492,6 +498,7 @@ namespace storm {
}
template class SparseMarkovAutomatonCslHelper<double>;
template std::vector<double> SparseMarkovAutomatonCslHelper<double>::computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, std::vector<double> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory);
}
}

5
src/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.h

@ -1,8 +1,6 @@
#ifndef STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_
#define STORM_MODELCHECKER_SPARSE_MARKOVAUTOMATON_CSL_MODELCHECKER_HELPER_H_
#include "src/models/sparse/StandardRewardModel.h"
#include "src/storage/BitVector.h"
#include "src/storage/MaximalEndComponent.h"
@ -12,13 +10,14 @@ namespace storm {
namespace modelchecker {
namespace helper {
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
template <typename ValueType>
class SparseMarkovAutomatonCslHelper {
public:
static std::vector<ValueType> computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, std::pair<double, double> const& boundsPair, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static std::vector<ValueType> computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, RewardModelType const& rewardModel, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static std::vector<ValueType> computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& exitRateVector, storm::storage::BitVector const& markovianStates, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);

1
src/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp

@ -19,6 +19,7 @@
#include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace modelchecker {

1
src/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp

@ -4,6 +4,7 @@
#include "src/storage/dd/CuddOdd.h"
#include "src/models/symbolic/Mdp.h"
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/modelchecker/results/SymbolicQualitativeCheckResult.h"

10
src/modelchecker/prctl/HybridMdpPrctlModelChecker.h

@ -3,11 +3,17 @@
#include "src/modelchecker/propositional/SymbolicPropositionalModelChecker.h"
#include "src/models/symbolic/Mdp.h"
#include "src/utility/solver.h"
#include "src/storage/dd/DdType.h"
namespace storm {
namespace models {
namespace symbolic {
template<storm::dd::DdType T> class Mdp;
}
}
namespace modelchecker {
template<storm::dd::DdType DdType, typename ValueType>
class HybridMdpPrctlModelChecker : public SymbolicPropositionalModelChecker<DdType> {

3
src/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp

@ -21,6 +21,9 @@
#include "src/storage/MaximalEndComponentDecomposition.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace modelchecker {
template<typename SparseMdpModelType>

2
src/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp

@ -15,6 +15,8 @@
#include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace modelchecker {
template<storm::dd::DdType DdType, typename ValueType>

4
src/modelchecker/prctl/helper/HybridDtmcPrctlHelper.cpp

@ -1,11 +1,15 @@
#include "src/modelchecker/prctl/helper/HybridDtmcPrctlHelper.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/storage/dd/CuddDdManager.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/CuddBdd.h"
#include "src/storage/dd/CuddOdd.h"
#include "src/utility/graph.h"
#include "src/utility/constants.h"
#include "src/models/symbolic/StandardRewardModel.h"

1
src/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp

@ -6,6 +6,7 @@
#include "src/storage/dd/CuddOdd.h"
#include "src/utility/graph.h"
#include "src/utility/constants.h"
#include "src/models/symbolic/StandardRewardModel.h"

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

@ -6,6 +6,9 @@
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/exceptions/InvalidStateException.h"
#include "src/exceptions/InvalidPropertyException.h"
@ -212,7 +215,7 @@ namespace storm {
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeLongRunAverage(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::LinearEquationSolverFactory<ValueType> const& linearEquationSolverFactory) {
return SparseCtmcCslHelper<ValueType, RewardModelType>::computeLongRunAverage(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory);
return SparseCtmcCslHelper<ValueType>::computeLongRunAverage(transitionMatrix, psiStates, nullptr, qualitative, linearEquationSolverFactory);
}
template class SparseDtmcPrctlHelper<double>;

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

@ -1,11 +1,16 @@
#include "src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/storage/MaximalEndComponentDecomposition.h"
#include "src/utility/macros.h"
#include "src/utility/vector.h"
#include "src/utility/graph.h"
#include "src/storage/expressions/Variable.h"
#include "src/storage/expressions/Expression.h"
#include "src/solver/MinMaxLinearEquationSolver.h"
#include "src/solver/LpSolver.h"
@ -15,8 +20,8 @@
namespace storm {
namespace modelchecker {
namespace helper {
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
// Determine the states that have 0 probability of reaching the target states.
@ -49,8 +54,8 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeNextProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Create the vector with which to multiply and initialize it correctly.
std::vector<ValueType> result(transitionMatrix.getRowCount());
storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
@ -61,8 +66,8 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
uint_fast64_t numberOfStates = transitionMatrix.getRowCount();
// We need to identify the states which have to be taken out of the matrix, i.e.
@ -118,8 +123,9 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeInstantaneousRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
template<typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Only compute the result if the model has a state-based reward this->getModel().
STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -132,8 +138,9 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeCumulativeRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
template<typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Only compute the result if the model has at least one reward this->getModel().
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
@ -154,11 +161,37 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeReachabilityRewards(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Only compute the result if the model has at least one reward this->getModel().
template<typename ValueType>
template<typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Only compute the result if the reward model is not empty.
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
return computeReachabilityRewardsHelper(minimize, transitionMatrix, backwardTransitions,
[&rewardModel] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
return rewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates);
},
targetStates, qualitative, minMaxLinearEquationSolverFactory);
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Only compute the result if the reward model is not empty.
STORM_LOG_THROW(!intervalRewardModel.empty(), storm::exceptions::InvalidPropertyException, "Missing reward model for formula. Skipping formula.");
return computeReachabilityRewardsHelper(minimize, transitionMatrix, backwardTransitions,
[&] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
std::vector<storm::Interval> fullIntervalRewardVector = intervalRewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates);
std::vector<ValueType> result(rowCount);
uint_fast64_t currentPosition = 0;
for (auto position : maybeStates) {
result[currentPosition] = minimize ? fullIntervalRewardVector[position].lower() : fullIntervalRewardVector[position].upper();
}
return result;
},
targetStates, qualitative, minMaxLinearEquationSolverFactory);
}
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewardsHelper(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// Determine which states have a reward of infinity by definition.
storm::storage::BitVector infinityStates;
storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true);
@ -191,11 +224,11 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, false);
// Prepare the right-hand side of the equation system.
std::vector<ValueType> b = rewardModel.getTotalRewardVector(submatrix.getRowCount(), transitionMatrix, maybeStates);
std::vector<ValueType> b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates);
// Create vector for results for maybe states.
std::vector<ValueType> x(maybeStates.getNumberOfSetBits());
// Solve the corresponding system of equations.
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> solver = minMaxLinearEquationSolverFactory.create(submatrix);
solver->solveEquationSystem(minimize, x, b);
@ -211,8 +244,8 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType, RewardModelType>::computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
template<typename ValueType>
std::vector<ValueType> SparseMdpPrctlHelper<ValueType>::computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory) {
// If there are no goal states, we avoid the computation and directly return zero.
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
if (psiStates.empty()) {
@ -361,8 +394,8 @@ namespace storm {
return result;
}
template<typename ValueType, typename RewardModelType>
ValueType SparseMdpPrctlHelper<ValueType, RewardModelType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::storage::MaximalEndComponent const& mec) {
template<typename ValueType>
ValueType SparseMdpPrctlHelper<ValueType>::computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& psiStates, storm::storage::MaximalEndComponent const& mec) {
std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC");
solver->setModelSense(minimize ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
@ -406,6 +439,10 @@ namespace storm {
}
template class SparseMdpPrctlHelper<double>;
template std::vector<double> SparseMdpPrctlHelper<double>::computeInstantaneousRewards(bool minimize, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepCount, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory);
template std::vector<double> SparseMdpPrctlHelper<double>::computeCumulativeRewards(bool minimize, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::models::sparse::StandardRewardModel<double> const& rewardModel, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory);
template std::vector<double> SparseMdpPrctlHelper<double>::computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::models::sparse::StandardRewardModel<double> const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<double> const& minMaxLinearEquationSolverFactory);
}
}
}

20
src/modelchecker/prctl/helper/SparseMdpPrctlHelper.h

@ -3,19 +3,26 @@
#include <vector>
#include "src/models/sparse/StandardRewardModel.h"
#include "src/storage/SparseMatrix.h"
#include "src/storage/BitVector.h"
#include "src/storage/MaximalEndComponent.h"
#include "src/utility/solver.h"
#include "src/adapters/CarlAdapter.h"
namespace storm {
namespace models {
namespace sparse {
template <typename ValueType>
class StandardRewardModel;
}
}
namespace modelchecker {
namespace helper {
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
template <typename ValueType>
class SparseMdpPrctlHelper {
public:
static std::vector<ValueType> computeBoundedUntilProbabilities(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
@ -24,15 +31,22 @@ namespace storm {
static std::vector<ValueType> computeUntilProbabilities(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeInstantaneousRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepCount, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeCumulativeRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
template <typename RewardModelType>
static std::vector<ValueType> computeReachabilityRewards(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static std::vector<ValueType> computeReachabilityRewards(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::models::sparse::StandardRewardModel<storm::Interval> const& intervalRewardModel, storm::storage::BitVector const& targetStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static std::vector<ValueType> computeLongRunAverage(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative, storm::utility::solver::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
private:
static std::vector<ValueType> computeReachabilityRewardsHelper(bool minimize, 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::MinMaxLinearEquationSolverFactory<ValueType> const& minMaxLinearEquationSolverFactory);
static ValueType computeLraForMaximalEndComponent(bool minimize, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec);
};

3
src/modelchecker/prctl/helper/SymbolicDtmcPrctlHelper.cpp

@ -6,9 +6,12 @@
#include "src/storage/dd/CuddBdd.h"
#include "src/storage/dd/CuddOdd.h"
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/utility/graph.h"
#include "src/utility/constants.h"
#include "src/exceptions/InvalidPropertyException.h"

5
src/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp

@ -1,11 +1,15 @@
#include "src/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.h"
#include "src/solver/SymbolicMinMaxLinearEquationSolver.h"
#include "src/storage/dd/CuddDdManager.h"
#include "src/storage/dd/CuddAdd.h"
#include "src/storage/dd/CuddBdd.h"
#include "src/storage/dd/CuddOdd.h"
#include "src/utility/graph.h"
#include "src/utility/constants.h"
#include "src/models/symbolic/StandardRewardModel.h"
@ -13,6 +17,7 @@
#include "src/modelchecker/results/SymbolicQuantitativeCheckResult.h"
#include "src/exceptions/InvalidPropertyException.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace modelchecker {

1
src/modelchecker/propositional/SparsePropositionalModelChecker.h

@ -3,7 +3,6 @@
#include "src/modelchecker/AbstractModelChecker.h"
#include "src/models/sparse/Model.h"
namespace storm {
namespace modelchecker {

10
src/modelchecker/propositional/SymbolicPropositionalModelChecker.h

@ -2,11 +2,19 @@
#define STORM_MODELCHECKER_SYMBOLICPROPOSITIONALMODELCHECKER_H_
#include "src/modelchecker/AbstractModelChecker.h"
#include "src/models/symbolic/Model.h"
#include "src/storage/dd/DdType.h"
namespace storm {
namespace models {
namespace symbolic {
template<storm::dd::DdType Type> class Model;
}
}
namespace modelchecker {
template<storm::dd::DdType Type>
class SymbolicPropositionalModelChecker : public AbstractModelChecker {
public:

1
src/models/ModelBase.h

@ -5,7 +5,6 @@
#include "src/models/ModelType.h"
#include "src/utility/macros.h"
#include "src/exceptions/InvalidOperationException.h"
namespace storm {
namespace models {

1
src/models/sparse/Dtmc.h

@ -4,7 +4,6 @@
#include "src/models/sparse/DeterministicModel.h"
#include "src/utility/OsDetection.h"
#include "src/utility/constants.h"
#include "src/adapters/CarlAdapter.h"
namespace storm {

5
src/models/sparse/Model.h

@ -9,11 +9,14 @@
#include "src/models/ModelBase.h"
#include "src/models/sparse/StateLabeling.h"
#include "src/storage/sparse/StateType.h"
#include "src/storage/BitVector.h"
#include "src/storage/SparseMatrix.h"
#include "src/utility/OsDetection.h"
namespace storm {
namespace storage {
class BitVector;
}
namespace models {
namespace sparse {

2
src/models/sparse/NondeterministicModel.cpp

@ -55,7 +55,7 @@ namespace storm {
template<typename ValueType, typename RewardModelType>
void NondeterministicModel<ValueType, RewardModelType>::printModelInformationToStream(std::ostream& out) const {
this->printModelInformationHeaderToStream(out);
out << "Choices: \t\t" << this->getNumberOfChoices() << std::endl;
out << "Choices: \t" << this->getNumberOfChoices() << std::endl;
this->printModelInformationFooterToStream(out);
}

15
src/models/sparse/StandardRewardModel.cpp

@ -141,7 +141,7 @@ namespace storm {
template<typename ValueType>
template<typename MatrixValueType>
std::vector<ValueType> StandardRewardModel<ValueType>::getTotalRewardVector(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::vector<ValueType> const& weights) const {
std::vector<ValueType> StandardRewardModel<ValueType>::getTotalRewardVector(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::vector<MatrixValueType> const& weights) const {
std::vector<ValueType> result = this->hasTransitionRewards() ? transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()) : (this->hasStateActionRewards() ? this->getStateActionRewardVector() : std::vector<ValueType>(transitionMatrix.getRowCount()));
if (!this->hasTransitionRewards() && this->hasStateActionRewards()) {
// If we initialized the result with the state-action rewards we can scale the result in place.
@ -150,7 +150,7 @@ namespace storm {
if (this->hasStateActionRewards() && this->hasTransitionRewards()) {
// If we initialized the result with the transition rewards and still have state-action rewards,
// we need to add the scaled vector directly.
storm::utility::vector::applyPointwise<ValueType>(weights, this->getStateActionRewardVector(), result, [] (ValueType const& a, ValueType const& b, ValueType const& c) { return c + a * b; } );
storm::utility::vector::applyPointwise<MatrixValueType, ValueType, ValueType>(weights, this->getStateActionRewardVector(), result, [] (MatrixValueType const& weight, ValueType const& rewardElement, ValueType const& resultElement) { return resultElement + weight * rewardElement; } );
}
if (this->hasStateRewards()) {
storm::utility::vector::addVectorToGroupedVector(result, this->getStateRewardVector(), transitionMatrix.getRowGroupIndices());
@ -243,7 +243,7 @@ namespace storm {
template std::vector<float> StandardRewardModel<float>::getTotalRewardVector(storm::storage::SparseMatrix<float> const& transitionMatrix, std::vector<float> const& weights) const;
template void StandardRewardModel<float>::reduceToStateBasedRewards(storm::storage::SparseMatrix<float> const& transitionMatrix, bool reduceToStateRewards);
template class StandardRewardModel<float>;
// template std::ostream& operator<<<float>(std::ostream& out, StandardRewardModel<float> const& rewardModel);
template std::ostream& operator<<<float>(std::ostream& out, StandardRewardModel<float> const& rewardModel);
#ifdef STORM_HAVE_CARL
template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::storage::BitVector const& filter) const;
@ -251,7 +251,14 @@ namespace storm {
template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& weights) const;
template void StandardRewardModel<storm::RationalFunction>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, bool reduceToStateRewards);
template class StandardRewardModel<storm::RationalFunction>;
// template std::ostream& operator<<<storm::RationalFunction>(std::ostream& out, StandardRewardModel<storm::RationalFunction> const& rewardModel);
template std::ostream& operator<<<storm::RationalFunction>(std::ostream& out, StandardRewardModel<storm::RationalFunction> const& rewardModel);
template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(uint_fast64_t numberOfRows, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::BitVector const& filter) const;
template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix) const;
template std::vector<storm::Interval> StandardRewardModel<storm::Interval>::getTotalRewardVector(storm::storage::SparseMatrix<double> const& transitionMatrix, std::vector<double> const& weights) const;
template void StandardRewardModel<storm::Interval>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards);
template class StandardRewardModel<storm::Interval>;
template std::ostream& operator<<<storm::Interval>(std::ostream& out, StandardRewardModel<storm::Interval> const& rewardModel);
#endif
}

2
src/models/sparse/StandardRewardModel.h

@ -178,7 +178,7 @@ namespace storm {
* @return The full state-action reward vector.
*/
template<typename MatrixValueType>
std::vector<ValueType> getTotalRewardVector(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::vector<ValueType> const& weights) const;
std::vector<ValueType> getTotalRewardVector(storm::storage::SparseMatrix<MatrixValueType> const& transitionMatrix, std::vector<MatrixValueType> const& weights) const;
/*!
* Creates a vector representing the complete reward vector based on the state-, state-action- and

1
src/models/symbolic/Model.cpp

@ -3,6 +3,7 @@
#include <boost/algorithm/string/join.hpp>
#include "src/exceptions/IllegalArgumentException.h"
#include "src/exceptions/InvalidOperationException.h"
#include "src/adapters/AddExpressionAdapter.h"

36
src/parser/ExpressionParser.cpp

@ -5,7 +5,7 @@
namespace storm {
namespace parser {
ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), powerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), trueFalse_(manager), manager(manager), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), powerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), trueFalse_(manager), manager(manager.getSharedPointer()), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&ExpressionParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
identifier.name("identifier");
@ -144,7 +144,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createOrExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -159,7 +159,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createAndExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -173,7 +173,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createRelationalExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -190,7 +190,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createEqualsExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -205,7 +205,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createPlusExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -220,7 +220,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createMultExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -235,7 +235,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createPowerExpression(storm::expressions::Expression const& e1, storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e2) const {
@ -249,7 +249,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createUnaryExpression(boost::optional<storm::expressions::OperatorType> const& operatorType, storm::expressions::Expression const& e1) const {
@ -268,7 +268,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createDoubleLiteralExpression(double value, bool& pass) const {
@ -278,17 +278,17 @@ namespace storm {
}
if (this->createExpressions) {
return manager.rational(value);
return manager->rational(value);
} else {
return manager.boolean(false);
return manager->boolean(false);
}
}
storm::expressions::Expression ExpressionParser::createIntegerLiteralExpression(int value) const {
if (this->createExpressions) {
return manager.integer(value);
return manager->integer(value);
} else {
return manager.boolean(false);
return manager->boolean(false);
}
}
@ -304,7 +304,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::createFloorCeilExpression(storm::expressions::OperatorType const& operatorType, storm::expressions::Expression const& e1) const {
@ -319,7 +319,7 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
}
return manager.boolean(false);
return manager->boolean(false);
}
storm::expressions::Expression ExpressionParser::getIdentifierExpression(std::string const& identifier, bool allowBacktracking, bool& pass) const {
@ -329,14 +329,14 @@ namespace storm {
if (expression == nullptr) {
if (allowBacktracking) {
pass = false;
return manager.boolean(false);
return manager->boolean(false);
} else {
STORM_LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
}
}
return *expression;
} else {
return manager.boolean(false);
return manager->boolean(false);
}
}

5
src/parser/ExpressionParser.h

@ -27,6 +27,9 @@ namespace storm {
*/
ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking = false);
ExpressionParser(ExpressionParser const& other) = default;
ExpressionParser& operator=(ExpressionParser const& other) = default;
/*!
* Sets an identifier mapping that is used to determine valid variables in the expression. The mapped-to
* expressions will be substituted wherever the key value appears in the parsed expression. After setting
@ -172,7 +175,7 @@ namespace storm {
trueFalseOperatorStruct trueFalse_;
// The manager responsible for the expressions.
storm::expressions::ExpressionManager const& manager;
std::shared_ptr<storm::expressions::ExpressionManager const> manager;
// A flag that indicates whether expressions should actually be generated or just a syntax check shall be
// performed.

354
src/parser/FormulaParser.cpp

@ -8,7 +8,238 @@
namespace storm {
namespace parser {
FormulaParser::FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : FormulaParser::base_type(start), expressionParser(*manager, keywords_, true) {
class FormulaParserGrammar : public qi::grammar<Iterator, std::vector<std::shared_ptr<storm::logic::Formula>>(), Skipper> {
public:
FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager = std::shared_ptr<storm::expressions::ExpressionManager>(new storm::expressions::ExpressionManager()));
FormulaParserGrammar(FormulaParserGrammar const& other) = default;
FormulaParserGrammar& operator=(FormulaParserGrammar const& other) = default;
/*!
* Adds an identifier and the expression it is supposed to be replaced with. This can, for example be used
* to substitute special identifiers in the formula by expressions.
*
* @param identifier The identifier that is supposed to be substituted.
* @param expression The expression it is to be substituted with.
*/
void addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression);
private:
struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
keywordsStruct() {
add
("true", 1)
("false", 2)
("min", 3)
("max", 4)
("F", 5)
("G", 6)
("X", 7);
}
};
// A parser used for recognizing the keywords.
keywordsStruct keywords_;
struct relationalOperatorStruct : qi::symbols<char, storm::logic::ComparisonType> {
relationalOperatorStruct() {
add
(">=", storm::logic::ComparisonType::GreaterEqual)
(">", storm::logic::ComparisonType::Greater)
("<=", storm::logic::ComparisonType::LessEqual)
("<", storm::logic::ComparisonType::Less);
}
};
// A parser used for recognizing the operators at the "relational" precedence level.
relationalOperatorStruct relationalOperator_;
struct binaryBooleanOperatorStruct : qi::symbols<char, storm::logic::BinaryBooleanStateFormula::OperatorType> {
binaryBooleanOperatorStruct() {
add
("&", storm::logic::BinaryBooleanStateFormula::OperatorType::And)
("|", storm::logic::BinaryBooleanStateFormula::OperatorType::Or);
}
};
// A parser used for recognizing the operators at the "binary" precedence level.
binaryBooleanOperatorStruct binaryBooleanOperator_;
struct unaryBooleanOperatorStruct : qi::symbols<char, storm::logic::UnaryBooleanStateFormula::OperatorType> {
unaryBooleanOperatorStruct() {
add
("!", storm::logic::UnaryBooleanStateFormula::OperatorType::Not);
}
};
// A parser used for recognizing the operators at the "unary" precedence level.
unaryBooleanOperatorStruct unaryBooleanOperator_;
struct optimalityOperatorStruct : qi::symbols<char, storm::logic::OptimalityType> {
optimalityOperatorStruct() {
add
("min", storm::logic::OptimalityType::Minimize)
("max", storm::logic::OptimalityType::Maximize);
}
};
// A parser used for recognizing the optimality operators.
optimalityOperatorStruct optimalityOperator_;
// Parser and manager used for recognizing expressions.
storm::parser::ExpressionParser expressionParser;
// Functor used for displaying error information.
struct ErrorHandler {
typedef qi::error_handler_result result_type;
template<typename T1, typename T2, typename T3, typename T4>
qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
std::stringstream whatAsString;
whatAsString << what;
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(where) << ": " << " expecting " << whatAsString.str() << ".");
return qi::fail;
}
};
// An error handler function.
phoenix::function<ErrorHandler> handler;
// A symbol table that is a mapping from identifiers that can be used in expressions to the expressions
// they are to be replaced with.
qi::symbols<char, storm::expressions::Expression> identifiers_;
qi::rule<Iterator, std::vector<std::shared_ptr<storm::logic::Formula>>(), Skipper> start;
qi::rule<Iterator, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>(), qi::locals<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>, Skipper> operatorInformation;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> probabilityOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expectedTimeOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> steadyStateOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simpleFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> stateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormulaWithoutUntil;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simplePathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> operatorFormula;
qi::rule<Iterator, std::string(), Skipper> label;
qi::rule<Iterator, std::string(), Skipper> rewardModelName;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> andStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> orStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> notStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> labelFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> conditionalFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> eventuallyFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula;
qi::rule<Iterator, boost::variant<std::pair<double, double>, uint_fast64_t>(), Skipper> timeBound;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> cumulativeRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> reachabilityRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> instantaneousRewardFormula;
// Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
// Methods that actually create the expression objects.
std::shared_ptr<storm::logic::Formula> createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula> createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula> createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const;
std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createProbabilityOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula);
std::shared_ptr<storm::logic::Formula> createBinaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType);
std::shared_ptr<storm::logic::Formula> createUnaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& subformula, boost::optional<storm::logic::UnaryBooleanStateFormula::OperatorType> const& operatorType);
};
FormulaParser::FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : manager(manager->getSharedPointer()), grammar(new FormulaParserGrammar(manager)) {
// Intentionally left empty.
}
FormulaParser::FormulaParser(FormulaParser const& other) : FormulaParser(other.manager) {
other.identifiers_.for_each([=] (std::string const& name, storm::expressions::Expression const& expression) { this->addIdentifierExpression(name, expression); });
}
FormulaParser& FormulaParser::operator=(FormulaParser const& other) {
this->manager = other.manager;
this->grammar = std::shared_ptr<FormulaParserGrammar>(new FormulaParserGrammar(this->manager));
other.identifiers_.for_each([=] (std::string const& name, storm::expressions::Expression const& expression) { this->addIdentifierExpression(name, expression); });
return *this;
}
std::shared_ptr<storm::logic::Formula> FormulaParser::parseSingleFormulaFromString(std::string const& formulaString) {
std::vector<std::shared_ptr<storm::logic::Formula>> formulas = parseFromString(formulaString);
STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::WrongFormatException, "Expected exactly one formula, but found " << formulas.size() << " instead.");
return formulas.front();
}
std::vector<std::shared_ptr<storm::logic::Formula>> FormulaParser::parseFromFile(std::string const& filename) {
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
std::vector<std::shared_ptr<storm::logic::Formula>> formulas;
// Now try to parse the contents of the file.
try {
std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
formulas = parseFromString(fileContent);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
return formulas;
}
std::vector<std::shared_ptr<storm::logic::Formula>> FormulaParser::parseFromString(std::string const& formulaString) {
PositionIteratorType first(formulaString.begin());
PositionIteratorType iter = first;
PositionIteratorType last(formulaString.end());
// Create empty result;
std::vector<std::shared_ptr<storm::logic::Formula>> result;
// Create grammar.
try {
// Start parsing.
bool succeeded = qi::phrase_parse(iter, last, *grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse formula.");
STORM_LOG_DEBUG("Parsed formula successfully.");
} catch (qi::expectation_failure<PositionIteratorType> const& e) {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, e.what_);
}
return result;
}
void FormulaParser::addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression) {
// Record the mapping and hand it over to the grammar.
this->identifiers_.add(identifier, expression);
grammar->addIdentifierExpression(identifier, expression);
}
FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : FormulaParserGrammar::base_type(start), expressionParser(*manager, keywords_, true) {
// Register all variables so we can parse them in the expressions.
for (auto variableTypePair : *manager) {
identifiers_.add(variableTypePair.first.getName(), variableTypePair.first);
@ -16,28 +247,28 @@ namespace storm {
// Set the identifier mapping to actually generate expressions.
expressionParser.setIdentifierMapping(&identifiers_);
instantaneousRewardFormula = (qi::lit("I=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParser::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("I=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParser::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)];
instantaneousRewardFormula = (qi::lit("I=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("I=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)];
instantaneousRewardFormula.name("instantaneous reward formula");
cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParser::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParser::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
cumulativeRewardFormula.name("cumulative reward formula");
reachabilityRewardFormula = (qi::lit("F") > stateFormula)[qi::_val = phoenix::bind(&FormulaParser::createReachabilityRewardFormula, phoenix::ref(*this), qi::_1)];
reachabilityRewardFormula = (qi::lit("F") > stateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createReachabilityRewardFormula, phoenix::ref(*this), qi::_1)];
reachabilityRewardFormula.name("reachability reward formula");
rewardPathFormula = reachabilityRewardFormula | cumulativeRewardFormula | instantaneousRewardFormula;
rewardPathFormula.name("reward path formula");
expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParser::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
expressionFormula = expressionParser[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicExpressionFormula, phoenix::ref(*this), qi::_1)];
expressionFormula.name("expression formula");
label = qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]];
label.name("label");
labelFormula = (qi::lit("\"") >> label >> qi::lit("\""))[qi::_val = phoenix::bind(&FormulaParser::createAtomicLabelFormula, phoenix::ref(*this), qi::_1)];
labelFormula = (qi::lit("\"") >> label >> qi::lit("\""))[qi::_val = phoenix::bind(&FormulaParserGrammar::createAtomicLabelFormula, phoenix::ref(*this), qi::_1)];
labelFormula.name("label formula");
booleanLiteralFormula = (qi::lit("true")[qi::_a = true] | qi::lit("false")[qi::_a = false])[qi::_val = phoenix::bind(&FormulaParser::createBooleanLiteralFormula, phoenix::ref(*this), qi::_a)];
booleanLiteralFormula = (qi::lit("true")[qi::_a = true] | qi::lit("false")[qi::_a = false])[qi::_val = phoenix::bind(&FormulaParserGrammar::createBooleanLiteralFormula, phoenix::ref(*this), qi::_a)];
booleanLiteralFormula.name("boolean literal formula");
operatorFormula = probabilityOperator | rewardOperator | steadyStateOperator;
@ -46,25 +277,25 @@ namespace storm {
atomicStateFormula = booleanLiteralFormula | labelFormula | expressionFormula | (qi::lit("(") > stateFormula > qi::lit(")")) | operatorFormula;
atomicStateFormula.name("atomic state formula");
notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParser::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)];
notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)];
notStateFormula.name("negation formula");
eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_2)];
eventuallyFormula = (qi::lit("F") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_2)];
eventuallyFormula.name("eventually formula");
globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createGloballyFormula, phoenix::ref(*this), qi::_1)];
globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createGloballyFormula, phoenix::ref(*this), qi::_1)];
globallyFormula.name("globally formula");
nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createNextFormula, phoenix::ref(*this), qi::_1)];
nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createNextFormula, phoenix::ref(*this), qi::_1)];
nextFormula.name("next formula");
pathFormulaWithoutUntil = eventuallyFormula | globallyFormula | nextFormula | stateFormula;
pathFormulaWithoutUntil.name("path formula");
untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -timeBound >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParserGrammar::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
untilFormula.name("until formula");
conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParser::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1)];
conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1)];
conditionalFormula.name("conditional formula");
timeBound = (qi::lit("[") > qi::double_ > qi::lit(",") > qi::double_ > qi::lit("]"))[qi::_val = phoenix::construct<std::pair<double, double>>(qi::_1, qi::_2)] | (qi::lit("<=") >> strict_double)[qi::_val = phoenix::construct<std::pair<double, double>>(0, qi::_1)] | (qi::lit("<=") > qi::uint_)[qi::_val = qi::_1];
@ -76,25 +307,25 @@ namespace storm {
operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::construct<std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>>(qi::_a, qi::_b, qi::_c)];
operatorInformation.name("operator information");
steadyStateOperator = (qi::lit("LRA") > operatorInformation > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createLongRunAverageOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
steadyStateOperator = (qi::lit("LRA") > operatorInformation > qi::lit("[") > stateFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createLongRunAverageOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
steadyStateOperator.name("long-run average operator");
rewardModelName = qi::lit("{\"") > label > qi::lit("\"}");
rewardModelName.name("reward model name");
rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
rewardOperator = (qi::lit("R") > -rewardModelName > operatorInformation > qi::lit("[") > rewardPathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createRewardOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
rewardOperator.name("reward operator");
expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
expectedTimeOperator = (qi::lit("ET") > operatorInformation > qi::lit("[") > eventuallyFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createExpectedTimeOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
expectedTimeOperator.name("expected time operator");
probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParser::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
probabilityOperator = (qi::lit("P") > operatorInformation > qi::lit("[") > pathFormula > qi::lit("]"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createProbabilityOperatorFormula, phoenix::ref(*this), qi::_1, qi::_2)];
probabilityOperator.name("probability operator");
andStateFormula = notStateFormula[qi::_val = qi::_1] >> *(qi::lit("&") >> notStateFormula)[qi::_val = phoenix::bind(&FormulaParser::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::And)];
andStateFormula = notStateFormula[qi::_val = qi::_1] >> *(qi::lit("&") >> notStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::And)];
andStateFormula.name("and state formula");
orStateFormula = andStateFormula[qi::_val = qi::_1] >> *(qi::lit("|") >> andStateFormula)[qi::_val = phoenix::bind(&FormulaParser::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::Or)];
orStateFormula = andStateFormula[qi::_val = qi::_1] >> *(qi::lit("|") >> andStateFormula)[qi::_val = phoenix::bind(&FormulaParserGrammar::createBinaryBooleanStateFormula, phoenix::ref(*this), qi::_val, qi::_1, storm::logic::BinaryBooleanStateFormula::OperatorType::Or)];
orStateFormula.name("or state formula");
stateFormula = (orStateFormula);
@ -154,60 +385,11 @@ namespace storm {
qi::on_error<qi::fail>(instantaneousRewardFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
}
void FormulaParser::addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression) {
void FormulaParserGrammar::addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression) {
this->identifiers_.add(identifier, expression);
}
std::shared_ptr<storm::logic::Formula> FormulaParser::parseSingleFormulaFromString(std::string const& formulaString) {
std::vector<std::shared_ptr<storm::logic::Formula>> formulas = parseFromString(formulaString);
STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::WrongFormatException, "Expected exactly one formula, but found " << formulas.size() << " instead.");
return formulas.front();
}
std::vector<std::shared_ptr<storm::logic::Formula>> FormulaParser::parseFromFile(std::string const& filename) {
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
std::vector<std::shared_ptr<storm::logic::Formula>> formulas;
// Now try to parse the contents of the file.
try {
std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
formulas = parseFromString(fileContent);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
return formulas;
}
std::vector<std::shared_ptr<storm::logic::Formula>> FormulaParser::parseFromString(std::string const& formulaString) {
PositionIteratorType first(formulaString.begin());
PositionIteratorType iter = first;
PositionIteratorType last(formulaString.end());
// Create empty result;
std::vector<std::shared_ptr<storm::logic::Formula>> result;
// Create grammar.
try {
// Start parsing.
bool succeeded = qi::phrase_parse(iter, last, *this, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse formula.");
STORM_LOG_DEBUG("Parsed formula successfully.");
} catch (qi::expectation_failure<PositionIteratorType> const& e) {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, e.what_);
}
return result;
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
if (timeBound.which() == 0) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::InstantaneousRewardFormula(static_cast<uint_fast64_t>(boost::get<unsigned>(timeBound))));
} else {
@ -217,7 +399,7 @@ namespace storm {
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
if (timeBound.which() == 0) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::CumulativeRewardFormula(static_cast<uint_fast64_t>(boost::get<unsigned>(timeBound))));
} else {
@ -227,24 +409,24 @@ namespace storm {
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::ReachabilityRewardFormula(stateFormula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createAtomicExpressionFormula(storm::expressions::Expression const& expression) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createAtomicExpressionFormula(storm::expressions::Expression const& expression) const {
STORM_LOG_THROW(expression.hasBooleanType(), storm::exceptions::WrongFormatException, "Expected expression of boolean type.");
return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicExpressionFormula(expression));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createBooleanLiteralFormula(bool literal) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createBooleanLiteralFormula(bool literal) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::BooleanLiteralFormula(literal));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createAtomicLabelFormula(std::string const& label) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createAtomicLabelFormula(std::string const& label) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const {
if (timeBound) {
if (timeBound.get().which() == 0) {
std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get());
@ -257,15 +439,15 @@ namespace storm {
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::GloballyFormula(subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::NextFormula(subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula) {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula) {
if (timeBound) {
if (timeBound.get().which() == 0) {
std::pair<double, double> const& bounds = boost::get<std::pair<double, double>>(timeBound.get());
@ -278,31 +460,31 @@ namespace storm {
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::ConditionalPathFormula(leftSubformula, rightSubformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::LongRunAverageOperatorFormula(std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::RewardOperatorFormula(rewardModelName, std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::ExpectedTimeOperatorFormula(std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createProbabilityOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createProbabilityOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::ProbabilityOperatorFormula(std::get<0>(operatorInformation), std::get<1>(operatorInformation), std::get<2>(operatorInformation), subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createBinaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType) {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createBinaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::BinaryBooleanStateFormula(operatorType, leftSubformula, rightSubformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createUnaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& subformula, boost::optional<storm::logic::UnaryBooleanStateFormula::OperatorType> const& operatorType) {
std::shared_ptr<storm::logic::Formula> FormulaParserGrammar::createUnaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& subformula, boost::optional<storm::logic::UnaryBooleanStateFormula::OperatorType> const& operatorType) {
if (operatorType) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::UnaryBooleanStateFormula(operatorType.get(), subformula));
} else {

164
src/parser/FormulaParser.h

@ -1,5 +1,5 @@
#ifndef STORM_PARSER_PRCTLPARSER_H_
#define STORM_PARSER_PRCTLPARSER_H_
#ifndef STORM_PARSER_FORMULAPARSER_H_
#define STORM_PARSER_FORMULAPARSER_H_
#include <sstream>
@ -12,9 +12,15 @@
namespace storm {
namespace parser {
class FormulaParser : public qi::grammar<Iterator, std::vector<std::shared_ptr<storm::logic::Formula>>(), Skipper> {
// Forward-declare grammar.
class FormulaParserGrammar;
class FormulaParser {
public:
FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager = std::shared_ptr<storm::expressions::ExpressionManager>(new storm::expressions::ExpressionManager()));
FormulaParser(FormulaParser const& other);
FormulaParser& operator=(FormulaParser const& other);
/*!
* Parses the formula given by the provided string.
@ -23,7 +29,7 @@ namespace storm {
* @return The resulting formula.
*/
std::shared_ptr<storm::logic::Formula> parseSingleFormulaFromString(std::string const& formulaString);
/*!
* Parses the formula given by the provided string.
*
@ -31,7 +37,7 @@ namespace storm {
* @return The contained formulas.
*/
std::vector<std::shared_ptr<storm::logic::Formula>> parseFromString(std::string const& formulaString);
/*!
* Parses the formulas in the given file.
*
@ -50,151 +56,17 @@ namespace storm {
void addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression);
private:
struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
keywordsStruct() {
add
("true", 1)
("false", 2)
("min", 3)
("max", 4)
("F", 5)
("G", 6)
("X", 7);
}
};
// A parser used for recognizing the keywords.
keywordsStruct keywords_;
struct relationalOperatorStruct : qi::symbols<char, storm::logic::ComparisonType> {
relationalOperatorStruct() {
add
(">=", storm::logic::ComparisonType::GreaterEqual)
(">", storm::logic::ComparisonType::Greater)
("<=", storm::logic::ComparisonType::LessEqual)
("<", storm::logic::ComparisonType::Less);
}
};
// A parser used for recognizing the operators at the "relational" precedence level.
relationalOperatorStruct relationalOperator_;
struct binaryBooleanOperatorStruct : qi::symbols<char, storm::logic::BinaryBooleanStateFormula::OperatorType> {
binaryBooleanOperatorStruct() {
add
("&", storm::logic::BinaryBooleanStateFormula::OperatorType::And)
("|", storm::logic::BinaryBooleanStateFormula::OperatorType::Or);
}
};
// A parser used for recognizing the operators at the "binary" precedence level.
binaryBooleanOperatorStruct binaryBooleanOperator_;
struct unaryBooleanOperatorStruct : qi::symbols<char, storm::logic::UnaryBooleanStateFormula::OperatorType> {
unaryBooleanOperatorStruct() {
add
("!", storm::logic::UnaryBooleanStateFormula::OperatorType::Not);
}
};
// A parser used for recognizing the operators at the "unary" precedence level.
unaryBooleanOperatorStruct unaryBooleanOperator_;
struct optimalityOperatorStruct : qi::symbols<char, storm::logic::OptimalityType> {
optimalityOperatorStruct() {
add
("min", storm::logic::OptimalityType::Minimize)
("max", storm::logic::OptimalityType::Maximize);
}
};
// The manager used to parse expressions.
std::shared_ptr<storm::expressions::ExpressionManager const> manager;
// A parser used for recognizing the optimality operators.
optimalityOperatorStruct optimalityOperator_;
// Parser and manager used for recognizing expressions.
storm::parser::ExpressionParser expressionParser;
// Functor used for displaying error information.
struct ErrorHandler {
typedef qi::error_handler_result result_type;
template<typename T1, typename T2, typename T3, typename T4>
qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
std::stringstream whatAsString;
whatAsString << what;
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(where) << ": " << " expecting " << whatAsString.str() << ".");
return qi::fail;
}
};
// An error handler function.
phoenix::function<ErrorHandler> handler;
// A symbol table that is a mapping from identifiers that can be used in expressions to the expressions
// they are to be replaced with.
// Keep track of added identifier expressions.
qi::symbols<char, storm::expressions::Expression> identifiers_;
qi::rule<Iterator, std::vector<std::shared_ptr<storm::logic::Formula>>(), Skipper> start;
qi::rule<Iterator, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>(), qi::locals<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>, Skipper> operatorInformation;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> probabilityOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expectedTimeOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> steadyStateOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simpleFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> stateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormulaWithoutUntil;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simplePathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> operatorFormula;
qi::rule<Iterator, std::string(), Skipper> label;
qi::rule<Iterator, std::string(), Skipper> rewardModelName;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> andStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> orStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> notStateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> labelFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expressionFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), qi::locals<bool>, Skipper> booleanLiteralFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> conditionalFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> eventuallyFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> nextFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> globallyFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> untilFormula;
qi::rule<Iterator, boost::variant<std::pair<double, double>, uint_fast64_t>(), Skipper> timeBound;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> rewardPathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> cumulativeRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> reachabilityRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> instantaneousRewardFormula;
// Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
// Methods that actually create the expression objects.
std::shared_ptr<storm::logic::Formula> createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula> createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula> createReachabilityRewardFormula(std::shared_ptr<storm::logic::Formula> const& stateFormula) const;
std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<boost::variant<std::pair<double, double>, uint_fast64_t>> const& timeBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(boost::optional<std::string> const& rewardModelName, std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createExpectedTimeOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createProbabilityOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula);
std::shared_ptr<storm::logic::Formula> createBinaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType);
std::shared_ptr<storm::logic::Formula> createUnaryBooleanStateFormula(std::shared_ptr<storm::logic::Formula> const& subformula, boost::optional<storm::logic::UnaryBooleanStateFormula::OperatorType> const& operatorType);
// The grammar used to parse the input.
std::shared_ptr<FormulaParserGrammar> grammar;
};
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_PRCTLPARSER_H_ */
#endif /* STORM_PARSER_FORMULAPARSER_H_ */

54
src/solver/AllowEarlyTerminationCondition.cpp

@ -0,0 +1,54 @@
#include "AllowEarlyTerminationCondition.h"
#include "src/utility/vector.h"
namespace storm {
namespace solver {
template<typename ValueType>
TerminateAfterFilteredSumPassesThresholdValue<ValueType>::TerminateAfterFilteredSumPassesThresholdValue(storm::storage::BitVector const& filter, ValueType threshold, bool terminateIfAbove) :
terminationThreshold(threshold), filter(filter), terminateIfAboveThreshold(terminateIfAbove)
{
// Intentionally left empty.
}
template<typename ValueType>
bool TerminateAfterFilteredSumPassesThresholdValue<ValueType>::terminateNow(const std::vector<ValueType>& currentValues) const {
assert(currentValues.size() >= filter.size());
ValueType currentThreshold = storm::utility::vector::sum_if(currentValues, filter);
if(this->terminateIfAboveThreshold) {
return currentThreshold >= this->terminationThreshold;
} else {
return currentThreshold <= this->terminationThreshold;
}
}
template<typename ValueType>
TerminateAfterFilteredExtremumPassesThresholdValue<ValueType>::TerminateAfterFilteredExtremumPassesThresholdValue(storm::storage::BitVector const& filter, ValueType threshold, bool terminateIfAbove, bool useMinimum) :
terminationThreshold(threshold), filter(filter), terminateIfAboveThreshold(terminateIfAbove), useMinimumAsExtremum(useMinimum)
{
// Intentionally left empty.
}
template<typename ValueType>
bool TerminateAfterFilteredExtremumPassesThresholdValue<ValueType>::terminateNow(const std::vector<ValueType>& currentValues) const {
assert(currentValues.size() >= filter.size());
ValueType initVal = terminateIfAboveThreshold ? terminationThreshold - 1 : terminationThreshold + 1;
ValueType currentThreshold = useMinimumAsExtremum ? storm::utility::vector::max_if(currentValues, filter, initVal) : storm::utility::vector::max_if(currentValues, filter, initVal);
if(this->terminateIfAboveThreshold) {
return currentThreshold >= this->terminationThreshold;
} else {
return currentThreshold <= this->terminationThreshold;
}
}
template class TerminateAfterFilteredExtremumPassesThresholdValue<double>;
template class TerminateAfterFilteredSumPassesThresholdValue<double>;
}
}

54
src/solver/AllowEarlyTerminationCondition.h

@ -0,0 +1,54 @@
#ifndef ALLOWEARLYTERMINATIONCONDITION_H
#define ALLOWEARLYTERMINATIONCONDITION_H
#include <vector>
#include "src/storage/BitVector.h"
namespace storm {
namespace solver {
template<typename ValueType>
class AllowEarlyTerminationCondition {
public:
virtual bool terminateNow(std::vector<ValueType> const& currentValues) const = 0;
};
template<typename ValueType>
class NoEarlyTerminationCondition : public AllowEarlyTerminationCondition<ValueType> {
public:
bool terminateNow(std::vector<ValueType> const& currentValues) const { return false; }
};
template<typename ValueType>
class TerminateAfterFilteredSumPassesThresholdValue : public AllowEarlyTerminationCondition<ValueType> {
public:
TerminateAfterFilteredSumPassesThresholdValue(storm::storage::BitVector const& filter, ValueType threshold, bool terminateAbove);
bool terminateNow(std::vector<ValueType> const& currentValues) const;
protected:
ValueType terminationThreshold;
storm::storage::BitVector filter;
bool terminateIfAboveThreshold;
};
template<typename ValueType>
class TerminateAfterFilteredExtremumPassesThresholdValue : public AllowEarlyTerminationCondition<ValueType>{
public:
TerminateAfterFilteredExtremumPassesThresholdValue(storm::storage::BitVector const& filter, ValueType threshold, bool terminateAbove, bool useMinimum);
bool terminateNow(std::vector<ValueType> const& currentValue) const;
protected:
ValueType terminationThreshold;
storm::storage::BitVector filter;
bool terminateIfAboveThreshold;
bool useMinimumAsExtremum;
};
}
}
#endif /* ALLOWEARLYTERMINATIONCONDITION_H */

4
src/solver/GmmxxMinMaxLinearEquationSolver.cpp

@ -53,7 +53,7 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < this->maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations && !this->earlyTermination->terminateNow(*currentX)) {
// Compute x' = A*x + b.
gmm::mult(*gmmxxMatrix, *currentX, *multiplyResult);
gmm::add(b, *multiplyResult);
@ -119,7 +119,7 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < this->maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations && !this->earlyTermination->terminateNow(*currentX)) {
// Take the sub-matrix according to the current choices
storm::storage::SparseMatrix<ValueType> submatrix = this->A.selectRowsFromRowGroups(this->policy, true);
submatrix.convertToEquationSystem();

4
src/solver/MinMaxLinearEquationSolver.cpp

@ -19,6 +19,10 @@ namespace storm {
}
}
void AbstractMinMaxLinearEquationSolver::setPolicyTracking(bool setToTrue) {
trackPolicy = setToTrue;
}
std::vector<storm::storage::sparse::state_type> AbstractMinMaxLinearEquationSolver::getPolicy() const {
STORM_LOG_THROW(!useValueIteration, storm::exceptions::NotImplementedException, "Getting policies after value iteration is not yet supported!");
return policy;

9
src/solver/MinMaxLinearEquationSolver.h

@ -5,6 +5,7 @@
#include <cstdint>
#include "SolverSelectionOptions.h"
#include "src/storage/sparse/StateType.h"
#include "AllowEarlyTerminationCondition.h"
namespace storm {
namespace storage {
@ -55,7 +56,7 @@ namespace storm {
protected:
MinMaxLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& matrix, double precision, bool relativeError, uint_fast64_t maxNrIterations, bool trackPolicy, MinMaxTechniqueSelection prefTech) :
AbstractMinMaxLinearEquationSolver(precision, relativeError, maxNrIterations, trackPolicy, prefTech),
A(matrix) {
A(matrix), earlyTermination(new NoEarlyTerminationCondition<ValueType>()) {
// Intentionally left empty.
}
@ -101,7 +102,13 @@ namespace storm {
*/
virtual void performMatrixVectorMultiplication(bool minimize, std::vector<ValueType>& x, std::vector<ValueType>* b = nullptr, uint_fast64_t n = 1, std::vector<ValueType>* multiplyResult = nullptr) const = 0;
void setEarlyTerminationCondition(std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> v) {
earlyTermination = std::move(v);
}
protected:
std::unique_ptr<AllowEarlyTerminationCondition<ValueType>> earlyTermination;
storm::storage::SparseMatrix<ValueType> const& A;
};

14
src/solver/NativeLinearEquationSolver.cpp

@ -12,12 +12,12 @@ namespace storm {
namespace solver {
template<typename ValueType>
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, SolutionMethod method, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : A(A), method(method), precision(precision), relative(relative), maximalNumberOfIterations(maximalNumberOfIterations) {
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSolutionMethod method, double precision, uint_fast64_t maximalNumberOfIterations, bool relative) : A(A), method(method), precision(precision), relative(relative), maximalNumberOfIterations(maximalNumberOfIterations) {
// Intentionally left empty.
}
template<typename ValueType>
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, SolutionMethod method) : A(A), method(method) {
NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSolutionMethod method) : A(A), method(method) {
// Get the settings object to customize linear solving.
storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings();
@ -29,9 +29,9 @@ namespace storm {
template<typename ValueType>
void NativeLinearEquationSolver<ValueType>::solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult) const {
if (method == SolutionMethod::SOR || method == SolutionMethod::GaussSeidel) {
if (method == NativeLinearEquationSolverSolutionMethod::SOR || method == NativeLinearEquationSolverSolutionMethod::GaussSeidel) {
// Define the omega used for SOR.
ValueType omega = method == SolutionMethod::SOR ? storm::settings::nativeEquationSolverSettings().getOmega() : storm::utility::one<ValueType>();
ValueType omega = method == NativeLinearEquationSolverSolutionMethod::SOR ? storm::settings::nativeEquationSolverSettings().getOmega() : storm::utility::one<ValueType>();
// To avoid copying the contents of the vector in the loop, we create a temporary x to swap with.
bool tmpXProvided = true;
@ -157,9 +157,9 @@ namespace storm {
template<typename ValueType>
std::string NativeLinearEquationSolver<ValueType>::methodToString() const {
switch (method) {
case SolutionMethod::Jacobi: return "jacobi";
case SolutionMethod::GaussSeidel: return "gauss-seidel";
case SolutionMethod::SOR: return "sor";
case NativeLinearEquationSolverSolutionMethod::Jacobi: return "jacobi";
case NativeLinearEquationSolverSolutionMethod::GaussSeidel: return "gauss-seidel";
case NativeLinearEquationSolverSolutionMethod::SOR: return "sor";
default: return "invalid";
}
}

15
src/solver/NativeLinearEquationSolver.h

@ -6,16 +6,17 @@
namespace storm {
namespace solver {
// An enumeration specifying the available solution methods.
enum class NativeLinearEquationSolverSolutionMethod {
Jacobi, GaussSeidel, SOR
};
/*!
* A class that uses StoRM's native matrix operations to implement the LinearEquationSolver interface.
*/
template<typename ValueType>
class NativeLinearEquationSolver : public LinearEquationSolver<ValueType> {
public:
// An enumeration specifying the available solution methods.
enum class SolutionMethod {
Jacobi, GaussSeidel, SOR
};
/*!
* Constructs a linear equation solver with parameters being set according to the settings object.
@ -23,7 +24,7 @@ namespace storm {
* @param A The matrix defining the coefficients of the linear equation system.
* @param method The method to use for solving linear equations.
*/
NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, SolutionMethod method = SolutionMethod::Jacobi);
NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSolutionMethod method = NativeLinearEquationSolverSolutionMethod::Jacobi);
/*!
* Constructs a linear equation solver with the given parameters.
@ -35,7 +36,7 @@ namespace storm {
* @param relative If set, the relative error rather than the absolute error is considered for convergence
* detection.
*/
NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, SolutionMethod method, double precision, uint_fast64_t maximalNumberOfIterations, bool relative = true);
NativeLinearEquationSolver(storm::storage::SparseMatrix<ValueType> const& A, NativeLinearEquationSolverSolutionMethod method, double precision, uint_fast64_t maximalNumberOfIterations, bool relative = true);
virtual void solveEquationSystem(std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult = nullptr) const override;
@ -53,7 +54,7 @@ namespace storm {
storm::storage::SparseMatrix<ValueType> const& A;
// The method to use for solving linear equation systems.
SolutionMethod method;
NativeLinearEquationSolverSolutionMethod method;
// The required precision for the iterative methods.
double precision;

4
src/solver/NativeMinMaxLinearEquationSolver.cpp

@ -53,7 +53,7 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the
// user-specified maximum number of iterations.
while (!converged && iterations < this->maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations && !this->earlyTermination->terminateNow(*currentX)) {
// Compute x' = A*x + b.
this->A.multiplyWithVector(*currentX, *multiplyResult);
storm::utility::vector::addVectors(*multiplyResult, b, *multiplyResult);
@ -121,7 +121,7 @@ namespace storm {
// Proceed with the iterations as long as the method did not converge or reach the user-specified maximum number
// of iterations.
while (!converged && iterations < this->maximalNumberOfIterations) {
while (!converged && iterations < this->maximalNumberOfIterations && !this->earlyTermination->terminateNow(*currentX)) {
// Take the sub-matrix according to the current choices
storm::storage::SparseMatrix<ValueType> submatrix = this->A.selectRowsFromRowGroups(this->policy, true);
submatrix.convertToEquationSystem();

2
src/solver/SolverSelectionOptions.h

@ -9,7 +9,7 @@ namespace storm {
ExtendEnumsWithSelectionField(MinMaxTechnique, PolicyIteration, ValueIteration)
ExtendEnumsWithSelectionField(LpSolverType, Gurobi, Glpk)
ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx)
ExtendEnumsWithSelectionField(EquationSolverType, Native, Gmmxx, Topological)
ExtendEnumsWithSelectionField(SmtSolverType, Z3, Mathsat)
}
}

1
src/storage/DeterministicModelBisimulationDecomposition.h

@ -13,6 +13,7 @@
#include "src/storage/Distribution.h"
#include "src/utility/constants.h"
#include "src/utility/OsDetection.h"
#include "src/exceptions/InvalidOperationException.h"
namespace storm {
namespace utility {

25
src/storage/SparseMatrix.cpp

@ -825,21 +825,24 @@ namespace storm {
#endif
template<typename ValueType>
std::vector<ValueType> SparseMatrix<ValueType>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<ValueType> const& otherMatrix) const {
std::vector<ValueType> result(rowCount, storm::utility::zero<ValueType>());
template<typename OtherValueType, typename ResultValueType>
std::vector<ResultValueType> SparseMatrix<ValueType>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<OtherValueType> const& otherMatrix) const {
std::vector<ResultValueType> result(rowCount, storm::utility::zero<ResultValueType>());
// Iterate over all elements of the current matrix and either continue with the next element in case the
// given matrix does not have a non-zero element at this column position, or multiply the two entries and
// add the result to the corresponding position in the vector.
for (index_type row = 0; row < rowCount && row < otherMatrix.rowCount; ++row) {
for (const_iterator it1 = this->begin(row), ite1 = this->end(row), it2 = otherMatrix.begin(row), ite2 = otherMatrix.end(row); it1 != ite1 && it2 != ite2; ++it1) {
for (index_type row = 0; row < rowCount && row < otherMatrix.getRowCount(); ++row) {
typename storm::storage::SparseMatrix<OtherValueType>::const_iterator it2 = otherMatrix.begin(row);
typename storm::storage::SparseMatrix<OtherValueType>::const_iterator ite2 = otherMatrix.end(row);
for (const_iterator it1 = this->begin(row), ite1 = this->end(row); it1 != ite1 && it2 != ite2; ++it1) {
if (it1->getColumn() < it2->getColumn()) {
continue;
} else {
// If the precondition of this method (i.e. that the given matrix is a submatrix
// of the current one) was fulfilled, we know now that the two elements are in
// the same column, so we can multiply and add them to the row sum vector.
result[row] += it2->getValue() * it1->getValue();
result[row] += it2->getValue() * OtherValueType(it1->getValue());
++it2;
}
}
@ -1161,18 +1164,27 @@ namespace storm {
template class SparseMatrixBuilder<double>;
template class SparseMatrix<double>;
template std::ostream& operator<<(std::ostream& out, SparseMatrix<double> const& matrix);
template std::vector<double> SparseMatrix<double>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<double> const& otherMatrix) const;
template std::vector<storm::RationalFunction> SparseMatrix<double>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::RationalFunction> const& otherMatrix) const;
template std::vector<storm::Interval> SparseMatrix<double>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::Interval> const& otherMatrix) const;
//float
template class MatrixEntry<typename SparseMatrix<float>::index_type, float>;
template std::ostream& operator<<(std::ostream& out, MatrixEntry<uint_fast64_t, float> const& entry);
template class SparseMatrixBuilder<float>;
template class SparseMatrix<float>;
template std::ostream& operator<<(std::ostream& out, SparseMatrix<float> const& matrix);
template std::vector<float> SparseMatrix<float>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<float> const& otherMatrix) const;
template std::vector<storm::RationalFunction> SparseMatrix<float>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::RationalFunction> const& otherMatrix) const;
//int
template class MatrixEntry<typename SparseMatrix<int>::index_type, int>;
template std::ostream& operator<<(std::ostream& out, MatrixEntry<uint_fast64_t, int> const& entry);
template class SparseMatrixBuilder<int>;
template class SparseMatrix<int>;
template std::ostream& operator<<(std::ostream& out, SparseMatrix<int> const& matrix);
template std::vector<storm::RationalFunction> SparseMatrix<int>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::RationalFunction> const& otherMatrix) const;
#ifdef STORM_HAVE_CARL
// Rat Function
template class MatrixEntry<typename SparseMatrix<RationalFunction>::index_type, RationalFunction>;
@ -1180,12 +1192,15 @@ namespace storm {
template class SparseMatrixBuilder<RationalFunction>;
template class SparseMatrix<RationalFunction>;
template std::ostream& operator<<(std::ostream& out, SparseMatrix<RationalFunction> const& matrix);
template std::vector<storm::RationalFunction> SparseMatrix<RationalFunction>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::RationalFunction> const& otherMatrix) const;
// Intervals
template class MatrixEntry<typename SparseMatrix<Interval>::index_type, Interval>;
template std::ostream& operator<<(std::ostream& out, MatrixEntry<uint_fast64_t, Interval> const& entry);
template class SparseMatrixBuilder<Interval>;
template class SparseMatrix<Interval>;
template std::ostream& operator<<(std::ostream& out, SparseMatrix<Interval> const& matrix);
template std::vector<storm::Interval> SparseMatrix<Interval>::getPointwiseProductRowSumVector(storm::storage::SparseMatrix<storm::Interval> const& otherMatrix) const;
#endif

3
src/storage/SparseMatrix.h

@ -678,7 +678,8 @@ namespace storm {
* @return A vector containing the sum of the entries in each row of the matrix resulting from pointwise
* multiplication of the current matrix with the given matrix.
*/
std::vector<value_type> getPointwiseProductRowSumVector(storm::storage::SparseMatrix<value_type> const& otherMatrix) const;
template<typename OtherValueType, typename ResultValueType = OtherValueType>
std::vector<ResultValueType> getPointwiseProductRowSumVector(storm::storage::SparseMatrix<OtherValueType> const& otherMatrix) const;
/*!
* Multiplies the matrix with the given vector and writes the result to the given result vector. If a

23
src/storage/expressions/SimpleValuation.cpp

@ -1,10 +1,14 @@
#include "src/storage/expressions/SimpleValuation.h"
#include <boost/functional/hash.hpp>
#include <boost/algorithm/string/join.hpp>
#include "src/storage/expressions/ExpressionManager.h"
#include "src/storage/expressions/Variable.h"
#include "src/utility/macros.h"
#include "src/exceptions/InvalidTypeException.h"
namespace storm {
namespace expressions {
SimpleValuation::SimpleValuation() : Valuation(nullptr) {
@ -87,6 +91,25 @@ namespace storm {
rationalValues[rationalVariable.getOffset()] = value;
}
std::string SimpleValuation::toPrettyString(std::set<storm::expressions::Variable> const& selectedVariables) const {
std::vector<std::string> assignments;
for (auto const& variable : selectedVariables) {
std::stringstream stream;
stream << variable.getName() << "=";
if (variable.hasBooleanType()) {
stream << std::boolalpha << this->getBooleanValue(variable) << std::noboolalpha;
} else if (variable.hasIntegerType()) {
stream << this->getIntegerValue(variable);
} else if (variable.hasRationalType()) {
stream << this->getRationalValue(variable);
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unexpected variable type.");
}
assignments.push_back(stream.str());
}
return "[" + boost::join(assignments, ", ") + "]";
}
std::ostream& operator<<(std::ostream& out, SimpleValuation const& valuation) {
out << "valuation {" << std::endl;
out << valuation.getManager() << std::endl;

10
src/storage/expressions/SimpleValuation.h

@ -3,7 +3,7 @@
#include <cstdint>
#include <vector>
#include <iostream>
#include <set>
#include "src/storage/expressions/Valuation.h"
@ -54,6 +54,14 @@ namespace storm {
virtual double getRationalValue(Variable const& rationalVariable) const override;
virtual void setRationalValue(Variable const& rationalVariable, double value) override;
/*!
* Returns a string representation of the valuation of the selected variables.
*
* @param selectedVariables The variables to select.
* @return The string representation.
*/
virtual std::string toPrettyString(std::set<storm::expressions::Variable> const& selectedVariables) const;
friend std::ostream& operator<<(std::ostream& out, SimpleValuation const& valuation);
private:

11
src/storage/prism/Program.cpp

@ -23,7 +23,7 @@ namespace storm {
globalIntegerVariables(globalIntegerVariables), globalIntegerVariableToIndexMap(),
formulas(formulas), formulaToIndexMap(), modules(modules), moduleToIndexMap(),
rewardModels(rewardModels), rewardModelToIndexMap(), initialConstruct(initialConstruct),
labels(labels), actionToIndexMap(actionToIndexMap), indexToActionMap(), actions(),
labels(labels), labelToIndexMap(), actionToIndexMap(actionToIndexMap), indexToActionMap(), actions(),
synchronizingActionIndices(), actionIndicesToModuleIndexMap(), variableToModuleIndexMap()
{
@ -328,6 +328,12 @@ namespace storm {
return this->labels;
}
storm::expressions::Expression const& Program::getLabelExpression(std::string const& label) const {
auto const& labelIndexPair = labelToIndexMap.find(label);
STORM_LOG_THROW(labelIndexPair != labelToIndexMap.end(), storm::exceptions::InvalidArgumentException, "Cannot retrieve expression for unknown label '" << label << "'.");
return this->labels[labelIndexPair->second].getStatePredicateExpression();
}
std::size_t Program::getNumberOfLabels() const {
return this->getLabels().size();
}
@ -385,6 +391,9 @@ namespace storm {
for (uint_fast64_t formulaIndex = 0; formulaIndex < this->getNumberOfFormulas(); ++formulaIndex) {
this->formulaToIndexMap[this->getFormulas()[formulaIndex].getName()] = formulaIndex;
}
for (uint_fast64_t labelIndex = 0; labelIndex < this->getNumberOfLabels(); ++labelIndex) {
this->labelToIndexMap[this->getLabels()[labelIndex].getName()] = labelIndex;
}
for (uint_fast64_t moduleIndex = 0; moduleIndex < this->getNumberOfModules(); ++moduleIndex) {
this->moduleToIndexMap[this->getModules()[moduleIndex].getName()] = moduleIndex;
}

10
src/storage/prism/Program.h

@ -346,6 +346,13 @@ namespace storm {
*/
std::vector<Label> const& getLabels() const;
/*!
* Retrieves the expression associated with the given label, if it exists.
*
* @param labelName The name of the label to retrieve.
*/
storm::expressions::Expression const& getLabelExpression(std::string const& label) const;
/*!
* Retrieves the number of labels in the program.
*
@ -501,6 +508,9 @@ namespace storm {
// The labels that are defined for this model.
std::vector<Label> labels;
// A mapping from labels to their indices.
std::map<std::string, uint_fast64_t> labelToIndexMap;
// A mapping from action names to their indices.
std::map<std::string, uint_fast64_t> actionToIndexMap;

10
src/storm.cpp

@ -1,22 +1,22 @@
// Include other headers.
#include "src/exceptions/BaseException.h"
#include "src/utility/macros.h"
#include "src/utility/cli.h"
#include "src/cli/cli.h"
#include "src/utility/initialize.h"
/*!
* Main entry point of the executable storm.
*/
int main(const int argc, const char** argv) {
try {
storm::utility::setUp();
storm::utility::cli::printHeader(argc, argv);
bool optionsCorrect = storm::utility::cli::parseOptions(argc, argv);
storm::cli::printHeader(argc, argv);
bool optionsCorrect = storm::cli::parseOptions(argc, argv);
if (!optionsCorrect) {
return -1;
}
// From this point on we are ready to carry out the actual computations.
storm::utility::cli::processOptions();
storm::cli::processOptions();
// All operations have now been performed, so we clean up everything and terminate.
storm::utility::cleanUp();

1025
src/utility/graph.cpp
File diff suppressed because it is too large
View File

794
src/utility/graph.h

@ -7,19 +7,33 @@
#include "utility/OsDetection.h"
#include "src/storage/sparse/StateType.h"
#include "src/models/symbolic/DeterministicModel.h"
#include "src/models/symbolic/NondeterministicModel.h"
#include "src/models/sparse/DeterministicModel.h"
#include "src/models/sparse/NondeterministicModel.h"
#include "src/utility/constants.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
#include "src/models/sparse/DeterministicModel.h"
#include "src/storage/dd/DdType.h"
namespace storm {
namespace storage {
class BitVector;
template<typename VT> class SparseMatrix;
}
namespace models {
namespace symbolic {
template<storm::dd::DdType T> class Model;
template<storm::dd::DdType T> class DeterministicModel;
template<storm::dd::DdType T> class NondeterministicModel;
}
}
namespace dd {
template<storm::dd::DdType T> class Bdd;
template<storm::dd::DdType T> class Add;
}
namespace utility {
namespace graph {
@ -34,38 +48,7 @@ namespace storm {
* @param targetStates The target states that may not be passed.
*/
template<typename T>
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates) {
storm::storage::BitVector reachableStates(initialStates);
// Initialize the stack used for the DFS with the states.
std::vector<uint_fast64_t> stack(initialStates.begin(), initialStates.end());
// Perform the actual DFS.
uint_fast64_t currentState = 0;
while (!stack.empty()) {
currentState = stack.back();
stack.pop_back();
for (auto const& successor : transitionMatrix.getRowGroup(currentState)) {
// Only explore the state if the transition was actually there and the successor has not yet
// been visited.
if (successor.getValue() != storm::utility::zero<T>() && !reachableStates.get(successor.getColumn())) {
// If the successor is one of the target states, we need to include it, but must not explore
// it further.
if (targetStates.get(successor.getColumn())) {
reachableStates.set(successor.getColumn());
} else if (constraintStates.get(successor.getColumn())) {
// However, if the state is in the constrained set of states, we need to follow it.
reachableStates.set(successor.getColumn());
stack.push_back(successor.getColumn());
}
}
}
}
return reachableStates;
}
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates);
/*!
* Performs a breadth-first search through the underlying graph structure to compute the distance from all
* states to the starting states of the search.
@ -75,35 +58,7 @@ namespace storm {
* @return The distances of each state to the initial states of the sarch.
*/
template<typename T>
std::vector<std::size_t> getDistances(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::BitVector const& initialStates) {
std::vector<std::size_t> distances(transitionMatrix.getRowGroupCount());
std::vector<std::pair<storm::storage::sparse::state_type, std::size_t>> stateQueue;
stateQueue.reserve(transitionMatrix.getRowGroupCount());
storm::storage::BitVector statesInQueue(transitionMatrix.getRowGroupCount());
storm::storage::sparse::state_type currentPosition = 0;
for (auto const& initialState : initialStates) {
stateQueue.emplace_back(initialState, 0);
statesInQueue.set(initialState);
}
// Perform a BFS.
while (currentPosition < stateQueue.size()) {
std::pair<storm::storage::sparse::state_type, std::size_t> const& stateDistancePair = stateQueue[currentPosition];
distances[stateDistancePair.first] = stateDistancePair.second;
for (auto const& successorEntry : transitionMatrix.getRowGroup(stateDistancePair.first)) {
if (!statesInQueue.get(successorEntry.getColumn())) {
stateQueue.emplace_back(successorEntry.getColumn(), stateDistancePair.second + 1);
statesInQueue.set(successorEntry.getColumn());
}
}
++currentPosition;
}
return distances;
}
std::vector<std::size_t> getDistances(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::BitVector const& initialStates);
/*!
* Performs a backward depth-first search trough the underlying graph structure
@ -118,61 +73,7 @@ namespace storm {
* @return A bit vector with all indices of states that have a probability greater than 0.
*/
template <typename T>
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) {
// Prepare the resulting bit vector.
uint_fast64_t numberOfStates = phiStates.size();
storm::storage::BitVector statesWithProbabilityGreater0(numberOfStates);
// Add all psi states as they already satisfy the condition.
statesWithProbabilityGreater0 |= psiStates;
// Initialize the stack used for the DFS with the states.
std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
// Initialize the stack for the step bound, if the number of steps is bounded.
std::vector<uint_fast64_t> stepStack;
std::vector<uint_fast64_t> remainingSteps;
if (useStepBound) {
stepStack.reserve(numberOfStates);
stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
remainingSteps.resize(numberOfStates);
for (auto state : psiStates) {
remainingSteps[state] = maximalSteps;
}
}
// Perform the actual DFS.
uint_fast64_t currentState, currentStepBound;
while (!stack.empty()) {
currentState = stack.back();
stack.pop_back();
if (useStepBound) {
currentStepBound = stepStack.back();
stepStack.pop_back();
}
for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState), entryIte = backwardTransitions.end(currentState); entryIt != entryIte; ++entryIt) {
if (phiStates[entryIt->getColumn()] && (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
// If we don't have a bound on the number of steps to take, just add the state to the stack.
if (!useStepBound) {
statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
stack.push_back(entryIt->getColumn());
} else if (currentStepBound > 0) {
// If there is at least one more step to go, we need to push the state and the new number of steps.
remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
stack.push_back(entryIt->getColumn());
stepStack.push_back(currentStepBound - 1);
}
}
}
}
// Return result.
return statesWithProbabilityGreater0;
}
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0);
/*!
* Computes the set of states of the given model for which all paths lead to
* the given set of target states and only visit states from the filter set
@ -188,11 +89,7 @@ namespace storm {
* @return A bit vector with all indices of states that have a probability greater than 1.
*/
template <typename T>
storm::storage::BitVector performProb1(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0) {
storm::storage::BitVector statesWithProbability1 = performProbGreater0(backwardTransitions, ~psiStates, ~statesWithProbabilityGreater0);
statesWithProbability1.complement();
return statesWithProbability1;
}
storm::storage::BitVector performProb1(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::BitVector const& statesWithProbabilityGreater0);
/*!
* Computes the set of states of the given model for which all paths lead to
@ -207,12 +104,7 @@ namespace storm {
* @return A bit vector with all indices of states that have a probability greater than 1.
*/
template <typename T>
storm::storage::BitVector performProb1(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
storm::storage::BitVector statesWithProbabilityGreater0 = performProbGreater0(backwardTransitions, phiStates, psiStates);
storm::storage::BitVector statesWithProbability1 = performProbGreater0(backwardTransitions, ~psiStates, ~(statesWithProbabilityGreater0));
statesWithProbability1.complement();
return statesWithProbability1;
}
storm::storage::BitVector performProb1(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a
@ -225,14 +117,7 @@ namespace storm {
* with probability 0 and the second stores all indices of states with probability 1.
*/
template <typename T>
static std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
storm::storage::SparseMatrix<T> backwardTransitions = model.getBackwardTransitions();
result.first = performProbGreater0(backwardTransitions, phiStates, psiStates);
result.second = performProb1(backwardTransitions, phiStates, psiStates, result.first);
result.first.complement();
return result;
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::models::sparse::DeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a
@ -245,13 +130,8 @@ namespace storm {
* with probability 0 and the second stores all indices of states with probability 1.
*/
template <typename T>
static std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
result.first = performProbGreater0(backwardTransitions, phiStates, psiStates);
result.second = performProb1(backwardTransitions, phiStates, psiStates, result.first);
result.first.complement();
return result;
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01(storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the set of states that has a positive probability of reaching psi states after only passing
@ -265,30 +145,7 @@ namespace storm {
* @return All states with positive probability.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProbGreater0(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>()) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0 = psiStates;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbabilityGreater0) {
if (stepBound && iterations >= stepBound.get()) {
break;
}
lastIterationStates = statesWithProbabilityGreater0;
statesWithProbabilityGreater0 = statesWithProbabilityGreater0.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0 &= transitionMatrix;
statesWithProbabilityGreater0 = statesWithProbabilityGreater0.existsAbstract(model.getColumnVariables());
statesWithProbabilityGreater0 &= phiStates;
statesWithProbabilityGreater0 |= lastIterationStates;
++iterations;
}
return statesWithProbabilityGreater0;
}
storm::dd::Bdd<Type> performProbGreater0(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, boost::optional<uint_fast64_t> const& stepBound = boost::optional<uint_fast64_t>());
/*!
* Computes the set of states that have a probability of one of reaching psi states after only passing
* through phi states before.
@ -302,11 +159,7 @@ namespace storm {
* @return All states with probability 1.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb1(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0) {
storm::dd::Bdd<Type> statesWithProbability1 = performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !statesWithProbabilityGreater0 && model.getReachableStates());
statesWithProbability1 = !statesWithProbability1 && model.getReachableStates();
return statesWithProbability1;
}
storm::dd::Bdd<Type> performProb1(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0);
/*!
* Computes the set of states that have a probability of one of reaching psi states after only passing
@ -319,10 +172,7 @@ namespace storm {
* @return All states with probability 1.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb1(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
storm::dd::Bdd<Type> statesWithProbabilityGreater0 = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
return performProb1(model, transitionMatrix, phiStates, psiStates, statesWithProbabilityGreater0);
}
storm::dd::Bdd<Type> performProb1(storm::models::symbolic::Model<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a
@ -334,14 +184,7 @@ namespace storm {
* @return A pair of BDDs that represent all states with probability 0 and 1, respectively.
*/
template <storm::dd::DdType Type>
static std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProbGreater0(model, transitionMatrix, phiStates, psiStates);
result.second = !performProbGreater0(model, transitionMatrix, !psiStates && model.getReachableStates(), !result.first && model.getReachableStates()) && model.getReachableStates();
result.first = !result.first && model.getReachableStates();
return result;
}
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01(storm::models::symbolic::DeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates);
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi in a
@ -354,14 +197,7 @@ namespace storm {
* @return A pair of BDDs that represent all states with probability 0 and 1, respectively.
*/
template <storm::dd::DdType Type>
static std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01(storm::models::symbolic::Model<Type> const& model, storm::dd::Add<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrixBdd = transitionMatrix.notZero();
result.first = performProbGreater0(model, transitionMatrixBdd, phiStates, psiStates);
result.second = !performProbGreater0(model, transitionMatrixBdd, !psiStates && model.getReachableStates(), !result.first && model.getReachableStates()) && model.getReachableStates();
result.first = !result.first && model.getReachableStates();
return result;
}
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01(storm::models::symbolic::Model<Type> const& model, storm::dd::Add<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates);
/*!
* Computes the sets of states that have probability greater 0 of satisfying phi until psi under at least
@ -378,67 +214,10 @@ namespace storm {
* @return A bit vector that represents all states with probability 0.
*/
template <typename T>
storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) {
size_t numberOfStates = phiStates.size();
// Prepare resulting bit vector.
storm::storage::BitVector statesWithProbabilityGreater0(numberOfStates);
// Add all psi states as the already satisfy the condition.
statesWithProbabilityGreater0 |= psiStates;
// Initialize the stack used for the DFS with the states
std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
// Initialize the stack for the step bound, if the number of steps is bounded.
std::vector<uint_fast64_t> stepStack;
std::vector<uint_fast64_t> remainingSteps;
if (useStepBound) {
stepStack.reserve(numberOfStates);
stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
remainingSteps.resize(numberOfStates);
for (auto state : psiStates) {
remainingSteps[state] = maximalSteps;
}
}
// Perform the actual DFS.
uint_fast64_t currentState, currentStepBound;
while (!stack.empty()) {
currentState = stack.back();
stack.pop_back();
if (useStepBound) {
currentStepBound = stepStack.back();
stepStack.pop_back();
}
for (typename storm::storage::SparseMatrix<T>::const_iterator entryIt = backwardTransitions.begin(currentState), entryIte = backwardTransitions.end(currentState); entryIt != entryIte; ++entryIt) {
if (phiStates.get(entryIt->getColumn()) && (!statesWithProbabilityGreater0.get(entryIt->getColumn()) || (useStepBound && remainingSteps[entryIt->getColumn()] < currentStepBound - 1))) {
// If we don't have a bound on the number of steps to take, just add the state to the stack.
if (!useStepBound) {
statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
stack.push_back(entryIt->getColumn());
} else if (currentStepBound > 0) {
// If there is at least one more step to go, we need to push the state and the new number of steps.
remainingSteps[entryIt->getColumn()] = currentStepBound - 1;
statesWithProbabilityGreater0.set(entryIt->getColumn(), true);
stack.push_back(entryIt->getColumn());
stepStack.push_back(currentStepBound - 1);
}
}
}
}
return statesWithProbabilityGreater0;
}
storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ;
template <typename T>
storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
storm::storage::BitVector statesWithProbability0 = performProbGreater0E(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
statesWithProbability0.complement();
return statesWithProbability0;
}
storm::storage::BitVector performProb0A(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the sets of states that have probability 0 of satisfying phi until psi under all
@ -455,10 +234,7 @@ namespace storm {
* @return A bit vector that represents all states with probability 0.
*/
template <typename T>
storm::storage::BitVector performProb0A(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
return performProb0A(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
}
storm::storage::BitVector performProb0A(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ;
/*!
* Computes the sets of states that have probability 1 of satisfying phi until psi under at least
* one possible resolution of non-determinism in a non-deterministic model. Stated differently,
@ -472,62 +248,7 @@ namespace storm {
* @return A bit vector that represents all states with probability 1.
*/
template <typename T>
storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
size_t numberOfStates = phiStates.size();
// Initialize the environment for the iterative algorithm.
storm::storage::BitVector currentStates(numberOfStates, true);
std::vector<uint_fast64_t> stack;
stack.reserve(numberOfStates);
// Perform the loop as long as the set of states gets larger.
bool done = false;
uint_fast64_t currentState;
while (!done) {
stack.clear();
storm::storage::BitVector nextStates(psiStates);
stack.insert(stack.end(), psiStates.begin(), psiStates.end());
while (!stack.empty()) {
currentState = stack.back();
stack.pop_back();
for (typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
if (phiStates.get(predecessorEntryIt->getColumn()) && !nextStates.get(predecessorEntryIt->getColumn())) {
// Check whether the predecessor has only successors in the current state set for one of the
// nondeterminstic choices.
for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
bool allSuccessorsInCurrentStates = true;
for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) {
if (!currentStates.get(successorEntryIt->getColumn())) {
allSuccessorsInCurrentStates = false;
break;
}
}
// If all successors for a given nondeterministic choice are in the current state set, we
// add it to the set of states for the next iteration and perform a backward search from
// that state.
if (allSuccessorsInCurrentStates) {
nextStates.set(predecessorEntryIt->getColumn(), true);
stack.push_back(predecessorEntryIt->getColumn());
break;
}
}
}
}
}
// Check whether we need to perform an additional iteration.
if (currentStates == nextStates) {
done = true;
} else {
currentStates = std::move(nextStates);
}
}
return currentStates;
}
storm::storage::BitVector performProb1E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the sets of states that have probability 1 of satisfying phi until psi under at least
@ -542,18 +263,10 @@ namespace storm {
* @return A bit vector that represents all states with probability 1.
*/
template <typename T>
storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
return performProb1E(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
}
storm::storage::BitVector performProb1E(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
template <typename T>
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
result.first = performProb0A(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
result.second = performProb1E(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
return result;
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ;
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi
@ -566,9 +279,7 @@ namespace storm {
* @return A pair of bit vectors that represent all states with probability 0 and 1, respectively.
*/
template <typename T>
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
return performProb01Max(model.getTransitionMatrix(), model.getTransitionMatrix().getRowGroupIndices(), model.getBackwardTransitions(), phiStates, psiStates);
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Max(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ;
/*!
* Computes the sets of states that have probability greater 0 of satisfying phi until psi under any
@ -585,81 +296,7 @@ namespace storm {
* @return A bit vector that represents all states with probability 0.
*/
template <typename T>
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) {
size_t numberOfStates = phiStates.size();
// Prepare resulting bit vector.
storm::storage::BitVector statesWithProbabilityGreater0(numberOfStates);
// Add all psi states as the already satisfy the condition.
statesWithProbabilityGreater0 |= psiStates;
// Initialize the stack used for the DFS with the states
std::vector<uint_fast64_t> stack(psiStates.begin(), psiStates.end());
// Initialize the stack for the step bound, if the number of steps is bounded.
std::vector<uint_fast64_t> stepStack;
std::vector<uint_fast64_t> remainingSteps;
if (useStepBound) {
stepStack.reserve(numberOfStates);
stepStack.insert(stepStack.begin(), psiStates.getNumberOfSetBits(), maximalSteps);
remainingSteps.resize(numberOfStates);
for (auto state : psiStates) {
remainingSteps[state] = maximalSteps;
}
}
// Perform the actual DFS.
uint_fast64_t currentState, currentStepBound;
while(!stack.empty()) {
currentState = stack.back();
stack.pop_back();
if (useStepBound) {
currentStepBound = stepStack.back();
stepStack.pop_back();
}
for(typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
if (phiStates.get(predecessorEntryIt->getColumn()) && (!statesWithProbabilityGreater0.get(predecessorEntryIt->getColumn()) || (useStepBound && remainingSteps[predecessorEntryIt->getColumn()] < currentStepBound - 1))) {
// Check whether the predecessor has at least one successor in the current state set for every
// nondeterministic choice.
bool addToStatesWithProbabilityGreater0 = true;
for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
bool hasAtLeastOneSuccessorWithProbabilityGreater0 = false;
for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) {
if (statesWithProbabilityGreater0.get(successorEntryIt->getColumn())) {
hasAtLeastOneSuccessorWithProbabilityGreater0 = true;
break;
}
}
if (!hasAtLeastOneSuccessorWithProbabilityGreater0) {
addToStatesWithProbabilityGreater0 = false;
break;
}
}
// If we need to add the state, then actually add it and perform further search from the state.
if (addToStatesWithProbabilityGreater0) {
// If we don't have a bound on the number of steps to take, just add the state to the stack.
if (!useStepBound) {
statesWithProbabilityGreater0.set(predecessorEntryIt->getColumn(), true);
stack.push_back(predecessorEntryIt->getColumn());
} else if (currentStepBound > 0) {
// If there is at least one more step to go, we need to push the state and the new number of steps.
remainingSteps[predecessorEntryIt->getColumn()] = currentStepBound - 1;
statesWithProbabilityGreater0.set(predecessorEntryIt->getColumn(), true);
stack.push_back(predecessorEntryIt->getColumn());
stepStack.push_back(currentStepBound - 1);
}
}
}
}
}
return statesWithProbabilityGreater0;
}
storm::storage::BitVector performProbGreater0A(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0);
/*!
* Computes the sets of states that have probability 0 of satisfying phi until psi under at least
@ -674,18 +311,9 @@ namespace storm {
* @return A bit vector that represents all states with probability 0.
*/
template <typename T>
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
storm::storage::BitVector statesWithProbability0 = performProbGreater0A(model.getTransitionMatrix(), model.getNondeterministicChoiceIndices(), backwardTransitions, phiStates, psiStates);
statesWithProbability0.complement();
return statesWithProbability0;
}
storm::storage::BitVector performProb0E(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
template <typename T>
storm::storage::BitVector performProb0E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
storm::storage::BitVector statesWithProbability0 = performProbGreater0A(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
statesWithProbability0.complement();
return statesWithProbability0;
}
storm::storage::BitVector performProb0E(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ;
/*!
* Computes the sets of states that have probability 1 of satisfying phi until psi under all
@ -700,79 +328,10 @@ namespace storm {
* @return A bit vector that represents all states with probability 0.
*/
template <typename T>
storm::storage::BitVector performProb1A( storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
size_t numberOfStates = phiStates.size();
// Initialize the environment for the iterative algorithm.
storm::storage::BitVector currentStates(numberOfStates, true);
std::vector<uint_fast64_t> stack;
stack.reserve(numberOfStates);
// Perform the loop as long as the set of states gets smaller.
bool done = false;
uint_fast64_t currentState;
while (!done) {
stack.clear();
storm::storage::BitVector nextStates(psiStates);
stack.insert(stack.end(), psiStates.begin(), psiStates.end());
while (!stack.empty()) {
currentState = stack.back();
stack.pop_back();
for(typename storm::storage::SparseMatrix<T>::const_iterator predecessorEntryIt = backwardTransitions.begin(currentState), predecessorEntryIte = backwardTransitions.end(currentState); predecessorEntryIt != predecessorEntryIte; ++predecessorEntryIt) {
if (phiStates.get(predecessorEntryIt->getColumn()) && !nextStates.get(predecessorEntryIt->getColumn())) {
// Check whether the predecessor has only successors in the current state set for all of the
// nondeterminstic choices and that for each choice there exists a successor that is already
// in the next states.
bool addToStatesWithProbability1 = true;
for (uint_fast64_t row = nondeterministicChoiceIndices[predecessorEntryIt->getColumn()]; row < nondeterministicChoiceIndices[predecessorEntryIt->getColumn() + 1]; ++row) {
bool hasAtLeastOneSuccessorWithProbability1 = false;
for (typename storm::storage::SparseMatrix<T>::const_iterator successorEntryIt = transitionMatrix.begin(row), successorEntryIte = transitionMatrix.end(row); successorEntryIt != successorEntryIte; ++successorEntryIt) {
if (!currentStates.get(successorEntryIt->getColumn())) {
addToStatesWithProbability1 = false;
goto afterCheckLoop;
}
if (nextStates.get(successorEntryIt->getColumn())) {
hasAtLeastOneSuccessorWithProbability1 = true;
}
}
if (!hasAtLeastOneSuccessorWithProbability1) {
addToStatesWithProbability1 = false;
break;
}
}
afterCheckLoop:
// If all successors for all nondeterministic choices are in the current state set, we
// add it to the set of states for the next iteration and perform a backward search from
// that state.
if (addToStatesWithProbability1) {
nextStates.set(predecessorEntryIt->getColumn(), true);
stack.push_back(predecessorEntryIt->getColumn());
}
}
}
}
// Check whether we need to perform an additional iteration.
if (currentStates == nextStates) {
done = true;
} else {
currentStates = std::move(nextStates);
}
}
return currentStates;
}
storm::storage::BitVector performProb1A( storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
template <typename T>
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
std::pair<storm::storage::BitVector, storm::storage::BitVector> result;
result.first = performProb0E(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
result.second = performProb1A(transitionMatrix, nondeterministicChoiceIndices, backwardTransitions, phiStates, psiStates);
return result;
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::storage::SparseMatrix<T> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) ;
/*!
* Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi
@ -785,9 +344,7 @@ namespace storm {
* @return A pair of bit vectors that represent all states with probability 0 and 1, respectively.
*/
template <typename T>
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
return performProb01Min(model.getTransitionMatrix(), model.getTransitionMatrix().getRowGroupIndices(), model.getBackwardTransitions(), phiStates, psiStates);
}
std::pair<storm::storage::BitVector, storm::storage::BitVector> performProb01Min(storm::models::sparse::NondeterministicModel<T> const& model, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates);
/*!
* Computes the set of states for which there exists a scheduler that achieves a probability greater than
@ -800,26 +357,7 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProbGreater0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0E = psiStates;
uint_fast64_t iterations = 0;
storm::dd::Bdd<Type> abstractedTransitionMatrix = transitionMatrix.existsAbstract(model.getNondeterminismVariables());
while (lastIterationStates != statesWithProbabilityGreater0E) {
lastIterationStates = statesWithProbabilityGreater0E;
statesWithProbabilityGreater0E = statesWithProbabilityGreater0E.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0E = statesWithProbabilityGreater0E.andExists(abstractedTransitionMatrix, model.getColumnVariables());
statesWithProbabilityGreater0E &= phiStates;
statesWithProbabilityGreater0E |= lastIterationStates;
++iterations;
}
return statesWithProbabilityGreater0E;
}
storm::dd::Bdd<Type> performProbGreater0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates);
/*!
* Computes the set of states for which there does not exist a scheduler that achieves a probability greater
* than zero of satisfying phi until psi.
@ -831,10 +369,7 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
return !performProbGreater0E(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
}
storm::dd::Bdd<Type> performProb0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
/*!
* Computes the set of states for which all schedulers achieve a probability greater than zero of satisfying
* phi until psi.
@ -846,27 +381,7 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProbGreater0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbabilityGreater0A = psiStates;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbabilityGreater0A) {
lastIterationStates = statesWithProbabilityGreater0A;
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.andExists(transitionMatrix, model.getColumnVariables());
statesWithProbabilityGreater0A |= model.getIllegalMask();
statesWithProbabilityGreater0A = statesWithProbabilityGreater0A.universalAbstract(model.getNondeterminismVariables());
statesWithProbabilityGreater0A &= phiStates;
statesWithProbabilityGreater0A |= psiStates;
++iterations;
}
return statesWithProbabilityGreater0A;
}
storm::dd::Bdd<Type> performProbGreater0A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
/*!
* Computes the set of states for which there exists a scheduler that achieves probability zero of satisfying
* phi until psi.
@ -878,9 +393,7 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
return !performProbGreater0A(model, transitionMatrix, phiStates, psiStates) && model.getReachableStates();
}
storm::dd::Bdd<Type> performProb0E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
/*!
* Computes the set of states for which all schedulers achieve probability one of satisfying phi until psi.
@ -894,26 +407,7 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb1A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0A) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Bdd<Type> lastIterationStates = manager.getBddZero();
storm::dd::Bdd<Type> statesWithProbability1A = psiStates || statesWithProbabilityGreater0A;
uint_fast64_t iterations = 0;
while (lastIterationStates != statesWithProbability1A) {
lastIterationStates = statesWithProbability1A;
statesWithProbability1A = statesWithProbability1A.swapVariables(model.getRowColumnMetaVariablePairs());
statesWithProbability1A = transitionMatrix.implies(statesWithProbability1A).universalAbstract(model.getColumnVariables());
statesWithProbability1A |= model.getIllegalMask();
statesWithProbability1A = statesWithProbability1A.universalAbstract(model.getNondeterminismVariables());
statesWithProbability1A &= statesWithProbabilityGreater0A;
statesWithProbability1A |= psiStates;
++iterations;
}
return statesWithProbability1A;
}
storm::dd::Bdd<Type> performProb1A(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0A);
/*!
* Computes the set of states for which there exists a scheduler that achieves probability one of satisfying
@ -928,63 +422,13 @@ namespace storm {
* @return A BDD representing all such states.
*/
template <storm::dd::DdType Type>
storm::dd::Bdd<Type> performProb1E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0E) {
// Initialize environment for backward search.
storm::dd::DdManager<Type> const& manager = model.getManager();
storm::dd::Bdd<Type> statesWithProbability1E = statesWithProbabilityGreater0E;
uint_fast64_t iterations = 0;
bool outerLoopDone = false;
while (!outerLoopDone) {
storm::dd::Bdd<Type> innerStates = manager.getBddZero();
bool innerLoopDone = false;
while (!innerLoopDone) {
storm::dd::Bdd<Type> temporary = statesWithProbability1E.swapVariables(model.getRowColumnMetaVariablePairs());
temporary = transitionMatrix.implies(temporary).universalAbstract(model.getColumnVariables());
storm::dd::Bdd<Type> temporary2 = innerStates.swapVariables(model.getRowColumnMetaVariablePairs());
temporary2 = transitionMatrix.andExists(temporary2, model.getColumnVariables());
temporary = temporary.andExists(temporary2, model.getNondeterminismVariables());
temporary &= phiStates;
temporary |= psiStates;
if (innerStates == temporary) {
innerLoopDone = true;
} else {
innerStates = temporary;
}
}
if (statesWithProbability1E == innerStates) {
outerLoopDone = true;
} else {
statesWithProbability1E = innerStates;
}
++iterations;
}
return statesWithProbability1E;
}
storm::dd::Bdd<Type> performProb1E(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& transitionMatrix, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates, storm::dd::Bdd<Type> const& statesWithProbabilityGreater0E) ;
template <storm::dd::DdType Type>
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Max(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProb0A(model, transitionMatrix, phiStates, psiStates);
result.second = performProb1E(model, transitionMatrix, phiStates, psiStates, !result.first && model.getReachableStates());
return result;
}
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Max(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
template <storm::dd::DdType Type>
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Min(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) {
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> result;
storm::dd::Bdd<Type> transitionMatrix = model.getTransitionMatrix().notZero();
result.first = performProb0E(model, transitionMatrix, phiStates, psiStates);
result.second = performProb1A(model, transitionMatrix, phiStates, psiStates, !result.first && model.getReachableStates());
return result;
}
std::pair<storm::dd::Bdd<Type>, storm::dd::Bdd<Type>> performProb01Min(storm::models::symbolic::NondeterministicModel<Type> const& model, storm::dd::Bdd<Type> const& phiStates, storm::dd::Bdd<Type> const& psiStates) ;
/*!
* Performs a topological sort of the states of the system according to the given transitions.
@ -993,73 +437,7 @@ namespace storm {
* @return A vector of indices that is a topological sort of the states.
*/
template <typename T>
std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<T> const& matrix) {
if (matrix.getRowCount() != matrix.getColumnCount()) {
LOG4CPLUS_ERROR(logger, "Provided matrix is required to be square.");
throw storm::exceptions::InvalidArgumentException() << "Provided matrix is required to be square.";
}
uint_fast64_t numberOfStates = matrix.getRowCount();
// Prepare the result. This relies on the matrix being square.
std::vector<uint_fast64_t> topologicalSort;
topologicalSort.reserve(numberOfStates);
// Prepare the stacks needed for recursion.
std::vector<uint_fast64_t> recursionStack;
recursionStack.reserve(matrix.getRowCount());
std::vector<typename storm::storage::SparseMatrix<T>::const_iterator> iteratorRecursionStack;
iteratorRecursionStack.reserve(numberOfStates);
// Perform a depth-first search over the given transitions and record states in the reverse order they were visited.
storm::storage::BitVector visitedStates(numberOfStates);
for (uint_fast64_t state = 0; state < numberOfStates; ++state) {
if (!visitedStates.get(state)) {
recursionStack.push_back(state);
iteratorRecursionStack.push_back(matrix.begin(state));
recursionStepForward:
while (!recursionStack.empty()) {
uint_fast64_t currentState = recursionStack.back();
typename storm::storage::SparseMatrix<T>::const_iterator successorIterator = iteratorRecursionStack.back();
visitedStates.set(currentState, true);
recursionStepBackward:
for (; successorIterator != matrix.end(currentState); ++successorIterator) {
if (!visitedStates.get(successorIterator->getColumn())) {
// Put unvisited successor on top of our recursion stack and remember that.
recursionStack.push_back(successorIterator->getColumn());
// Also, put initial value for iterator on corresponding recursion stack.
iteratorRecursionStack.push_back(matrix.begin(successorIterator->getColumn()));
goto recursionStepForward;
}
}
topologicalSort.push_back(currentState);
// If we reach this point, we have completed the recursive descent for the current state.
// That is, we need to pop it from the recursion stacks.
recursionStack.pop_back();
iteratorRecursionStack.pop_back();
// If there is at least one state under the current one in our recursion stack, we need
// to restore the topmost state as the current state and jump to the part after the
// original recursive call.
if (recursionStack.size() > 0) {
currentState = recursionStack.back();
successorIterator = iteratorRecursionStack.back();
goto recursionStepBackward;
}
}
}
}
return topologicalSort;
}
std::vector<uint_fast64_t> getTopologicalSort(storm::storage::SparseMatrix<T> const& matrix) ;
/*!
* A class needed to compare the distances for two states in the Dijkstra search.
@ -1084,59 +462,7 @@ namespace storm {
std::pair<std::vector<T>, std::vector<uint_fast64_t>> performDijkstra(storm::models::sparse::Model<T> const& model,
storm::storage::SparseMatrix<T> const& transitions,
storm::storage::BitVector const& startingStates,
storm::storage::BitVector const* filterStates = nullptr) {
LOG4CPLUS_INFO(logger, "Performing Dijkstra search.");
const uint_fast64_t noPredecessorValue = storm::utility::zero<uint_fast64_t>();
std::vector<T> probabilities(model.getNumberOfStates(), storm::utility::zero<T>());
std::vector<uint_fast64_t> predecessors(model.getNumberOfStates(), noPredecessorValue);
// Set the probability to 1 for all starting states.
std::set<std::pair<T, uint_fast64_t>, DistanceCompare<T>> probabilityStateSet;
for (auto state : startingStates) {
probabilityStateSet.emplace(storm::utility::one<T>(), state);
probabilities[state] = storm::utility::one<T>();
}
// As long as there is one reachable state, we need to consider it.
while (!probabilityStateSet.empty()) {
// Get the state with the least distance from the set and remove it.
std::pair<T, uint_fast64_t> probabilityStatePair = *probabilityStateSet.begin();
probabilityStateSet.erase(probabilityStateSet.begin());
// Now check the new distances for all successors of the current state.
typename storm::storage::SparseMatrix<T>::Rows row = transitions.getRow(probabilityStatePair.second);
for (auto const& transition : row) {
// Only follow the transition if it lies within the filtered states.
if (filterStates != nullptr && filterStates->get(transition.first)) {
// Calculate the distance we achieve when we take the path to the successor via the current state.
T newDistance = probabilityStatePair.first * transition.second;
// We found a cheaper way to get to the target state of the transition.
if (newDistance > probabilities[transition.first]) {
// Remove the old distance.
if (probabilities[transition.first] != noPredecessorValue) {
probabilityStateSet.erase(std::make_pair(probabilities[transition.first], transition.first));
}
// Set and add the new distance.
probabilities[transition.first] = newDistance;
predecessors[transition.first] = probabilityStatePair.second;
probabilityStateSet.insert(std::make_pair(newDistance, transition.first));
}
}
}
}
// Move the values into the result and return it.
std::pair<std::vector<T>, std::vector<uint_fast64_t>> result;
result.first = std::move(probabilities);
result.second = std::move(predecessors);
LOG4CPLUS_INFO(logger, "Done performing Dijkstra search.");
return result;
}
storm::storage::BitVector const* filterStates = nullptr);
} // namespace graph
} // namespace utility

72
src/utility/solver.cpp

@ -2,8 +2,10 @@
#include "src/solver/SymbolicGameSolver.h"
#include <vector>
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/solver/SymbolicMinMaxLinearEquationSolver.h"
#include "src/solver/NativeLinearEquationSolver.h"
#include "src/solver/GmmxxLinearEquationSolver.h"
@ -61,18 +63,18 @@ namespace storm {
NativeLinearEquationSolverFactory<ValueType>::NativeLinearEquationSolverFactory() {
switch (storm::settings::nativeEquationSolverSettings().getLinearEquationSystemMethod()) {
case settings::modules::NativeEquationSolverSettings::LinearEquationMethod::Jacobi:
this->method = storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod::Jacobi;
this->method = storm::solver::NativeLinearEquationSolverSolutionMethod::Jacobi;
break;
case settings::modules::NativeEquationSolverSettings::LinearEquationMethod::GaussSeidel:
this->method = storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod::GaussSeidel;
this->method = storm::solver::NativeLinearEquationSolverSolutionMethod::GaussSeidel;
case settings::modules::NativeEquationSolverSettings::LinearEquationMethod::SOR:
this->method = storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod::SOR;
this->method = storm::solver::NativeLinearEquationSolverSolutionMethod::SOR;
}
omega = storm::settings::nativeEquationSolverSettings().getOmega();
}
template<typename ValueType>
NativeLinearEquationSolverFactory<ValueType>::NativeLinearEquationSolverFactory(typename storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod method, ValueType omega) : method(method), omega(omega) {
NativeLinearEquationSolverFactory<ValueType>::NativeLinearEquationSolverFactory(typename storm::solver::NativeLinearEquationSolverSolutionMethod method, ValueType omega) : method(method), omega(omega) {
// Intentionally left empty.
}
@ -82,30 +84,56 @@ namespace storm {
}
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> MinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
storm::solver::EquationSolverType equationSolver = storm::settings::generalSettings().getEquationSolver();
switch (equationSolver) {
case storm::solver::EquationSolverType::Gmmxx: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
case storm::solver::EquationSolverType::Native: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::NativeMinMaxLinearEquationSolver<ValueType>(matrix));
default: return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
}
MinMaxLinearEquationSolverFactory<ValueType>::MinMaxLinearEquationSolverFactory(storm::solver::EquationSolverTypeSelection solver)
{
prefTech = storm::solver::MinMaxTechniqueSelection::FROMSETTINGS;
setSolverType(solver);
}
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> GmmxxMinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix));
void MinMaxLinearEquationSolverFactory<ValueType>::setSolverType(storm::solver::EquationSolverTypeSelection solverTypeSel) {
if(solverTypeSel == storm::solver::EquationSolverTypeSelection::FROMSETTINGS) {
this->solverType = storm::settings::generalSettings().getEquationSolver();
} else {
this->solverType = storm::solver::convert(solverTypeSel);
}
}
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> NativeMinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::NativeMinMaxLinearEquationSolver<ValueType>(matrix));
}
void MinMaxLinearEquationSolverFactory<ValueType>::setPreferredTechnique(storm::solver::MinMaxTechniqueSelection preferredTech) {
this->prefTech = preferredTech;
}
template<typename ValueType>
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> TopologicalMinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix) const {
return std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>>(new storm::solver::TopologicalMinMaxLinearEquationSolver<ValueType>(matrix));
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> MinMaxLinearEquationSolverFactory<ValueType>::create(storm::storage::SparseMatrix<ValueType> const& matrix, bool trackPolicy) const {
std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> p1;
switch (solverType) {
case storm::solver::EquationSolverType::Gmmxx:
{
p1.reset(new storm::solver::GmmxxMinMaxLinearEquationSolver<ValueType>(matrix, this->prefTech));
break;
}
case storm::solver::EquationSolverType::Native:
{
p1.reset(new storm::solver::NativeMinMaxLinearEquationSolver<ValueType>(matrix, this->prefTech));
break;
}
case storm::solver::EquationSolverType::Topological:
{
STORM_LOG_THROW(prefTech == storm::solver::MinMaxTechniqueSelection::PolicyIteration, storm::exceptions::NotImplementedException, "Policy iteration for topological solver is not supported.");
p1.reset(new storm::solver::TopologicalMinMaxLinearEquationSolver<ValueType>(matrix));
break;
}
}
p1->setPolicyTracking(trackPolicy);
return p1;
}
std::unique_ptr<storm::solver::LpSolver> LpSolverFactory::create(std::string const& name) const {
storm::solver::LpSolverType lpSolver = storm::settings::generalSettings().getLpSolver();
switch (lpSolver) {
@ -156,9 +184,7 @@ namespace storm {
template class GmmxxLinearEquationSolverFactory<double>;
template class NativeLinearEquationSolverFactory<double>;
template class MinMaxLinearEquationSolverFactory<double>;
template class GmmxxMinMaxLinearEquationSolverFactory<double>;
template class NativeMinMaxLinearEquationSolverFactory<double>;
template class TopologicalMinMaxLinearEquationSolverFactory<double>;
}
}
}

57
src/utility/solver.h

@ -1,22 +1,28 @@
#ifndef STORM_UTILITY_SOLVER_H_
#define STORM_UTILITY_SOLVER_H_
#include "src/solver/SymbolicGameSolver.h"
#include "src/solver/SymbolicMinMaxLinearEquationSolver.h"
#include "src/solver/SymbolicLinearEquationSolver.h"
#include "src/solver/LinearEquationSolver.h"
#include "src/solver/NativeLinearEquationSolver.h"
#include <set>
#include <vector>
#include "src/storage/dd/DdType.h"
#include "src/utility/ExtendSettingEnumWithSelectionField.h"
#include "src/solver/SolverSelectionOptions.h"
namespace storm {
namespace solver {
template<storm::dd::DdType T> class SymbolicGameSolver;
template<storm::dd::DdType T, typename V> class SymbolicLinearEquationSolver;
template<storm::dd::DdType T, typename V> class SymbolicMinMaxLinearEquationSolver;
template<typename V> class LinearEquationSolver;
template<typename V> class MinMaxLinearEquationSolver;
class LpSolver;
class SmtSolver;
template<typename ValueType> class NativeLinearEquationSolver;
enum class NativeLinearEquationSolverSolutionMethod;
}
namespace storage {
template<typename V> class SparseMatrix;
}
namespace dd {
@ -26,6 +32,7 @@ namespace storm {
namespace expressions {
class Variable;
class ExpressionManager;
}
namespace utility {
@ -65,12 +72,12 @@ namespace storm {
class NativeLinearEquationSolverFactory : public LinearEquationSolverFactory<ValueType> {
public:
NativeLinearEquationSolverFactory();
NativeLinearEquationSolverFactory(typename storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod method, ValueType omega);
NativeLinearEquationSolverFactory(typename storm::solver::NativeLinearEquationSolverSolutionMethod method, ValueType omega);
virtual std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const override;
private:
typename storm::solver::NativeLinearEquationSolver<ValueType>::SolutionMethod method;
typename storm::solver::NativeLinearEquationSolverSolutionMethod method;
ValueType omega;
};
@ -83,30 +90,22 @@ namespace storm {
template<typename ValueType>
class MinMaxLinearEquationSolverFactory {
public:
MinMaxLinearEquationSolverFactory(storm::solver::EquationSolverTypeSelection solverType = storm::solver::EquationSolverTypeSelection::FROMSETTINGS);
/*!
* Creates a new nondeterministic linear equation solver instance with the given matrix.
*/
virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const;
};
template<typename ValueType>
class NativeMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> {
public:
virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const override;
};
template<typename ValueType>
class GmmxxMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> {
public:
virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const override;
};
template<typename ValueType>
class TopologicalMinMaxLinearEquationSolverFactory : public MinMaxLinearEquationSolverFactory<ValueType> {
public:
virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix) const override;
};
virtual std::unique_ptr<storm::solver::MinMaxLinearEquationSolver<ValueType>> create(storm::storage::SparseMatrix<ValueType> const& matrix, bool trackPolicy = false) const;
void setSolverType(storm::solver::EquationSolverTypeSelection solverType);
void setPreferredTechnique(storm::solver::MinMaxTechniqueSelection);
protected:
/// The type of solver which should be created.
storm::solver::EquationSolverType solverType;
/// The preferred technique to be used by the solver.
/// Notice that we save the selection enum here, which allows different solvers to use different techniques.
storm::solver::MinMaxTechniqueSelection prefTech;
};
class LpSolverFactory {
public:
/*!

37
src/utility/cli.h → src/utility/storm.h

@ -1,5 +1,6 @@
#ifndef STORM_UTILITY_CLI_H_
#define STORM_UTILITY_CLI_H_
#ifndef STORM_H
#define STORM_H
#include <iostream>
#include <iomanip>
@ -15,8 +16,6 @@
// Headers that provide auxiliary functionality.
#include "src/utility/storm-version.h"
#include "src/utility/OsDetection.h"
#include "src/settings/SettingsManager.h"
@ -34,6 +33,7 @@
// Model headers.
#include "src/models/ModelBase.h"
#include "src/models/sparse/Model.h"
#include "src/models/sparse/StandardRewardModel.h"
#include "src/models/symbolic/Model.h"
#include "src/models/symbolic/StandardRewardModel.h"
@ -72,25 +72,9 @@
#include "src/exceptions/NotImplementedException.h"
namespace storm {
namespace utility {
namespace cli {
std::string getCurrentWorkingDirectory();
void printHeader(const int argc, const char* argv[]);
void printUsage();
/*!
* Parses the given command line arguments.
*
* @param argc The argc argument of main().
* @param argv The argv argument of main().
* @return True iff the program should continue to run after parsing the options.
*/
bool parseOptions(const int argc, const char* argv[]);
template<typename ValueType>
template<typename ValueType>
std::shared_ptr<storm::models::sparse::Model<ValueType>> buildExplicitModel(std::string const& transitionsFile, std::string const& labelingFile, boost::optional<std::string> const& stateRewardsFile = boost::optional<std::string>(), boost::optional<std::string> const& transitionRewardsFile = boost::optional<std::string>()) {
return storm::parser::AutoParser::parseModel(transitionsFile, labelingFile, stateRewardsFile ? stateRewardsFile.get() : "", transitionRewardsFile ? transitionRewardsFile.get() : "");
}
@ -411,9 +395,8 @@ namespace storm {
}
}
void processOptions();
}
}
}
#endif
#endif /* STORM_H */

36
src/utility/vector.h

@ -200,8 +200,8 @@ namespace storm {
* @param secondOperand The second operand.
* @param target The target vector.
*/
template<class T>
void applyPointwise(std::vector<T> const& firstOperand, std::vector<T> const& secondOperand, std::vector<T>& target, std::function<T (T const&, T const&, T const&)> const& function) {
template<class InValueType1, class InValueType2, class OutValueType>
void applyPointwise(std::vector<InValueType1> const& firstOperand, std::vector<InValueType2> const& secondOperand, std::vector<OutValueType>& target, std::function<OutValueType (InValueType1 const&, InValueType2 const&, OutValueType const&)> const& function) {
#ifdef STORM_HAVE_INTELTBB
tbb::parallel_for(tbb::blocked_range<uint_fast64_t>(0, target.size()),
[&](tbb::blocked_range<uint_fast64_t> const& range) {
@ -238,8 +238,8 @@ namespace storm {
* @param secondOperand The second operand.
* @param target The target vector.
*/
template<class T>
void applyPointwise(std::vector<T> const& firstOperand, std::vector<T> const& secondOperand, std::vector<T>& target, std::function<T (T const&, T const&)> function) {
template<class InValueType1, class InValueType2, class OutValueType>
void applyPointwise(std::vector<InValueType1> const& firstOperand, std::vector<InValueType2> const& secondOperand, std::vector<OutValueType>& target, std::function<OutValueType (InValueType1 const&, InValueType2 const&)> function) {
#ifdef STORM_HAVE_INTELTBB
tbb::parallel_for(tbb::blocked_range<uint_fast64_t>(0, target.size()),
[&](tbb::blocked_range<uint_fast64_t> const& range) {
@ -257,8 +257,8 @@ namespace storm {
* @param target The target vector.
* @param function The function to apply.
*/
template<class T>
void applyPointwise(std::vector<T> const& operand, std::vector<T>& target, std::function<T (T const&)> const& function) {
template<class InValueType, class OutValueType>
void applyPointwise(std::vector<InValueType> const& operand, std::vector<OutValueType>& target, std::function<OutValueType (InValueType const&)> const& function) {
#ifdef STORM_HAVE_INTELTBB
tbb::parallel_for(tbb::blocked_range<uint_fast64_t>(0, target.size()),
[&](tbb::blocked_range<uint_fast64_t> const& range) {
@ -276,9 +276,9 @@ namespace storm {
* @param secondOperand The second operand
* @param target The target vector.
*/
template<class T>
void addVectors(std::vector<T> const& firstOperand, std::vector<T> const& secondOperand, std::vector<T>& target) {
applyPointwise<T>(firstOperand, secondOperand, target, std::plus<T>());
template<class InValueType1, class InValueType2, class OutValueType>
void addVectors(std::vector<InValueType1> const& firstOperand, std::vector<InValueType2> const& secondOperand, std::vector<OutValueType>& target) {
applyPointwise<InValueType1, InValueType2, OutValueType>(firstOperand, secondOperand, target, std::plus<>());
}
/*!
@ -288,9 +288,9 @@ namespace storm {
* @param secondOperand The second operand
* @param target The target vector.
*/
template<class T>
void subtractVectors(std::vector<T> const& firstOperand, std::vector<T> const& secondOperand, std::vector<T>& target) {
applyPointwise<T>(firstOperand, secondOperand, target, std::minus<T>());
template<class InValueType1, class InValueType2, class OutValueType>
void subtractVectors(std::vector<InValueType1> const& firstOperand, std::vector<InValueType2> const& secondOperand, std::vector<OutValueType>& target) {
applyPointwise<InValueType1, InValueType2, OutValueType>(firstOperand, secondOperand, target, std::minus<>());
}
/*!
@ -300,9 +300,9 @@ namespace storm {
* @param secondOperand The second operand
* @param target The target vector.
*/
template<class T>
void multiplyVectorsPointwise(std::vector<T> const& firstOperand, std::vector<T> const& secondOperand, std::vector<T>& target) {
applyPointwise<T>(firstOperand, secondOperand, target, std::multiplies<T>());
template<class InValueType1, class InValueType2, class OutValueType>
void multiplyVectorsPointwise(std::vector<InValueType1> const& firstOperand, std::vector<InValueType2> const& secondOperand, std::vector<OutValueType>& target) {
applyPointwise<InValueType1, InValueType2, OutValueType>(firstOperand, secondOperand, target, std::multiplies<>());
}
/*!
@ -311,9 +311,9 @@ namespace storm {
* @param target The first summand and target vector.
* @param summand The second summand.
*/
template<class T>
void scaleVectorInPlace(std::vector<T>& target, T const& factor) {
applyPointwise<T>(target, target, [&] (T const& argument) { return argument * factor; });
template<class ValueType1, class ValueType2>
void scaleVectorInPlace(std::vector<ValueType1>& target, ValueType2 const& factor) {
applyPointwise<ValueType1, ValueType2>(target, target, [&] (ValueType1 const& argument) -> ValueType1 { return argument * factor; });
}
/*!

5
test/functional/modelchecker/GmmxxHybridMdpPrctlModelCheckerTest.cpp

@ -11,6 +11,7 @@
#include "src/parser/FormulaParser.h"
#include "src/builder/DdPrismModelBuilder.h"
#include "src/models/symbolic/Dtmc.h"
#include "src/models/symbolic/Mdp.h"
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/settings/SettingsManager.h"
@ -41,7 +42,7 @@ TEST(GmmxxHybridMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
@ -138,7 +139,7 @@ TEST(GmmxxHybridMdpPrctlModelCheckerTest, AsynchronousLeader) {
std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");

8
test/functional/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp

@ -28,7 +28,7 @@ TEST(GmmxxMdpPrctlModelCheckerTest, Dice) {
ASSERT_EQ(mdp->getNumberOfStates(), 169ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 436ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
@ -92,7 +92,7 @@ TEST(GmmxxMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::sparse::Mdp<double>> stateRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -114,7 +114,7 @@ TEST(GmmxxMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::sparse::Mdp<double>> stateAndTransitionRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -144,7 +144,7 @@ TEST(GmmxxMdpPrctlModelCheckerTest, AsynchronousLeader) {
ASSERT_EQ(3172ull, mdp->getNumberOfStates());
ASSERT_EQ(7144ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");

10
test/functional/modelchecker/NativeDtmcPrctlModelCheckerTest.cpp

@ -9,7 +9,7 @@
#include "src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
#include "src/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "src/settings/SettingsManager.h"
#include "src/solver/NativeLinearEquationSolver.h"
#include "src/settings/modules/GeneralSettings.h"
#include "src/settings/modules/NativeEquationSolverSettings.h"
@ -153,7 +153,7 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolverSolutionMethod::SOR, 0.9)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
@ -177,7 +177,7 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolverSolutionMethod::SOR, 0.9)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
@ -201,7 +201,7 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRASingleBscc) {
dtmc.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*dtmc, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolverSolutionMethod::SOR, 0.9)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");
@ -264,7 +264,7 @@ TEST(SparseDtmcPrctlModelCheckerTest, LRA) {
mdp.reset(new storm::models::sparse::Dtmc<double>(transitionMatrix, ap));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolver<double>::SolutionMethod::SOR, 0.9)));
storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::LinearEquationSolverFactory<double>>(new storm::utility::solver::NativeLinearEquationSolverFactory<double>(storm::solver::NativeLinearEquationSolverSolutionMethod::SOR, 0.9)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRA=? [\"a\"]");

5
test/functional/modelchecker/NativeHybridMdpPrctlModelCheckerTest.cpp

@ -40,8 +40,7 @@ TEST(NativeHybridMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
std::unique_ptr<storm::modelchecker::CheckResult> result = checker.check(*formula);
@ -137,7 +136,7 @@ TEST(NativeHybridMdpPrctlModelCheckerTest, AsynchronousLeader) {
std::shared_ptr<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>> mdp = model->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD>>();
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::HybridMdpPrctlModelChecker<storm::dd::DdType::CUDD, double> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");

18
test/functional/modelchecker/NativeMdpPrctlModelCheckerTest.cpp

@ -27,7 +27,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
ASSERT_EQ(mdp->getNumberOfStates(), 169ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 436ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
@ -91,7 +91,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::sparse::Mdp<double>> stateRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*stateRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*stateRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -113,7 +113,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Dice) {
std::shared_ptr<storm::models::sparse::Mdp<double>> stateAndTransitionRewardMdp = abstractModel->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -143,7 +143,7 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) {
ASSERT_EQ(3172ull, mdp->getNumberOfStates());
ASSERT_EQ(7144ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");
@ -207,7 +207,7 @@ TEST(SparseMdpPrctlModelCheckerTest, LRA_SingleMec) {
mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
@ -239,7 +239,7 @@ TEST(SparseMdpPrctlModelCheckerTest, LRA_SingleMec) {
mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
@ -280,7 +280,7 @@ TEST(SparseMdpPrctlModelCheckerTest, LRA_SingleMec) {
mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
@ -366,7 +366,7 @@ TEST(SparseMdpPrctlModelCheckerTest, LRA) {
mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");
@ -488,7 +488,7 @@ TEST(SparseMdpPrctlModelCheckerTest, LRA) {
mdp.reset(new storm::models::sparse::Mdp<double>(transitionMatrix, ap));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("LRAmax=? [\"a\"]");

8
test/functional/modelchecker/TopologicalValueIterationMdpPrctlModelCheckerTest.cpp

@ -26,7 +26,7 @@ TEST(TopologicalValueIterationMdpPrctlModelCheckerTest, Dice) {
ASSERT_EQ(mdp->getNumberOfStates(), 169ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 436ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> mc(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> mc(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
@ -87,7 +87,7 @@ TEST(TopologicalValueIterationMdpPrctlModelCheckerTest, Dice) {
// ------------- state rewards --------------
std::shared_ptr<storm::models::sparse::Mdp<double>> stateRewardMdp = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", "")->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*stateRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateRewardModelChecker(*stateRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -112,7 +112,7 @@ TEST(TopologicalValueIterationMdpPrctlModelCheckerTest, Dice) {
// -------------------------------- state and transition reward ------------------------
std::shared_ptr<storm::models::sparse::Mdp<double>> stateAndTransitionRewardMdp = storm::parser::AutoParser::parseModel(STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.tra", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.lab", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.state.rew", STORM_CPP_BASE_PATH "/examples/mdp/two_dice/two_dice.flip.trans.rew")->as<storm::models::sparse::Mdp<double>>();
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> stateAndTransitionRewardModelChecker(*stateAndTransitionRewardMdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
formula = formulaParser.parseSingleFormulaFromString("Rmin=? [F \"done\"]");
@ -143,7 +143,7 @@ TEST(TopologicalValueIterationMdpPrctlModelCheckerTest, AsynchronousLeader) {
ASSERT_EQ(mdp->getNumberOfStates(), 3172ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 7144ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> mc(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> mc(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");

29
test/functional/solver/GmmxxMinMaxLinearEquationSolverTest.cpp

@ -25,6 +25,35 @@ TEST(GmmxxMinMaxLinearEquationSolver, SolveWithStandardOptions) {
ASSERT_LT(std::abs(x[0] - 0.989991), storm::settings::gmmxxEquationSolverSettings().getPrecision());
}
// TODO add better tests here.
TEST(GmmxxMinMaxLinearEquationSolver, SolveWithStandardOptionsAndEarlyTermination) {
storm::storage::SparseMatrixBuilder<double> builder(0, 0, 0, false, true);
ASSERT_NO_THROW(builder.newRowGroup(0));
ASSERT_NO_THROW(builder.addNextValue(0, 0, 0.9));
storm::storage::SparseMatrix<double> A;
ASSERT_NO_THROW(A = builder.build(2));
std::vector<double> x(1);
std::vector<double> b = {0.099, 0.5};
double bound = 0.8;
storm::solver::GmmxxMinMaxLinearEquationSolver<double> solver(A);
solver.setEarlyTerminationCondition(std::unique_ptr<storm::solver::AllowEarlyTerminationCondition<double>>(new storm::solver::TerminateAfterFilteredExtremumPassesThresholdValue<double>(storm::storage::BitVector(1, true), bound, true, true)));
ASSERT_NO_THROW(solver.solveEquationSystem(true, x, b));
ASSERT_LT(std::abs(x[0] - 0.5), storm::settings::gmmxxEquationSolverSettings().getPrecision());
ASSERT_NO_THROW(solver.solveEquationSystem(false, x, b));
ASSERT_LT(std::abs(x[0] - 0.989991), 0.989991 - bound - storm::settings::gmmxxEquationSolverSettings().getPrecision());
bound = 0.6;
solver.setEarlyTerminationCondition(std::unique_ptr<storm::solver::AllowEarlyTerminationCondition<double>>(new storm::solver::TerminateAfterFilteredExtremumPassesThresholdValue<double>(storm::storage::BitVector(1, true), bound, true, true)));
ASSERT_NO_THROW(solver.solveEquationSystem(false, x, b));
ASSERT_LT(std::abs(x[0] - 0.989991), 0.989991 - bound - storm::settings::gmmxxEquationSolverSettings().getPrecision());
}
TEST(GmmxxMinMaxLinearEquationSolver, MatrixVectorMultiplication) {
storm::storage::SparseMatrixBuilder<double> builder(0, 0, 0, false, true);
ASSERT_NO_THROW(builder.newRowGroup(0));

4
test/performance/modelchecker/GmmxxMdpPrctlModelCheckerTest.cpp

@ -24,7 +24,7 @@ TEST(GmxxMdpPrctlModelCheckerTest, AsynchronousLeader) {
ASSERT_EQ(2095783ull, mdp->getNumberOfStates());
ASSERT_EQ(7714385ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");
@ -82,7 +82,7 @@ TEST(GmxxMdpPrctlModelCheckerTest, Consensus) {
ASSERT_EQ(63616ull, mdp->getNumberOfStates());
ASSERT_EQ(213472ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::GmmxxMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Gmmxx)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"finished\"]");

4
test/performance/modelchecker/NativeMdpPrctlModelCheckerTest.cpp

@ -25,7 +25,7 @@ TEST(SparseMdpPrctlModelCheckerTest, AsynchronousLeader) {
ASSERT_EQ(2095783ull, mdp->getNumberOfStates());
ASSERT_EQ(7714385ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");
@ -83,7 +83,7 @@ TEST(SparseMdpPrctlModelCheckerTest, Consensus) {
ASSERT_EQ(63616ull, mdp->getNumberOfStates());
ASSERT_EQ(213472ull, mdp->getNumberOfTransitions());
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::NativeMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Native)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"finished\"]");

4
test/performance/modelchecker/TopologicalValueIterationMdpPrctlModelCheckerTest.cpp

@ -20,7 +20,7 @@ TEST(DISABLED_TopologicalValueIterationMdpPrctlModelCheckerTest, AsynchronousLea
ASSERT_EQ(mdp->getNumberOfStates(), 2095783ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 7714385ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"elected\"]");
@ -67,7 +67,7 @@ TEST(DISABLED_TopologicalValueIterationMdpPrctlModelCheckerTest, Consensus) {
ASSERT_EQ(mdp->getNumberOfStates(), 63616ull);
ASSERT_EQ(mdp->getNumberOfTransitions(), 213472ull);
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::TopologicalMinMaxLinearEquationSolverFactory<double>()));
storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>> checker(*mdp, std::unique_ptr<storm::utility::solver::MinMaxLinearEquationSolverFactory<double>>(new storm::utility::solver::MinMaxLinearEquationSolverFactory<double>(storm::solver::EquationSolverTypeSelection::Topological)));
std::shared_ptr<storm::logic::Formula> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"finished\"]");

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