diff --git a/src/adapters/ExplicitModelAdapter.h b/src/adapters/ExplicitModelAdapter.h index 7befe5ee8..6fbb8cb00 100644 --- a/src/adapters/ExplicitModelAdapter.h +++ b/src/adapters/ExplicitModelAdapter.h @@ -312,7 +312,7 @@ namespace storm { } // Check that the resulting distribution is in fact a distribution. - LOG_THROW(std::abs(1 - probabilitySum) < storm::settings::SettingsManager::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble(), storm::exceptions::WrongFormatException, "Probabilities do not sum to one for command '" << command << "'."); + LOG_THROW(std::abs(1 - probabilitySum) < storm::settings::generalSettings().getPrecision(), storm::exceptions::WrongFormatException, "Probabilities do not sum to one for command '" << command << "'."); } } @@ -418,7 +418,7 @@ namespace storm { } // Check that the resulting distribution is in fact a distribution. - if (std::abs(1 - probabilitySum) > storm::settings::SettingsManager::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) { + if (std::abs(1 - probabilitySum) > storm::settings::generalSettings().getPrecision()) { LOG4CPLUS_ERROR(logger, "Sum of update probabilities do not some to one for some command."); throw storm::exceptions::WrongFormatException() << "Sum of update probabilities do not some to one for some command."; } @@ -502,7 +502,7 @@ namespace storm { // If the current state does not have a single choice, we equip it with a self-loop if that was // requested and issue an error otherwise. if (totalNumberOfChoices == 0) { - if (storm::settings::SettingsManager::getInstance()->isSet("fixDeadlocks")) { + if (storm::settings::generalSettings().isFixDeadlocksSet()) { // Insert empty choice labeling for added self-loop transitions. choiceLabels.push_back(boost::container::flat_set<uint_fast64_t>()); transitionMatrixBuilder.addNextValue(currentRow, currentState, storm::utility::constantOne<ValueType>()); diff --git a/src/counterexamples/MILPMinimalLabelSetGenerator.h b/src/counterexamples/MILPMinimalLabelSetGenerator.h index 5f999b06e..04face217 100644 --- a/src/counterexamples/MILPMinimalLabelSetGenerator.h +++ b/src/counterexamples/MILPMinimalLabelSetGenerator.h @@ -1025,7 +1025,7 @@ namespace storm { // Delegate the actual computation work to the function of equal name. auto startTime = std::chrono::high_resolution_clock::now(); - boost::container::flat_set<uint_fast64_t> usedLabelSet = getMinimalLabelSet(labeledMdp, phiStates, psiStates, bound, strictBound, true, storm::settings::SettingsManager::getInstance()->isSet("schedcuts")); + boost::container::flat_set<uint_fast64_t> usedLabelSet = getMinimalLabelSet(labeledMdp, phiStates, psiStates, bound, strictBound, true, storm::settings::counterexampleGeneratorSettings().useSchedulerCuts()); auto endTime = std::chrono::high_resolution_clock::now(); std::cout << std::endl << "Computed minimal label set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl; diff --git a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h index 345d9d721..b927b6203 100644 --- a/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h +++ b/src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h @@ -235,7 +235,7 @@ namespace storm { // (1) Compute the accuracy we need to achieve the required error bound. ValueType maxExitRate = this->getModel().getMaximalExitRate(); - ValueType delta = (2 * storm::settings::SettingsManager::getInstance()->getOptionByLongName("digiprecision").getArgument(0).getValueAsDouble()) / (upperBound * maxExitRate * maxExitRate); + ValueType delta = (2 * storm::settings::generalSettings().getPrecision()) / (upperBound * maxExitRate * maxExitRate); // (2) Compute the number of steps we need to make for the interval. uint_fast64_t numberOfSteps = static_cast<uint_fast64_t>(std::ceil((upperBound - lowerBound) / delta)); diff --git a/src/modelchecker/prctl/CreatePrctlModelChecker.h b/src/modelchecker/prctl/CreatePrctlModelChecker.h index d07261ebc..f31fb246a 100644 --- a/src/modelchecker/prctl/CreatePrctlModelChecker.h +++ b/src/modelchecker/prctl/CreatePrctlModelChecker.h @@ -13,20 +13,8 @@ * @param dtmc A reference to the DTMC for which the model checker is to be created. * @return A pointer to the resulting model checker. */ -storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Dtmc<double> const & dtmc) { - // Create the appropriate model checker. - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - std::string const& linsolver = s->getOptionByLongName("linsolver").getArgument(0).getValueAsString(); - if (linsolver == "gmm++") { - return new storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double>(dtmc, new storm::solver::GmmxxLinearEquationSolver<double>()); - } else if (linsolver == "native") { - return new storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double>(dtmc, new storm::solver::NativeLinearEquationSolver<double>()); - } - - // The control flow should never reach this point, as there is a default setting for matrixlib. - std::string message = "No matrix library suitable for DTMC model checking has been set."; - throw storm::exceptions::InvalidSettingsException() << message; - return nullptr; +storm::modelchecker::prctl::AbstractModelChecker<double>* createPrctlModelChecker(storm::models::Dtmc<double> const& dtmc) { + return new storm::modelchecker::prctl::SparseDtmcPrctlModelChecker<double>(dtmc); } /*! diff --git a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h index 40cec5558..a6fb9dd39 100644 --- a/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h +++ b/src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h @@ -11,6 +11,7 @@ #include "src/modelchecker/prctl/AbstractModelChecker.h" #include "src/models/Dtmc.h" #include "src/solver/LinearEquationSolver.h" +#include "src/utility/solver.h" #include "src/utility/vector.h" #include "src/utility/graph.h" @@ -33,10 +34,14 @@ public: * * @param model The DTMC to be checked. */ - explicit SparseDtmcPrctlModelChecker(storm::models::Dtmc<Type> const& model, storm::solver::LinearEquationSolver<Type>* linearEquationSolver) : AbstractModelChecker<Type>(model), linearEquationSolver(linearEquationSolver) { + explicit SparseDtmcPrctlModelChecker(storm::models::Dtmc<Type> const& model, std::unique_ptr<storm::solver::LinearEquationSolver<Type>>&& linearEquationSolver) : AbstractModelChecker<Type>(model), linearEquationSolver(std::move(linearEquationSolver)) { // Intentionally left empty. } + explicit SparseDtmcPrctlModelChecker(storm::models::Dtmc<Type> const& model) : AbstractModelChecker<Type>(model), linearEquationSolver(storm::utility::solver::getLinearEquationSolver<Type>()) { + // Intentionally left empty. + } + /*! * Copy constructs a SparseDtmcPrctlModelChecker from the given model checker. In particular, this means that the newly * constructed model checker will have the model of the given model checker as its associated model. diff --git a/src/models/Ctmdp.h b/src/models/Ctmdp.h index c29c16b8c..103e3d264 100644 --- a/src/models/Ctmdp.h +++ b/src/models/Ctmdp.h @@ -126,9 +126,7 @@ private: * Checks probability matrix if all rows sum up to one. */ bool checkValidityOfProbabilityMatrix() { - // Get the settings object to customize linear solving. - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - double precision = s->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); + double precision = storm::settings::generalSettings().getPrecision(); for (uint_fast64_t row = 0; row < this->getTransitionMatrix().getRowCount(); row++) { T sum = this->getTransitionMatrix().getRowSum(row); if (sum == 0) continue; diff --git a/src/models/Dtmc.h b/src/models/Dtmc.h index ec625b6d8..0252b7533 100644 --- a/src/models/Dtmc.h +++ b/src/models/Dtmc.h @@ -297,9 +297,7 @@ private: * Checks probability matrix if all rows sum up to one. */ bool checkValidityOfProbabilityMatrix() { - // Get the settings object to customize linear solving. - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - double precision = s->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); + double precision = storm::settings::generalSettings().getPrecision(); if (this->getTransitionMatrix().getRowCount() != this->getTransitionMatrix().getColumnCount()) { // not square diff --git a/src/models/Mdp.h b/src/models/Mdp.h index b647f6813..53d7cc192 100644 --- a/src/models/Mdp.h +++ b/src/models/Mdp.h @@ -197,9 +197,7 @@ private: * Checks probability matrix if all rows sum up to one. */ bool checkValidityOfProbabilityMatrix() { - // Get the settings object to customize linear solving. - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - double precision = s->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); + double precision = storm::settings::generalSettings().getPrecision(); for (uint_fast64_t row = 0; row < this->getTransitionMatrix().getRowCount(); row++) { T sum = this->getTransitionMatrix().getRowSum(row); diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp index 165f8d8f2..43c26f8fb 100644 --- a/src/parser/DeterministicSparseTransitionParser.cpp +++ b/src/parser/DeterministicSparseTransitionParser.cpp @@ -93,7 +93,7 @@ namespace storm { uint_fast64_t row, col, lastRow = 0; double val; - bool fixDeadlocks = storm::settings::SettingsManager::getInstance()->isSet("fixDeadlocks"); + bool fixDeadlocks = storm::settings::generalSettings().isFixDeadlocksSet(); bool hadDeadlocks = false; bool rowHadDiagonalEntry = false; diff --git a/src/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/parser/MarkovAutomatonSparseTransitionParser.cpp index 7e235827c..e001d2b1d 100644 --- a/src/parser/MarkovAutomatonSparseTransitionParser.cpp +++ b/src/parser/MarkovAutomatonSparseTransitionParser.cpp @@ -15,7 +15,7 @@ namespace storm { MarkovAutomatonSparseTransitionParser::FirstPassResult MarkovAutomatonSparseTransitionParser::firstPass(char const* buf) { MarkovAutomatonSparseTransitionParser::FirstPassResult result; - bool fixDeadlocks = storm::settings::SettingsManager::getInstance()->isSet("fixDeadlocks"); + bool fixDeadlocks = storm::settings::generalSettings().isFixDeadlocksSet(); // Skip the format hint if it is there. buf = trimWhitespaces(buf); @@ -157,7 +157,7 @@ namespace storm { MarkovAutomatonSparseTransitionParser::Result MarkovAutomatonSparseTransitionParser::secondPass(char const* buf, FirstPassResult const& firstPassResult) { Result result(firstPassResult); - bool fixDeadlocks = storm::settings::SettingsManager::getInstance()->isSet("fixDeadlocks"); + bool fixDeadlocks = storm::settings::generalSettings().isFixDeadlocksSet(); // Skip the format hint if it is there. buf = trimWhitespaces(buf); diff --git a/src/parser/NondeterministicSparseTransitionParser.cpp b/src/parser/NondeterministicSparseTransitionParser.cpp index 01f3281cd..971f7cdfe 100644 --- a/src/parser/NondeterministicSparseTransitionParser.cpp +++ b/src/parser/NondeterministicSparseTransitionParser.cpp @@ -100,7 +100,7 @@ namespace storm { // Initialize variables for the parsing run. uint_fast64_t source = 0, target = 0, lastSource = 0, choice = 0, lastChoice = 0, curRow = 0; double val = 0.0; - bool fixDeadlocks = storm::settings::SettingsManager::getInstance()->isSet("fixDeadlocks"); + bool fixDeadlocks = storm::settings::generalSettings().isFixDeadlocksSet(); bool hadDeadlocks = false; // The first state already starts a new row group of the matrix. diff --git a/src/settings/Argument.cpp b/src/settings/Argument.cpp deleted file mode 100644 index 047dc13e9..000000000 --- a/src/settings/Argument.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "src/settings/Argument.h" - -namespace storm { - namespace settings { - const std::string Argument::trueString = "true"; - const std::string Argument::falseString = "false"; - } -} \ No newline at end of file diff --git a/src/settings/Argument.h b/src/settings/Argument.h index c756ff5d8..e93ce0c84 100644 --- a/src/settings/Argument.h +++ b/src/settings/Argument.h @@ -127,9 +127,9 @@ namespace storm { case ArgumentType::Boolean: { bool iValue = ArgumentTypeInferation::inferToBoolean(ArgumentType::Boolean, this->getArgumentValue()); if (iValue) { - return trueString; + return "true"; } else { - return falseString; + return "false"; } } default: return ArgumentBase::convertToString(this->argumentValue); @@ -190,10 +190,6 @@ namespace storm { // A flag indicating whether a default value has been provided. bool hasDefaultValue; - // Static constants for the string representations of true and false. - static const std::string trueString; - static const std::string falseString; - void setDefaultValue(T const& newDefault) { LOG_THROW(this->validate(newDefault), storm::exceptions::IllegalArgumentValueException, "The default value for the argument did not pass all validation functions."); this->defaultValue = newDefault; diff --git a/src/settings/Option.h b/src/settings/Option.h index 689c11191..0876b8741 100644 --- a/src/settings/Option.h +++ b/src/settings/Option.h @@ -21,16 +21,20 @@ namespace storm { namespace settings { - // Forward-declare settings manager class. + // Forward-declare settings manager and module settings classes. class SettingsManager; + namespace modules { + class ModuleSettings; + } /*! * This class represents one command-line option. */ class Option { public: - // Declare settings manager class as friend. + // Declare settings manager and module settings classes as friends. friend class SettingsManager; + friend class modules::ModuleSettings; /*! * Creates an option with the given parameters. diff --git a/src/settings/SettingMemento.cpp b/src/settings/SettingMemento.cpp index 5a1a55390..3f031b34a 100644 --- a/src/settings/SettingMemento.cpp +++ b/src/settings/SettingMemento.cpp @@ -1,17 +1,17 @@ -#include "src/settings/SettingsMemento.h" +#include "src/settings/SettingMemento.h" #include "src/settings/modules/ModuleSettings.h" namespace storm { namespace settings { - SettingMemento::SettingMemento(ModuleSettings& settings, std::string const& longOptionName, bool resetToState) : settings(settings), optionName(longOptionName), resetToState(resetToState) { + SettingMemento::SettingMemento(modules::ModuleSettings& settings, std::string const& longOptionName, bool resetToState) : settings(settings), optionName(longOptionName), resetToState(resetToState) { // Intentionally left empty. } /*! * Destructs the memento object and resets the value of the option to its original state. */ - virtual SettingMemento::~SettingMemento() { + SettingMemento::~SettingMemento() { if (resetToState) { settings.set(optionName); } else { diff --git a/src/settings/SettingMemento.h b/src/settings/SettingMemento.h index 342cdd666..551142fd2 100644 --- a/src/settings/SettingMemento.h +++ b/src/settings/SettingMemento.h @@ -6,7 +6,10 @@ namespace storm { namespace settings { - class ModuleSettings; + // Forward-declare the module settings. + namespace modules { + class ModuleSettings; + } /*! * This class is used to reset the state of an option that was temporarily set to a different status. @@ -21,7 +24,7 @@ namespace storm { * @param resetToState A flag that indicates the status to which the option is to be reset upon * deconstruction of this object. */ - SettingMemento(ModuleSettings& settings, std::string const& longOptionName, bool resetToState); + SettingMemento(modules::ModuleSettings& settings, std::string const& longOptionName, bool resetToState); /*! * Destructs the memento object and resets the value of the option to its original state. @@ -30,7 +33,7 @@ namespace storm { private: // The settings object in which the setting is to be restored. - ModuleSettings& settings; + modules::ModuleSettings& settings; // The long name of the option that was temporarily set. std::string const optionName; diff --git a/src/settings/SettingsManager.cpp b/src/settings/SettingsManager.cpp index 2581edd52..d9a109835 100644 --- a/src/settings/SettingsManager.cpp +++ b/src/settings/SettingsManager.cpp @@ -3,14 +3,23 @@ #include <cstring> #include <cctype> #include <mutex> +#include <boost/algorithm/string.hpp> #include "src/exceptions/OptionParserException.h" namespace storm { namespace settings { - SettingsManager::SettingsManager() : generalSettings(*this), debugSettings(*this), counterexampleGeneratorSettings(*this), cuddSettings(*this), gmmxxSettings(*this), nativeEquationSolverSettings(*this), glpkSettings(*this), gurobiSettings(*this) { - // Intentionally left empty. + SettingsManager::SettingsManager() { + // Register all known settings modules. + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::GeneralSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::DebugSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::CounterexampleGeneratorSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::CuddSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::GmmxxEquationSolverSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::NativeEquationSolverSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::GlpkSettings(*this))); + this->addModule(std::unique_ptr<modules::ModuleSettings>(new modules::GurobiSettings(*this))); } SettingsManager::~SettingsManager() { @@ -18,283 +27,42 @@ namespace storm { } SettingsManager& SettingsManager::manager() { + static SettingsManager settingsManager; return settingsManager; } + void SettingsManager::setFromCommandLine(int const argc, char const * const argv[]) { + // We convert the arguments to a vector of strings and strip off the first element since it refers to the + // name of the program. + std::vector<std::string> argumentVector(argc - 1); + for (uint_fast64_t i = 1; i < argc; ++i) { + argumentVector[i - 1] = std::string(argv[i]); + } + + this->setFromExplodedString(argumentVector); + } - } -} - - -/*! - * @brief Create new instance. - * - * Creates a new Settings instance and passes the arguments to the constructor of Settings. - * - * @param argc should be argc passed to main function - * @param argv should be argv passed to main function - * @param filename either NULL or name of config file - * @return The new instance of Settings. - */ -void storm::settings::SettingsManager::parse(int const argc, char const * const argv[]) { - storm::settings::SettingsManager* myInstance = storm::settings::SettingsManager::getInstance(); - myInstance->parseCommandLine(argc, argv); -} - -bool storm::settings::SettingsManager::hasAssignment(std::string const& option) { - return (option.find_first_of('=', 0) != std::string::npos); -} - -storm::settings::stringPair_t storm::settings::SettingsManager::splitOptionString(std::string const& option) { - size_t splitLocation = option.find_first_of('=', 0); - if (splitLocation == std::string::npos) { - // Second half is empty - return std::make_pair(option, ""); - } else if (splitLocation + 1 >= option.length()) { - // Remove the = character - return std::make_pair(option.substr(0, option.size() - 1), ""); - } - return std::make_pair(option.substr(0, splitLocation), option.substr(splitLocation + 1, std::string::npos)); -} - -void storm::settings::SettingsManager::handleAssignment(std::string const& longOptionName, std::vector<std::string> arguments) { - std::string optionName = storm::utility::StringHelper::stringToLower(longOptionName); - - Option* option = this->getPtrByLongName(optionName); - - // Mark as Set - option->setHasOptionBeenSet(); - - uint_fast64_t givenArgsCount = arguments.size(); - - if (givenArgsCount > option->getArgumentCount()) { - LOG4CPLUS_ERROR(logger, "SettingsManager::handleAssignment: Unable to parse arguments for option \"" << longOptionName << "\": " << arguments.size() << " arguments given, but expected no more than " << option->getArgumentCount() << "."); - throw storm::exceptions::OptionParserException() << "Unable to parse arguments for option \"" << longOptionName << "\": " << arguments.size() << " arguments given, but expected no more than " << option->getArgumentCount() << "."; - } - - for (uint_fast64_t i = 0; i < option->getArgumentCount(); ++i) { - if (i < givenArgsCount) { - storm::settings::fromStringAssignmentResult_t assignmentResult = option->getArgument(i).fromStringValue(arguments.at(i)); - if (!assignmentResult.first) { - LOG4CPLUS_ERROR(logger, "SettingsManager::handleAssignment: Unable to parse arguments for option \"" << longOptionName << "\": argument " << option->getArgument(i).getArgumentName() << " rejected the given value \"" << arguments.at(i) << "\" with message:\r\n" << assignmentResult.second << "."); - throw storm::exceptions::OptionParserException() << "Unable to parse arguments for option \"" << longOptionName << "\": argument " << option->getArgument(i).getArgumentName() << " rejected the given value \"" << arguments.at(i) << "\" with message:\r\n" << assignmentResult.second << "."; - } - } else { - // There is no given value for this argument, only optional - if (!option->getArgument(i).getIsOptional()) { - LOG4CPLUS_ERROR(logger, "Settings::handleAssignment: Unable to parse arguments for option \"" << longOptionName << "\": " << arguments.size() << " arguments given, but more arguments were expected."); - throw storm::exceptions::OptionParserException() << "Unable to parse arguments for option \"" << longOptionName << "\": " << arguments.size() << " arguments given, but more arguments were expected."; - } else { - option->getArgument(i).setFromDefaultValue(); - } - } - } -} - -std::vector<std::string> storm::settings::SettingsManager::argvToStringArray(int const argc, char const * const argv[]) { - // Ignore argv[0], it contains the program path and name - std::vector<std::string> result; - for (int i = 1; i < argc; ++i) { - result.push_back(std::string(argv[i])); - } - return result; -} - -bool storm::settings::SettingsManager::checkArgumentSyntaxForOption(std::string const& argvString) { - if (argvString.size() < 2) { - return false; - } - - if ((argvString.at(0) != '-') || ((argvString.at(1) != '-') && !isalpha(argvString.at(1)))) { - return false; - } - - for (size_t i = 2; i < argvString.size(); ++i) { - if (!isalpha(argvString.at(i))) { - return false; - } - } - return true; -} - -std::vector<bool> storm::settings::SettingsManager::scanForOptions(std::vector<std::string> const& arguments) { - std::vector<bool> result; - result.reserve(arguments.size()); - for (auto it = arguments.cbegin(); it != arguments.cend(); ++it) { - result.push_back(checkArgumentSyntaxForOption(*it)); - } - return result; -} - -void storm::settings::SettingsManager::parseCommandLine(int const argc, char const * const argv[]) { - LOG4CPLUS_DEBUG(logger, "Settings::parseCommandLine: Parsing " << argc << " arguments."); - - std::vector<std::string> stringArgv = argvToStringArray(argc, argv); - std::vector<bool> optionPositions = scanForOptions(stringArgv); - - bool optionActive = false; - std::string longOptionName; - std::vector<std::string> argCache; - for (size_t i = 0; i <= stringArgv.size(); ++i) { - if (i == stringArgv.size()) { - if (optionActive) { - this->handleAssignment(longOptionName, argCache); - argCache.clear(); - } - break; - } else if (optionPositions.at(i)) { - if (optionActive) { - this->handleAssignment(longOptionName, argCache); - argCache.clear(); - } - - std::string const& nextOption = stringArgv.at(i); - if (nextOption.at(0) == '-' && nextOption.at(1) != '-') { - // Short Option - std::string nextShortOptionName = storm::utility::StringHelper::stringToLower(nextOption.substr(1, nextOption.size() - 1)); - if (!this->containsShortName(nextShortOptionName)) { - LOG4CPLUS_ERROR(logger, "Settings::parseCommandLine: Unknown option name \"" << nextShortOptionName << "\"."); - throw storm::exceptions::OptionParserException() << "Unknown option name \"" << nextShortOptionName << "\"."; - } else { - longOptionName = this->getByShortName(nextShortOptionName).getLongName(); - optionActive = true; - } - } else { - // Long Option - std::string nextLongOptionName = storm::utility::StringHelper::stringToLower(nextOption.substr(2, nextOption.size() - 2)); - if (!this->containsLongName(nextLongOptionName)) { - LOG4CPLUS_ERROR(logger, "Settings::parseCommandLine: Unknown option name \"" << nextLongOptionName << "\"."); - throw storm::exceptions::OptionParserException() << "Unknown option name \"" << nextLongOptionName << "\"."; - } else { - longOptionName = this->getByLongName(nextLongOptionName).getLongName(); - optionActive = true; - } - } - } else if (optionActive) { - // Next argument for an Option found - argCache.push_back(stringArgv.at(i)); - } else { - // No Option active and this is no option. - LOG4CPLUS_ERROR(logger, "Settings::parseCommandLine: Found stray argument while parsing a given configuration, \"" << stringArgv.at(i) << "\" is neither a known option nor preceeded by an option."); - throw storm::exceptions::OptionParserException() << "Found stray argument while parsing a given configuration; \"" << stringArgv.at(i) << "\" is neither a known option nor preceeded by an option."; - } - } - - for (auto it = this->options.cbegin(); it != this->options.cend(); ++it) { - if (!it->second.get()->getHasOptionBeenSet()) { - if (it->second.get()->getIsRequired()) { - LOG4CPLUS_ERROR(logger, "Settings::parseCommandLine: Missing required option \"" << it->second.get()->getLongName() << "\"."); - throw storm::exceptions::OptionParserException() << "Missing required option \"" << it->second.get()->getLongName() << "\"."; - } else { - // Set defaults on optional values - for (uint_fast64_t i = 0; i < it->second.get()->getArgumentCount(); ++i) { - if (it->second.get()->getArgument(i).getHasDefaultValue()) { - it->second.get()->getArgument(i).setFromDefaultValue(); - } - } - } - } - } -} - -storm::settings::SettingsManager* storm::settings::SettingsManager::getInstance() { - // Usually, this would require double-checked locking. - // But since C++11, this is the way to go: - static storm::settings::SettingsManager pInstance; - - return &pInstance; -} - -storm::settings::SettingsManager& storm::settings::SettingsManager::addOption(Option* option) { - // For automatic management of option's lifetime - std::shared_ptr<Option> optionPtr(option); - - std::string lowerLongName = storm::utility::StringHelper::stringToLower(option->getLongName()); - std::string lowerShortName = storm::utility::StringHelper::stringToLower(option->getShortName()); - - auto longNameIterator = this->options.find(lowerLongName); - auto shortNameIterator = this->shortNames.find(lowerShortName); - - if (longNameIterator == this->options.end()) { - // Not found - if (!(shortNameIterator == this->shortNames.end())) { - // There exists an option which uses the same shortname - //LOG4CPLUS_ERROR(logger, "Settings::addOption: Error: The Option \"" << shortNameIterator->second << "\" from Module \"" << this->options.find(shortNameIterator->second)->second.get()->getModuleName() << "\" uses the same ShortName as the Option \"" << option->getLongName() << "\" from Module \"" << option->getModuleName() << "\"!"); - throw storm::exceptions::OptionUnificationException() << "Error: The option \"" << shortNameIterator->second << "\" of module \"" << this->options.find(shortNameIterator->second)->second.get()->getModuleName() << "\" uses the same name as option \"" << option->getLongName() << "\" of module \"" << option->getModuleName() << "\"."; - } - - // Copy Shared_ptr - this->options.insert(std::make_pair(lowerLongName, std::shared_ptr<Option>(optionPtr))); - this->optionPointers.push_back(std::shared_ptr<Option>(optionPtr)); - // Ignore Options with empty shortName - if (!lowerShortName.empty()) { - this->shortNames.insert(std::make_pair(lowerShortName, lowerLongName)); - } - } else { - // This will fail if the shortNames are not identical, so no additional checks here. - longNameIterator->second.get()->unify(*option); - } - - return *this; -} - -std::string storm::settings::SettingsManager::getHelpText() const { - - // Copy all option names into a vector and sort it - std::vector<std::string> optionNames; - optionNames.reserve(this->options.size()); - - size_t longNameMaxSize = 0; - size_t shortNameMaxSize = 0; - size_t argumentNameMaxSize = 0; - // Get the maximum size of the long and short Names and copy the long names for sorting - std::for_each(this->options.cbegin(), this->options.cend(), [&] (std::pair<std::string, std::shared_ptr<storm::settings::Option>> const& it) -> void { - longNameMaxSize = std::max(longNameMaxSize, it.first.size()); - shortNameMaxSize = std::max(shortNameMaxSize, it.second.get()->getShortName().size()); - optionNames.push_back(it.first); - std::for_each(it.second.get()->arguments.cbegin(), it.second.get()->arguments.cend(), [&] (std::shared_ptr<ArgumentBase> const& arg) -> void { - argumentNameMaxSize = std::max(argumentNameMaxSize, arg.get()->getArgumentName().size()); - }); - }); - // Sort the long names - std::sort(optionNames.begin(), optionNames.end(), [] (std::string const& a, std::string const& b) -> bool { return a.compare(b) < 0; }); - - std::stringstream ss; - - /* - Layout: - --longName -shortName Description - ArgumentName (ArgumentType) ArgumentDescription - */ - const std::string delimiter = " "; - - for (auto it = optionNames.cbegin(); it != optionNames.cend(); ++it) { - Option const& o = this->getByLongName(*it); - std::string const& longName = o.getLongName(); - ss << delimiter << "--" << longName; - // Fill up the remaining space after the long Name - for (uint_fast64_t i = longName.size(); i < longNameMaxSize; ++i) { - ss << " "; - } - std::string const& shortName = o.getShortName(); - ss << delimiter << "-" << shortName; - // Fill up the remaining space after the short Name - for (uint_fast64_t i = shortName.size(); i < shortNameMaxSize; ++i) { - ss << " "; - } - ss << delimiter << o.getDescription() << std::endl; - - for (auto i = 0; i < o.getArgumentCount(); ++i) { - ArgumentBase const& a = o.getArgument(i); - std::string const& argumentName = a.getArgumentName(); - ss << delimiter << delimiter << delimiter << delimiter << "argument <" << (i+1) << "> - " << argumentName; - // Fill up the remaining space after the argument Name - for (uint_fast64_t i = argumentName.size(); i < argumentNameMaxSize; ++i) { - ss << " "; - } - ss << "(" << ArgumentTypeHelper::toString(a.getArgumentType()) << ")" << delimiter << a.getArgumentDescription() << std::endl; - } - } + void SettingsManager::setFromString(std::string const& commandLineString) { + std::vector<std::string> argumentVector; + boost::split(argumentVector, commandLineString, boost::is_any_of("\t ")); + this->setFromExplodedString(argumentVector); + } + + void SettingsManager::setFromExplodedString(std::vector<std::string> const& commandLineArguments) { + LOG_ASSERT(false, "Not yet implemented"); + } + + void SettingsManager::setFromConfigurationFile(std::string const& configFilename) { + LOG_ASSERT(false, "Not yet implemented"); + } + + void SettingsManager::printHelp(std::string const& moduleName) const { + LOG_ASSERT(false, "Not yet implemented"); + } + + void SettingsManager::addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings) { + LOG_ASSERT(false, "Not yet implemented"); + } - return ss.str(); + } } \ No newline at end of file diff --git a/src/settings/SettingsManager.h b/src/settings/SettingsManager.h index 2f719b6f2..89913bf7a 100644 --- a/src/settings/SettingsManager.h +++ b/src/settings/SettingsManager.h @@ -34,8 +34,6 @@ namespace storm { namespace settings { - class InternalOptionMemento; - /*! * Provides the central API for the registration of command line options and parsing the options from the * command line. Since this class is a singleton, the only instance is accessible via a call to the manager() @@ -43,9 +41,6 @@ namespace storm { */ class SettingsManager { public: - // Declare the memento class as a friend so it can manipulate the internal state. - friend class InternalOptionMemento; - /*! * This function parses the given command line arguments and sets all registered options accordingly. If the * command line cannot be matched using the known options, an exception is thrown. @@ -53,7 +48,7 @@ namespace storm { * @param argc The number of command line arguments. * @param argv The command line arguments. */ - static void setFromCommandLine(int const argc, char const * const argv[]); + void setFromCommandLine(int const argc, char const * const argv[]); /*! * This function parses the given command line arguments (represented by one big string) and sets all @@ -62,7 +57,7 @@ namespace storm { * * @param commandLineString The command line arguments as one string. */ - static void setFromString(std::string const& commandLineString); + void setFromString(std::string const& commandLineString); /*! * This function parses the given command line arguments (represented by several strings) and sets all @@ -71,69 +66,46 @@ namespace storm { * * @param commandLineArguments The command line arguments. */ - static void setFromExplodedString(std::vector<std::string> const& commandLineArguments); + void setFromExplodedString(std::vector<std::string> const& commandLineArguments); /*! * This function parses the given file and sets all registered options accordingly. If the settings cannot * be matched using the known options, an exception is thrown. */ - static void setFromConfigurationFile(std::string const& configFilename); + void setFromConfigurationFile(std::string const& configFilename); /*! - * Retrieves the general settings. - * - * @return An object that allows accessing the general settings. - */ - storm::settings::modules::GeneralSettings const& getGeneralSettings() const; - - /*! - * Retrieves the debug settings. - * - * @return An object that allows accessing the debug settings. - */ - storm::settings::modules::DebugSettings const& getDebugSettings() const; - - /*! - * Retrieves the counterexample generator settings. - * - * @return An object that allows accessing the counterexample generator settings. - */ - storm::settings::modules::CounterexampleGeneratorSettings const& getCounterexampleGeneratorSettings() const; - - /*! - * Retrieves the CUDD settings. - * - * @return An object that allows accessing the CUDD settings. - */ - storm::settings::modules::CuddSettings const& getCuddSettings() const; - - /*! - * Retrieves the settings of the gmm++-based equation solver. + * This function prints a help message to the standard output. Optionally, a module name can be given. If + * it is present, name must correspond to a known module. Then, only the help text for this module is + * printed. * - * @return An object that allows accessing the settings of the gmm++-based equation solver. + * @return moduleName The name of the module for which to show the help or "all" if the full help text is to + * be printed. */ - storm::settings::modules::GmmxxEquationSolverSettings const& getGmmxxEquationSolverSettings() const; - + void printHelp(std::string const& moduleName = "all") const; + /*! - * Retrieves the settings of the native equation solver. + * Retrieves the only existing instance of a settings manager. * - * @return An object that allows accessing the settings of the native equation solver. + * @return The only existing instance of a settings manager */ - storm::settings::modules::NativeEquationSolverSettings const& getNativeEquationSolverSettings() const; - + static SettingsManager& manager(); + /*! - * Retrieves the settings of glpk. + * Adds a new module with the given name. If the module could not be successfully added, an exception is + * thrown. * - * @return An object that allows accessing the settings of glpk. + * @param moduleSettings The settings of the module to add. */ - storm::settings::modules::GlpkSettings const& getGlpkSettings() const; - + void addModule(std::unique_ptr<modules::ModuleSettings>&& moduleSettings); + /*! - * Retrieves the settings of Gurobi. + * Retrieves the settings of the module with the given name. * - * @return An object that allows accessing the settings of Gurobi. + * @param moduleName The name of the module for which to retrieve the settings. + * @return An object that provides access to the settings of the module. */ - storm::settings::modules::GurobiSettings const& getGurobiSettings() const; + modules::ModuleSettings const& getModule(std::string const& moduleName) const; private: /*! @@ -146,33 +118,6 @@ namespace storm { * This destructor is private, since we need to forbid explicit destruction of the manager. */ virtual ~SettingsManager(); - - // An object that provides access to the general settings. - storm::settings::modules::GeneralSettings generalSettings; - - // An object that provides access to the debug settings. - storm::settings::modules::DebugSettings debugSettings; - - // An object that provides access to the counterexample generator settings. - storm::settings::modules::CounterexampleGeneratorSettings counterexampleGeneratorSettings; - - // An object that provides access to the CUDD settings. - storm::settings::modules::CuddSettings cuddSettings; - - // An object that provides access to the gmm++ settings. - storm::settings::modules::GmmxxEquationSolverSettings gmmxxEquationSolverSettings; - - // An object that provides access to the native equation solver settings. - storm::settings::modules::NativeEquationSolverSettings nativeEquationSolverSettings; - - // An object that provides access to the glpk settings. - storm::settings::modules::GlpkSettings glpkSettings; - - // An object that provides access to the Gurobi settings. - storm::settings::modules::GurobiSettings gurobiSettings; - - // The single instance of the manager class. Since it's static, it will automatically be distructed upon termination. - static SettingsManager settingsManager; // A set of all known (i.e. registered) module names. std::set<std::string> moduleNames; @@ -181,41 +126,93 @@ namespace storm { // to be compatible in the sense that calling isCompatible(...) pairwise on all options must always return true. std::unordered_map<std::string, std::vector<std::shared_ptr<Option>>> options; - /*! - * This function prints a help message to the standard output. Optionally, a module name can be given. If - * it is present, name must correspond to a known module. Then, only the help text for this module is - * printed. - * - * @return moduleName The name of the module for which to show the help or "all" if the full help text is to - * be printed. - */ - void printHelp(std::string const& moduleName = "all") const; - - /*! - * Registers a new module with the given name and options. If the module could not be successfully registered, - * an exception is thrown. - * - * @param moduleName The name of the module to register. - * @param options The set of options that the module registers. - */ - void registerModule(std::string const& moduleName, std::vector<std::shared_ptr<Option>> const& options); - - /*! - * Retrieves the only existing instance of a settings manager. - * - * @return The only existing instance of a settings manager - */ - static SettingsManager& manager(); - // Helper functions - stringPair_t splitOptionString(std::string const& option); - bool hasAssignment(std::string const& option); void handleAssignment(std::string const& longOptionName, std::vector<std::string> arguments); - std::vector<std::string> argvToStringArray(int const argc, char const * const argv[]); std::vector<bool> scanForOptions(std::vector<std::string> const& arguments); bool checkArgumentSyntaxForOption(std::string const& argvString); }; + /*! + * Retrieves the settings manager. + * + * @return The only settings manager. + */ + SettingsManager& manager() { + return SettingsManager::manager(); + } + + /*! + * Retrieves the general settings. + * + * @return An object that allows accessing the general settings. + */ + storm::settings::modules::GeneralSettings const& generalSettings() { + return dynamic_cast<storm::settings::modules::GeneralSettings const&>(manager().getModule(storm::settings::modules::GeneralSettings::moduleName)); + } + + /*! + * Retrieves the debug settings. + * + * @return An object that allows accessing the debug settings. + */ + storm::settings::modules::DebugSettings const& debugSettings() { + return dynamic_cast<storm::settings::modules::DebugSettings const&>(manager().getModule(storm::settings::modules::DebugSettings::moduleName)); + } + + /*! + * Retrieves the counterexample generator settings. + * + * @return An object that allows accessing the counterexample generator settings. + */ + storm::settings::modules::CounterexampleGeneratorSettings const& counterexampleGeneratorSettings() { + return dynamic_cast<storm::settings::modules::CounterexampleGeneratorSettings const&>(manager().getModule(storm::settings::modules::CounterexampleGeneratorSettings::moduleName)); + } + + /*! + * Retrieves the CUDD settings. + * + * @return An object that allows accessing the CUDD settings. + */ + storm::settings::modules::CuddSettings const& cuddSettings() { + return dynamic_cast<storm::settings::modules::CuddSettings const&>(manager().getModule(storm::settings::modules::CuddSettings::moduleName)); + } + + /*! + * Retrieves the settings of the gmm++-based equation solver. + * + * @return An object that allows accessing the settings of the gmm++-based equation solver. + */ + storm::settings::modules::GmmxxEquationSolverSettings const& gmmxxEquationSolverSettings() { + return dynamic_cast<storm::settings::modules::GmmxxEquationSolverSettings const&>(manager().getModule(storm::settings::modules::GmmxxEquationSolverSettings::moduleName)); + } + + /*! + * Retrieves the settings of the native equation solver. + * + * @return An object that allows accessing the settings of the native equation solver. + */ + storm::settings::modules::NativeEquationSolverSettings const& nativeEquationSolverSettings() { + return dynamic_cast<storm::settings::modules::NativeEquationSolverSettings const&>(manager().getModule(storm::settings::modules::NativeEquationSolverSettings::moduleName)); + } + + /*! + * Retrieves the settings of glpk. + * + * @return An object that allows accessing the settings of glpk. + */ + storm::settings::modules::GlpkSettings const& glpkSettings() { + return dynamic_cast<storm::settings::modules::GlpkSettings const&>(manager().getModule(storm::settings::modules::GlpkSettings::moduleName)); + } + + /*! + * Retrieves the settings of Gurobi. + * + * @return An object that allows accessing the settings of Gurobi. + */ + storm::settings::modules::GurobiSettings const& gurobiSettings() { + return dynamic_cast<storm::settings::modules::GurobiSettings const&>(manager().getModule(storm::settings::modules::GurobiSettings::moduleName)); + } + } // namespace settings } // namespace storm diff --git a/src/settings/modules/CounterexampleGeneratorSettings.cpp b/src/settings/modules/CounterexampleGeneratorSettings.cpp index 0fad20609..f6ff3347c 100644 --- a/src/settings/modules/CounterexampleGeneratorSettings.cpp +++ b/src/settings/modules/CounterexampleGeneratorSettings.cpp @@ -12,19 +12,14 @@ namespace storm { const std::string CounterexampleGeneratorSettings::schedulerCutsOptionName = "schedcuts"; const std::string CounterexampleGeneratorSettings::statisticsOptionName = "stats"; - CounterexampleGeneratorSettings::CounterexampleGeneratorSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; + CounterexampleGeneratorSettings::CounterexampleGeneratorSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { std::vector<std::string> techniques = {"sat", "milp"}; - options.push_back(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command set. Note that this requires the model to be given in a symbolic format.") + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, minimalCommandSetOptionName, true, "Computes a counterexample for the given model in terms of a minimal command set. Note that this requires the model to be given in a symbolic format.") .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file containing the properties for which counterexamples are to be generated.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used to derive the counterexample. Available are {milp, maxsat}").setDefaultValueString("maxsat").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(techniques)).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, statisticsOptionName, true, "Sets whether to display statistics for counterexample generation.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based minimal command counterexample generation.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based minimal command counterexample generation.").build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, statisticsOptionName, true, "Sets whether to display statistics for counterexample generation.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, encodeReachabilityOptionName, true, "Sets whether to encode reachability for MAXSAT-based minimal command counterexample generation.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, schedulerCutsOptionName, true, "Sets whether to add the scheduler cuts for MILP-based minimal command counterexample generation.").build()); } } // namespace modules diff --git a/src/settings/modules/CounterexampleGeneratorSettings.h b/src/settings/modules/CounterexampleGeneratorSettings.h index d3a9626ab..33b394a6e 100644 --- a/src/settings/modules/CounterexampleGeneratorSettings.h +++ b/src/settings/modules/CounterexampleGeneratorSettings.h @@ -60,7 +60,9 @@ namespace storm { /*! * Retrieves whether scheduler cuts are to be used if the MAXSAT-based technique is used to generate a - * minimal command set counterexample + * minimal command set counterexample. + * + * @return True iff scheduler cuts are to be used. */ bool useSchedulerCuts() const; @@ -71,9 +73,11 @@ namespace storm { */ bool showStatistics() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string minimalCommandSetOptionName; static const std::string encodeReachabilityOptionName; static const std::string schedulerCutsOptionName; diff --git a/src/settings/modules/CuddSettings.cpp b/src/settings/modules/CuddSettings.cpp index 406cac4b7..dffef2457 100644 --- a/src/settings/modules/CuddSettings.cpp +++ b/src/settings/modules/CuddSettings.cpp @@ -11,12 +11,10 @@ namespace storm { const std::string maximalMemoryOptionName = "maxmem"; const std::string reorderOptionName = "reorder"; - CuddSettings::CuddSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; - options.push_back(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "Sets the precision used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision up to which to constants are considered to be different.").setDefaultValueDouble(1e-15).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); + CuddSettings::CuddSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "Sets the precision used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision up to which to constants are considered to be different.").setDefaultValueDouble(1e-15).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, maximalMemoryOptionName, true, "Sets the upper bound of memory available to Cudd in MB.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("mb", "The memory available to Cudd (0 means unlimited).").setDefaultValueUnsignedInteger(2048).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, maximalMemoryOptionName, true, "Sets the upper bound of memory available to Cudd in MB.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("mb", "The memory available to Cudd (0 means unlimited).").setDefaultValueUnsignedInteger(2048).build()).build()); std::vector<std::string> reorderingTechniques; reorderingTechniques.push_back("none"); @@ -37,10 +35,7 @@ namespace storm { reorderingTechniques.push_back("annealing"); reorderingTechniques.push_back("genetic"); reorderingTechniques.push_back("exact"); - options.push_back(storm::settings::OptionBuilder(moduleName, reorderOptionName, true, "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {none, random, randompivot, sift, siftconv, ssift, ssiftconv, gsift, gsiftconv, win2, win2conv, win3, win3conv, win4, win4conv, annealing, genetic, exact}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, reorderOptionName, true, "Sets the reordering technique used by Cudd.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("method", "Sets which technique is used by Cudd's reordering routines. Must be in {none, random, randompivot, sift, siftconv, ssift, ssiftconv, gsift, gsiftconv, win2, win2conv, win3, win3conv, win4, win4conv, annealing, genetic, exact}.").setDefaultValueString("gsift").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(reorderingTechniques)).build()).build()); } } // namespace modules diff --git a/src/settings/modules/CuddSettings.h b/src/settings/modules/CuddSettings.h index e0e588953..db59ddc77 100644 --- a/src/settings/modules/CuddSettings.h +++ b/src/settings/modules/CuddSettings.h @@ -43,9 +43,11 @@ namespace storm { */ ReorderingTechnique getReorderingTechnique() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string precisionOptionName; static const std::string maximalMemoryOptionName; static const std::string reorderOptionName; diff --git a/src/settings/modules/DebugSettings.cpp b/src/settings/modules/DebugSettings.cpp index 3fa44529a..c78f47b14 100644 --- a/src/settings/modules/DebugSettings.cpp +++ b/src/settings/modules/DebugSettings.cpp @@ -12,16 +12,11 @@ namespace storm { const std::string DebugSettings::logfileOptionName = "logfile"; const std::string DebugSettings::logfileOptionShortName = "l"; - DebugSettings::DebugSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; - options.push_back(storm::settings::OptionBuilder(moduleName, debugOptionName, false, "Print debug output.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, traceOptionName, false, "Print even more debug output.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, logfileOptionName, false, "If specified, the log output will also be written to this file.").setShortName(logfileOptionShortName) + DebugSettings::DebugSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, debugOptionName, false, "Print debug output.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, traceOptionName, false, "Print even more debug output.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, logfileOptionName, false, "If specified, the log output will also be written to this file.").setShortName(logfileOptionShortName) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file to write the log.").build()).build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); } } // namespace modules diff --git a/src/settings/modules/DebugSettings.h b/src/settings/modules/DebugSettings.h index 9a65c53c9..024246b68 100644 --- a/src/settings/modules/DebugSettings.h +++ b/src/settings/modules/DebugSettings.h @@ -47,9 +47,11 @@ namespace storm { */ std::string getLogfilename() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string debugOptionName; static const std::string traceOptionName; static const std::string logfileOptionName; diff --git a/src/settings/modules/GeneralSettings.cpp b/src/settings/modules/GeneralSettings.cpp index a13ea57e6..961f1e140 100644 --- a/src/settings/modules/GeneralSettings.cpp +++ b/src/settings/modules/GeneralSettings.cpp @@ -11,6 +11,8 @@ namespace storm { const std::string GeneralSettings::helpOptionShortName = "h"; const std::string GeneralSettings::verboseOptionName = "verbose"; const std::string GeneralSettings::verboseOptionShortName = "v"; + const std::string GeneralSettings::precisionOptionName = "precision"; + const std::string GeneralSettings::precisionOptionShortName = "p"; const std::string GeneralSettings::exportDotOptionName = "exportdot"; const std::string GeneralSettings::configOptionName = "config"; const std::string GeneralSettings::configOptionShortName = "c"; @@ -33,51 +35,48 @@ namespace storm { const std::string GeneralSettings::constantsOptionName = "constants"; const std::string GeneralSettings::constantsOptionShortName = "const"; - GeneralSettings::GeneralSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; + GeneralSettings::GeneralSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { std::vector<std::string> moduleNames = {"all", "general", "debug", "cudd", "counterexample", "glpk", "gurobi", "gmm++", "native"}; - options.push_back(storm::settings::OptionBuilder(moduleName, helpOptionName, false, "Shows all available options, arguments and descriptions.").setShortName(helpOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("module", "The module for which to show the help or 'all' for all modules.").setDefaultValueString("all").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(moduleNames)).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, verboseOptionName, false, "Enables more verbose output.").setShortName(verboseOptionShortName).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, exportDotOptionName, "", "If given, the loaded model will be written to the specified file in the dot format.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file to which the model is to be written.").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, configOptionName, false, "If given, this file will be read and parsed for additional configuration settings.").setShortName(configOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the configuration.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, explicitOptionName, false, "Parses the model given in an explicit (sparse) representation.").setShortName(explicitOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the transitions.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the state labeling.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, symbolicOptionName, false, "Parses the model given in a symbolic representation.").setShortName(symbolicOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the symbolic model.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, pctlOptionName, false, "Specifies the PCTL formulas that are to be checked on the model.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the PCTL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, cslOptionName, false, "Specifies the CSL formulas that are to be checked on the model.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the CSL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, ltlOptionName, false, "Specifies the LTL formulas that are to be checked on the model.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the LTL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, counterexampleOptionName, false, "Generates a counterexample for the given PRCTL formulas if not satisfied by the model") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file to which the counterexample is to be written.").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, helpOptionName, false, "Shows all available options, arguments and descriptions.").setShortName(helpOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("module", "The module for which to show the help or 'all' for all modules.").setDefaultValueString("all").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(moduleNames)).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, verboseOptionName, false, "Enables more verbose output.").setShortName(verboseOptionShortName).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "The internally used precision.").setShortName(precisionOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to use.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, exportDotOptionName, "", "If given, the loaded model will be written to the specified file in the dot format.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file to which the model is to be written.").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, configOptionName, false, "If given, this file will be read and parsed for additional configuration settings.").setShortName(configOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the configuration.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, explicitOptionName, false, "Parses the model given in an explicit (sparse) representation.").setShortName(explicitOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("transition filename", "The name of the file from which to read the transitions.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("labeling filename", "The name of the file from which to read the state labeling.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, symbolicOptionName, false, "Parses the model given in a symbolic representation.").setShortName(symbolicOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the symbolic model.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, pctlOptionName, false, "Specifies the PCTL formulas that are to be checked on the model.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the PCTL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, cslOptionName, false, "Specifies the CSL formulas that are to be checked on the model.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the CSL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, ltlOptionName, false, "Specifies the LTL formulas that are to be checked on the model.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the LTL formulas.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, counterexampleOptionName, false, "Generates a counterexample for the given PRCTL formulas if not satisfied by the model") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file to which the counterexample is to be written.").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, transitionRewardsOptionName, "", "If given, the transition rewards are read from this file and added to the explicit model. Note that this requires the model to be given as an explicit model (i.e., via --" + explicitOptionName + ").") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the transition rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, stateRewardsOptionName, false, "If given, the state rewards are read from this file and added to the explicit model. Note that this requires the model to be given as an explicit model (i.e., via --" + explicitOptionName + ").") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the state rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, fixDeadlockOptionName, false, "If the model contains deadlock states, they need to be fixed by setting this option.").setShortName(fixDeadlockOptionShortName).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, transitionRewardsOptionName, "", "If given, the transition rewards are read from this file and added to the explicit model. Note that this requires the model to be given as an explicit model (i.e., via --" + explicitOptionName + ").") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the transition rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, stateRewardsOptionName, false, "If given, the state rewards are read from this file and added to the explicit model. Note that this requires the model to be given as an explicit model (i.e., via --" + explicitOptionName + ").") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The file from which to read the state rewards.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, fixDeadlockOptionName, false, "If the model contains deadlock states, they need to be fixed by setting this option.").setShortName(fixDeadlockOptionShortName).build()); std::vector<std::string> linearEquationSolver = {"gmm++", "native"}; - options.push_back(storm::settings::OptionBuilder(moduleName, eqSolverOptionName, false, "Sets which solver is preferred for solving systems of linear equations.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the solver to prefer. Available are: gmm++ and native.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, timeoutOptionName, false, "If given, computation will abort after the timeout has been reached.").setShortName(timeoutOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("time", "The number of seconds after which to timeout.").setDefaultValueUnsignedInteger(0).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, eqSolverOptionName, false, "Sets which solver is preferred for solving systems of linear equations.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the solver to prefer. Available are: gmm++ and native.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(linearEquationSolver)).setDefaultValueString("gmm++").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, timeoutOptionName, false, "If given, computation will abort after the timeout has been reached.").setShortName(timeoutOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("time", "The number of seconds after which to timeout.").setDefaultValueUnsignedInteger(0).build()).build()); std::vector<std::string> lpSolvers = {"gurobi", "glpk"}; - options.push_back(storm::settings::OptionBuilder(moduleName, lpSolverOptionName, false, "Sets which LP solver is preferred.") - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of an LP solver. Available are: gurobi and glpk.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(lpSolvers)).setDefaultValueString("glpk").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, constantsOptionName, false, "Specifies the constant replacements to use in symbolic models. Note that Note that this requires the model to be given as an symbolic model (i.e., via --" + symbolicOptionName + ").").setShortName(constantsOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("values", "A comma separated list of constants and their value, e.g. a=1,b=2,c=3.").setDefaultValueString("").build()).build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, lpSolverOptionName, false, "Sets which LP solver is preferred.") + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of an LP solver. Available are: gurobi and glpk.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(lpSolvers)).setDefaultValueString("glpk").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, constantsOptionName, false, "Specifies the constant replacements to use in symbolic models. Note that Note that this requires the model to be given as an symbolic model (i.e., via --" + symbolicOptionName + ").").setShortName(constantsOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("values", "A comma separated list of constants and their value, e.g. a=1,b=2,c=3.").setDefaultValueString("").build()).build()); } } // namespace modules diff --git a/src/settings/modules/GeneralSettings.h b/src/settings/modules/GeneralSettings.h index 9f5c55c7f..504114d48 100644 --- a/src/settings/modules/GeneralSettings.h +++ b/src/settings/modules/GeneralSettings.h @@ -11,7 +11,7 @@ namespace storm { * This class represents the general settings. */ class GeneralSettings : public ModuleSettings { - public: + public: // An enumeration of all available LP solvers. enum class LpSolver { Gurobi, glpk }; @@ -47,6 +47,13 @@ namespace storm { */ bool isVerboseSet() const; + /*! + * Retrieves the precision to use for numerical operations. + * + * @return The precision to use for numerical operations. + */ + double getPrecision() const; + /*! * Retrieves whether the export-to-dot option was set. * @@ -248,14 +255,18 @@ namespace storm { * @return The string that defines the constants of a symbolic model. */ std::string getConstantDefinitionString() const; - + + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string helpOptionName; static const std::string helpOptionShortName; static const std::string verboseOptionName; static const std::string verboseOptionShortName; + static const std::string precisionOptionName; + static const std::string precisionOptionShortName; static const std::string exportDotOptionName; static const std::string configOptionName; static const std::string configOptionShortName; diff --git a/src/settings/modules/GlpkSettings.cpp b/src/settings/modules/GlpkSettings.cpp index 7b859c143..9534fc4e3 100644 --- a/src/settings/modules/GlpkSettings.cpp +++ b/src/settings/modules/GlpkSettings.cpp @@ -10,13 +10,9 @@ namespace storm { const std::string GlpkSettings::integerToleranceOption = "inttol"; const std::string GlpkSettings::outputOptionName = "output"; - GlpkSettings::GlpkSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; - options.push_back(storm::settings::OptionBuilder(moduleName, outputOptionName, true, "If set, the glpk output will be printed to the command line.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, integerToleranceOption, true, "Sets glpk's precision for integer variables.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + GlpkSettings::GlpkSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, outputOptionName, true, "If set, the glpk output will be printed to the command line.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, integerToleranceOption, true, "Sets glpk's precision for integer variables.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); } } // namespace modules diff --git a/src/settings/modules/GlpkSettings.h b/src/settings/modules/GlpkSettings.h index 37420d117..c23b2add0 100644 --- a/src/settings/modules/GlpkSettings.h +++ b/src/settings/modules/GlpkSettings.h @@ -26,9 +26,18 @@ namespace storm { */ bool isOutputSet() const; + /*! + * Retrieves the integer tolerance to be used. + * + * @return The integer tolerance to be used. + */ + double getIntegerTolerance() const; + + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string integerToleranceOption; static const std::string outputOptionName; }; diff --git a/src/settings/modules/GmmxxEquationSolverSettings.cpp b/src/settings/modules/GmmxxEquationSolverSettings.cpp index 1e66f2b4f..2658fd0e2 100644 --- a/src/settings/modules/GmmxxEquationSolverSettings.cpp +++ b/src/settings/modules/GmmxxEquationSolverSettings.cpp @@ -15,26 +15,21 @@ namespace storm { const std::string GmmxxEquationSolverSettings::precisionOptionName = "precision"; const std::string GmmxxEquationSolverSettings::absoluteOptionName = "absolute"; - GmmxxEquationSolverSettings::GmmxxEquationSolverSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; + GmmxxEquationSolverSettings::GmmxxEquationSolverSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { std::vector<std::string> methods = {"bicgstab", "qmr", "gmres", "jacobi"}; - options.push_back(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the gmm++ engine. Available are {bicgstab, qmr, gmres, jacobi}.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(methods)).setDefaultValueString("gmres").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the gmm++ engine. Available are {bicgstab, qmr, gmres, jacobi}.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(methods)).setDefaultValueString("gmres").build()).build()); // Register available preconditioners. std::vector<std::string> preconditioner = {"ilu", "diagonal", "ildlt", "none"}; - options.push_back(storm::settings::OptionBuilder(moduleName, preconditionOptionName, true, "The preconditioning technique used for solving linear equation systems. Available are {ilu, diagonal, none}.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the preconditioning method.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(preconditioner)).setDefaultValueString("ilu").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, preconditionOptionName, true, "The preconditioning technique used for solving linear equation systems. Available are {ilu, diagonal, none}.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the preconditioning method.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(preconditioner)).setDefaultValueString("ilu").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, restartOptionName, true, "The number of iteration until restarted methods are actually restarted.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The number of iterations.").setDefaultValueUnsignedInteger(50).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, restartOptionName, true, "The number of iteration until restarted methods are actually restarted.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The number of iterations.").setDefaultValueUnsignedInteger(50).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, true, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("iterations", "The maximal iteration count.").setDefaultValueUnsignedInteger(10000).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, true, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("iterations", "The maximal iteration count.").setDefaultValueUnsignedInteger(10000).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, absoluteOptionName, true, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, absoluteOptionName, true, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); } } // namespace modules diff --git a/src/settings/modules/GmmxxEquationSolverSettings.h b/src/settings/modules/GmmxxEquationSolverSettings.h index 3fc1295a0..7504f7456 100644 --- a/src/settings/modules/GmmxxEquationSolverSettings.h +++ b/src/settings/modules/GmmxxEquationSolverSettings.h @@ -16,7 +16,7 @@ namespace storm { enum class LinearEquationTechnique { Bicgstab, Qmr, Gmres, Jacobi }; // An enumeration of all available preconditioning techniques. - enum class PreconditioningTechnique { Ilu, Diagonal, Ildlt, None }; + enum class PreconditioningTechnique { Ilu, Diagonal, None }; // An enumeration of all available convergence criteria. enum class ConvergenceCriterion { Absolute, Relative }; @@ -70,9 +70,11 @@ namespace storm { */ ConvergenceCriterion getConvergenceCriterion() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string techniqueOptionName; static const std::string preconditionOptionName; static const std::string restartOptionName; diff --git a/src/settings/modules/GurobiSettings.cpp b/src/settings/modules/GurobiSettings.cpp index a9713b31e..be78a59ee 100644 --- a/src/settings/modules/GurobiSettings.cpp +++ b/src/settings/modules/GurobiSettings.cpp @@ -11,17 +11,12 @@ namespace storm { const std::string GurobiSettings::threadsOption = "threads"; const std::string GurobiSettings::outputOption = "output"; - GurobiSettings::GurobiSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; - options.push_back(storm::settings::OptionBuilder(moduleName, threadsOption, true, "The number of threads that may be used by Gurobi.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The number of threads.").setDefaultValueUnsignedInteger(1).build()).build()); + GurobiSettings::GurobiSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, threadsOption, true, "The number of threads that may be used by Gurobi.").addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The number of threads.").setDefaultValueUnsignedInteger(1).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, outputOption, true, "If set, the Gurobi output will be printed to the command line.").build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, outputOption, true, "If set, the Gurobi output will be printed to the command line.").build()); - options.push_back(storm::settings::OptionBuilder(moduleName, integerToleranceOption, true, "Sets Gurobi's precision for integer variables.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, integerToleranceOption, true, "Sets Gurobi's precision for integer variables.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); } } // namespace modules diff --git a/src/settings/modules/GurobiSettings.h b/src/settings/modules/GurobiSettings.h index 763490ae9..d0e92127b 100644 --- a/src/settings/modules/GurobiSettings.h +++ b/src/settings/modules/GurobiSettings.h @@ -40,9 +40,11 @@ namespace storm { */ bool isOutputSet() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string integerToleranceOption; static const std::string threadsOption; static const std::string outputOption; diff --git a/src/settings/modules/ModuleSettings.cpp b/src/settings/modules/ModuleSettings.cpp index 239bd822e..8a877c6d7 100644 --- a/src/settings/modules/ModuleSettings.cpp +++ b/src/settings/modules/ModuleSettings.cpp @@ -4,7 +4,7 @@ namespace storm { namespace settings { namespace modules { - ModuleSettings::ModuleSettings(storm::settings::SettingsManager& settingsManager) : settingsManager(settingsManager) { + ModuleSettings::ModuleSettings(storm::settings::SettingsManager& settingsManager, std::string const& moduleName) : settingsManager(settingsManager), moduleName(moduleName) { // Intentionally left empty. } @@ -16,12 +16,12 @@ namespace storm { return this->settingsManager; } - void ModuleSettings::set(std::string const& name) const { - return this->getOption(longName).setHasOptionBeenSet(); + void ModuleSettings::set(std::string const& name) { + return this->getOption(name).setHasOptionBeenSet(); } - void ModuleSettings::unset(std::string const& longName) const { - return this->getOption(longName).setHasOptionBeenSet(false); + void ModuleSettings::unset(std::string const& name) { + return this->getOption(name).setHasOptionBeenSet(false); } } // namespace modules diff --git a/src/settings/modules/ModuleSettings.h b/src/settings/modules/ModuleSettings.h index 6f3e70ad2..6acb7d200 100644 --- a/src/settings/modules/ModuleSettings.h +++ b/src/settings/modules/ModuleSettings.h @@ -5,12 +5,12 @@ #include <unordered_map> #include "src/settings/Option.h" -#include "src/settings/SettingMemento.h" namespace storm { namespace settings { - // Forward-declare SettingsManager class. + // Forward-declare some classes. class SettingsManager; + class SettingMemento; namespace modules { @@ -19,12 +19,16 @@ namespace storm { */ class ModuleSettings { public: + // Declare the memento class as a friend so it can manipulate the internal state. + friend class storm::settings::SettingMemento; + /*! * Constructs a new settings object. * * @param settingsManager The manager responsible for these settings. + * @param moduleName The name of the module for which to build the settings. */ - ModuleSettings(storm::settings::SettingsManager& settingsManager); + ModuleSettings(storm::settings::SettingsManager& settingsManager, std::string const& moduleName); /*! * Checks whether the settings are consistent. If they are inconsistent, an exception is thrown. @@ -53,12 +57,9 @@ namespace storm { storm::settings::SettingsManager const& getSettingsManager() const; /*! - * Adds the option with the given long name to the list of options of this module. - * - * @param longName The long name of the option. - * @param option The actual option associated with the given name. + * Retrieves the name of the module to which these settings belong. */ - void addOption(std::string const& longName, std::shared_ptr<Option> const& option); + std::string const& getModuleName() const; /*! * Retrieves the option with the given long name. If no such option exists, an exception is thrown. @@ -82,7 +83,7 @@ namespace storm { * * @param name The name of the option to set. */ - void set(std::string const& name) const; + void set(std::string const& name); /*! * Unsets the option with the specified name. This requires the option to not have any arguments. This @@ -90,12 +91,22 @@ namespace storm { * * @param name The name of the option to unset. */ - void unset(std::string const& longName) const; + void unset(std::string const& name); + + /*! + * Adds and registers the given option. + * + * @param option The option to add and register. + */ + void addAndRegisterOption(std::shared_ptr<Option> option) const; private: // The settings manager responsible for the settings. storm::settings::SettingsManager const& settingsManager; + // The name of the module. + std::string moduleName; + // A mapping of option names of the module to the actual options. std::unordered_map<std::string, std::shared_ptr<Option>> options; }; diff --git a/src/settings/modules/NativeEquationSolverSettings.cpp b/src/settings/modules/NativeEquationSolverSettings.cpp index 191df9371..ddf50650b 100644 --- a/src/settings/modules/NativeEquationSolverSettings.cpp +++ b/src/settings/modules/NativeEquationSolverSettings.cpp @@ -13,20 +13,15 @@ namespace storm { const std::string NativeEquationSolverSettings::precisionOptionName = "precision"; const std::string NativeEquationSolverSettings::absoluteOptionName = "absolute"; - NativeEquationSolverSettings::NativeEquationSolverSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager) { - // First, we need to create all options of this module. - std::vector<std::shared_ptr<Option>> options; + NativeEquationSolverSettings::NativeEquationSolverSettings(storm::settings::SettingsManager& settingsManager) : ModuleSettings(settingsManager, moduleName) { std::vector<std::string> methods = { "jacobi" }; - options.push_back(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine. Available are: { jacobi }.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(methods)).setDefaultValueString("jacobi").build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, techniqueOptionName, true, "The method to be used for solving linear equation systems with the native engine. Available are: { jacobi }.").addArgument(storm::settings::ArgumentBuilder::createStringArgument("name", "The name of the method to use.").addValidationFunctionString(storm::settings::ArgumentValidators::stringInListValidator(methods)).setDefaultValueString("jacobi").build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, true, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(10000).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, maximalIterationsOptionName, true, "The maximal number of iterations to perform before iterative solving is aborted.").setShortName(maximalIterationsOptionShortName).addArgument(storm::settings::ArgumentBuilder::createUnsignedIntegerArgument("count", "The maximal iteration count.").setDefaultValueUnsignedInteger(10000).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, precisionOptionName, true, "The precision used for detecting convergence of iterative methods.").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("value", "The precision to achieve.").setDefaultValueDouble(1e-06).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build()); - options.push_back(storm::settings::OptionBuilder(moduleName, absoluteOptionName, true, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); - - // Finally, register all options that we just created. - settingsManager.registerModule(moduleName, options); + this->addAndRegisterOption(storm::settings::OptionBuilder(moduleName, absoluteOptionName, true, "Sets whether the relative or the absolute error is considered for detecting convergence.").build()); } } // namespace modules diff --git a/src/settings/modules/NativeEquationSolverSettings.h b/src/settings/modules/NativeEquationSolverSettings.h index da3d06fa4..04b58822a 100644 --- a/src/settings/modules/NativeEquationSolverSettings.h +++ b/src/settings/modules/NativeEquationSolverSettings.h @@ -48,9 +48,11 @@ namespace storm { */ ConvergenceCriterion getConvergenceCriterion() const; + // The name of the module. + static const std::string moduleName; + private: // Define the string names of the options as constants. - static const std::string moduleName; static const std::string techniqueOptionName; static const std::string maximalIterationsOptionName; static const std::string maximalIterationsOptionShortName; diff --git a/src/solver/GlpkLpSolver.cpp b/src/solver/GlpkLpSolver.cpp index e68528fa6..b61679929 100644 --- a/src/solver/GlpkLpSolver.cpp +++ b/src/solver/GlpkLpSolver.cpp @@ -21,7 +21,7 @@ namespace storm { glp_set_prob_name(lp, name.c_str()); // Set whether the glpk output shall be printed to the command line. - glp_term_out(storm::settings::SettingsManager::getInstance()->isSet("debug") || storm::settings::SettingsManager::getInstance()->isSet("glpkoutput") ? GLP_ON : GLP_OFF); + glp_term_out(storm::settings::debugSettings().isDebugSet() || storm::settings::glpkSettings().isOutputSet() ? GLP_ON : GLP_OFF); // Because glpk uses 1-based indexing (wtf!?), we need to put dummy elements into the matrix vectors. rowIndices.push_back(0); @@ -145,13 +145,13 @@ namespace storm { // Determine the type of the constraint and add it properly. switch (constraint.getOperator()) { case storm::expressions::OperatorType::Less: - glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightCoefficients.second - storm::settings::SettingsManager::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble()); + glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightCoefficients.second - storm::settings::glpkSettings().getIntegerTolerance()); break; case storm::expressions::OperatorType::LessOrEqual: glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_UP, 0, rightCoefficients.second); break; case storm::expressions::OperatorType::Greater: - glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightCoefficients.second + storm::settings::SettingsManager::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), 0); + glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightCoefficients.second + storm::settings::glpkSettings().getIntegerTolerance(), 0); break; case storm::expressions::OperatorType::GreaterOrEqual: glp_set_row_bnds(this->lp, nextConstraintIndex, GLP_LO, rightCoefficients.second, 0); @@ -187,7 +187,7 @@ namespace storm { glp_iocp* parameters = new glp_iocp(); glp_init_iocp(parameters); parameters->presolve = GLP_ON; - parameters->tol_int = storm::settings::SettingsManager::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(); + parameters->tol_int = storm::settings::glpkSettings().getIntegerTolerance(); error = glp_intopt(this->lp, parameters); delete parameters; @@ -285,7 +285,7 @@ namespace storm { } // Now check the desired precision was actually achieved. - LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::SettingsManager::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in glpk solution (" << value << ")."); + LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::glpkSettings().getIntegerTolerance(), storm::exceptions::InvalidStateException, "Illegal value for integer variable in glpk solution (" << value << ")."); return static_cast<int_fast64_t>(value); } @@ -307,7 +307,7 @@ namespace storm { value = glp_get_col_prim(this->lp, static_cast<int>(variableIndexPair->second)); } - LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::SettingsManager::getInstance()->getOptionByLongName("glpkinttol").getArgument(0).getValueAsDouble(), storm::exceptions::InvalidStateException, "Illegal value for binary variable in glpk solution (" << value << ")."); + LOG_THROW(std::abs(static_cast<int>(value) - value) <= storm::settings::glpkSettings().getIntegerTolerance(), storm::exceptions::InvalidStateException, "Illegal value for binary variable in glpk solution (" << value << ")."); return static_cast<bool>(value); } diff --git a/src/solver/GmmxxLinearEquationSolver.cpp b/src/solver/GmmxxLinearEquationSolver.cpp index 5f3d92275..6c0802996 100644 --- a/src/solver/GmmxxLinearEquationSolver.cpp +++ b/src/solver/GmmxxLinearEquationSolver.cpp @@ -24,34 +24,34 @@ namespace storm { template<typename ValueType> GmmxxLinearEquationSolver<ValueType>::GmmxxLinearEquationSolver() { // Get the settings object to customize linear solving. - storm::settings::SettingsManager* settings = storm::settings::SettingsManager::getInstance(); + storm::settings::modules::GmmxxEquationSolverSettings const& settings =storm::settings::gmmxxEquationSolverSettings(); // Get appropriate settings. - maximalNumberOfIterations = settings->getOptionByLongName("maxiter").getArgument(0).getValueAsUnsignedInteger(); - precision = settings->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); - relative = !settings->isSet("absolute"); - restart = settings->getOptionByLongName("gmmrestart").getArgument(0).getValueAsUnsignedInteger(); + maximalNumberOfIterations = settings.getMaximalIterationCount(); + precision = settings.getPrecision();; + relative = settings.getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative; + restart = settings.getRestartIterationCount(); // Determine the method to be used. - std::string const& methodAsString = settings->getOptionByLongName("gmmlin").getArgument(0).getValueAsString(); - if (methodAsString == "bicgstab") { - method = BICGSTAB; - } else if (methodAsString == "qmr") { - method = QMR; - } else if (methodAsString == "gmres") { - method = GMRES; - } else if (methodAsString == "jacobi") { - method = JACOBI; + storm::settings::modules::GmmxxEquationSolverSettings::LinearEquationTechnique methodAsSetting = settings.getLinearEquationSystemTechnique(); + if (methodAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::LinearEquationTechnique::Bicgstab) { + method = SolutionMethod::Bicgstab; + } else if (methodAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::LinearEquationTechnique::Qmr) { + method = SolutionMethod::Qmr; + } else if (methodAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::LinearEquationTechnique::Gmres) { + method = SolutionMethod::Gmres; + } else if (methodAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::LinearEquationTechnique::Jacobi) { + method = SolutionMethod::Jacobi; } // Check which preconditioner to use. - std::string const& preconditionAsString = settings->getOptionByLongName("gmmpre").getArgument(0).getValueAsString(); - if (preconditionAsString == "ilu") { - preconditioner = ILU; - } else if (preconditionAsString == "diagonal") { - preconditioner = DIAGONAL; - } else if (preconditionAsString == "none") { - preconditioner = NONE; + storm::settings::modules::GmmxxEquationSolverSettings::PreconditioningTechnique preconditionAsSetting = settings.getPreconditioningTechnique(); + if (preconditionAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::PreconditioningTechnique::Ilu) { + preconditioner = Preconditioner::Ilu; + } else if (preconditionAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::PreconditioningTechnique::Diagonal) { + preconditioner = Preconditioner::Diagonal; + } else if (preconditionAsSetting == storm::settings::modules::GmmxxEquationSolverSettings::PreconditioningTechnique::None) { + preconditioner = Preconditioner::None; } } @@ -63,38 +63,38 @@ namespace storm { template<typename ValueType> void GmmxxLinearEquationSolver<ValueType>::solveEquationSystem(storm::storage::SparseMatrix<ValueType> const& A, std::vector<ValueType>& x, std::vector<ValueType> const& b, std::vector<ValueType>* multiplyResult) const { LOG4CPLUS_INFO(logger, "Using method '" << methodToString() << "' with preconditioner " << preconditionerToString() << "'."); - if (method == JACOBI && preconditioner != NONE) { + if (method == SolutionMethod::Jacobi && preconditioner != Preconditioner::None) { LOG4CPLUS_WARN(logger, "Jacobi method currently does not support preconditioners. The requested preconditioner will be ignored."); } - if (method == BICGSTAB || method == QMR || method == GMRES) { + if (method == SolutionMethod::Bicgstab || method == SolutionMethod::Qmr || method == SolutionMethod::Gmres) { std::unique_ptr<gmm::csr_matrix<ValueType>> gmmA = storm::adapters::GmmxxAdapter::toGmmxxSparseMatrix<ValueType>(A); // Prepare an iteration object that determines the accuracy and the maximum number of iterations. gmm::iteration iter(precision, 0, maximalNumberOfIterations); - if (method == BICGSTAB) { - if (preconditioner == ILU) { + if (method == SolutionMethod::Bicgstab) { + if (preconditioner == Preconditioner::Ilu) { gmm::bicgstab(*gmmA, x, b, gmm::ilu_precond<gmm::csr_matrix<ValueType>>(*gmmA), iter); - } else if (preconditioner == DIAGONAL) { + } else if (preconditioner == Preconditioner::Diagonal) { gmm::bicgstab(*gmmA, x, b, gmm::diagonal_precond<gmm::csr_matrix<ValueType>>(*gmmA), iter); - } else if (preconditioner == NONE) { + } else if (preconditioner == Preconditioner::None) { gmm::bicgstab(*gmmA, x, b, gmm::identity_matrix(), iter); } - } else if (method == QMR) { - if (preconditioner == ILU) { + } else if (method == SolutionMethod::Qmr) { + if (preconditioner == Preconditioner::Ilu) { gmm::qmr(*gmmA, x, b, gmm::ilu_precond<gmm::csr_matrix<ValueType>>(*gmmA), iter); - } else if (preconditioner == DIAGONAL) { + } else if (preconditioner == Preconditioner::Diagonal) { gmm::qmr(*gmmA, x, b, gmm::diagonal_precond<gmm::csr_matrix<ValueType>>(*gmmA), iter); - } else if (preconditioner == NONE) { + } else if (preconditioner == Preconditioner::None) { gmm::qmr(*gmmA, x, b, gmm::identity_matrix(), iter); } - } else if (method == GMRES) { - if (preconditioner == ILU) { + } else if (method == SolutionMethod::Qmr) { + if (preconditioner == Preconditioner::Ilu) { gmm::gmres(*gmmA, x, b, gmm::ilu_precond<gmm::csr_matrix<ValueType>>(*gmmA), restart, iter); - } else if (preconditioner == DIAGONAL) { + } else if (preconditioner == Preconditioner::Diagonal) { gmm::gmres(*gmmA, x, b, gmm::diagonal_precond<gmm::csr_matrix<ValueType>>(*gmmA), restart, iter); - } else if (preconditioner == NONE) { + } else if (preconditioner == Preconditioner::None) { gmm::gmres(*gmmA, x, b, gmm::identity_matrix(), restart, iter); } } @@ -105,7 +105,7 @@ namespace storm { } else { LOG4CPLUS_WARN(logger, "Iterative solver did not converge."); } - } else if (method == JACOBI) { + } else if (method == SolutionMethod::Jacobi) { uint_fast64_t iterations = solveLinearEquationSystemWithJacobi(A, x, b, multiplyResult); // Check if the solver converged and issue a warning otherwise. @@ -216,29 +216,20 @@ namespace storm { template<typename ValueType> std::string GmmxxLinearEquationSolver<ValueType>::methodToString() const { - if (method == BICGSTAB) { - return "bicgstab"; - } else if (method == QMR) { - return "qmr"; - } else if (method == GMRES) { - return "gmres"; - } else if (method == JACOBI) { - return "jacobi"; - } else { - throw storm::exceptions::InvalidStateException() << "Illegal method '" << method << "' set in GmmxxLinearEquationSolver."; + switch (method) { + case SolutionMethod::Bicgstab: return "bicgstab"; + case SolutionMethod::Qmr: return "qmr"; + case SolutionMethod::Gmres: return "gmres"; + case SolutionMethod::Jacobi: return "jacobi"; } } template<typename ValueType> std::string GmmxxLinearEquationSolver<ValueType>::preconditionerToString() const { - if (preconditioner == ILU) { - return "ilu"; - } else if (preconditioner == DIAGONAL) { - return "diagonal"; - } else if (preconditioner == NONE) { - return "none"; - } else { - throw storm::exceptions::InvalidStateException() << "Illegal preconditioner '" << preconditioner << "' set in GmmxxLinearEquationSolver."; + switch (preconditioner) { + case Preconditioner::Ilu: return "ilu"; + case Preconditioner::Diagonal: return "diagonal"; + case Preconditioner::None: return "none"; } } diff --git a/src/solver/GmmxxLinearEquationSolver.h b/src/solver/GmmxxLinearEquationSolver.h index a67de0764..63f97a9cb 100644 --- a/src/solver/GmmxxLinearEquationSolver.h +++ b/src/solver/GmmxxLinearEquationSolver.h @@ -13,13 +13,13 @@ namespace storm { class GmmxxLinearEquationSolver : public LinearEquationSolver<ValueType> { public: // An enumeration specifying the available preconditioners. - enum Preconditioner { - ILU, DIAGONAL, NONE + enum class Preconditioner { + Ilu, Diagonal, None }; // An enumeration specifying the available solution methods. - enum SolutionMethod { - BICGSTAB, QMR, GMRES, JACOBI + enum class SolutionMethod { + Bicgstab, Qmr, Gmres, Jacobi }; /*! diff --git a/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp b/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp index 5de34200e..abd11ad73 100644 --- a/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp +++ b/src/solver/GmmxxNondeterministicLinearEquationSolver.cpp @@ -12,12 +12,12 @@ namespace storm { template<typename ValueType> GmmxxNondeterministicLinearEquationSolver<ValueType>::GmmxxNondeterministicLinearEquationSolver() { // Get the settings object to customize solving. - storm::settings::SettingsManager* settings = storm::settings::SettingsManager::getInstance(); + storm::settings::modules::GmmxxEquationSolverSettings const& settings = storm::settings::gmmxxEquationSolverSettings(); // Get appropriate settings. - maximalNumberOfIterations = settings->getOptionByLongName("maxiter").getArgument(0).getValueAsUnsignedInteger(); - precision = settings->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); - relative = !settings->isSet("absolute"); + maximalNumberOfIterations = settings.getMaximalIterationCount(); + precision = settings.getPrecision(); + relative = settings.getConvergenceCriterion() == storm::settings::modules::GmmxxEquationSolverSettings::ConvergenceCriterion::Relative; } template<typename ValueType> diff --git a/src/solver/NativeLinearEquationSolver.cpp b/src/solver/NativeLinearEquationSolver.cpp index 47ca2f0e4..14c520068 100644 --- a/src/solver/NativeLinearEquationSolver.cpp +++ b/src/solver/NativeLinearEquationSolver.cpp @@ -17,17 +17,17 @@ namespace storm { template<typename ValueType> NativeLinearEquationSolver<ValueType>::NativeLinearEquationSolver() { // Get the settings object to customize linear solving. - storm::settings::SettingsManager* settings = storm::settings::SettingsManager::getInstance(); + storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings(); // Get appropriate settings. - maximalNumberOfIterations = settings->getOptionByLongName("maxiter").getArgument(0).getValueAsUnsignedInteger(); - precision = settings->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); - relative = !settings->isSet("absolute"); + maximalNumberOfIterations = settings.getMaximalIterationCount(); + precision = settings.getPrecision(); + relative = settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative; // Determine the method to be used. - std::string const& methodAsString = settings->getOptionByLongName("nativelin").getArgument(0).getValueAsString(); - if (methodAsString == "jacobi") { - method = JACOBI; + storm::settings::modules::NativeEquationSolverSettings::LinearEquationTechnique methodAsSetting = settings.getLinearEquationSystemTechnique(); + if (methodAsSetting == storm::settings::modules::NativeEquationSolverSettings::LinearEquationTechnique::Jacobi) { + method = SolutionMethod::Jacobi; } } @@ -127,10 +127,8 @@ namespace storm { template<typename ValueType> std::string NativeLinearEquationSolver<ValueType>::methodToString() const { - if (method == JACOBI) { - return "jacobi"; - } else { - throw storm::exceptions::InvalidStateException() << "Illegal method '" << method << "' set in NativeLinearEquationSolver."; + switch (method) { + case SolutionMethod::Jacobi: return "jacobi"; } } diff --git a/src/solver/NativeLinearEquationSolver.h b/src/solver/NativeLinearEquationSolver.h index af94cdb43..69504b627 100644 --- a/src/solver/NativeLinearEquationSolver.h +++ b/src/solver/NativeLinearEquationSolver.h @@ -13,8 +13,8 @@ namespace storm { class NativeLinearEquationSolver : public LinearEquationSolver<ValueType> { public: // An enumeration specifying the available solution methods. - enum SolutionMethod { - JACOBI + enum class SolutionMethod { + Jacobi }; /*! diff --git a/src/solver/NativeNondeterministicLinearEquationSolver.cpp b/src/solver/NativeNondeterministicLinearEquationSolver.cpp index 478448ed5..04867cab3 100644 --- a/src/solver/NativeNondeterministicLinearEquationSolver.cpp +++ b/src/solver/NativeNondeterministicLinearEquationSolver.cpp @@ -11,12 +11,12 @@ namespace storm { template<typename ValueType> NativeNondeterministicLinearEquationSolver<ValueType>::NativeNondeterministicLinearEquationSolver() { // Get the settings object to customize solving. - storm::settings::SettingsManager* settings = storm::settings::SettingsManager::getInstance(); + storm::settings::modules::NativeEquationSolverSettings const& settings = storm::settings::nativeEquationSolverSettings(); // Get appropriate settings. - maximalNumberOfIterations = settings->getOptionByLongName("maxiter").getArgument(0).getValueAsUnsignedInteger(); - precision = settings->getOptionByLongName("precision").getArgument(0).getValueAsDouble(); - relative = !settings->isSet("absolute"); + maximalNumberOfIterations = settings.getMaximalIterationCount(); + precision = settings.getPrecision(); + relative = settings.getConvergenceCriterion() == storm::settings::modules::NativeEquationSolverSettings::ConvergenceCriterion::Relative; } template<typename ValueType> diff --git a/src/storage/dd/CuddDdManager.cpp b/src/storage/dd/CuddDdManager.cpp index e98d7f8fe..cd19fa037 100644 --- a/src/storage/dd/CuddDdManager.cpp +++ b/src/storage/dd/CuddDdManager.cpp @@ -10,47 +10,30 @@ namespace storm { namespace dd { DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager(), reorderingTechnique(CUDD_REORDER_NONE) { - this->cuddManager.SetMaxMemory(static_cast<unsigned long>(storm::settings::SettingsManager::getInstance()->getOptionByLongName("cuddmaxmem").getArgument(0).getValueAsUnsignedInteger() * 1024ul * 1024ul)); - this->cuddManager.SetEpsilon(storm::settings::SettingsManager::getInstance()->getOptionByLongName("cuddprec").getArgument(0).getValueAsDouble()); + this->cuddManager.SetMaxMemory(static_cast<unsigned long>(storm::settings::cuddSettings().getMaximalMemory() * 1024ul * 1024ul)); + this->cuddManager.SetEpsilon(storm::settings::cuddSettings().getConstantPrecision()); // Now set the selected reordering technique. - std::string const& reorderingTechnique = storm::settings::SettingsManager::getInstance()->getOptionByLongName("reorder").getArgument(0).getValueAsString(); - if (reorderingTechnique == "none") { - this->reorderingTechnique = CUDD_REORDER_NONE; - } else if (reorderingTechnique == "random") { - this->reorderingTechnique = CUDD_REORDER_RANDOM; - } else if (reorderingTechnique == "randompivot") { - this->reorderingTechnique = CUDD_REORDER_RANDOM_PIVOT; - } else if (reorderingTechnique == "sift") { - this->reorderingTechnique = CUDD_REORDER_SIFT; - } else if (reorderingTechnique == "siftconv") { - this->reorderingTechnique = CUDD_REORDER_SIFT_CONVERGE; - } else if (reorderingTechnique == "ssift") { - this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT; - } else if (reorderingTechnique == "ssiftconv") { - this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT_CONV; - } else if (reorderingTechnique == "gsift") { - this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT; - } else if (reorderingTechnique == "gsiftconv") { - this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT_CONV; - } else if (reorderingTechnique == "win2") { - this->reorderingTechnique = CUDD_REORDER_WINDOW2; - } else if (reorderingTechnique == "win2conv") { - this->reorderingTechnique = CUDD_REORDER_WINDOW2_CONV; - } else if (reorderingTechnique == "win3") { - this->reorderingTechnique = CUDD_REORDER_WINDOW3; - } else if (reorderingTechnique == "win3conv") { - this->reorderingTechnique = CUDD_REORDER_WINDOW3_CONV; - } else if (reorderingTechnique == "win4") { - this->reorderingTechnique = CUDD_REORDER_WINDOW4; - } else if (reorderingTechnique == "win4conv") { - this->reorderingTechnique = CUDD_REORDER_WINDOW4_CONV; - } else if (reorderingTechnique == "annealing") { - this->reorderingTechnique = CUDD_REORDER_ANNEALING; - } else if (reorderingTechnique == "genetic") { - this->reorderingTechnique = CUDD_REORDER_GENETIC; - } else if (reorderingTechnique == "exact") { - this->reorderingTechnique = CUDD_REORDER_EXACT; + storm::settings::modules::CuddSettings::ReorderingTechnique reorderingTechniqueAsSetting = storm::settings::cuddSettings().getReorderingTechnique(); + switch (reorderingTechniqueAsSetting) { + case storm::settings::modules::CuddSettings::ReorderingTechnique::None: this->reorderingTechnique = CUDD_REORDER_NONE; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Random: this->reorderingTechnique = CUDD_REORDER_RANDOM; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::RandomPivot: this->reorderingTechnique = CUDD_REORDER_RANDOM_PIVOT; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Sift: this->reorderingTechnique = CUDD_REORDER_SIFT; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::SiftConv: this->reorderingTechnique = CUDD_REORDER_SIFT_CONVERGE; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::SymmetricSift: this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::SymmetricSiftConv: this->reorderingTechnique = CUDD_REORDER_SYMM_SIFT_CONV; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::GroupSift: this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::GroupSiftConv: this->reorderingTechnique = CUDD_REORDER_GROUP_SIFT_CONV; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win2: this->reorderingTechnique = CUDD_REORDER_WINDOW2; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win2Conv: this->reorderingTechnique = CUDD_REORDER_WINDOW2_CONV; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win3: this->reorderingTechnique = CUDD_REORDER_WINDOW3; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win3Conv: this->reorderingTechnique = CUDD_REORDER_WINDOW3_CONV; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win4: this->reorderingTechnique = CUDD_REORDER_WINDOW4; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Win4Conv: this->reorderingTechnique = CUDD_REORDER_WINDOW4_CONV; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Annealing: this->reorderingTechnique = CUDD_REORDER_ANNEALING; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Genetic: this->reorderingTechnique = CUDD_REORDER_GENETIC; break; + case storm::settings::modules::CuddSettings::ReorderingTechnique::Exact: this->reorderingTechnique = CUDD_REORDER_EXACT; break; } } diff --git a/src/storm.cpp b/src/storm.cpp index 6bc2bad72..eafdb78c8 100644 --- a/src/storm.cpp +++ b/src/storm.cpp @@ -42,7 +42,7 @@ #include "src/solver/NativeLinearEquationSolver.h" #include "src/solver/GmmxxNondeterministicLinearEquationSolver.h" #include "src/solver/GurobiLpSolver.h" -#include "src/counterexamples/GenerateCounterexample.h" +// #include "src/counterexamples/GenerateCounterexample.h" #include "src/counterexamples/MILPMinimalLabelSetGenerator.h" #include "src/counterexamples/SMTMinimalCommandSetGenerator.h" #include "src/counterexamples/PathBasedSubsystemGenerator.h" @@ -73,9 +73,9 @@ * @param modelchecker The model checker that is to be invoked on all given formulae. */ void checkPrctlFormulae(storm::modelchecker::prctl::AbstractModelChecker<double> const& modelchecker) { - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - if (s->isSet("prctl")) { - std::string const chosenPrctlFile = s->getOptionByLongName("prctl").getArgument(0).getValueAsString(); + storm::settings::modules::GeneralSettings const& settings = storm::settings::generalSettings(); + if (settings.isPctlSet()) { + std::string chosenPrctlFile = settings.getPctlPropertiesFilename(); LOG4CPLUS_INFO(logger, "Parsing prctl file: " << chosenPrctlFile << "."); std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(chosenPrctlFile); @@ -110,12 +110,12 @@ int main(const int argc, const char* argv[]) { // If parsing failed or the option to see the usage was set, program execution stops here. return 0; } - + + storm::settings::modules::GeneralSettings settings = storm::settings::generalSettings(); + // If requested by the user, we install a timeout signal to abort computation. - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - uint_fast64_t timeout = s->getOptionByLongName("timeout").getArgument(0).getValueAsUnsignedInteger(); - if (timeout != 0) { - stormSetAlarm(timeout); + if (settings.isTimeoutSet()) { + stormSetAlarm(settings.getTimeoutInSeconds()); } // Execution Time measurement, start @@ -123,17 +123,17 @@ int main(const int argc, const char* argv[]) { // Now, the settings are received and the specified model is parsed. The actual actions taken depend on whether // the model was provided in explicit or symbolic format. - if (s->isSet("explicit")) { - std::string const chosenTransitionSystemFile = s->getOptionByLongName("explicit").getArgument(0).getValueAsString(); - std::string const chosenLabelingFile = s->getOptionByLongName("explicit").getArgument(1).getValueAsString(); + if (settings.isExplicitSet()) { + std::string const chosenTransitionSystemFile = settings.getTransitionFilename(); + std::string const chosenLabelingFile = settings.getLabelingFilename(); std::string chosenStateRewardsFile = ""; - if (s->isSet("stateRewards")) { - chosenStateRewardsFile = s->getOptionByLongName("stateRewards").getArgument(0).getValueAsString(); + if (settings.isStateRewardsSet()) { + chosenStateRewardsFile = settings.getStateRewardsFilename(); } std::string chosenTransitionRewardsFile = ""; - if (s->isSet("transitionRewards")) { - chosenTransitionRewardsFile = s->getOptionByLongName("transitionRewards").getArgument(0).getValueAsString(); + if (settings.isTransitionRewardsSet()) { + chosenTransitionRewardsFile = settings.getTransitionRewardsFilename(); } std::shared_ptr<storm::models::AbstractModel<double>> model = storm::parser::AutoParser::parseModel(chosenTransitionSystemFile, chosenLabelingFile, chosenStateRewardsFile, chosenTransitionRewardsFile); @@ -142,19 +142,19 @@ int main(const int argc, const char* argv[]) { std::chrono::high_resolution_clock::time_point parsingEnd = std::chrono::high_resolution_clock::now(); std::cout << "Parsing the given model took " << std::chrono::duration_cast<std::chrono::milliseconds>(parsingEnd - executionStart).count() << " milliseconds." << std::endl; - if (s->isSet("exportdot")) { + if (settings.isExportDotSet()) { std::ofstream outputFileStream; - outputFileStream.open(s->getOptionByLongName("exportdot").getArgument(0).getValueAsString(), std::ofstream::out); + outputFileStream.open(settings.getExportDotFilename(), std::ofstream::out); model->writeDotToStream(outputFileStream); outputFileStream.close(); } // Should there be a counterexample generated in case the formula is not satisfied? - if(s->isSet("counterexample")) { + if(settings.isCounterexampleSet()) { // Counterexample Time Measurement, Start std::chrono::high_resolution_clock::time_point counterexampleStart = std::chrono::high_resolution_clock::now(); - generateCounterExample(model); + // generateCounterExample(model); // Counterexample Time Measurement, End std::chrono::high_resolution_clock::time_point counterexampleEnd = std::chrono::high_resolution_clock::now(); @@ -213,13 +213,13 @@ int main(const int argc, const char* argv[]) { std::chrono::high_resolution_clock::time_point modelcheckingEnd = std::chrono::high_resolution_clock::now(); std::cout << "Running the ModelChecker took " << std::chrono::duration_cast<std::chrono::milliseconds>(modelcheckingEnd - modelcheckingStart).count() << " milliseconds." << std::endl; } - } else if (s->isSet("symbolic")) { + } else if (settings.isSymbolicSet()) { // Program Translation Time Measurement, Start std::chrono::high_resolution_clock::time_point programTranslationStart = std::chrono::high_resolution_clock::now(); // First, we build the model using the given symbolic model description and constant definitions. - std::string const& programFile = s->getOptionByLongName("symbolic").getArgument(0).getValueAsString(); - std::string const& constants = s->getOptionByLongName("constants").getArgument(0).getValueAsString(); + std::string const& programFile = settings.getSymbolicModelFilename(); + std::string const& constants = settings.getConstantDefinitionString(); storm::prism::Program program = storm::parser::PrismParser::parse(programFile); std::shared_ptr<storm::models::AbstractModel<double>> model = storm::adapters::ExplicitModelAdapter<double>::translateProgram(program, constants); model->printModelInformationToStream(std::cout); @@ -236,7 +236,7 @@ int main(const int argc, const char* argv[]) { double value = modelChecker.computeReachabilityProbability(*model->as<storm::models::Dtmc<double>>(), trueStates, targetStates); std::cout << "computed value " << value << std::endl; - if (s->isSet("mincmd")) { + if (storm::settings::counterexampleGeneratorSettings().isMinimalCommandGenerationSet()) { if (model->getType() != storm::models::MDP) { LOG4CPLUS_ERROR(logger, "Minimal command counterexample generation is only supported for models of type MDP."); throw storm::exceptions::InternalTypeErrorException() << "Minimal command counterexample generation is only supported for models of type MDP."; @@ -245,13 +245,13 @@ int main(const int argc, const char* argv[]) { std::shared_ptr<storm::models::Mdp<double>> mdp = model->as<storm::models::Mdp<double>>(); // Determine whether we are required to use the MILP-version or the SAT-version. - bool useMILP = s->getOptionByLongName("mincmd").getArgumentByName("method").getValueAsString() == "milp"; + bool useMILP = storm::settings::counterexampleGeneratorSettings().useMilpBasedMinimalCommandSetGeneration(); // MinCMD Time Measurement, Start std::chrono::high_resolution_clock::time_point minCmdStart = std::chrono::high_resolution_clock::now(); // Now parse the property file and receive the list of parsed formulas. - std::string const& propertyFile = s->getOptionByLongName("mincmd").getArgumentByName("propertyFile").getValueAsString(); + std::string const& propertyFile = storm::settings::generalSettings().getPctlPropertiesFilename(); std::list<std::shared_ptr<storm::properties::prctl::PrctlFilter<double>>> formulaList = storm::parser::PrctlFileParser::parsePrctlFile(propertyFile); // Now generate the counterexamples for each formula. @@ -266,7 +266,7 @@ int main(const int argc, const char* argv[]) { // MinCMD Time Measurement, End std::chrono::high_resolution_clock::time_point minCmdEnd = std::chrono::high_resolution_clock::now(); std::cout << "Minimal command Counterexample generation took " << std::chrono::duration_cast<std::chrono::milliseconds>(minCmdEnd - minCmdStart).count() << " milliseconds." << std::endl; - } else if (s->isSet("prctl")) { + } else if (settings.isPctlSet()) { // // Depending on the model type, the appropriate model checking procedure is chosen. // storm::modelchecker::prctl::AbstractModelChecker<double>* modelchecker = nullptr; // diff --git a/src/utility/CLI.h b/src/utility/CLI.h index 5df81d10b..d70c89f57 100644 --- a/src/utility/CLI.h +++ b/src/utility/CLI.h @@ -127,35 +127,36 @@ void printHeader(const int argc, const char* argv[]) { * @return True iff the program should continue to run after parsing the options. */ bool parseOptions(const int argc, const char* argv[]) { - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); + storm::settings::SettingsManager& manager = storm::settings::manager(); try { - storm::settings::SettingsManager::parse(argc, argv); + manager.setFromCommandLine(argc, argv); } catch (storm::exceptions::OptionParserException& e) { std::cout << "Could not recover from settings error: " << e.what() << "." << std::endl; - std::cout << std::endl << s->getHelpText(); + std::cout << std::endl; + manager.printHelp(); return false; } - if (s->isSet("help")) { - std::cout << storm::settings::SettingsManager::getInstance()->getHelpText(); + if (storm::settings::generalSettings().isHelpSet()) { + storm::settings::manager().printHelp(); return false; } - if (s->isSet("verbose")) { + if (storm::settings::generalSettings().isVerboseSet()) { logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::INFO_LOG_LEVEL); LOG4CPLUS_INFO(logger, "Enabled verbose mode, log output gets printed to console."); } - if (s->isSet("debug")) { + if (storm::settings::debugSettings().isDebugSet()) { logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL); logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::DEBUG_LOG_LEVEL); LOG4CPLUS_INFO(logger, "Enabled very verbose mode, log output gets printed to console."); } - if (s->isSet("trace")) { + if (storm::settings::debugSettings().isTraceSet()) { logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL); logger.getAppender("mainConsoleAppender")->setThreshold(log4cplus::TRACE_LOG_LEVEL); LOG4CPLUS_INFO(logger, "Enabled trace mode, log output gets printed to console."); } - if (s->isSet("logfile")) { + if (storm::settings::debugSettings().isLogfileSet()) { setUpFileLogging(); } return true; diff --git a/src/utility/InitializeLogging.h b/src/utility/InitializeLogging.h index eefd0f604..ea8394705 100644 --- a/src/utility/InitializeLogging.h +++ b/src/utility/InitializeLogging.h @@ -27,8 +27,7 @@ void initializeLogger() { * Sets up the logging to file. */ void setUpFileLogging() { - storm::settings::SettingsManager* s = storm::settings::SettingsManager::getInstance(); - log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender(s->getOptionByLongName("logfile").getArgument(0).getValueAsString())); + log4cplus::SharedAppenderPtr fileLogAppender(new log4cplus::FileAppender(storm::settings::debugSettings().getLogfilename())); fileLogAppender->setName("mainFileAppender"); fileLogAppender->setLayout(std::auto_ptr<log4cplus::Layout>(new log4cplus::PatternLayout("%-5p - %D{%H:%M:%S} (%r ms) - %F:%L: %m%n"))); logger.addAppender(fileLogAppender); diff --git a/src/utility/solver.cpp b/src/utility/solver.cpp index 5531f61e5..e18cab3f2 100644 --- a/src/utility/solver.cpp +++ b/src/utility/solver.cpp @@ -14,44 +14,35 @@ namespace storm { namespace utility { namespace solver { - std::shared_ptr<storm::solver::LpSolver> getLpSolver(std::string const& name) { - std::string const& lpSolver = storm::settings::SettingsManager::getInstance()->getOptionByLongName("lpsolver").getArgument(0).getValueAsString(); - if (lpSolver == "gurobi") { - return std::shared_ptr<storm::solver::LpSolver>(new storm::solver::GurobiLpSolver(name)); - } else if (lpSolver == "glpk") { - return std::shared_ptr<storm::solver::LpSolver>(new storm::solver::GlpkLpSolver(name)); + std::unique_ptr<storm::solver::LpSolver> getLpSolver(std::string const& name) { + storm::settings::modules::GeneralSettings::LpSolver lpSolver = storm::settings::generalSettings().getLpSolver(); + switch (lpSolver) { + case storm::settings::modules::GeneralSettings::LpSolver::Gurobi: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GurobiLpSolver(name)); + case storm::settings::modules::GeneralSettings::LpSolver::glpk: return std::unique_ptr<storm::solver::LpSolver>(new storm::solver::GlpkLpSolver(name)); } - - throw storm::exceptions::InvalidSettingsException() << "No suitable LP solver selected."; } template<typename ValueType> - std::shared_ptr<storm::solver::LinearEquationSolver<ValueType>> getLinearEquationSolver() { - std::string const& linearEquationSolver = storm::settings::SettingsManager::getInstance()->getOptionByLongName("linsolver").getArgument(0).getValueAsString(); - if (linearEquationSolver == "gmm++") { - return std::shared_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::GmmxxLinearEquationSolver<ValueType>()); - } else if (linearEquationSolver == "native") { - return std::shared_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::NativeLinearEquationSolver<ValueType>()); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> getLinearEquationSolver() { + storm::settings::modules::GeneralSettings::EquationSolver equationSolver = storm::settings::generalSettings().getEquationSolver(); + switch (equationSolver) { + case storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::GmmxxLinearEquationSolver<ValueType>()); + case storm::settings::modules::GeneralSettings::EquationSolver::Native: return std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>>(new storm::solver::NativeLinearEquationSolver<ValueType>()); } - - throw storm::exceptions::InvalidSettingsException() << "No suitable linear equation solver selected."; } template<typename ValueType> - std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> getNondeterministicLinearEquationSolver() { - std::string const& nondeterministicLinearEquationSolver = storm::settings::SettingsManager::getInstance()->getOptionByLongName("ndsolver").getArgument(0).getValueAsString(); - if (nondeterministicLinearEquationSolver == "gmm++") { - return std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>>(new storm::solver::GmmxxNondeterministicLinearEquationSolver<ValueType>()); - } else if (nondeterministicLinearEquationSolver == "native") { - return std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>>(new storm::solver::NativeNondeterministicLinearEquationSolver<ValueType>()); + std::unique_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> getNondeterministicLinearEquationSolver() { + storm::settings::modules::GeneralSettings::EquationSolver equationSolver = storm::settings::generalSettings().getEquationSolver(); + switch (equationSolver) { + case storm::settings::modules::GeneralSettings::EquationSolver::Gmmxx: return std::unique_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>>(new storm::solver::GmmxxNondeterministicLinearEquationSolver<ValueType>()); + case storm::settings::modules::GeneralSettings::EquationSolver::Native: return std::unique_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>>(new storm::solver::NativeNondeterministicLinearEquationSolver<ValueType>()); } - - throw storm::exceptions::InvalidSettingsException() << "No suitable nondeterministic linear equation solver selected."; } - template std::shared_ptr<storm::solver::LinearEquationSolver<double>> getLinearEquationSolver(); + template std::unique_ptr<storm::solver::LinearEquationSolver<double>> getLinearEquationSolver(); - template std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<double>> getNondeterministicLinearEquationSolver(); + template std::unique_ptr<storm::solver::NondeterministicLinearEquationSolver<double>> getNondeterministicLinearEquationSolver(); } } } \ No newline at end of file diff --git a/src/utility/solver.h b/src/utility/solver.h index e5e7d456f..357a42f0a 100644 --- a/src/utility/solver.h +++ b/src/utility/solver.h @@ -11,13 +11,13 @@ namespace storm { namespace utility { namespace solver { - std::shared_ptr<storm::solver::LpSolver> getLpSolver(std::string const& name); + std::unique_ptr<storm::solver::LpSolver> getLpSolver(std::string const& name); template<typename ValueType> - std::shared_ptr<storm::solver::LinearEquationSolver<ValueType>> getLinearEquationSolver(); + std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> getLinearEquationSolver(); template<typename ValueType> - std::shared_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> getNondeterministicLinearEquationSolver(); + std::unique_ptr<storm::solver::NondeterministicLinearEquationSolver<ValueType>> getNondeterministicLinearEquationSolver(); } }