diff --git a/src/storm/cli/cli.cpp b/src/storm/cli/cli.cpp index 84c7c1c96..e8f1e5f8b 100644 --- a/src/storm/cli/cli.cpp +++ b/src/storm/cli/cli.cpp @@ -221,6 +221,12 @@ namespace storm { storm::utility::initializeFileLogging(); } + boost::optional> propertyFilter; + std::string propertyFilterString = storm::settings::getModule().getPropertyFilter(); + if (propertyFilterString != "all") { + propertyFilter = storm::parsePropertyFilter(storm::settings::getModule().getPropertyFilter()); + } + auto ioSettings = storm::settings::getModule(); if (ioSettings.isPrismOrJaniInputSet()) { storm::storage::SymbolicModelDescription model; @@ -244,29 +250,21 @@ namespace storm { } - // Then proceed to parsing the properties (if given), since the model we are building may depend on the property. - STORM_LOG_TRACE("Parsing properties."); - uint64_t i = 0; - // Get the string that assigns values to the unknown currently undefined constants in the model and formula. std::string constantDefinitionString = ioSettings.getConstantDefinitionString(); std::map constantDefinitions; + // Then proceed to parsing the properties (if given), since the model we are building may depend on the property. + STORM_LOG_TRACE("Parsing properties."); if (storm::settings::getModule().isPropertySet()) { - std::vector> formulas; if (model.isJaniModel()) { - formulas = storm::parseFormulasForJaniModel(storm::settings::getModule().getProperty(), model.asJaniModel()); + properties = storm::parsePropertiesForJaniModel(storm::settings::getModule().getProperty(), model.asJaniModel(), propertyFilter); } else { - formulas = storm::parseFormulasForPrismProgram(storm::settings::getModule().getProperty(), model.asPrismProgram()); + properties = storm::parsePropertiesForPrismProgram(storm::settings::getModule().getProperty(), model.asPrismProgram(), propertyFilter); } constantDefinitions = model.parseConstantDefinitions(constantDefinitionString); - formulas = substituteConstantsInFormulas(formulas, constantDefinitions); - - for (auto const& formula : formulas) { - properties.emplace_back(std::to_string(i), formula); - ++i; - } + properties = substituteConstantsInProperties(properties, constantDefinitions); } else { constantDefinitions = model.parseConstantDefinitions(constantDefinitionString); } @@ -303,12 +301,7 @@ namespace storm { // in formulas. std::vector properties; if (storm::settings::getModule().isPropertySet()) { - uint64_t i = 0; - for(auto const& formula : storm::parseFormulasForExplicit(storm::settings::getModule().getProperty())) { - properties.emplace_back(std::to_string(i), formula); - ++i; - - } + properties = storm::parsePropertiesForExplicit(storm::settings::getModule().getProperty(), propertyFilter); } buildAndCheckExplicitModel(properties, true); diff --git a/src/storm/cli/entrypoints.h b/src/storm/cli/entrypoints.h index dab863e69..9462f2643 100644 --- a/src/storm/cli/entrypoints.h +++ b/src/storm/cli/entrypoints.h @@ -267,7 +267,7 @@ namespace storm { template void buildAndCheckSymbolicModelWithSymbolicEngine(bool hybrid, storm::storage::SymbolicModelDescription const& model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { // Start by building the model. - auto markovModel = buildSymbolicModel(model, formulasInProperties(properties)); + auto markovModel = buildSymbolicModel(model, extractFormulasFromProperties(properties)); // Print some information about the model. markovModel->printModelInformationToStream(std::cout); @@ -282,7 +282,7 @@ namespace storm { template void buildAndCheckSymbolicModelWithSparseEngine(storm::storage::SymbolicModelDescription const& model, std::vector const& properties, bool onlyInitialStatesRelevant = false) { - auto formulas = formulasInProperties(properties); + auto formulas = extractFormulasFromProperties(properties); // Start by building the model. std::shared_ptr markovModel = buildSparseModel(model, formulas); @@ -362,7 +362,7 @@ namespace storm { std::shared_ptr model = buildExplicitModel(settings.getTransitionFilename(), settings.getLabelingFilename(), settings.isStateRewardsSet() ? boost::optional(settings.getStateRewardsFilename()) : boost::none, settings.isTransitionRewardsSet() ? boost::optional(settings.getTransitionRewardsFilename()) : boost::none, settings.isChoiceLabelingSet() ? boost::optional(settings.getChoiceLabelingFilename()) : boost::none); // Preprocess the model if needed. - BRANCH_ON_MODELTYPE(model, model, ValueType, storm::dd::DdType::CUDD, preprocessModel, formulasInProperties(properties)); + BRANCH_ON_MODELTYPE(model, model, ValueType, storm::dd::DdType::CUDD, preprocessModel, extractFormulasFromProperties(properties)); // Print some information about the model. model->printModelInformationToStream(std::cout); diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index e1ba36dcc..18ff5b247 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -7,6 +7,8 @@ #include "storm/storage/prism/Program.h" #include "storm/storage/jani/Model.h" +#include "storm/logic/Formulas.h" + // If the parser fails due to ill-formed data, this exception is thrown. #include "storm/exceptions/WrongFormatException.h" @@ -48,22 +50,22 @@ namespace storm { } std::shared_ptr FormulaParser::parseSingleFormulaFromString(std::string const& formulaString) const { - std::vector> formulas = parseFromString(formulaString); - STORM_LOG_THROW(formulas.size() == 1, storm::exceptions::WrongFormatException, "Expected exactly one formula, but found " << formulas.size() << " instead."); - return formulas.front(); + std::vector property = parseFromString(formulaString); + STORM_LOG_THROW(property.size() == 1, storm::exceptions::WrongFormatException, "Expected exactly one formula, but found " << property.size() << " instead."); + return property.front().getRawFormula(); } - std::vector> FormulaParser::parseFromFile(std::string const& filename) const { + std::vector FormulaParser::parseFromFile(std::string const& filename) const { // Open file and initialize result. std::ifstream inputFileStream(filename, std::ios::in); STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'."); - std::vector> formulas; + std::vector properties; // Now try to parse the contents of the file. try { std::string fileContent((std::istreambuf_iterator(inputFileStream)), (std::istreambuf_iterator())); - formulas = parseFromString(fileContent); + properties = parseFromString(fileContent); } catch(std::exception& e) { // In case of an exception properly close the file before passing exception. inputFileStream.close(); @@ -72,16 +74,16 @@ namespace storm { // Close the stream in case everything went smoothly and return result. inputFileStream.close(); - return formulas; + return properties; } - std::vector> FormulaParser::parseFromString(std::string const& formulaString) const { + std::vector FormulaParser::parseFromString(std::string const& formulaString) const { PositionIteratorType first(formulaString.begin()); PositionIteratorType iter = first; PositionIteratorType last(formulaString.end()); // Create empty result; - std::vector> result; + std::vector result; // Create grammar. try { diff --git a/src/storm/parser/FormulaParser.h b/src/storm/parser/FormulaParser.h index 7917be3ac..c9aa5c5f3 100644 --- a/src/storm/parser/FormulaParser.h +++ b/src/storm/parser/FormulaParser.h @@ -5,7 +5,7 @@ #include "storm/parser/SpiritParserDefinitions.h" #include "storm/parser/ExpressionParser.h" -#include "storm/logic/Formulas.h" +#include "storm/storage/jani/Property.h" #include "storm/storage/expressions/Expression.h" #include "storm/utility/macros.h" @@ -14,6 +14,10 @@ namespace storm { class Program; } + namespace logic { + class Formula; + } + namespace parser { // Forward-declare grammar. @@ -38,20 +42,20 @@ namespace storm { std::shared_ptr parseSingleFormulaFromString(std::string const& formulaString) const; /*! - * Parses the formula given by the provided string. + * Parses the property given by the provided string. * - * @param formulaString The formula as a string. - * @return The contained formulas. + * @param propertyString The formula as a string. + * @return The contained properties. */ - std::vector> parseFromString(std::string const& formulaString) const; + std::vector parseFromString(std::string const& propertyString) const; /*! - * Parses the formulas in the given file. + * Parses the properties in the given file. * * @param filename The name of the file to parse. - * @return The contained formulas. + * @return The contained properties. */ - std::vector> parseFromFile(std::string const& filename) const; + std::vector parseFromFile(std::string const& filename) const; /*! * Adds an identifier and the expression it is supposed to be replaced with. This can, for example be used diff --git a/src/storm/parser/FormulaParserGrammar.cpp b/src/storm/parser/FormulaParserGrammar.cpp index 321878464..1cc54c135 100644 --- a/src/storm/parser/FormulaParserGrammar.cpp +++ b/src/storm/parser/FormulaParserGrammar.cpp @@ -4,11 +4,11 @@ namespace storm { namespace parser { - FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), manager(nullptr), expressionParser(*manager, keywords_, true, true) { + FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), manager(nullptr), expressionParser(*manager, keywords_, true, true), propertyCount(0) { initialize(); } - FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), manager(manager), expressionParser(*manager, keywords_, true, true) { + FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), manager(manager), expressionParser(*manager, keywords_, true, true), propertyCount(0) { initialize(); } @@ -116,10 +116,13 @@ namespace storm { identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_') | qi::char_('.')) >> *(qi::alnum | qi::char_('_')))]]]; identifier.name("identifier"); + formulaName = qi::lit("\"") >> identifier >> qi::lit("\"") >> qi::lit(":"); + formulaName.name("formula name"); + constantDefinition = (qi::lit("const") > qi::eps[qi::_a = true] > -(qi::lit("int") | qi::lit("double")[qi::_a = false]) >> identifier)[phoenix::bind(&FormulaParserGrammar::addConstant, phoenix::ref(*this), qi::_1, qi::_a)]; constantDefinition.name("constant definition"); - start = qi::eps > ((stateFormula[phoenix::push_back(qi::_val, qi::_1)] | qi::eps(phoenix::bind(&FormulaParserGrammar::areConstantDefinitionsAllowed, phoenix::ref(*this))) >> constantDefinition) % +(qi::char_("\n;"))) >> qi::skip(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; + start = qi::eps > (((-formulaName >> stateFormula)[phoenix::bind(&FormulaParserGrammar::addProperty, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)] | qi::eps(phoenix::bind(&FormulaParserGrammar::areConstantDefinitionsAllowed, phoenix::ref(*this))) >> constantDefinition) % +(qi::char_("\n;"))) >> qi::skip(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi; start.name("start"); // Enable the following lines to print debug output for most the rules. @@ -193,6 +196,15 @@ namespace storm { addIdentifierExpression(name, newVariable); } + void FormulaParserGrammar::addProperty(std::vector& properties, boost::optional const& name, std::shared_ptr const& formula) { + if (name) { + properties.emplace_back(name.get(), formula); + } else { + properties.emplace_back(std::to_string(propertyCount), formula); + } + ++propertyCount; + } + bool FormulaParserGrammar::areConstantDefinitionsAllowed() const { return static_cast(manager); } diff --git a/src/storm/parser/FormulaParserGrammar.h b/src/storm/parser/FormulaParserGrammar.h index 32bdbff28..c25e1394c 100644 --- a/src/storm/parser/FormulaParserGrammar.h +++ b/src/storm/parser/FormulaParserGrammar.h @@ -5,6 +5,7 @@ #include "storm/parser/SpiritErrorHandler.h" #include "storm/exceptions/WrongFormatException.h" +#include "storm/storage/jani/Property.h" #include "storm/logic/Formulas.h" #include "storm/parser/ExpressionParser.h" @@ -17,7 +18,7 @@ namespace storm { namespace parser { - class FormulaParserGrammar : public qi::grammar>(), Skipper> { + class FormulaParserGrammar : public qi::grammar(), Skipper> { public: FormulaParserGrammar(std::shared_ptr const& manager); FormulaParserGrammar(std::shared_ptr const& manager); @@ -121,10 +122,11 @@ namespace storm { // they are to be replaced with. qi::symbols identifiers_; - qi::rule>(), Skipper> start; + qi::rule(), Skipper> start; qi::rule, Skipper> constantDefinition; qi::rule identifier; + qi::rule formulaName; qi::rule, boost::optional, boost::optional>, Skipper> operatorInformation; qi::rule rewardMeasureType; @@ -171,6 +173,7 @@ namespace storm { bool areConstantDefinitionsAllowed() const; void addConstant(std::string const& name, bool integer); + void addProperty(std::vector& properties, boost::optional const& name, std::shared_ptr const& formula); std::pair, boost::optional> createTimeBoundFromInterval(storm::expressions::Expression const& lowerBound, storm::expressions::Expression const& upperBound) const; std::pair, boost::optional> createTimeBoundFromSingleBound(storm::expressions::Expression const& bound, bool upperBound, bool strict) const; @@ -199,6 +202,8 @@ namespace storm { // An error handler function. phoenix::function handler; + + uint64_t propertyCount; }; } diff --git a/src/storm/settings/modules/GeneralSettings.cpp b/src/storm/settings/modules/GeneralSettings.cpp index 8640dedbb..373d20175 100644 --- a/src/storm/settings/modules/GeneralSettings.cpp +++ b/src/storm/settings/modules/GeneralSettings.cpp @@ -44,8 +44,10 @@ namespace storm { this->addOption(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.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build()); - this->addOption(storm::settings::OptionBuilder(moduleName, propertyOptionName, false, "Specifies the formulas to be checked on the model.").setShortName(propertyOptionShortName) - .addArgument(storm::settings::ArgumentBuilder::createStringArgument("formula or filename", "The formula or the file containing the formulas.").build()).build()); + this->addOption(storm::settings::OptionBuilder(moduleName, propertyOptionName, false, "Specifies the properties to be checked on the model.").setShortName(propertyOptionShortName) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("property or filename", "The formula or the file containing the formulas.").build()) + .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filter", "The names of the properties to check.").setDefaultValueString("all").build()) + .build()); this->addOption(storm::settings::OptionBuilder(moduleName, parametricRegionOptionName, false, "Sets whether to use the parametric Region engine.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, bisimulationOptionName, false, "Sets whether to perform bisimulation minimization.").setShortName(bisimulationOptionShortName).build()); this->addOption(storm::settings::OptionBuilder(moduleName, parametricOptionName, false, "Sets whether to enable parametric model checking.").build()); @@ -85,9 +87,13 @@ namespace storm { } std::string GeneralSettings::getProperty() const { - return this->getOption(propertyOptionName).getArgumentByName("formula or filename").getValueAsString(); + return this->getOption(propertyOptionName).getArgumentByName("property or filename").getValueAsString(); } - + + std::string GeneralSettings::getPropertyFilter() const { + return this->getOption(propertyOptionName).getArgumentByName("filter").getValueAsString(); + } + bool GeneralSettings::isBisimulationSet() const { return this->getOption(bisimulationOptionName).getHasOptionBeenSet(); } diff --git a/src/storm/settings/modules/GeneralSettings.h b/src/storm/settings/modules/GeneralSettings.h index feda9f226..23ccfef2f 100644 --- a/src/storm/settings/modules/GeneralSettings.h +++ b/src/storm/settings/modules/GeneralSettings.h @@ -85,6 +85,13 @@ namespace storm { */ std::string getProperty() const; + /*! + * Retrieves the property filter. + * + * @return The property filter. + */ + std::string getPropertyFilter() const; + /*! * Retrieves whether the option to perform bisimulation minimization is set. * diff --git a/src/storm/storage/jani/Property.cpp b/src/storm/storage/jani/Property.cpp index c26ede01d..896810526 100644 --- a/src/storm/storage/jani/Property.cpp +++ b/src/storm/storage/jani/Property.cpp @@ -28,10 +28,18 @@ namespace storm { return this->comment; } + Property Property::substitute(std::map const& substitution) const { + return Property(name, filterExpression.substitute(substitution), comment); + } + FilterExpression const& Property::getFilter() const { return this->filterExpression; } + std::shared_ptr Property::getRawFormula() const { + return this->filterExpression.getFormula(); + } + std::ostream& operator<<(std::ostream& os, Property const& p) { return os << "(" << p.getName() << ") : " << p.getFilter(); } diff --git a/src/storm/storage/jani/Property.h b/src/storm/storage/jani/Property.h index 4cafc0f8d..9d28d715a 100644 --- a/src/storm/storage/jani/Property.h +++ b/src/storm/storage/jani/Property.h @@ -28,19 +28,23 @@ namespace storm { class FilterExpression { public: - explicit FilterExpression(std::shared_ptr formula, storm::modelchecker::FilterType ft = storm::modelchecker::FilterType::VALUES) : values(formula), ft(ft) {} + explicit FilterExpression(std::shared_ptr formula, storm::modelchecker::FilterType ft = storm::modelchecker::FilterType::VALUES) : formula(formula), ft(ft) {} std::shared_ptr const& getFormula() const { - return values; + return formula; } storm::modelchecker::FilterType getFilterType() const { return ft; } + + FilterExpression substitute(std::map const& substitution) const { + return FilterExpression(formula->substitute(substitution), ft); + } private: // For now, we assume that the states are always the initial states. - std::shared_ptr values; + std::shared_ptr formula; storm::modelchecker::FilterType ft; }; @@ -58,6 +62,7 @@ namespace storm { * @param comment An optional comment */ Property(std::string const& name, std::shared_ptr const& formula, std::string const& comment = ""); + /** * Constructs the property * @param name the name @@ -65,18 +70,24 @@ namespace storm { * @param comment An optional comment */ Property(std::string const& name, FilterExpression const& fe, std::string const& comment = ""); + /** * Get the provided name * @return the name */ std::string const& getName() const; + /** * Get the provided comment, if any * @return the comment */ std::string const& getComment() const; + Property substitute(std::map const& substitution) const; + FilterExpression const& getFilter() const; + + std::shared_ptr getRawFormula() const; private: std::string name; std::string comment; diff --git a/src/storm/utility/cli.cpp b/src/storm/utility/cli.cpp index 4009a8883..b8da7a264 100644 --- a/src/storm/utility/cli.cpp +++ b/src/storm/utility/cli.cpp @@ -59,6 +59,17 @@ namespace storm { return constantDefinitions; } + + std::vector parseCommaSeparatedStrings(std::string const& input) { + std::vector result; + if (!input.empty()) { + boost::split(result, input, boost::is_any_of(",")); + for (auto& entry : result) { + boost::trim(entry); + } + } + return result; + } } } diff --git a/src/storm/utility/cli.h b/src/storm/utility/cli.h index bd6d218d6..63909698d 100644 --- a/src/storm/utility/cli.h +++ b/src/storm/utility/cli.h @@ -11,6 +11,7 @@ namespace storm { std::map parseConstantDefinitionString(storm::expressions::ExpressionManager const& manager, std::string const& constantDefinitionString); + std::vector parseCommaSeparatedStrings(std::string const& input); } } } diff --git a/src/storm/utility/storm.cpp b/src/storm/utility/storm.cpp index 9c8ab20f2..8ad4283b1 100644 --- a/src/storm/utility/storm.cpp +++ b/src/storm/utility/storm.cpp @@ -10,11 +10,10 @@ namespace storm{ - std::vector> formulasInProperties(std::vector const& properties) { - + std::vector> extractFormulasFromProperties(std::vector const& properties) { std::vector> formulas; for (auto const& prop : properties) { - formulas.push_back(prop.getFilter().getFormula()); + formulas.push_back(prop.getRawFormula()); } return formulas; } @@ -42,45 +41,72 @@ namespace storm{ } } - /** - * Helper - * @param FormulaParser - * @return The formulas. - */ - std::vector> parseFormulas(storm::parser::FormulaParser& formulaParser, std::string const& inputString) { + std::vector parseProperties(storm::parser::FormulaParser& formulaParser, std::string const& inputString, boost::optional> const& propertyFilter = boost::none) { // If the given property looks like a file (containing a dot and there exists a file with that name), // we try to parse it as a file, otherwise we assume it's a property. + std::vector properties; if (inputString.find(".") != std::string::npos && std::ifstream(inputString).good()) { - return formulaParser.parseFromFile(inputString); + properties = formulaParser.parseFromFile(inputString); } else { - return formulaParser.parseFromString(inputString); + properties = formulaParser.parseFromString(inputString); } + + return filterProperties(properties, propertyFilter); } - std::vector> parseFormulasForExplicit(std::string const& inputString) { + std::vector parsePropertiesForExplicit(std::string const& inputString, boost::optional> const& propertyFilter) { auto exprManager = std::make_shared(); storm::parser::FormulaParser formulaParser(exprManager); - return parseFormulas(formulaParser, inputString); + return parseProperties(formulaParser, inputString, propertyFilter); } - std::vector> substituteConstantsInFormulas(std::vector> const& formulas, std::map const& substitution) { - std::vector> preprocessedFormulas; - - for (auto const& formula : formulas) { - preprocessedFormulas.emplace_back(formula->substitute(substitution)); + std::vector substituteConstantsInProperties(std::vector const& properties, std::map const& substitution) { + std::vector preprocessedProperties; + for (auto const& property : properties) { + preprocessedProperties.emplace_back(property.substitute(substitution)); } - return preprocessedFormulas; + return preprocessedProperties; } - std::vector> parseFormulasForJaniModel(std::string const& inputString, storm::jani::Model const& model) { + std::vector parsePropertiesForJaniModel(std::string const& inputString, storm::jani::Model const& model, boost::optional> const& propertyFilter) { storm::parser::FormulaParser formulaParser(model.getManager().getSharedPointer()); - auto formulas = parseFormulas(formulaParser, inputString); - return substituteConstantsInFormulas(formulas, model.getConstantsSubstitution()); + auto formulas = parseProperties(formulaParser, inputString, propertyFilter); + return substituteConstantsInProperties(formulas, model.getConstantsSubstitution()); } - std::vector> parseFormulasForPrismProgram(std::string const& inputString, storm::prism::Program const& program) { + std::vector parsePropertiesForPrismProgram(std::string const& inputString, storm::prism::Program const& program, boost::optional> const& propertyFilter) { storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer()); - auto formulas = parseFormulas(formulaParser, inputString); - return substituteConstantsInFormulas(formulas, program.getConstantsSubstitution()); - } + auto formulas = parseProperties(formulaParser, inputString, propertyFilter); + return substituteConstantsInProperties(formulas, program.getConstantsSubstitution()); + } + + boost::optional> parsePropertyFilter(boost::optional const& propertyFilter) { + std::vector propertyNames = storm::utility::cli::parseCommaSeparatedStrings(propertyFilter.get()); + std::set propertyNameSet(propertyNames.begin(), propertyNames.end()); + return propertyNameSet; + } + + std::vector filterProperties(std::vector const& properties, boost::optional> const& propertyFilter) { + if (propertyFilter) { + std::set const& propertyNameSet = propertyFilter.get(); + std::vector result; + std::set reducedPropertyNames; + for (auto const& property : properties) { + if (propertyNameSet.find(property.getName()) != propertyNameSet.end()) { + result.push_back(property); + reducedPropertyNames.insert(property.getName()); + } + } + + if (reducedPropertyNames.size() < propertyNameSet.size()) { + std::set missingProperties; + std::set_difference(propertyNameSet.begin(), propertyNameSet.end(), reducedPropertyNames.begin(), reducedPropertyNames.end(), std::inserter(missingProperties, missingProperties.begin())); + STORM_LOG_WARN("Filtering unknown properties " << boost::join(missingProperties, ", ") << "."); + } + + return result; + } else { + return properties; + } + } } diff --git a/src/storm/utility/storm.h b/src/storm/utility/storm.h index fce54187b..46fcfdb67 100644 --- a/src/storm/utility/storm.h +++ b/src/storm/utility/storm.h @@ -105,13 +105,15 @@ namespace storm { return storm::parser::AutoParser<>::parseModel(transitionsFile, labelingFile, stateRewardsFile ? stateRewardsFile.get() : "", transitionRewardsFile ? transitionRewardsFile.get() : "", choiceLabelingFile ? choiceLabelingFile.get() : "" ); } - std::vector> formulasInProperties(std::vector const& properties); + std::vector> extractFormulasFromProperties(std::vector const& properties); std::pair> parseJaniModel(std::string const& path); storm::prism::Program parseProgram(std::string const& path); - std::vector> substituteConstantsInFormulas(std::vector> const& formulas, std::map const& substitution); - std::vector> parseFormulasForExplicit(std::string const& inputString); - std::vector> parseFormulasForPrismProgram(std::string const& inputString, storm::prism::Program const& program); - std::vector> parseFormulasForJaniModel(std::string const& inputString, storm::jani::Model const& model); + std::vector substituteConstantsInProperties(std::vector const& properties, std::map const& substitution); + std::vector parsePropertiesForExplicit(std::string const& inputString, boost::optional> const& propertyFilter = boost::none); + std::vector parsePropertiesForPrismProgram(std::string const& inputString, storm::prism::Program const& program, boost::optional> const& propertyFilter = boost::none); + std::vector parsePropertiesForJaniModel(std::string const& inputString, storm::jani::Model const& model, boost::optional> const& propertyFilter = boost::none); + boost::optional> parsePropertyFilter(boost::optional const& propertyFilter); + std::vector filterProperties(std::vector const& properties, boost::optional> const& propertyFilter); template std::shared_ptr> buildSparseModel(storm::storage::SymbolicModelDescription const& model, std::vector> const& formulas) { @@ -466,7 +468,7 @@ namespace storm { // Program and formula storm::prism::Program program = parseProgram(programFilePath); program = storm::utility::prism::preprocess(program, constantsString); - std::vector> formulas = parseFormulasForPrismProgram(formulaString, program); + std::vector> formulas = extractFormulasFromProperties(parsePropertiesForPrismProgram(formulaString, program)); if(formulas.size()!=1) { STORM_LOG_ERROR("The given formulaString does not specify exactly one formula"); return false; diff --git a/src/test/modelchecker/SparseDtmcRegionModelCheckerTest.cpp b/src/test/modelchecker/SparseDtmcRegionModelCheckerTest.cpp index 3f40c305d..6e71528af 100644 --- a/src/test/modelchecker/SparseDtmcRegionModelCheckerTest.cpp +++ b/src/test/modelchecker/SparseDtmcRegionModelCheckerTest.cpp @@ -24,7 +24,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Brp_Prob) { // Program and formula storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -95,7 +95,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Brp_Rew) { storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -184,7 +184,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Brp_Rew_Infty) { carl::VariablePool::getInstance().clear(); storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -228,7 +228,7 @@ TEST(SparseDtmcRegionModelCheckerTest, DISABLED_Brp_Rew_4Par) { carl::VariablePool::getInstance().clear(); storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -292,7 +292,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Crowds_Prob) { storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -384,7 +384,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Crowds_Prob_1Par) { storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -450,7 +450,7 @@ TEST(SparseDtmcRegionModelCheckerTest, Crowds_Prob_Const) { storm::prism::Program program = storm::parseProgram(programFile); program = storm::utility::prism::preprocess(program, constantsAsString); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program);; + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); diff --git a/src/test/modelchecker/SparseMdpRegionModelCheckerTest.cpp b/src/test/modelchecker/SparseMdpRegionModelCheckerTest.cpp index 8fd7c74d0..69ed514da 100644 --- a/src/test/modelchecker/SparseMdpRegionModelCheckerTest.cpp +++ b/src/test/modelchecker/SparseMdpRegionModelCheckerTest.cpp @@ -23,7 +23,7 @@ TEST(SparseMdpRegionModelCheckerTest, two_dice_Prob) { carl::VariablePool::getInstance().clear(); storm::prism::Program program = storm::parseProgram(programFile); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaFile, program); + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaFile, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); @@ -91,7 +91,7 @@ TEST(SparseMdpRegionModelCheckerTest, DISABLED_coin_Prob) { carl::VariablePool::getInstance().clear(); storm::prism::Program program = storm::parseProgram(programFile); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program); + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); std::shared_ptr> model = storm::buildSparseModel(program, formulas)->as>(); auto const& regionSettings = storm::settings::getModule(); storm::modelchecker::region::SparseRegionModelCheckerSettings settings(regionSettings.getSampleMode(), regionSettings.getApproxMode(), regionSettings.getSmtMode()); diff --git a/src/test/parser/FormulaParserTest.cpp b/src/test/parser/FormulaParserTest.cpp index 15ffc4055..012555e8b 100644 --- a/src/test/parser/FormulaParserTest.cpp +++ b/src/test/parser/FormulaParserTest.cpp @@ -154,11 +154,10 @@ TEST(FormulaParserTest, MultiObjectiveFormulaTest) { storm::parser::FormulaParser formulaParser; std::string input = "multi(P<0.9 [ F \"a\" ], R<42 [ F \"b\" ], Pmin=? [ F\"c\" ])"; - std::vector> formulas; - ASSERT_NO_THROW(formulas = formulaParser.parseFromString(input)); - ASSERT_EQ(1ull, formulas.size()); - ASSERT_TRUE(formulas[0]->isMultiObjectiveFormula()); - storm::logic::MultiObjectiveFormula mof = formulas[0]->asMultiObjectiveFormula(); + std::shared_ptr formula; + ASSERT_NO_THROW(formula = formulaParser.parseSingleFormulaFromString(input)); + ASSERT_TRUE(formula->isMultiObjectiveFormula()); + storm::logic::MultiObjectiveFormula mof = formula->asMultiObjectiveFormula(); ASSERT_EQ(3ull, mof.getNumberOfSubformulas()); ASSERT_TRUE(mof.getSubformula(0).isProbabilityOperatorFormula()); diff --git a/src/test/utility/ModelInstantiatorTest.cpp b/src/test/utility/ModelInstantiatorTest.cpp index 498dfbf55..145881598 100644 --- a/src/test/utility/ModelInstantiatorTest.cpp +++ b/src/test/utility/ModelInstantiatorTest.cpp @@ -26,7 +26,7 @@ TEST(ModelInstantiatorTest, BrpProb) { // Program and formula storm::prism::Program program = storm::parseProgram(programFile); program.checkValidity(); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program); + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); ASSERT_TRUE(formulas.size()==1); // Parametric model storm::generator::NextStateGeneratorOptions options(*formulas.front()); @@ -144,7 +144,7 @@ TEST(ModelInstantiatorTest, Brp_Rew) { // Program and formula storm::prism::Program program = storm::parseProgram(programFile); program.checkValidity(); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program); + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); ASSERT_TRUE(formulas.size()==1); // Parametric model storm::generator::NextStateGeneratorOptions options(*formulas.front()); @@ -214,7 +214,7 @@ TEST(ModelInstantiatorTest, Consensus) { // Program and formula storm::prism::Program program = storm::parseProgram(programFile); program.checkValidity(); - std::vector> formulas = storm::parseFormulasForPrismProgram(formulaAsString, program); + std::vector> formulas = storm::extractFormulasFromProperties(storm::parsePropertiesForPrismProgram(formulaAsString, program)); ASSERT_TRUE(formulas.size()==1); // Parametric model storm::generator::NextStateGeneratorOptions options(*formulas.front());