Browse Source

Merge remote-tracking branch 'origin/master' into storm-pars-analysis-monotonicity

main
Jip Spel 7 years ago
parent
commit
5a05a2ac33
  1. 3
      src/storm-cli-utilities/model-handling.h
  2. 20
      src/storm-conv/api/storm-conv.cpp
  3. 4
      src/storm-conv/converter/options/JaniConversionOptions.cpp
  4. 6
      src/storm-conv/converter/options/JaniConversionOptions.h
  5. 6
      src/storm-conv/settings/modules/JaniExportSettings.cpp
  6. 3
      src/storm-conv/settings/modules/JaniExportSettings.h
  7. 6
      src/storm-gspn/builder/JaniGSPNBuilder.cpp
  8. 26
      src/storm-parsers/parser/JaniParser.cpp
  9. 3
      src/storm/builder/ExplicitModelBuilder.cpp
  10. 6
      src/storm/generator/TransientVariableInformation.cpp
  11. 12
      src/storm/logic/OperatorFormula.cpp
  12. 9
      src/storm/logic/OperatorFormula.h
  13. 17
      src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp
  14. 1
      src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h
  15. 2
      src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp
  16. 8
      src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp
  17. 25
      src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp
  18. 2
      src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp
  19. 4
      src/storm/settings/modules/CoreSettings.cpp
  20. 7
      src/storm/settings/modules/CoreSettings.h
  21. 4
      src/storm/settings/modules/MinMaxEquationSolverSettings.cpp
  22. 5
      src/storm/settings/modules/MinMaxEquationSolverSettings.h
  23. 1
      src/storm/storage/jani/ArrayEliminator.cpp
  24. 2
      src/storm/storage/jani/Edge.h
  25. 4
      src/storm/storage/jani/JaniLocationExpander.cpp
  26. 164
      src/storm/storage/jani/JaniScopeChanger.cpp
  27. 57
      src/storm/storage/jani/JaniScopeChanger.h
  28. 15
      src/storm/storage/jani/LValue.cpp
  29. 20
      src/storm/storage/jani/Property.cpp
  30. 3
      src/storm/storage/jani/Property.h
  31. 45
      src/storm/storage/jani/VariableSet.cpp
  32. 5
      src/storm/storage/jani/VariableSet.h
  33. 21
      src/storm/utility/graph.cpp
  34. 10
      src/storm/utility/graph.h
  35. 6
      src/storm/utility/solver.cpp

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

