From a08cb4ac1854491a5852977a8bc8c08457734f3c Mon Sep 17 00:00:00 2001 From: dehnert Date: Thu, 12 Jul 2018 11:51:11 +0200 Subject: [PATCH] making game solver respect equation solver format --- src/storm-pars-cli/storm-pars.cpp | 252 ++++++++++++------ .../SparseCtmcInstantiationModelChecker.cpp | 27 ++ .../SparseCtmcInstantiationModelChecker.h | 28 ++ .../SparseDtmcInstantiationModelChecker.cpp | 6 +- .../SparseInstantiationModelChecker.cpp | 6 +- .../SparseMdpInstantiationModelChecker.cpp | 2 +- .../settings/modules/ParametricSettings.cpp | 6 + .../settings/modules/ParametricSettings.h | 6 + src/storm/solver/StandardGameSolver.cpp | 4 +- .../TopologicalLinearEquationSolver.cpp | 4 +- 10 files changed, 245 insertions(+), 96 deletions(-) create mode 100644 src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp create mode 100644 src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h diff --git a/src/storm-pars-cli/storm-pars.cpp b/src/storm-pars-cli/storm-pars.cpp index ff7c075f8..32d63ae52 100644 --- a/src/storm-pars-cli/storm-pars.cpp +++ b/src/storm-pars-cli/storm-pars.cpp @@ -15,6 +15,8 @@ #include "storm/utility/Stopwatch.h" #include "storm/utility/macros.h" +#include "storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h" + #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/IOSettings.h" @@ -29,7 +31,19 @@ namespace storm { typedef typename storm::cli::SymbolicInput SymbolicInput; - + template + struct SampleInformation { + SampleInformation(bool graphPreserving = false) : graphPreserving(graphPreserving) { + // Intentionally left empty. + } + + bool empty() const { + return cartesianProducts.empty(); + } + + std::vector::type, std::vector::type>>> cartesianProducts; + bool graphPreserving; + }; template std::vector> parseRegions(std::shared_ptr const& model) { @@ -42,12 +56,12 @@ namespace storm { } template - std::map::type, std::vector::type>> parseSamples(std::shared_ptr const& model, std::string const& sampleString) { + SampleInformation parseSamples(std::shared_ptr const& model, std::string const& sampleString, bool graphPreserving) { STORM_LOG_THROW(model->isSparseModel(), storm::exceptions::NotSupportedException, "Sampling is only supported for sparse models."); - std::map::type, std::vector::type>> samplesForVariables; + SampleInformation sampleInfo(graphPreserving); if (sampleString.empty()) { - return samplesForVariables; + return sampleInfo; } // Get all parameters from the model. @@ -56,52 +70,59 @@ namespace storm { modelParameters = storm::models::sparse::getProbabilityParameters(sparseModel); auto rewParameters = storm::models::sparse::getRewardParameters(sparseModel); modelParameters.insert(rewParameters.begin(), rewParameters.end()); - - // Get the values string for each variable. - std::vector valuesForVariables; - boost::split(valuesForVariables, sampleString, boost::is_any_of(",")); - for (auto& values : valuesForVariables) { - boost::trim(values); - } - - std::set::type> encounteredParameters; - for (auto const& varValues : valuesForVariables) { - auto equalsPosition = varValues.find("="); - STORM_LOG_THROW(equalsPosition != varValues.npos, storm::exceptions::WrongFormatException, "Incorrect format of samples."); - std::string variableName = varValues.substr(0, equalsPosition); - boost::trim(variableName); - std::string values = varValues.substr(equalsPosition + 1); - boost::trim(values); + + std::vector cartesianProducts; + boost::split(cartesianProducts, sampleString, boost::is_any_of(";")); + for (auto& product : cartesianProducts) { + boost::trim(product); - bool foundParameter = false; - typename utility::parametric::VariableType::type theParameter; - for (auto const& parameter : modelParameters) { - std::stringstream parameterStream; - parameterStream << parameter; - std::cout << parameterStream.str() << " vs " << variableName << std::endl; - if (parameterStream.str() == variableName) { - foundParameter = true; - theParameter = parameter; - encounteredParameters.insert(parameter); - } + // Get the values string for each variable. + std::vector valuesForVariables; + boost::split(valuesForVariables, product, boost::is_any_of(",")); + for (auto& values : valuesForVariables) { + boost::trim(values); } - STORM_LOG_THROW(foundParameter, storm::exceptions::WrongFormatException, "Unknown parameter '" << variableName << "'."); - - std::vector splitValues; - boost::split(splitValues, values, boost::is_any_of(":")); - STORM_LOG_THROW(!splitValues.empty(), storm::exceptions::WrongFormatException, "Expecting at least one value per parameter."); - auto& list = samplesForVariables[theParameter]; - for (auto& value : splitValues) { - boost::trim(value); + std::set::type> encounteredParameters; + sampleInfo.cartesianProducts.emplace_back(); + auto& newCartesianProduct = sampleInfo.cartesianProducts.back(); + for (auto const& varValues : valuesForVariables) { + auto equalsPosition = varValues.find("="); + STORM_LOG_THROW(equalsPosition != varValues.npos, storm::exceptions::WrongFormatException, "Incorrect format of samples."); + std::string variableName = varValues.substr(0, equalsPosition); + boost::trim(variableName); + std::string values = varValues.substr(equalsPosition + 1); + boost::trim(values); + + bool foundParameter = false; + typename utility::parametric::VariableType::type theParameter; + for (auto const& parameter : modelParameters) { + std::stringstream parameterStream; + parameterStream << parameter; + if (parameterStream.str() == variableName) { + foundParameter = true; + theParameter = parameter; + encounteredParameters.insert(parameter); + } + } + STORM_LOG_THROW(foundParameter, storm::exceptions::WrongFormatException, "Unknown parameter '" << variableName << "'."); + + std::vector splitValues; + boost::split(splitValues, values, boost::is_any_of(":")); + STORM_LOG_THROW(!splitValues.empty(), storm::exceptions::WrongFormatException, "Expecting at least one value per parameter."); - list.push_back(storm::utility::convertNumber::type>(value)); + auto& list = newCartesianProduct[theParameter]; + + for (auto& value : splitValues) { + boost::trim(value); + list.push_back(storm::utility::convertNumber::type>(value)); + } } + + STORM_LOG_THROW(encounteredParameters == modelParameters, storm::exceptions::WrongFormatException, "Variables for all parameters are required when providing samples."); } - STORM_LOG_THROW(encounteredParameters == modelParameters, storm::exceptions::WrongFormatException, "Variables for all parameters are required when providing samples.") - - return samplesForVariables; + return sampleInfo; } template @@ -169,9 +190,24 @@ namespace storm { } template - void printInitialStatesResult(std::unique_ptr const& result, storm::jani::Property const& property, storm::utility::Stopwatch* watch = nullptr) { + void printInitialStatesResult(std::unique_ptr const& result, storm::jani::Property const& property, storm::utility::Stopwatch* watch = nullptr, storm::utility::parametric::Valuation const* valuation = nullptr) { if (result) { - STORM_PRINT_AND_LOG("Result (initial states): " << std::endl); + STORM_PRINT_AND_LOG("Result (initial states)"); + if (valuation) { + bool first = true; + std::stringstream ss; + for (auto const& entry : *valuation) { + if (!first) { + ss << ", "; + } else { + first = false; + } + ss << entry.first << "=" << entry.second; + } + + STORM_PRINT_AND_LOG(" for instance [" << ss.str() << "]"); + } + STORM_PRINT_AND_LOG(": ") auto const* regionCheckResult = dynamic_cast const*>(result.get()); if (regionCheckResult != nullptr) { @@ -195,7 +231,7 @@ namespace storm { STORM_PRINT_AND_LOG(*result << std::endl); } if (watch) { - STORM_PRINT_AND_LOG("Time for model checking: " << *watch << "." << std::endl); + STORM_PRINT_AND_LOG("Time for model checking: " << *watch << "." << std::endl << std::endl); } } else { STORM_PRINT_AND_LOG(" failed, property is unsupported by selected engine/settings." << std::endl); @@ -214,8 +250,78 @@ namespace storm { } } + template class ModelCheckerType, typename ModelType, typename ValueType, typename SolveValueType = double> + void verifyPropertiesAtSamplePoints(ModelType const& model, SymbolicInput const& input, SampleInformation const& samples) { + + // When samples are provided, we create an instantiation model checker. + ModelCheckerType modelchecker(model); + + for (auto const& property : input.properties) { + storm::cli::printModelCheckingProperty(property); + + modelchecker.specifyFormula(storm::api::createTask(property.getRawFormula(), true)); + modelchecker.setInstantiationsAreGraphPreserving(samples.graphPreserving); + + storm::utility::parametric::Valuation valuation; + + std::vector::type> parameters; + std::vector::type>::const_iterator> iterators; + std::vector::type>::const_iterator> iteratorEnds; + + storm::utility::Stopwatch watch(true); + for (auto const& product : samples.cartesianProducts) { + parameters.clear(); + iterators.clear(); + iteratorEnds.clear(); + + for (auto const& entry : product) { + parameters.push_back(entry.first); + iterators.push_back(entry.second.cbegin()); + iteratorEnds.push_back(entry.second.cend()); + } + + bool done = false; + while (!done) { + // Read off valuation. + for (uint64_t i = 0; i < parameters.size(); ++i) { + valuation[parameters[i]] = *iterators[i]; + } + + storm::utility::Stopwatch valuationWatch(true); + std::unique_ptr result = modelchecker.check(Environment(), valuation); + valuationWatch.stop(); + + if (result) { + result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model.getInitialStates())); + } + printInitialStatesResult(result, property, &valuationWatch, &valuation); + + for (uint64_t i = 0; i < parameters.size(); ++i) { + ++iterators[i]; + if (iterators[i] == iteratorEnds[i]) { + // Reset iterator and proceed to move next iterator. + iterators[i] = product.at(parameters[i]).cbegin(); + + // If the last iterator was removed, we are done. + if (i == parameters.size() - 1) { + done = true; + } + } else { + // If an iterator was moved but not reset, we have another valuation to check. + break; + } + } + + } + } + + watch.stop(); + STORM_PRINT_AND_LOG("Overall time for sampling all instances: " << watch << std::endl << std::endl); + } + } + template - void verifyPropertiesWithSparseEngine(std::shared_ptr> const& model, SymbolicInput const& input, std::map::type, std::vector::type>> const& samples) { + void verifyPropertiesWithSparseEngine(std::shared_ptr> const& model, SymbolicInput const& input, SampleInformation const& samples) { if (samples.empty()) { verifyProperties(input.properties, @@ -235,43 +341,15 @@ namespace storm { } }); } else { - STORM_LOG_THROW(model->isOfType(storm::models::ModelType::Dtmc), storm::exceptions::NotSupportedException, "Sampling is currently only supported for DTMCs."); - - // When samples are provided, we create an instantiation model checker. - std::unique_ptr, double>> modelchecker(*model->template as>()); - - for (auto const& property : input.properties) { - storm::cli::printModelCheckingProperty(property); - - modelchecker->specifyFormula(property.getRawFormula(storm::api::createTask(property.getRawFormula(), true))); - - // TODO: check. - modelchecker->setInstantiationsAreGraphPreserving(true); - - storm::utility::parametric::Valuation valuation; - - // Enumerate all sample points. - for () { - bool first = true; - std::stringstream ss; - ss << "Treating instance ["; - for (auto const& entry : valuation) { - if (!first) { - ss << ", "; - } else { - first = false; - } - ss << entry.first << ": " << entry.second; - } - ss << "]..."; - STORM_PRINT_AND_LOG(ss.str()); - - storm::utility::Stopwatch watch(true); - std::unique_ptr result = modelchecker->check(Environment(), valuation); - watch.stop(); - - printInitialStatesResult(result, property, &watch); - } + STORM_LOG_TRACE("Sampling the model at given points."); + if (model->isOfType(storm::models::ModelType::Dtmc)) { + verifyPropertiesAtSamplePoints, ValueType, double>(*model->template as>(), input, samples); + } else if (model->isOfType(storm::models::ModelType::Ctmc)) { + verifyPropertiesAtSamplePoints, ValueType, double>(*model->template as>(), input, samples); + } else if (model->isOfType(storm::models::ModelType::Ctmc)) { + verifyPropertiesAtSamplePoints, ValueType, double>(*model->template as>(), input, samples); + } else { + STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Sampling is currently only supported for DTMCs, CTMCs and MDPs."); } } } @@ -331,7 +409,7 @@ namespace storm { } template - void verifyWithSparseEngine(std::shared_ptr> const& model, SymbolicInput const& input, std::vector> const& regions, std::map::type, std::vector::type>> const& samples) { + void verifyWithSparseEngine(std::shared_ptr> const& model, SymbolicInput const& input, std::vector> const& regions, SampleInformation const& samples) { if (regions.empty()) { storm::pars::verifyPropertiesWithSparseEngine(model, input, samples); } else { @@ -340,7 +418,7 @@ namespace storm { } template - void verifyParametricModel(std::shared_ptr const& model, SymbolicInput const& input, std::vector> const& regions, std::map::type, std::vector::type>> const& samples) { + void verifyParametricModel(std::shared_ptr const& model, SymbolicInput const& input, std::vector> const& regions, SampleInformation const& samples) { STORM_LOG_ASSERT(model->isSparseModel(), "Unexpected model type."); storm::pars::verifyWithSparseEngine(model->as>(), input, regions, samples); } @@ -376,7 +454,7 @@ namespace storm { } std::vector> regions = parseRegions(model); - std::map::type, std::vector::type>> samples = parseSamples(model, parSettings.getSamples()); + SampleInformation samples = parseSamples(model, parSettings.getSamples(), parSettings.isSamplesAreGraphPreservingSet()); if (model) { storm::cli::exportModel(model, input); diff --git a/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp new file mode 100644 index 000000000..4af65eb19 --- /dev/null +++ b/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.cpp @@ -0,0 +1,27 @@ +#include "storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h" + +#include "storm/modelchecker/csl/SparseCtmcCslModelChecker.h" + +#include "storm/exceptions/InvalidStateException.h" + +namespace storm { + namespace modelchecker { + + template + SparseCtmcInstantiationModelChecker::SparseCtmcInstantiationModelChecker(SparseModelType const& parametricModel) : SparseInstantiationModelChecker(parametricModel), modelInstantiator(parametricModel) { + //Intentionally left empty + } + + template + std::unique_ptr SparseCtmcInstantiationModelChecker::check(Environment const& env, storm::utility::parametric::Valuation const& valuation) { + STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before."); + auto const& instantiatedModel = modelInstantiator.instantiate(valuation); + storm::modelchecker::SparseCtmcCslModelChecker> modelChecker(instantiatedModel); + + return modelChecker.check(env, *this->currentCheckTask); + } + + template class SparseCtmcInstantiationModelChecker, double>; + template class SparseCtmcInstantiationModelChecker, storm::RationalNumber>; + } +} diff --git a/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h b/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h new file mode 100644 index 000000000..4e4b7643f --- /dev/null +++ b/src/storm-pars/modelchecker/instantiation/SparseCtmcInstantiationModelChecker.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#include "storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.h" +#include "storm-pars/utility/ModelInstantiator.h" +#include "storm/models/sparse/Dtmc.h" +#include "storm/models/sparse/StandardRewardModel.h" +#include "storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h" + +namespace storm { + namespace modelchecker { + + /*! + * Class to efficiently check a formula on a parametric model with different parameter instantiations. + */ + template + class SparseCtmcInstantiationModelChecker : public SparseInstantiationModelChecker { + public: + SparseCtmcInstantiationModelChecker(SparseModelType const& parametricModel); + + virtual std::unique_ptr check(Environment const& env, storm::utility::parametric::Valuation const& valuation) override; + + storm::utility::ModelInstantiator> modelInstantiator; + }; + } +} diff --git a/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp index d13f3bf44..5de3d8fd3 100644 --- a/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp +++ b/src/storm-pars/modelchecker/instantiation/SparseDtmcInstantiationModelChecker.cpp @@ -20,11 +20,11 @@ namespace storm { std::unique_ptr SparseDtmcInstantiationModelChecker::check(Environment const& env, storm::utility::parametric::Valuation const& valuation) { STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before."); auto const& instantiatedModel = modelInstantiator.instantiate(valuation); - STORM_LOG_ASSERT(instantiatedModel.getTransitionMatrix().isProbabilistic(), "Instantiated matrix is not probabilistic!"); + STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(), storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic."); storm::modelchecker::SparseDtmcPrctlModelChecker> modelChecker(instantiatedModel); // Check if there are some optimizations implemented for the specified property - if(this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) { + if (this->currentCheckTask->getFormula().isInFragment(storm::logic::reachability())) { return checkReachabilityProbabilityFormula(env, modelChecker); } else if (this->currentCheckTask->getFormula().isInFragment(storm::logic::propositional().setRewardOperatorsAllowed(true).setReachabilityRewardFormulasAllowed(true).setOperatorAtTopLevelRequired(true).setNestedOperatorsAllowed(false))) { return checkReachabilityRewardFormula(env, modelChecker); @@ -144,4 +144,4 @@ namespace storm { template class SparseDtmcInstantiationModelChecker, storm::RationalNumber>; } -} \ No newline at end of file +} diff --git a/src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp index d81d5b9a6..7d5143a50 100644 --- a/src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp +++ b/src/storm-pars/modelchecker/instantiation/SparseInstantiationModelChecker.cpp @@ -2,6 +2,7 @@ #include "storm/adapters/RationalFunctionAdapter.h" #include "storm/models/sparse/Dtmc.h" +#include "storm/models/sparse/Ctmc.h" #include "storm/models/sparse/Mdp.h" #include "storm/models/sparse/StandardRewardModel.h" @@ -12,10 +13,9 @@ namespace storm { template SparseInstantiationModelChecker::SparseInstantiationModelChecker(SparseModelType const& parametricModel) : parametricModel(parametricModel), instantiationsAreGraphPreserving(false) { - //Intentionally left empty + // Intentionally left empty } - template void SparseInstantiationModelChecker::specifyFormula(storm::modelchecker::CheckTask const& checkTask) { currentFormula = checkTask.getFormula().asSharedPointer(); @@ -33,9 +33,11 @@ namespace storm { } template class SparseInstantiationModelChecker, double>; + template class SparseInstantiationModelChecker, double>; template class SparseInstantiationModelChecker, double>; template class SparseInstantiationModelChecker, storm::RationalNumber>; + template class SparseInstantiationModelChecker, storm::RationalNumber>; template class SparseInstantiationModelChecker, storm::RationalNumber>; } diff --git a/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp b/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp index a2a6c0094..3dc4866d3 100644 --- a/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp +++ b/src/storm-pars/modelchecker/instantiation/SparseMdpInstantiationModelChecker.cpp @@ -23,7 +23,7 @@ namespace storm { std::unique_ptr SparseMdpInstantiationModelChecker::check(Environment const& env, storm::utility::parametric::Valuation const& valuation) { STORM_LOG_THROW(this->currentCheckTask, storm::exceptions::InvalidStateException, "Checking has been invoked but no property has been specified before."); auto const& instantiatedModel = modelInstantiator.instantiate(valuation); - STORM_LOG_ASSERT(instantiatedModel.getTransitionMatrix().isProbabilistic(), "Instantiated matrix is not probabilistic!"); + STORM_LOG_THROW(instantiatedModel.getTransitionMatrix().isProbabilistic(), storm::exceptions::InvalidArgumentException, "Instantiation point is invalid as the transition matrix becomes non-stochastic."); storm::modelchecker::SparseMdpPrctlModelChecker> modelChecker(instantiatedModel); // Check if there are some optimizations implemented for the specified property diff --git a/src/storm-pars/settings/modules/ParametricSettings.cpp b/src/storm-pars/settings/modules/ParametricSettings.cpp index a02851dac..54b959e05 100644 --- a/src/storm-pars/settings/modules/ParametricSettings.cpp +++ b/src/storm-pars/settings/modules/ParametricSettings.cpp @@ -19,6 +19,7 @@ namespace storm { const std::string ParametricSettings::transformContinuousShortOptionName = "tc"; const std::string ParametricSettings::onlyWellformednessConstraintsOptionName = "onlyconstraints"; const std::string ParametricSettings::samplesOptionName = "samples"; + const std::string ParametricSettings::samplesGraphPreservingOptionName = "samples-graph-preserving"; ParametricSettings::ParametricSettings() : ModuleSettings(moduleName) { this->addOption(storm::settings::OptionBuilder(moduleName, exportResultOptionName, false, "A path to a file where the parametric result should be saved.") @@ -28,6 +29,7 @@ namespace storm { this->addOption(storm::settings::OptionBuilder(moduleName, onlyWellformednessConstraintsOptionName, false, "Sets whether you only want to obtain the wellformedness constraints").build()); this->addOption(storm::settings::OptionBuilder(moduleName, samplesOptionName, false, "The points at which to sample the model.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("samples", "The samples given in the form 'Var1=Val1:Val2:...:Valk,Var2=...").setDefaultValueString("").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, samplesGraphPreservingOptionName, false, "Sets whether it can be assumed that the samples are graph-preserving.").build()); } bool ParametricSettings::exportResultToFile() const { @@ -54,6 +56,10 @@ namespace storm { return this->getOption(samplesOptionName).getArgumentByName("samples").getValueAsString(); } + bool ParametricSettings::isSamplesAreGraphPreservingSet() const { + return this->getOption(samplesGraphPreservingOptionName).getHasOptionBeenSet(); + } + } // namespace modules } // namespace settings } // namespace storm diff --git a/src/storm-pars/settings/modules/ParametricSettings.h b/src/storm-pars/settings/modules/ParametricSettings.h index 195b0936c..374c8e839 100644 --- a/src/storm-pars/settings/modules/ParametricSettings.h +++ b/src/storm-pars/settings/modules/ParametricSettings.h @@ -54,6 +54,11 @@ namespace storm { */ std::string getSamples() const; + /*! + * Retrieves whether the samples are graph preserving. + */ + bool isSamplesAreGraphPreservingSet() const; + const static std::string moduleName; private: @@ -63,6 +68,7 @@ namespace storm { const static std::string transformContinuousShortOptionName; const static std::string onlyWellformednessConstraintsOptionName; const static std::string samplesOptionName; + const static std::string samplesGraphPreservingOptionName; }; } // namespace modules diff --git a/src/storm/solver/StandardGameSolver.cpp b/src/storm/solver/StandardGameSolver.cpp index 6140a5c15..9656af643 100644 --- a/src/storm/solver/StandardGameSolver.cpp +++ b/src/storm/solver/StandardGameSolver.cpp @@ -123,7 +123,9 @@ namespace storm { } else { // Update the solver. getInducedMatrixVector(x, b, player1Choices, player2Choices, submatrix, subB); - submatrix.convertToEquationSystem(); + if (this->linearEquationSolverFactory->getEquationProblemFormat(environmentOfSolver) == LinearEquationSolverProblemFormat::EquationSystem) { + submatrix.convertToEquationSystem(); + } submatrixSolver->setMatrix(std::move(submatrix)); } diff --git a/src/storm/solver/TopologicalLinearEquationSolver.cpp b/src/storm/solver/TopologicalLinearEquationSolver.cpp index 0e6896370..877ba76dd 100644 --- a/src/storm/solver/TopologicalLinearEquationSolver.cpp +++ b/src/storm/solver/TopologicalLinearEquationSolver.cpp @@ -169,8 +169,8 @@ namespace storm { if (asEquationSystem) { sccA.convertToEquationSystem(); } - //std::cout << "Solving SCC " << scc << std::endl; - //std::cout << "Matrix is " << sccA << std::endl; +// std::cout << "Solving SCC " << scc << std::endl; +// std::cout << "Matrix is " << sccA << std::endl; this->sccSolver->setMatrix(std::move(sccA)); // x Vector