Browse Source

Merge branch 'qcomp2020' into signals

main
Matthias Volk 5 years ago
parent
commit
679327ee9d
  1. 5
      CHANGELOG.md
  2. 4
      src/storm-cli-utilities/cli.cpp
  3. 123
      src/storm-cli-utilities/model-handling.h
  4. 8
      src/storm-dft-cli/storm-dft.cpp
  5. 4
      src/storm-dft/settings/DftSettings.cpp
  6. 10
      src/storm-dft/settings/modules/FaultTreeSettings.cpp
  7. 4
      src/storm-dft/settings/modules/FaultTreeSettings.h
  8. 4
      src/storm-pars-cli/storm-pars.cpp
  9. 4
      src/storm-pars/settings/ParsSettings.cpp
  10. 4
      src/storm-pomdp-cli/storm-pomdp.cpp
  11. 89
      src/storm/generator/PrismNextStateGenerator.cpp
  12. 3
      src/storm/generator/PrismNextStateGenerator.h
  13. 3
      src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp
  14. 4
      src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp
  15. 2
      src/storm/solver/NativeLinearEquationSolver.cpp
  16. 20
      src/storm/utility/Portfolio.cpp
  17. 9
      src/storm/utility/Portfolio.h

5
CHANGELOG.md

@ -15,6 +15,11 @@ Version 1.4.x
- Added option `--build:buildchoiceorig` to build a model (PRISM or JANI) with choice origins (which are exported with, e.g. `--exportscheduler`).
- Apply the maximum progress assumption while building a Markov automata with the Dd engine.
- Added option `--build:nomaxprog` to disable applying the maximum progress assumption during model building (for Markov Automata)
- Added hybrid engine for Markov Automata
- Implemented optimistic value iteration for sound computations and used it as a default
- Unif+ for time bounded properties on Markov automata now computes results with relative precision. Use `--absolute` for the previous behavior.
- Various performance improvements for model building with the sparse engine
- `storm-dft`: Symmetry reduction is now enabled by default and can be disabled via `--nosymmetryreduction`
- `storm-pomdp`: Only accept POMDPs that are canonical
- `storm-pomdp`: Prism language extended with observable expressions
- `storm-pomdp`: Various fixes that prevented usage.

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