@ -61,6 +61,7 @@ namespace storm {
void parseSymbolicModelDescription(storm::settings::modules::IOSettings const& ioSettings, SymbolicInput& input, storm::builder::BuilderType const& builderType) {
if (ioSettings.isPrismOrJaniInputSet()) {
storm::utility::Stopwatch modelParsingWatch(true);
if (ioSettings.isPrismInputSet()) {
input.model = storm::api::parseProgram(ioSettings.getPrismInputFilename(), storm::settings::getModule<storm::settings::modules::BuildSettings>().isPrismCompatibilityEnabled());
} else {
@ -81,6 +82,8 @@ namespace storm {
input.properties = std::move(janiInput.second);
}
}
modelParsingWatch.stop();
STORM_PRINT("Time for model input parsing: " << modelParsingWatch << "." << std::endl << std::endl);
}
}

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

@ -4,6 +4,7 @@
#include "storm/storage/jani/Property.h"
#include "storm/storage/jani/Constant.h"
#include "storm/storage/jani/JaniLocationExpander.h"
#include "storm/storage/jani/JaniScopeChanger.h"
#include "storm/storage/jani/JSONExporter.h"
#include "storm/settings/SettingsManager.h"
@ -18,7 +19,26 @@ namespace storm {
janiModel = janiModel.substituteConstants();
}
if (options.localVars) {
STORM_LOG_WARN_COND(!options.globalVars, "Ignoring 'globalvars' option, since 'localvars' is also set.");
storm::jani::JaniScopeChanger().makeVariablesLocal(janiModel, properties);
} else if (options.globalVars) {
storm::jani::JaniScopeChanger().makeVariablesGlobal(janiModel);
}
if (!options.locationVariables.empty()) {
// Make variables local if necessary/possible
for (auto const& pair : options.locationVariables) {
if (janiModel.hasGlobalVariable(pair.second)) {
auto var = janiModel.getGlobalVariable(pair.second).getExpressionVariable();
if (storm::jani::JaniScopeChanger().canMakeVariableLocal(var, janiModel, properties, janiModel.getAutomatonIndex(pair.first)).first) {
storm::jani::JaniScopeChanger().makeVariableLocal(var, janiModel, janiModel.getAutomatonIndex(pair.first));
} else {
STORM_LOG_ERROR("Can not transform variable " << pair.second << " into locations since it can not be made local to automaton " << pair.first << ".");
}
}
}
for (auto const& pair : options.locationVariables) {
storm::jani::JaniLocationExpander expander(janiModel);
expander.transform(pair.first, pair.second);

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

@ -3,11 +3,11 @@
namespace storm {
namespace converter {
JaniConversionOptions::JaniConversionOptions() : edgeAssignments(false), flatten(false), substituteConstants(true), allowedModelFeatures(storm::jani::getAllKnownModelFeatures()), addPropertyConstants(true) {
JaniConversionOptions::JaniConversionOptions() : edgeAssignments(false), flatten(false), substituteConstants(true), localVars(false), globalVars(false), allowedModelFeatures(storm::jani::getAllKnownModelFeatures()), addPropertyConstants(true) {
// Intentionally left empty
}
JaniConversionOptions::JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings) : locationVariables(settings.getLocationVariables()), edgeAssignments(settings.isAllowEdgeAssignmentsSet()), flatten(settings.isExportFlattenedSet()), substituteConstants(true), allowedModelFeatures(storm::jani::getAllKnownModelFeatures()), addPropertyConstants(true) {
JaniConversionOptions::JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings) : locationVariables(settings.getLocationVariables()), edgeAssignments(settings.isAllowEdgeAssignmentsSet()), flatten(settings.isExportFlattenedSet()), substituteConstants(true), localVars(settings.isLocalVarsSet()), globalVars(settings.isGlobalVarsSet()), allowedModelFeatures(storm::jani::getAllKnownModelFeatures()), addPropertyConstants(true) {
if (settings.isEliminateFunctionsSet()) {
allowedModelFeatures.remove(storm::jani::ModelFeature::Functions);
}

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

@ -27,6 +27,12 @@ namespace storm {
/// If set, constants in expressions are substituted with their definition
bool substituteConstants;
/// If set, variables will be made local wherever possible
bool localVars;
/// If set, variables will be made global wherever possible
bool globalVars;
/// If given, the model will get this name
boost::optional<std::string> modelName;

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

@ -18,6 +18,7 @@ namespace storm {
const std::string JaniExportSettings::exportFlattenOptionName = "flatten";
const std::string JaniExportSettings::locationVariablesOptionName = "location-variables";
const std::string JaniExportSettings::globalVariablesOptionName = "globalvars";
const std::string JaniExportSettings::localVariablesOptionName = "localvars";
const std::string JaniExportSettings::compactJsonOptionName = "compactjson";
const std::string JaniExportSettings::eliminateArraysOptionName = "remove-arrays";
const std::string JaniExportSettings::eliminateFunctionsOptionName = "remove-functions";
@ -27,6 +28,7 @@ namespace storm {
this->addOption(storm::settings::OptionBuilder(moduleName, edgeAssignmentsOptionName, false, "If set, the output model can have transient edge assignments. This can simplify the jani model but is not compliant to the jani standard.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, exportFlattenOptionName, false, "Flattens the composition of Automata to obtain an equivalent model that contains exactly one automaton").build());
this->addOption(storm::settings::OptionBuilder(moduleName, globalVariablesOptionName, false, "If set, variables will preferably be made global, e.g., to guarantee the same variable order as in the input file.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, localVariablesOptionName, false, "If set, variables will preferably be made local.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, compactJsonOptionName, false, "If set, the size of the resulting jani file will be reduced at the cost of (human-)readability.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, eliminateArraysOptionName, false, "If set, transforms the model such that array variables/expressions are eliminated.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, eliminateFunctionsOptionName, false, "If set, transforms the model such that functions are eliminated.").build());
@ -64,6 +66,10 @@ namespace storm {
return this->getOption(globalVariablesOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isLocalVarsSet() const {
return this->getOption(localVariablesOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isCompactJsonSet() const {
return this->getOption(compactJsonOptionName).getHasOptionBeenSet();
}

3
src/storm-conv/settings/modules/JaniExportSettings.h

@ -22,6 +22,8 @@ namespace storm {
bool isGlobalVarsSet() const;
bool isLocalVarsSet() const;
bool isCompactJsonSet() const;
bool isEliminateArraysSet() const;
@ -40,6 +42,7 @@ namespace storm {
static const std::string exportFlattenOptionName;
static const std::string locationVariablesOptionName;
static const std::string globalVariablesOptionName;
static const std::string localVariablesOptionName;
static const std::string compactJsonOptionName;
static const std::string eliminateArraysOptionName;
static const std::string eliminateFunctionsOptionName;

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

@ -141,6 +141,10 @@ namespace storm {
}
for (auto const& trans : gspn.getTimedTransitions()) {
if(storm::utility::isZero(trans.getRate())) {
STORM_LOG_WARN("Transitions with rate zero are not allowed in JANI. Skipping this transition");
continue;
}
storm::expressions::Expression guard = expressionManager->boolean(true);
std::vector<storm::jani::Assignment> assignments;
@ -296,7 +300,7 @@ namespace storm {
auto expTimeDeadlock = std::make_shared<storm::logic::TimeOperatorFormula>(
std::make_shared<storm::logic::EventuallyFormula>(deadlock, storm::logic::FormulaContext::Time),
storm::logic::OperatorInformation(storm::solver::OptimizationDirection::Maximize));
storm::logic::OperatorInformation(storm::solver::OptimizationDirection::Minimize));
standardProperties.emplace_back("MinExpTimeDeadlock", expTimeDeadlock, emptyVariableSet, "The minimal expected time to reach a deadlock.");
}

26
src/storm-parsers/parser/JaniParser.cpp

@ -1416,7 +1416,7 @@ namespace storm {
STORM_LOG_THROW(automatonStructure.count("edges") > 0, storm::exceptions::InvalidJaniException, "Automaton '" << name << "' must have a list of edges");
for(auto const& edgeEntry : automatonStructure.at("edges")) {
for (auto const& edgeEntry : automatonStructure.at("edges")) {
// source location
STORM_LOG_THROW(edgeEntry.count("location") == 1, storm::exceptions::InvalidJaniException, "Each edge in automaton '" << name << "' must have a source");
std::string sourceLoc = getString(edgeEntry.at("location"), "source location for edge in automaton '" + name + "'");
@ -1441,15 +1441,35 @@ namespace storm {
// guard
STORM_LOG_THROW(edgeEntry.count("guard") <= 1, storm::exceptions::InvalidJaniException, "Guard can be given at most once in edge from '" << sourceLoc << "' in automaton '" << name << "'");
storm::expressions::Expression guardExpr = expressionManager->boolean(true);
if(edgeEntry.count("guard") == 1) {
if (edgeEntry.count("guard") == 1) {
STORM_LOG_THROW(edgeEntry.at("guard").count("exp") == 1, storm::exceptions::InvalidJaniException, "Guard in edge from '" + sourceLoc + "' in automaton '" + name + "' must have one expression");
guardExpr = parseExpression(edgeEntry.at("guard").at("exp"), scope.refine("guard expression in edge from '" + sourceLoc));
STORM_LOG_THROW(guardExpr.hasBooleanType(), storm::exceptions::InvalidJaniException, "Guard " << guardExpr << " does not have Boolean type.");
}
assert(guardExpr.isInitialized());
std::shared_ptr<storm::jani::TemplateEdge> templateEdge = std::make_shared<storm::jani::TemplateEdge>(guardExpr);
// edge assignments
if (edgeEntry.count("assignments") > 0) {
STORM_LOG_THROW(edgeEntry.count("assignments") == 1, storm::exceptions::InvalidJaniException, "Multiple edge assignments in edge from '" + sourceLoc + "' in automaton '" + name + "'.");
for (auto const& assignmentEntry : edgeEntry.at("assignments")) {
// ref
STORM_LOG_THROW(assignmentEntry.count("ref") == 1, storm::exceptions::InvalidJaniException, "Assignment in edge from '" << sourceLoc << "' in automaton '" << name << "' must have one ref field");
storm::jani::LValue lValue = parseLValue(assignmentEntry.at("ref"), scope.refine("Assignment variable in edge from '" + sourceLoc + "' in automaton '" + name + "'"));
// value
STORM_LOG_THROW(assignmentEntry.count("value") == 1, storm::exceptions::InvalidJaniException, "Assignment in edge from '" << sourceLoc << "' in automaton '" << name << "' must have one value field");
storm::expressions::Expression assignmentExpr = parseExpression(assignmentEntry.at("value"), scope.refine("assignment in edge from '" + sourceLoc + "' in automaton '" + name + "'"));
// TODO check types
// index
int64_t assignmentIndex = 0; // default.
if(assignmentEntry.count("index") > 0) {
assignmentIndex = getSignedInt(assignmentEntry.at("index"), "assignment index in edge from '" + sourceLoc + "' in automaton '" + name + "'");
}
templateEdge->getAssignments().add(storm::jani::Assignment(lValue, assignmentExpr, assignmentIndex));
}
}
// destinations
STORM_LOG_THROW(edgeEntry.count("destinations") == 1, storm::exceptions::InvalidJaniException, "A single list of destinations must be given in edge from '" << sourceLoc << "' in automaton '" << name << "'");
std::vector<std::pair<uint64_t, storm::expressions::Expression>> destinationLocationsAndProbabilities;
for(auto const& destEntry : edgeEntry.at("destinations")) {

3
src/storm/builder/ExplicitModelBuilder.cpp

@ -130,7 +130,8 @@ namespace storm {
// Let the generator create all initial states.
this->stateStorage.initialStateIndices = generator->getInitialStates(stateToIdCallback);
STORM_LOG_THROW(!this->stateStorage.initialStateIndices.empty(), storm::exceptions::WrongFormatException, "The model does not have a single initial state.");
// Now explore the current state until there is no more reachable state.
uint_fast64_t currentRowGroup = 0;
uint_fast64_t currentRow = 0;

6
src/storm/generator/TransientVariableInformation.cpp

@ -175,9 +175,9 @@ namespace storm {
}
}
template class TransientVariableInformation<double>;
template class TransientVariableInformation<storm::RationalNumber>;
template class TransientVariableInformation<storm::RationalFunction>;
template struct TransientVariableInformation<double>;
template struct TransientVariableInformation<storm::RationalNumber>;
template struct TransientVariableInformation<storm::RationalFunction>;
}
}

12
src/storm/logic/OperatorFormula.cpp

@ -60,6 +60,10 @@ namespace storm {
void OperatorFormula::setBound(Bound const& newBound) {
operatorInformation.bound = newBound;
}
void OperatorFormula::removeBound() {
operatorInformation.bound = boost::none;
}
bool OperatorFormula::hasOptimalityType() const {
return static_cast<bool>(operatorInformation.optimalityType);
@ -68,6 +72,14 @@ namespace storm {
OptimizationDirection const& OperatorFormula::getOptimalityType() const {
return operatorInformation.optimalityType.get();
}
void OperatorFormula::setOptimalityType(storm::solver::OptimizationDirection newOptimalityType) {
operatorInformation.optimalityType = newOptimalityType;
}
void OperatorFormula::removeOptimalityType() {
operatorInformation.optimalityType = boost::none;
}
bool OperatorFormula::isOperatorFormula() const {
return true;

9
src/storm/logic/OperatorFormula.h

@ -30,18 +30,23 @@ namespace storm {
// Bound-related accessors.
bool hasBound() const;
Bound const& getBound() const;
void setBound(Bound const& newBound);
void removeBound();
ComparisonType getComparisonType() const;
void setComparisonType(ComparisonType newComparisonType);
storm::expressions::Expression const& getThreshold() const;
template <typename ValueType>
ValueType getThresholdAs() const;
void setThreshold(storm::expressions::Expression const& newThreshold);
Bound const& getBound() const;
void setBound(Bound const& newBound);
// Optimality-type-related accessors.
bool hasOptimalityType() const;
storm::solver::OptimizationDirection const& getOptimalityType() const;
void setOptimalityType(storm::solver::OptimizationDirection newOptimalityType);
void removeOptimalityType();
virtual bool isOperatorFormula() const override;
OperatorInformation const& getOperatorInformation() const;

17
src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp

@ -7,6 +7,7 @@
#include "storm/modelchecker/results/SymbolicQualitativeCheckResult.h"
#include "storm/storage/dd/DdManager.h"
#include "storm/storage/dd/Add.h"
#include "storm/storage/dd/Bdd.h"
@ -30,14 +31,14 @@ namespace storm {
template<typename CValueType, typename std::enable_if<storm::NumberTraits<CValueType>::SupportsExponential, int>::type>
bool HybridCtmcCslModelChecker<ModelType>::canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true));
return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true).setTimeOperatorsAllowed(true));
}
template <typename ModelType>
template<typename CValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type>
bool HybridCtmcCslModelChecker<ModelType>::canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isInFragment(storm::logic::prctl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false));
return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true).setTimeOperatorsAllowed(true).setBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false));
}
template<typename ModelType>
@ -60,7 +61,6 @@ namespace storm {
return storm::modelchecker::helper::HybridCtmcCslHelper::computeNextProbabilities<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), subResult.getTruthValuesVector());
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) {
storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
@ -70,6 +70,17 @@ namespace storm {
return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet());
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) {
storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula());
SymbolicQualitativeCheckResult<DdType> const& subResult = subResultPointer->asSymbolicQualitativeCheckResult<DdType>();
storm::models::symbolic::StandardRewardModel<DdType, ValueType> timeRewardModel(this->getModel().getManager().getConstant(storm::utility::one<ValueType>()), boost::none, boost::none);
return storm::modelchecker::helper::HybridCtmcCslHelper::computeReachabilityRewards<DdType, ValueType>(env, this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), timeRewardModel, subResult.getTruthValuesVector(), checkTask.isQualitativeSet());
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeBoundedUntilProbabilities(Environment const& env, CheckTask<storm::logic::BoundedUntilFormula, ValueType> const& checkTask) {
storm::logic::BoundedUntilFormula const& pathFormula = checkTask.getFormula();

1
src/storm/modelchecker/csl/HybridCtmcCslModelChecker.h

@ -32,6 +32,7 @@ namespace storm {
virtual std::unique_ptr<CheckResult> computeInstantaneousRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeCumulativeRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityRewards(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override;
virtual std::unique_ptr<CheckResult> computeReachabilityTimes(Environment const& env, storm::logic::RewardMeasureType rewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) override;
private:
template<typename CValueType = ValueType, typename std::enable_if<storm::NumberTraits<CValueType>::SupportsExponential, int>::type = 0>

2
src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp

@ -44,7 +44,7 @@ namespace storm {
template<typename CValueType, typename std::enable_if<!storm::NumberTraits<CValueType>::SupportsExponential, int>::type>
bool SparseCtmcCslModelChecker<SparseCtmcModelType>::canHandleImplementation(CheckTask<storm::logic::Formula, CValueType> const& checkTask) const {
storm::logic::Formula const& formula = checkTask.getFormula();
return formula.isInFragment(storm::logic::prctl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true).setTotalRewardFormulasAllowed(true).setTimeBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false));
return formula.isInFragment(storm::logic::csrl().setGloballyFormulasAllowed(false).setLongRunAverageRewardFormulasAllowed(true).setLongRunAverageProbabilitiesAllowed(true).setTimeAllowed(true).setTotalRewardFormulasAllowed(true).setBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false).setInstantaneousFormulasAllowed(false));
}
template <typename SparseCtmcModelType>

8
src/storm/modelchecker/csl/helper/SparseMarkovAutomatonCslHelper.cpp

@ -16,6 +16,7 @@
#include "storm/utility/macros.h"
#include "storm/utility/vector.h"
#include "storm/utility/graph.h"
#include "storm/utility/NumberTraits.h"
#include "storm/storage/expressions/Variable.h"
#include "storm/storage/expressions/Expression.h"
@ -824,7 +825,12 @@ namespace storm {
}
// Solve MEC with the method specified in the settings
storm::solver::LraMethod method = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>().getLraMethod();
auto minMaxSettings = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>();
storm::solver::LraMethod method = minMaxSettings.getLraMethod();
if (storm::NumberTraits<ValueType>::IsExact && minMaxSettings.isLraMethodSetFromDefaultValue() && method != storm::solver::LraMethod::LinearProgramming) {
STORM_LOG_INFO("Selecting 'LP' as the solution technique for long-run properties to guarantee exact results. If you want to override this, please explicitly specify a different LRA method.");
method = storm::solver::LraMethod::LinearProgramming;
}
if (method == storm::solver::LraMethod::LinearProgramming) {
return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, exitRateVector, markovianStates, rewardModel, mec);
} else if (method == storm::solver::LraMethod::ValueIteration) {

25
src/storm/modelchecker/prctl/helper/SparseMdpPrctlHelper.cpp

@ -34,6 +34,7 @@
#include "storm/utility/Stopwatch.h"
#include "storm/utility/ProgressMeasurement.h"
#include "storm/utility/export.h"
#include "storm/utility/NumberTraits.h"
#include "storm/transformer/EndComponentEliminator.h"
@ -778,8 +779,11 @@ namespace storm {
}
// Sanity check for created scheduler.
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || (!scheduler->isPartialScheduler() && scheduler->isDeterministicScheduler() && scheduler->isMemorylessScheduler()), "Unexpected format of obtained scheduler.");
STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler");
// Return result.
return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(scheduler));
}
@ -918,7 +922,7 @@ namespace storm {
template<typename RewardModelType>
MDPSparseModelCheckingHelperReturnType<ValueType> SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(Environment const& env, storm::solver::SolveGoal<ValueType>&& goal, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates, bool qualitative, bool produceScheduler, ModelCheckerHint const& hint) {
// 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.");
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Reward model for formula is empty. Skipping formula.");
return computeReachabilityRewardsHelper(env, std::move(goal), transitionMatrix, backwardTransitions,
[&rewardModel] (uint_fast64_t rowCount, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
return rewardModel.getTotalRewardVector(rowCount, transitionMatrix, maybeStates);
@ -1049,7 +1053,7 @@ namespace storm {
scheduler.setChoice(0, state);
}
} else {
storm::utility::graph::computeSchedulerProb0E(qualitativeStateSets.infinityStates, transitionMatrix, scheduler);
storm::utility::graph::computeSchedulerRewInf(qualitativeStateSets.infinityStates, transitionMatrix, scheduler);
for (auto const& state : qualitativeStateSets.rewardZeroStates) {
scheduler.setChoice(0, state);
}
@ -1276,7 +1280,11 @@ namespace storm {
}
// Sanity check for created scheduler.
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || (!scheduler->isPartialScheduler() && scheduler->isDeterministicScheduler() && scheduler->isMemorylessScheduler()), "Unexpected format of obtained scheduler.");
STORM_LOG_ASSERT(!produceScheduler || scheduler, "Expected that a scheduler was obtained.");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || !scheduler->isPartialScheduler(), "Expected a fully defined scheduler");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isDeterministicScheduler(), "Expected a deterministic scheduler");
STORM_LOG_ASSERT((!produceScheduler && !scheduler) || scheduler->isMemorylessScheduler(), "Expected a memoryless scheduler");
return MDPSparseModelCheckingHelperReturnType<ValueType>(std::move(result), std::move(scheduler));
}
@ -1478,7 +1486,12 @@ namespace storm {
}
// Solve MEC with the method specified in the settings
storm::solver::LraMethod method = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>().getLraMethod();
auto minMaxSettings = storm::settings::getModule<storm::settings::modules::MinMaxEquationSolverSettings>();
storm::solver::LraMethod method = minMaxSettings.getLraMethod();
if (storm::NumberTraits<ValueType>::IsExact && minMaxSettings.isLraMethodSetFromDefaultValue() && method != storm::solver::LraMethod::LinearProgramming) {
STORM_LOG_INFO("Selecting 'LP' as the solution technique for long-run properties to guarantee exact results. If you want to override this, please explicitly specify a different LRA method.");
method = storm::solver::LraMethod::LinearProgramming;
}
if (method == storm::solver::LraMethod::LinearProgramming) {
return computeLraForMaximalEndComponentLP(env, dir, transitionMatrix, rewardModel, mec);
} else if (method == storm::solver::LraMethod::ValueIteration) {

2
src/storm/modelchecker/prctl/helper/SymbolicMdpPrctlHelper.cpp

@ -202,7 +202,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
std::unique_ptr<CheckResult> SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(Environment const& env, OptimizationDirection dir, storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, storm::dd::Add<DdType, ValueType> const& transitionMatrix, RewardModelType const& rewardModel, uint_fast64_t stepBound) {
// 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.");
STORM_LOG_THROW(!rewardModel.empty(), storm::exceptions::InvalidPropertyException, "Reward model for formula is empty. Skipping formula.");
// Compute the reward vector to add in each step based on the available reward models.
storm::dd::Add<DdType, ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix, model.getColumnVariables());

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

@ -112,6 +112,10 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown LP solver '" << lpSolverName << "'.");
}
bool CoreSettings::isLpSolverSetFromDefaultValue() const {
return !this->getOption(lpSolverOptionName).getHasOptionBeenSet() || this->getOption(lpSolverOptionName).getArgumentByName("name").wasSetFromDefaultValue();
}
storm::solver::SmtSolverType CoreSettings::getSmtSolver() const {
std::string smtSolverName = this->getOption(smtSolverOptionName).getArgumentByName("name").getValueAsString();
if (smtSolverName == "z3") {

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

@ -94,6 +94,13 @@ namespace storm {
* @return The selected LP solver.
*/
storm::solver::LpSolverType getLpSolver() const;
/*!
* Retrieves whether the lp solver has been set from its default value.
*
* @return True iff it has been set from its default value.
*/
bool isLpSolverSetFromDefaultValue() const;
/*!
* Retrieves the selected SMT solver.

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

@ -111,6 +111,10 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentValueException, "Unknown lra solving technique '" << lraMethodString << "'.");
}
bool MinMaxEquationSolverSettings::isLraMethodSetFromDefaultValue() const {
return !this->getOption(lraMethodOptionName).getArgumentByName("name").getHasBeenSet() || this->getOption(lraMethodOptionName).getArgumentByName("name").wasSetFromDefaultValue();
}
MinMaxEquationSolverSettings::MarkovAutomatonBoundedReachabilityMethod MinMaxEquationSolverSettings::getMarkovAutomatonBoundedReachabilityMethod() const {
std::string techniqueAsString = this->getOption(markovAutomatonBoundedReachabilityMethodOptionName).getArgumentByName("name").getValueAsString();
if (techniqueAsString == "imca") {

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

@ -93,6 +93,11 @@ namespace storm {
*/
storm::solver::LraMethod getLraMethod() const;
/*!
* Retrieves whether the LraMethod was set from a default value.
*/
bool isLraMethodSetFromDefaultValue() const;
/*!
* Retrieves the method to be used for bounded reachability on MAs.
*

1
src/storm/storage/jani/ArrayEliminator.cpp

@ -614,7 +614,6 @@ namespace storm {
}
void insertLValueArrayAccessReplacements(std::vector<Assignment const*> const& arrayAccesses, std::vector<storm::jani::Variable const*> const& arrayVariableReplacements, int64_t level, std::vector<Assignment>& newAssignments) const {
storm::expressions::Variable const& arrayVariable = arrayAccesses.front()->getLValue().getArray().getExpressionVariable();
bool onlyConstantIndices = true;
for (auto const& aa : arrayAccesses) {
if (aa->getLValue().getArrayIndex().containsVariables()) {

2
src/storm/storage/jani/Edge.h

@ -163,7 +163,7 @@ namespace storm {
std::vector<EdgeDestination> destinations;
/// The color of the edge, used to persistently mark and identify specific edges (by the user)
uint64_t color;
uint64_t color = 0;
};
std::ostream& operator<<(std::ostream& stream, Edge const& edge);

4
src/storm/storage/jani/JaniLocationExpander.cpp

@ -67,10 +67,8 @@ namespace storm {
for (int64_t i = variableLowerBound; i <= variableUpperBound; i++) {
std::string newLocationName = loc.getName() + "_" + variableName + "_" + std::to_string(i);
substitutionMap[eliminatedExpressionVariable] = original.getExpressionManager().integer(i);
std::cout << "eliminate " << eliminatedExpressionVariable.getName() << " with " << i << std::endl;
OrderedAssignments newAssignments = loc.getAssignments().clone();
newAssignments.substitute(substitutionMap);
std::cout << newAssignments << std::endl;
uint64_t newLocationIndex = newAutomaton.addLocation(Location(newLocationName, newAssignments));
locationVariableValueMap[origIndex][i] = newLocationIndex;
@ -100,8 +98,8 @@ namespace storm {
int64_t value;
for (auto const& assignment : oa) {
if (assignment.getVariable() == *variable) {
oa.remove(assignment);
value = assignment.getAssignedExpression().evaluateAsInt();
oa.remove(assignment);
break;
}
}

164
src/storm/storage/jani/JaniScopeChanger.cpp

@ -0,0 +1,164 @@
#include "storm/storage/jani/JaniScopeChanger.h"
#include <map>
#include <set>
#include <boost/any.hpp>
#include "storm/storage/expressions/Variable.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Property.h"
#include "storm/storage/jani/traverser/JaniTraverser.h"
namespace storm {
namespace jani {
namespace detail {
class VariableAccessedTraverser : public ConstJaniTraverser {
public:
VariableAccessedTraverser(std::set<storm::expressions::Variable> const& varSet) : varSet(varSet) {
// Intentionally left empty
}
using ConstJaniTraverser::traverse;
virtual void traverse(storm::expressions::Expression const& expression, boost::any const& data) override {
bool* result = boost::any_cast<bool *>(data);
if (*result) { return; }
*result = expression.containsVariable(varSet);
}
private:
std::set<storm::expressions::Variable> const& varSet;
};
std::set<uint64_t> getAutomataAccessingVariable(storm::expressions::Variable const& variable, Model const& model) {
std::set<uint64_t> res;
for (uint64_t i = 0; i < model.getNumberOfAutomata(); ++i) {
if (model.getAutomaton(i).getVariables().hasVariable(variable)) {
res.insert(i);
} else {
VariableAccessedTraverser vat({variable});
bool varAccessed = false;
vat.traverse(model.getAutomaton(i), &varAccessed);
if (varAccessed) {
res.insert(i);
}
}
}
return res;
}
}
void JaniScopeChanger::makeVariableGlobal(storm::expressions::Variable const& variable, Model& model) const {
uint64_t automatonIndex = 0;
for (; automatonIndex < model.getNumberOfAutomata(); ++automatonIndex) {
if (model.getAutomaton(automatonIndex).getVariables().hasVariable(variable)) {
break;
}
}
std::map<Variable const*, std::reference_wrapper<Variable const>> remapping;
auto oldJaniVar = model.getAutomaton(automatonIndex).getVariables().eraseVariable(variable);
remapping.emplace(oldJaniVar.get(), model.addVariable(*oldJaniVar));
// Only one automaton accesses this variable
model.getAutomaton(automatonIndex).changeAssignmentVariables(remapping);
}
void JaniScopeChanger::makeVariableLocal(storm::expressions::Variable const& variable, Model& model, uint64_t automatonIndex) const {
std::map<Variable const*, std::reference_wrapper<Variable const>> remapping;
auto oldJaniVar = model.getGlobalVariables().eraseVariable(variable);
remapping.emplace(oldJaniVar.get(), model.getAutomaton(automatonIndex).addVariable(*oldJaniVar));
// Only one automaton accesses this variable (otherwise this call would be illegal)
model.getAutomaton(automatonIndex).changeAssignmentVariables(remapping);
}
bool JaniScopeChanger::canMakeVariableGlobal(storm::expressions::Variable const& variable, Model const& model) const {
if (model.hasGlobalVariable(variable.getName())) {
return false;
}
// Check whether there are multiple local variables with this name
bool foundVar = false;
for (auto const& aut : model.getAutomata()) {
if (aut.hasVariable(variable.getName())) {
if (foundVar) {
return false;
}
foundVar = true;
}
}
return foundVar;
}
std::pair<bool, uint64_t> JaniScopeChanger::canMakeVariableLocal(storm::expressions::Variable const& variable, Model const& model, std::vector<Property> const& properties, boost::optional<uint64_t> automatonIndex) const {
uint64_t index = model.getNumberOfAutomata();
if (!model.getGlobalVariables().hasVariable(variable)) {
return {false, index};
}
auto accessingAutomata = detail::getAutomataAccessingVariable(variable, model);
if (accessingAutomata.size() > 1 || (automatonIndex.is_initialized() && accessingAutomata.count(automatonIndex.get()) == 0)) {
return {false, index};
}
if (model.getInitialStatesRestriction().containsVariable({variable})) {
return {false, index};
}
for (auto const& rewExp : model.getNonTrivialRewardExpressions()) {
if (rewExp.second.containsVariable({variable})) {
return {false, index};
}
}
for (auto const& funDef : model.getGlobalFunctionDefinitions()) {
if (funDef.second.getFunctionBody().containsVariable({variable})) {
return {false, index};
}
}
for (auto const& p : properties) {
if (p.getUsedVariablesAndConstants().count(variable) > 0) {
return {false, index};
}
if (p.getUsedLabels().count(variable.getName()) > 0) {
return {false, index};
}
}
if (accessingAutomata.empty()) {
index = automatonIndex.is_initialized() ? automatonIndex.get() : 0;
} else {
index = *accessingAutomata.begin();
assert(!automatonIndex.is_initialized() || index == automatonIndex.get());
}
return {true, index};
}
void JaniScopeChanger::makeVariablesGlobal(Model& model) const {
for (uint64_t i = 0; i < model.getNumberOfAutomata(); ++i) {
// Make sure to not erase from a set while iterating over it...
std::set<storm::expressions::Variable> varsToMakeGlobal;
for (auto const& v : model.getAutomaton(i).getVariables()) {
if (canMakeVariableGlobal(v.getExpressionVariable(), model)) {
varsToMakeGlobal.insert(v.getExpressionVariable());
}
}
for (auto const& v : varsToMakeGlobal) {
makeVariableGlobal(v, model);
}
}
}
void JaniScopeChanger::makeVariablesLocal(Model& model, std::vector<Property> const& properties) const {
// Make sure to not erase from a set while iterating over it...
std::map<storm::expressions::Variable, uint64_t> varsToMakeLocal;
for (auto const& v : model.getGlobalVariables()) {
auto makeLocal = canMakeVariableLocal(v.getExpressionVariable(), model, properties);
if (makeLocal.first) {
varsToMakeLocal[v.getExpressionVariable()] = makeLocal.second;
}
}
for (auto const& v : varsToMakeLocal) {
makeVariableLocal(v.first, model, v.second);
}
}
}
}

57
src/storm/storage/jani/JaniScopeChanger.h

@ -0,0 +1,57 @@
#pragma once
#include <vector>
#include <boost/optional.hpp>
namespace storm {
namespace expressions {
class Variable;
}
namespace jani {
class Model;
class Property;
class JaniScopeChanger {
public:
JaniScopeChanger() = default;
/*!
* Moves the given variable to the global scope.
* It is *not* checked whether this introduces name clashes
*/
void makeVariableGlobal(storm::expressions::Variable const& variable, Model& model) const;
/*!
* Moves the given variable into the local scope of the automaton with the given index.
* It is *not* checked whether this introduces out-of-scope accesses.
*/
void makeVariableLocal(storm::expressions::Variable const& variable, Model& model, uint64_t automatonIndex) const;
/*!
* Checks whether this variable can be made global without introducing name clashes.
*/
bool canMakeVariableGlobal(storm::expressions::Variable const& variable, Model const& model) const;
/*!
* Checks whether this variable can be made local without introducing out-of-scope accesses.
* Returns true if this is a case as well as an automaton index where to pout the variable
*/
std::pair<bool, uint64_t> canMakeVariableLocal(storm::expressions::Variable const& variable, Model const& model, std::vector<Property> const& properties = {}, boost::optional<uint64_t> automatonIndex = boost::none) const;
/*!
* Moves as many variables to the global scope as possible
*/
void makeVariablesGlobal(Model& model) const;
/*!
* Moves as many variables to a local scope as possible
*/
void makeVariablesLocal(Model& model, std::vector<Property> const& properties = {}) const;
};
}
}

15
src/storm/storage/jani/LValue.cpp

@ -50,14 +50,23 @@ namespace storm {
LValue LValue::changeAssignmentVariables(std::map<Variable const*, std::reference_wrapper<Variable const>> const& remapping) const {
if (isVariable()) {
return LValue(remapping.at(variable));
auto it = remapping.find(variable);
if (it == remapping.end()) {
return *this;
} else {
return LValue(it->second);
}
} else {
STORM_LOG_ASSERT(isArrayAccess(), "Unhandled LValue.");
return LValue(LValue(remapping.at(variable)), arrayIndex);
auto it = remapping.find(variable);
if (it == remapping.end()) {
return *this;
} else {
return LValue(LValue(it->second), arrayIndex);
}
}
}
bool LValue::operator<(LValue const& other) const {
if (isVariable()) {
return !other.isVariable() || variable->getExpressionVariable() < other.getVariable().getExpressionVariable();

20
src/storm/storage/jani/Property.cpp

@ -70,6 +70,26 @@ namespace storm {
bool Property::containsUndefinedConstants() const {
return !undefinedConstants.empty();
}
std::set<storm::expressions::Variable> Property::getUsedVariablesAndConstants() const {
auto res = getUndefinedConstants();
getFilter().getFormula()->gatherUsedVariables(res);
getFilter().getStatesFormula()->gatherUsedVariables(res);
return res;
}
std::set<std::string> Property::getUsedLabels() const {
std::set<std::string> res;
auto labFormSet = getFilter().getFormula()->getAtomicLabelFormulas();
for (auto const& f : labFormSet) {
res.insert(f->getLabel());
}
labFormSet = getFilter().getStatesFormula()->getAtomicLabelFormulas();
for (auto const& f : labFormSet) {
res.insert(f->getLabel());
}
return res;
}
std::ostream& operator<<(std::ostream& os, Property const& p) {
return os << "(" << p.getName() << "): " << p.getFilter();

3
src/storm/storage/jani/Property.h

@ -129,8 +129,11 @@ namespace storm {
std::set<storm::expressions::Variable> const& getUndefinedConstants() const;
bool containsUndefinedConstants() const;
std::set<storm::expressions::Variable> getUsedVariablesAndConstants() const;
std::set<std::string> getUsedLabels() const;
std::shared_ptr<storm::logic::Formula const> getRawFormula() const;
private:
std::string name;
std::string comment;

45
src/storm/storage/jani/VariableSet.cpp

@ -196,6 +196,51 @@ namespace storm {
return getVariable(it->second);
}
template <typename VarType>
void eraseFromVariableVector(std::vector<std::shared_ptr<VarType>>& varVec, storm::expressions::Variable const& variable) {
for (auto vIt = varVec.begin(); vIt != varVec.end(); ++vIt) {
if ((*vIt)->getExpressionVariable() == variable) {
varVec.erase(vIt);
break;
}
}
}
std::shared_ptr<Variable> VariableSet::eraseVariable(storm::expressions::Variable const& variable) {
auto vToVIt = variableToVariable.find(variable);
STORM_LOG_THROW(vToVIt != variableToVariable.end(), storm::exceptions::InvalidArgumentException, "Unable to erase unknown variable '" << variable.getName() << "'.");
std::shared_ptr<Variable> janiVar = std::move(vToVIt->second);
variableToVariable.erase(vToVIt);
nameToVariable.erase(variable.getName());
eraseFromVariableVector(variables, variable);
if (janiVar->isBooleanVariable()) {
eraseFromVariableVector(booleanVariables, variable);
}
if (janiVar->isBooleanVariable()) {
eraseFromVariableVector(booleanVariables, variable);
}
if (janiVar->isBoundedIntegerVariable()) {
eraseFromVariableVector(boundedIntegerVariables, variable);
}
if (janiVar->isUnboundedIntegerVariable()) {
eraseFromVariableVector(unboundedIntegerVariables, variable);
}
if (janiVar->isRealVariable()) {
eraseFromVariableVector(realVariables, variable);
}
if (janiVar->isArrayVariable()) {
eraseFromVariableVector(arrayVariables, variable);
}
if (janiVar->isClockVariable()) {
eraseFromVariableVector(clockVariables, variable);
}
if (janiVar->isTransient()) {
eraseFromVariableVector(transientVariables, variable);
}
return janiVar;
}
typename detail::Variables<Variable>::iterator VariableSet::begin() {
return detail::Variables<Variable>::make_iterator(variables.begin());
}

5
src/storm/storage/jani/VariableSet.h

@ -153,6 +153,11 @@ namespace storm {
* Retrieves the variable object associated with the given expression variable (if any).
*/
Variable const& getVariable(storm::expressions::Variable const& variable) const;
/*!
* Erases the given variable from this set.
*/
std::shared_ptr<Variable> eraseVariable(storm::expressions::Variable const& variable);
/*!
* Retrieves whether this variable set contains a transient variable.

21
src/storm/utility/graph.cpp

@ -402,6 +402,8 @@ namespace storm {
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = transitionMatrix.getRowGroupIndices();
for (auto const& state : states) {
bool setValue = false;
STORM_LOG_ASSERT(nondeterministicChoiceIndices[state+1] - nondeterministicChoiceIndices[state] > 0, "Expected at least one action enabled in state " << state);
for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) {
bool allSuccessorsInStates = true;
for (auto const& element : transitionMatrix.getRow(choice)) {
@ -414,9 +416,11 @@ namespace storm {
for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
scheduler.setChoice(choice - nondeterministicChoiceIndices[state], state, memState);
}
setValue = true;
break;
}
}
STORM_LOG_ASSERT(setValue, "Expected that at least one action for state " << state << " stays within the selected state");
}
}
@ -425,6 +429,7 @@ namespace storm {
std::vector<uint_fast64_t> const& nondeterministicChoiceIndices = transitionMatrix.getRowGroupIndices();
for (auto const& state : states) {
bool setValue = false;
for (uint_fast64_t choice = nondeterministicChoiceIndices[state]; choice < nondeterministicChoiceIndices[state + 1]; ++choice) {
bool oneSuccessorInStates = false;
for (auto const& element : transitionMatrix.getRow(choice)) {
@ -437,9 +442,11 @@ namespace storm {
for (uint_fast64_t memState = 0; memState < scheduler.getNumberOfMemoryStates(); ++memState) {
scheduler.setChoice(choice - nondeterministicChoiceIndices[state], state, memState);
}
setValue = true;
break;
}
}
STORM_LOG_ASSERT(setValue, "Expected that at least one action for state " << state << " leads with positive probability to the selected state");
}
}
@ -490,6 +497,11 @@ namespace storm {
void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::Scheduler<T>& scheduler) {
computeSchedulerStayingInStates(prob0EStates, transitionMatrix, scheduler);
}
template <typename T>
void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::Scheduler<T>& scheduler) {
computeSchedulerWithOneSuccessorInStates(rewInfStates, transitionMatrix, scheduler);
}
template <typename T>
void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter) {
@ -1661,7 +1673,10 @@ namespace storm {
template void computeSchedulerProbGreater0E(storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter);
template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::Scheduler<double>& scheduler);
template void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::Scheduler<double>& scheduler);
template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<double> const& transitionMatrix, storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<double>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<double> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ;
@ -1730,7 +1745,9 @@ namespace storm {
template void computeSchedulerProbGreater0E(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter);
template void computeSchedulerProb0E(storm::storage::BitVector const& prob0EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::Scheduler<storm::RationalNumber>& scheduler);
template void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::Scheduler<storm::RationalNumber>& scheduler);
template void computeSchedulerProb1E(storm::storage::BitVector const& prob1EStates, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<storm::RationalNumber>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
template storm::storage::BitVector performProbGreater0E(storm::storage::SparseMatrix<storm::RationalNumber> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, bool useStepBound = false, uint_fast64_t maximalSteps = 0) ;

10
src/storm/utility/graph.h

@ -284,6 +284,16 @@ namespace storm {
template <typename T>
void computeSchedulerProbGreater0E(storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::SparseMatrix<T> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, storm::storage::Scheduler<T>& scheduler, boost::optional<storm::storage::BitVector> const& rowFilter = boost::none);
/*!
* Computes a scheduler for the given states that have a scheduler that has a reward infinity.
*
* @param rewInfStates The states that have a scheduler achieving reward infinity.
* @param transitionMatrix The transition matrix of the system.
* @param scheduler The resulting scheduler for the rewInf States. The scheduler is not set at other states.
*/
template <typename T>
void computeSchedulerRewInf(storm::storage::BitVector const& rewInfStates, storm::storage::SparseMatrix<T> const& transitionMatrix, storm::storage::Scheduler<T>& scheduler);
/*!
* Computes a scheduler for the given states that have a scheduler that has a probability 0.
*

6
src/storm/utility/solver.cpp

@ -15,6 +15,7 @@
#include "storm/solver/MathsatSmtSolver.h"
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/CoreSettings.h"
#include "storm/utility/NumberTraits.h"
#include "storm/exceptions/InvalidSettingsException.h"
@ -25,8 +26,11 @@ namespace storm {
template<typename ValueType>
std::unique_ptr<storm::solver::LpSolver<ValueType>> LpSolverFactory<ValueType>::create(std::string const& name, storm::solver::LpSolverTypeSelection solvT) const {
storm::solver::LpSolverType t;
if(solvT == storm::solver::LpSolverTypeSelection::FROMSETTINGS) {
if (solvT == storm::solver::LpSolverTypeSelection::FROMSETTINGS) {
t = storm::settings::getModule<storm::settings::modules::CoreSettings>().getLpSolver();
if (storm::NumberTraits<ValueType>::IsExact && t != storm::solver::LpSolverType::Z3 && storm::settings::getModule<storm::settings::modules::CoreSettings>().isLpSolverSetFromDefaultValue()) {
t = storm::solver::LpSolverType::Z3;
}
} else {
t = convert(solvT);
}

Loading…
Cancel
Save