@ -249,10 +249,10 @@ namespace storm {
SymbolicInput symbolicInput = parseSymbolicInput();
// Obtain settings for model processing
ModelProcessingInformation mpi = getModelProcessingInformation(symbolicInput);
ModelProcessingInformation mpi;
// Preprocess the symbolic input
symbolicInput = preprocessSymbolicInput(symbolicInput, mpi.engine);
std::tie(symbolicInput, mpi) = preprocessSymbolicInput(symbolicInput);
// Export symbolic input (if requested)
exportSymbolicInput(symbolicInput);

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

@ -156,6 +156,9 @@ namespace storm {
// If set, bisimulation will be applied.
bool applyBisimulation;
// If set, a transformation to Jani will be enforced
bool transformToJani;
// Which data type is to be used for numbers ...
enum class ValueType {
FinitePrecision,
@ -175,16 +178,17 @@ namespace storm {
void getModelProcessingInformationPortfolio(SymbolicInput const& input, ModelProcessingInformation& mpi) {
auto hints = storm::settings::getModule<storm::settings::modules::HintSettings>();
STORM_LOG_THROW(input.model.is_initialized(), storm::exceptions::InvalidArgumentException, "Portfolio engine requires a symbolic model (PRISM or JANI.");
STORM_LOG_THROW(input.model.is_initialized(), storm::exceptions::InvalidArgumentException, "Portfolio engine requires a JANI input model.");
STORM_LOG_THROW(input.model->isJaniModel(), storm::exceptions::InvalidArgumentException, "Portfolio engine requires a JANI input model.");
std::vector<storm::jani::Property> const& properties = input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties;
STORM_LOG_THROW(!properties.empty(), storm::exceptions::InvalidArgumentException, "Portfolio engine requires a property.");
STORM_LOG_WARN_COND(properties.size() == 1, "Portfolio engine does not support decisions based on multiple properties. Only the first property will be considered.");
storm::utility::Portfolio pf;
if (hints.isNumberStatesSet()) {
pf.predict(input.model.get(), properties.front(), hints.getNumberStates());
pf.predict(input.model->asJaniModel(), properties.front(), hints.getNumberStates());
} else {
pf.predict(input.model.get(), properties.front());
pf.predict(input.model->asJaniModel(), properties.front());
}
mpi.engine = pf.getEngine();
@ -194,11 +198,22 @@ namespace storm {
if (pf.enableExact() && mpi.verificationValueType == ModelProcessingInformation::ValueType::FinitePrecision) {
mpi.verificationValueType = ModelProcessingInformation::ValueType::Exact;
}
STORM_PRINT_AND_LOG( "Portfolio engine picked the following settings: " << std::endl << "\tengine=" << mpi.engine << "\t bisimulation=" << mpi.applyBisimulation << "\t exact=" << (mpi.verificationValueType != ModelProcessingInformation::ValueType::FinitePrecision) << std::endl)
STORM_PRINT_AND_LOG( "Portfolio engine picked the following settings: " << std::endl
<< "\tengine=" << mpi.engine
<< std::boolalpha
<< "\t bisimulation=" << mpi.applyBisimulation
<< "\t exact=" << (mpi.verificationValueType != ModelProcessingInformation::ValueType::FinitePrecision)
<< std::noboolalpha << std::endl);
}
ModelProcessingInformation getModelProcessingInformation(SymbolicInput const& input) {
/*!
* Sets the model processing information based on the given input.
* Finding the right model processing information might require a conversion to jani.
* In this case, the jani conversion is stored in the transformedJaniInput pointer (unless it is null)
*/
ModelProcessingInformation getModelProcessingInformation(SymbolicInput const& input, std::shared_ptr<SymbolicInput> const& transformedJaniInput = nullptr) {
ModelProcessingInformation mpi;
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
auto coreSettings = storm::settings::getModule<storm::settings::modules::CoreSettings>();
auto generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
auto bisimulationSettings = storm::settings::getModule<storm::settings::modules::BisimulationSettings>();
@ -219,10 +234,29 @@ namespace storm {
}
// Since the remaining settings could depend on the ones above, we need apply the portfolio engine now.
bool usePortfolio = mpi.engine == storm::utility::Engine::Portfolio;
bool usePortfolio = input.model.is_initialized() && mpi.engine == storm::utility::Engine::Portfolio;
if (usePortfolio) {
// This can potentially overwrite the settings above, but will not overwrite settings that were explicitly set by the user (e.g. we will not disable bisimulation or disable exact arithmetic)
getModelProcessingInformationPortfolio(input, mpi);
if (input.model->isJaniModel()) {
// This can potentially overwrite the settings above, but will not overwrite settings that were explicitly set by the user (e.g. we will not disable bisimulation or disable exact arithmetic)
getModelProcessingInformationPortfolio(input, mpi);
} else {
// Transform Prism to jani first
STORM_LOG_ASSERT(input.model->isPrismProgram(), "Unexpected type of input.");
SymbolicInput janiInput;
janiInput.properties = input.properties;
storm::prism::Program const& prog = input.model.get().asPrismProgram();
auto modelAndProperties = prog.toJani(input.preprocessedProperties.is_initialized() ? input.preprocessedProperties.get() : input.properties);
janiInput.model = modelAndProperties.first;
if (!modelAndProperties.second.empty()) {
janiInput.preprocessedProperties = std::move(modelAndProperties.second);
}
// This can potentially overwrite the settings above, but will not overwrite settings that were explicitly set by the user (e.g. we will not disable bisimulation or disable exact arithmetic)
getModelProcessingInformationPortfolio(janiInput, mpi);
if (transformedJaniInput) {
// We cache the transformation result.
*transformedJaniInput = std::move(janiInput);
}
}
}
// Check whether these settings are compatible with the provided input.
@ -250,8 +284,16 @@ namespace storm {
STORM_LOG_WARN("The model checking query does not seem to be supported for the selected engine. Storm will try to solve the query, but you will most likely get an error for at least one of the provided properties.");
}
}
// Set whether a transformation to jani is required or necessary
mpi.transformToJani = ioSettings.isPrismToJaniSet();
auto builderType = storm::utility::getBuilderType(mpi.engine);
bool transformToJaniForJit = builderType == storm::builder::BuilderType::Jit;
STORM_LOG_WARN_COND(mpi.transformToJani || !transformToJaniForJit, "The JIT-based model builder is only available for JANI models, automatically converting the PRISM input model.");
bool transformToJaniForDdMA = (builderType == storm::builder::BuilderType::Dd) && (input.model->getModelType() == storm::storage::SymbolicModelDescription::ModelType::MA);
STORM_LOG_WARN_COND(mpi.transformToJani || !transformToJaniForDdMA, "Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the PRISM input model.");
mpi.transformToJani |= (transformToJaniForJit || transformToJaniForDdMA);
// Set the Valuetype used during model building
mpi.buildValueType = mpi.verificationValueType;
if (bisimulationSettings.useExactArithmeticInDdBisimulation()) {
@ -289,17 +331,11 @@ namespace storm {
}
}
SymbolicInput preprocessSymbolicInput(SymbolicInput const& input, storm::utility::Engine const& engine) {
std::pair<SymbolicInput, ModelProcessingInformation> preprocessSymbolicInput(SymbolicInput const& input) {
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
auto builderType = storm::utility::getBuilderType(engine);
SymbolicInput output = input;
if (output.model && output.model.get().isJaniModel()) {
storm::jani::ModelFeatures supportedFeatures = storm::api::getSupportedJaniFeatures(builderType);
storm::api::simplifyJaniModel(output.model.get().asJaniModel(), output.properties, supportedFeatures);
}
// Substitute constant definitions in symbolic input.
std::string constantDefinitionString = ioSettings.getConstantDefinitionString();
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
@ -310,34 +346,37 @@ namespace storm {
if (!output.properties.empty()) {
output.properties = storm::api::substituteConstantsInProperties(output.properties, constantDefinitions);
}
ensureNoUndefinedPropertyConstants(output.properties);
auto transformedJani = std::make_shared<SymbolicInput>();
ModelProcessingInformation mpi = getModelProcessingInformation(output, transformedJani);
auto builderType = storm::utility::getBuilderType(mpi.engine);
// Check whether conversion for PRISM to JANI is requested or necessary.
if (input.model && input.model.get().isPrismProgram()) {
bool transformToJani = ioSettings.isPrismToJaniSet();
bool transformToJaniForJit = builderType == storm::builder::BuilderType::Jit;
STORM_LOG_WARN_COND(transformToJani || !transformToJaniForJit, "The JIT-based model builder is only available for JANI models, automatically converting the PRISM input model.");
bool transformToJaniForDdMA = (builderType == storm::builder::BuilderType::Dd) && (input.model->getModelType() == storm::storage::SymbolicModelDescription::ModelType::MA);
STORM_LOG_WARN_COND(transformToJani || !transformToJaniForDdMA, "Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the PRISM input model.");
transformToJani |= (transformToJaniForJit || transformToJaniForDdMA);
if (transformToJani) {
storm::prism::Program const& model = output.model.get().asPrismProgram();
auto modelAndProperties = model.toJani(output.properties);
// Remove functions here
modelAndProperties.first.substituteFunctions();
output.model = modelAndProperties.first;
if (!modelAndProperties.second.empty()) {
output.preprocessedProperties = std::move(modelAndProperties.second);
if (output.model && output.model.get().isPrismProgram()) {
if (mpi.transformToJani) {
if (transformedJani->model) {
// Use the cached transformation if possible
output = std::move(*transformedJani);
} else {
storm::prism::Program const& model = output.model.get().asPrismProgram();
auto modelAndProperties = model.toJani(output.properties);
output.model = modelAndProperties.first;
if (!modelAndProperties.second.empty()) {
output.preprocessedProperties = std::move(modelAndProperties.second);
}
}
}
}
return output;
if (output.model && output.model.get().isJaniModel()) {
storm::jani::ModelFeatures supportedFeatures = storm::api::getSupportedJaniFeatures(builderType);
storm::api::simplifyJaniModel(output.model.get().asJaniModel(), output.properties, supportedFeatures);
}
return {output, mpi};
}
void exportSymbolicInput(SymbolicInput const& input) {
@ -350,16 +389,6 @@ namespace storm {
}
}
SymbolicInput parseAndPreprocessSymbolicInput(storm::utility::Engine const& engine) {
// Get the used builder type to handle cases where preprocessing depends on it
auto buildSettings = storm::settings::getModule<storm::settings::modules::BuildSettings>();
SymbolicInput input = parseSymbolicInput();
input = preprocessSymbolicInput(input, engine);
exportSymbolicInput(input);
return input;
}
std::vector<std::shared_ptr<storm::logic::Formula const>> createFormulasToRespect(std::vector<storm::jani::Property> const& properties) {
std::vector<std::shared_ptr<storm::logic::Formula const>> result = storm::api::extractFormulasFromProperties(properties);

8
src/storm-dft-cli/storm-dft.cpp

@ -21,8 +21,6 @@
*/
template<typename ValueType>
void processOptions() {
// Start by setting some urgent options (log levels, resources, etc.)
storm::cli::setUrgentOptions();
auto const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>();
auto const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>();
@ -265,10 +263,16 @@ int main(const int argc, const char** argv) {
if (!storm::cli::parseOptions(argc, argv)) {
return -1;
}
// Start by setting some urgent options (log levels, resources, etc.)
storm::cli::setUrgentOptions();
storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule<storm::settings::modules::GeneralSettings>();
if (generalSettings.isParametricSet()) {
processOptions<storm::RationalFunction>();
} else if (generalSettings.isExactSet()) {
STORM_LOG_WARN("Exact solving over rational numbers is not implemented. Performing exact solving using rational functions instead.");
processOptions<storm::RationalFunction>();
} else {
processOptions<double>();
}

4
src/storm-dft/settings/DftSettings.cpp

@ -25,6 +25,8 @@
#include "storm-gspn/settings/modules/GSPNExportSettings.h"
#include "storm/settings/modules/TransformationSettings.h"
#include "storm/settings/modules/HintSettings.h"
#include "storm/settings/modules/OviSolverSettings.h"
#include "storm/settings/modules/TimeBoundedSolverSettings.h"
namespace storm {
@ -51,6 +53,8 @@ namespace storm {
storm::settings::addModule<storm::settings::modules::EliminationSettings>();
storm::settings::addModule<storm::settings::modules::MinMaxEquationSolverSettings>();
storm::settings::addModule<storm::settings::modules::MultiplierSettings>();
storm::settings::addModule<storm::settings::modules::OviSolverSettings>();
storm::settings::addModule<storm::settings::modules::TimeBoundedSolverSettings>();
storm::settings::addModule<storm::settings::modules::GameSolverSettings>(false);
// storm::settings::addModule<storm::settings::modules::BisimulationSettings>();
storm::settings::addModule<storm::settings::modules::ResourceSettings>();

10
src/storm-dft/settings/modules/FaultTreeSettings.cpp

@ -15,8 +15,8 @@ namespace storm {
namespace modules {
const std::string FaultTreeSettings::moduleName = "dft";
const std::string FaultTreeSettings::symmetryReductionOptionName = "symmetryreduction";
const std::string FaultTreeSettings::symmetryReductionOptionShortName = "symred";
const std::string FaultTreeSettings::noSymmetryReductionOptionName = "nosymmetryreduction";
const std::string FaultTreeSettings::noSymmetryReductionOptionShortName = "nosymred";
const std::string FaultTreeSettings::modularisationOptionName = "modularisation";
const std::string FaultTreeSettings::disableDCOptionName = "disabledc";
const std::string FaultTreeSettings::allowDCRelevantOptionName = "allowdcrelevant";
@ -32,8 +32,8 @@ namespace storm {
#endif
FaultTreeSettings::FaultTreeSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, symmetryReductionOptionName, false, "Exploit symmetric structure of model.").setShortName(
symmetryReductionOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, noSymmetryReductionOptionName, false, "Do not exploit symmetric structure of model.").setShortName(
noSymmetryReductionOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, modularisationOptionName, false, "Use modularisation (not applicable for expected time).").build());
this->addOption(storm::settings::OptionBuilder(moduleName, disableDCOptionName, false, "Disable Don't Care propagation.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, firstDependencyOptionName, false,
@ -62,7 +62,7 @@ namespace storm {
}
bool FaultTreeSettings::useSymmetryReduction() const {
return this->getOption(symmetryReductionOptionName).getHasOptionBeenSet();
return !this->getOption(noSymmetryReductionOptionName).getHasOptionBeenSet();
}
bool FaultTreeSettings::useModularisation() const {

4
src/storm-dft/settings/modules/FaultTreeSettings.h

@ -130,8 +130,8 @@ namespace storm {
private:
// Define the string names of the options as constants.
static const std::string symmetryReductionOptionName;
static const std::string symmetryReductionOptionShortName;
static const std::string noSymmetryReductionOptionName;
static const std::string noSymmetryReductionOptionShortName;
static const std::string modularisationOptionName;
static const std::string disableDCOptionName;
static const std::string allowDCRelevantOptionName;

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

@ -783,8 +783,8 @@ namespace storm {
// Parse and preprocess symbolic input (PRISM, JANI, properties, etc.)
auto symbolicInput = storm::cli::parseSymbolicInput();
auto mpi = storm::cli::getModelProcessingInformation(symbolicInput);
symbolicInput = storm::cli::preprocessSymbolicInput(symbolicInput, mpi.engine);
storm::cli::ModelProcessingInformation mpi;
std::tie(symbolicInput, mpi) = storm::cli::preprocessSymbolicInput(symbolicInput);
processInputWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalFunction>(symbolicInput, mpi);
}

4
src/storm-pars/settings/ParsSettings.cpp

@ -27,6 +27,8 @@
#include "storm/settings/modules/MultiplierSettings.h"
#include "storm/settings/modules/TransformationSettings.h"
#include "storm/settings/modules/HintSettings.h"
#include "storm/settings/modules/OviSolverSettings.h"
#include "storm/settings/modules/TimeBoundedSolverSettings.h"
@ -59,6 +61,8 @@ namespace storm {
storm::settings::addModule<storm::settings::modules::JitBuilderSettings>();
storm::settings::addModule<storm::settings::modules::MultiplierSettings>();
storm::settings::addModule<storm::settings::modules::TransformationSettings>();
storm::settings::addModule<storm::settings::modules::OviSolverSettings>();
storm::settings::addModule<storm::settings::modules::TimeBoundedSolverSettings>();
storm::settings::addModule<storm::settings::modules::HintSettings>();
}

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

@ -98,8 +98,8 @@ int main(const int argc, const char** argv) {
auto const& pomdpSettings = storm::settings::getModule<storm::settings::modules::POMDPSettings>();
auto symbolicInput = storm::cli::parseSymbolicInput();
auto mpi = storm::cli::getModelProcessingInformation(symbolicInput);
symbolicInput = storm::cli::preprocessSymbolicInput(symbolicInput, mpi.engine);
storm::cli::ModelProcessingInformation mpi;
std::tie(symbolicInput, mpi) = storm::cli::preprocessSymbolicInput(symbolicInput);
// We should not export here if we are going to do some processing first.
auto model = storm::cli::buildPreprocessExportModelWithValueTypeAndDdlib<storm::dd::DdType::Sylvan, storm::RationalNumber>(symbolicInput, mpi);

89
src/storm/generator/PrismNextStateGenerator.cpp

@ -288,22 +288,18 @@ namespace storm {
result.setExpanded();
std::vector<Choice<ValueType>> allChoices;
std::vector<Choice<ValueType>> allLabeledChoices;
if (this->getOptions().isApplyMaximalProgressAssumptionSet()) {
// First explore only edges without a rate
allChoices = getUnlabeledChoices(*this->state, stateToIdCallback, CommandFilter::Probabilistic);
allLabeledChoices = getLabeledChoices(*this->state, stateToIdCallback, CommandFilter::Probabilistic);
if (allChoices.empty() && allLabeledChoices.empty()) {
addLabeledChoices(allChoices, *this->state, stateToIdCallback, CommandFilter::Probabilistic);
if (allChoices.empty()) {
// Expand the Markovian edges if there are no probabilistic ones.
allChoices = getUnlabeledChoices(*this->state, stateToIdCallback, CommandFilter::Markovian);
allLabeledChoices = getLabeledChoices(*this->state, stateToIdCallback, CommandFilter::Markovian);
addLabeledChoices(allChoices, *this->state, stateToIdCallback, CommandFilter::Markovian);
}
} else {
allChoices = getUnlabeledChoices(*this->state, stateToIdCallback);
allLabeledChoices = getLabeledChoices(*this->state, stateToIdCallback);
}
for (auto& choice : allLabeledChoices) {
allChoices.push_back(std::move(choice));
addLabeledChoices(allChoices, *this->state, stateToIdCallback);
}
std::size_t totalNumberOfChoices = allChoices.size();
@ -428,11 +424,25 @@ namespace storm {
return newState;
}
struct ActiveCommandData {
ActiveCommandData(storm::prism::Module const* modulePtr, std::set<uint_fast64_t> const* commandIndicesPtr, typename std::set<uint_fast64_t>::const_iterator currentCommandIndexIt) : modulePtr(modulePtr), commandIndicesPtr(commandIndicesPtr), currentCommandIndexIt(currentCommandIndexIt) {
// Intentionally left empty
}
storm::prism::Module const* modulePtr;
std::set<uint_fast64_t> const* commandIndicesPtr;
typename std::set<uint_fast64_t>::const_iterator currentCommandIndexIt;
};
template<typename ValueType, typename StateType>
boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> PrismNextStateGenerator<ValueType, StateType>::getActiveCommandsByActionIndex(uint_fast64_t const& actionIndex, CommandFilter const& commandFilter) {
boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> result((std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>()));
// First check whether there is at least one enabled command at each module
// This avoids evaluating unnecessarily many guards.
// If we find one module without an enabled command, we return boost::none.
// At the same time, we store pointers to the relevant modules, the relevant command sets and the first enabled command within each set.
// Iterate over all modules.
std::vector<ActiveCommandData> activeCommands;
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
storm::prism::Module const& module = program.getModule(i);
@ -446,14 +456,47 @@ namespace storm {
// If the module contains the action, but there is no command in the module that is labeled with
// this action, we don't have any feasible command combinations.
if (commandIndices.empty()) {
return boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>>();
return boost::none;
}
// Look up commands by their indices and check if the guard evaluates to true in the given state.
bool hasOneEnabledCommand = false;
for (auto commandIndexIt = commandIndices.begin(), commandIndexIte = commandIndices.end(); commandIndexIt != commandIndexIte; ++commandIndexIt) {
storm::prism::Command const& command = module.getCommand(*commandIndexIt);
if (commandFilter != CommandFilter::All) {
STORM_LOG_ASSERT(commandFilter == CommandFilter::Markovian || commandFilter == CommandFilter::Probabilistic, "Unexpected command filter.");
if ((commandFilter == CommandFilter::Markovian) != command.isMarkovian()) {
continue;
}
}
if (this->evaluator->asBool(command.getGuardExpression())) {
// Found the first enabled command for this module.
hasOneEnabledCommand = true;
activeCommands.emplace_back(&module, &commandIndices, commandIndexIt);
break;
}
}
if (!hasOneEnabledCommand) {
return boost::none;
}
}
// If we reach this point, there has to be at least one active command for each relevant module.
std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>> result;
// Iterate over all command sets.
for (auto const& activeCommand : activeCommands) {
std::vector<std::reference_wrapper<storm::prism::Command const>> commands;
auto commandIndexIt = activeCommand.currentCommandIndexIt;
// The command at the current position is already known to be enabled
commands.push_back(activeCommand.modulePtr->getCommand(*commandIndexIt));
// Look up commands by their indices and add them if the guard evaluates to true in the given state.
for (uint_fast64_t commandIndex : commandIndices) {
storm::prism::Command const& command = module.getCommand(commandIndex);
auto commandIndexIte = activeCommand.commandIndicesPtr->end();
for (++commandIndexIt; commandIndexIt != commandIndexIte; ++commandIndexIt) {
storm::prism::Command const& command = activeCommand.modulePtr->getCommand(*commandIndexIt);
if (commandFilter != CommandFilter::All) {
STORM_LOG_ASSERT(commandFilter == CommandFilter::Markovian || commandFilter == CommandFilter::Probabilistic, "Unexpected command filter.");
if ((commandFilter == CommandFilter::Markovian) != command.isMarkovian()) {
@ -465,16 +508,10 @@ namespace storm {
}
}
// If there was no enabled command although the module has some command with the required action label,
// we must not return anything.
if (commands.size() == 0) {
return boost::none;
}
result.get().push_back(std::move(commands));
result.push_back(std::move(commands));
}
STORM_LOG_ASSERT(!result->empty(), "Expected non-empty list.");
STORM_LOG_ASSERT(!result.empty(), "Expected non-empty list.");
return result;
}
@ -576,8 +613,7 @@ namespace storm {
}
template<typename ValueType, typename StateType>
std::vector<Choice<ValueType>> PrismNextStateGenerator<ValueType, StateType>::getLabeledChoices(CompressedState const& state, StateToIdCallback stateToIdCallback, CommandFilter const& commandFilter) {
std::vector<Choice<ValueType>> result;
void PrismNextStateGenerator<ValueType, StateType>::addLabeledChoices(std::vector<Choice<ValueType>>& choices, CompressedState const& state, StateToIdCallback stateToIdCallback, CommandFilter const& commandFilter) {
for (uint_fast64_t actionIndex : program.getSynchronizingActionIndices()) {
boost::optional<std::vector<std::vector<std::reference_wrapper<storm::prism::Command const>>>> optionalActiveCommandLists = getActiveCommandsByActionIndex(actionIndex, commandFilter);
@ -604,10 +640,10 @@ namespace storm {
// At this point, we applied all commands of the current command combination and newTargetStates
// contains all target states and their respective probabilities. That means we are now ready to
// add the choice to the list of transitions.
result.push_back(Choice<ValueType>(actionIndex));
choices.push_back(Choice<ValueType>(actionIndex));
// Now create the actual distribution.
Choice<ValueType>& choice = result.back();
Choice<ValueType>& choice = choices.back();
// Remember the choice label and origins only if we were asked to.
if (this->options.isBuildChoiceLabelsSet()) {
@ -623,6 +659,7 @@ namespace storm {
// Add the probabilities/rates to the newly created choice.
ValueType probabilitySum = storm::utility::zero<ValueType>();
choice.reserve(std::distance(distribution.begin(), distribution.end()));
for (auto const& stateProbability : distribution) {
choice.addProbability(stateProbability.getState(), stateProbability.getValue());
if (this->options.isExplorationChecksSet()) {
@ -664,8 +701,6 @@ namespace storm {
}
}
}
return result;
}
template<typename ValueType, typename StateType>

3
src/storm/generator/PrismNextStateGenerator.h

@ -95,10 +95,11 @@ namespace storm {
/*!
* Retrieves all labeled choices possible from the given state.
*
* @param choices The new choices are inserted in this vector
* @param state The state for which to retrieve the unlabeled choices.
* @return The labeled choices of the state.
*/
std::vector<Choice<ValueType>> getLabeledChoices(CompressedState const& state, StateToIdCallback stateToIdCallback, CommandFilter const& commandFilter = CommandFilter::All);
void addLabeledChoices(std::vector<Choice<ValueType>>& choices, CompressedState const& state, StateToIdCallback stateToIdCallback, CommandFilter const& commandFilter = CommandFilter::All);
/*!

3
src/storm/modelchecker/csl/helper/SparseCtmcCslHelper.cpp

@ -16,6 +16,7 @@
#include "storm/adapters/RationalFunctionAdapter.h"
#include "storm/environment/solver/LongRunAverageSolverEnvironment.h"
#include "storm/environment/solver/TopologicalSolverEnvironment.h"
#include "storm/environment/solver/TimeBoundedSolverEnvironment.h"
#include "storm/utility/macros.h"
#include "storm/utility/vector.h"
@ -1028,7 +1029,7 @@ namespace storm {
// Use Fox-Glynn to get the truncation points and the weights.
// std::tuple<uint_fast64_t, uint_fast64_t, ValueType, std::vector<ValueType>> foxGlynnResult = storm::utility::numerical::getFoxGlynnCutoff(lambda, 1e+300, storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision() / 8.0);
storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda, storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision() / 8.0);
storm::utility::numerical::FoxGlynnResult<ValueType> foxGlynnResult = storm::utility::numerical::foxGlynn(lambda, storm::utility::convertNumber<ValueType>(env.solver().timeBounded().getPrecision()) / 8.0);
STORM_LOG_DEBUG("Fox-Glynn cutoff points: left=" << foxGlynnResult.left << ", right=" << foxGlynnResult.right);
// Scale the weights so they add up to one.

4
src/storm/solver/IterativeMinMaxLinearEquationSolver.cpp

@ -50,8 +50,8 @@ namespace storm {
}
} else if (env.solver().isForceSoundness() && method != MinMaxMethod::SoundValueIteration && method != MinMaxMethod::IntervalIteration && method != MinMaxMethod::PolicyIteration && method != MinMaxMethod::RationalSearch && method != MinMaxMethod::OptimisticValueIteration) {
if (env.solver().minMax().isMethodSetFromDefault()) {
STORM_LOG_INFO("Selecting 'sound value iteration' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method.");
method = MinMaxMethod::SoundValueIteration;
method = MinMaxMethod::OptimisticValueIteration;
STORM_LOG_INFO("Selecting '" << toString(method) << "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method.");
} else {
STORM_LOG_WARN("The selected solution method does not guarantee sound results.");
}

2
src/storm/solver/NativeLinearEquationSolver.cpp

@ -987,7 +987,7 @@ namespace storm {
}
} else if (env.solver().isForceSoundness() && method != NativeLinearEquationSolverMethod::SoundValueIteration && method != NativeLinearEquationSolverMethod::OptimisticValueIteration && method != NativeLinearEquationSolverMethod::IntervalIteration && method != NativeLinearEquationSolverMethod::RationalSearch) {
if (env.solver().native().isMethodSetFromDefault()) {
method = NativeLinearEquationSolverMethod::SoundValueIteration;
method = NativeLinearEquationSolverMethod::OptimisticValueIteration;
STORM_LOG_INFO("Selecting '" + toString(method) + "' as the solution technique to guarantee sound results. If you want to override this, please explicitly specify a different method.");
} else {
STORM_LOG_WARN("The selected solution method does not guarantee sound results.");

20
src/storm/utility/Portfolio.cpp

@ -34,15 +34,7 @@ namespace storm {
}
struct Features {
Features(storm::storage::SymbolicModelDescription const& modelDescription, storm::jani::Property const& property) {
if (!modelDescription.isJaniModel()) {
initialize(modelDescription.toJani().asJaniModel(), property);
} else {
initialize(modelDescription.asJaniModel(), property);
}
}
void initialize(storm::jani::Model const& model, storm::jani::Property const& property) {
Features(storm::jani::Model const& model, storm::jani::Property const& property) {
continuousTime = !model.isDiscreteTimeModel();
nondeterminism = !model.isDeterministicModel();
propertyType = getPropertyType(property);
@ -65,9 +57,9 @@ namespace storm {
// Intentionally left empty
}
void Portfolio::predict(storm::storage::SymbolicModelDescription const& modelDescription, storm::jani::Property const& property) {
void Portfolio::predict(storm::jani::Model const& model, storm::jani::Property const& property) {
typedef pfinternal::PropertyType PropertyType;
auto f = pfinternal::Features(modelDescription, property);
auto f = pfinternal::Features(model, property);
{ // Decision tree start
if (f.numEdges <= 618) {
@ -171,12 +163,12 @@ namespace storm {
}
void Portfolio::predict(storm::storage::SymbolicModelDescription const& modelDescription, storm::jani::Property const& property, uint64_t stateEstimate) {
void Portfolio::predict(storm::jani::Model const& model, storm::jani::Property const& property, uint64_t stateEstimate) {
typedef pfinternal::PropertyType PropertyType;
auto f = pfinternal::Features(modelDescription, property);
auto f = pfinternal::Features(model, property);
f.stateEstimate = stateEstimate;
// TODO: Actually make use of the estimate
predict(modelDescription, property);
predict(model, property);
}
storm::utility::Engine Portfolio::getEngine() const {

9
src/storm/utility/Portfolio.h

@ -5,13 +5,10 @@
namespace storm {
namespace jani {
class Model;
class Property;
}
namespace storage {
class SymbolicModelDescription;
}
namespace utility {
class Portfolio {
public:
@ -20,13 +17,13 @@ namespace storm {
/*!
* Predicts "good" settings for the provided model checking query
*/
void predict(storm::storage::SymbolicModelDescription const& modelDescription, storm::jani::Property const& property);
void predict(storm::jani::Model const& model, storm::jani::Property const& property);
/*!
* Predicts "good" settings for the provided model checking query
* @param stateEstimate A hint that gives a (rough) estimate for the number of states.
*/
void predict(storm::storage::SymbolicModelDescription const& modelDescription, storm::jani::Property const& property, uint64_t stateEstimate);
void predict(storm::jani::Model const& model, storm::jani::Property const& property, uint64_t stateEstimate);
/// Retrieve "good" settings after calling predict.
storm::utility::Engine getEngine() const;

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