diff --git a/src/storm-parsers/parser/FormulaParserGrammar.cpp b/src/storm-parsers/parser/FormulaParserGrammar.cpp index ceca76e8e..6f565fc20 100644 --- a/src/storm-parsers/parser/FormulaParserGrammar.cpp +++ b/src/storm-parsers/parser/FormulaParserGrammar.cpp @@ -123,13 +123,18 @@ namespace storm { multiFormula = (qi::lit("multi") > qi::lit("(") >> ((pathFormula(storm::logic::FormulaContext::Probability) | stateFormula) % qi::lit(",")) >> qi::lit(")"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createMultiFormula, phoenix::ref(*this), qi::_1)]; multiFormula.name("Multi formula"); - - stateFormula = (orStateFormula | multiFormula); - stateFormula.name("state formula"); - + identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_') | qi::char_('.')) >> *(qi::alnum | qi::char_('_')))]]]; identifier.name("identifier"); + quantileBoundVariable = ((qi::lit("min")[qi::_a = storm::solver::OptimizationDirection::Minimize] | qi::lit("max")[qi::_a = storm::solver::OptimizationDirection::Maximize]) >> identifier)[qi::_val = phoenix::bind(&FormulaParserGrammar::createQuantileBoundVariables, phoenix::ref(*this), qi::_a, qi::_1)]; + quantileBoundVariable.name("Quantile bound variable"); + quantileFormula = (qi::lit("quantile") > qi::lit("(") >> (quantileBoundVariable % qi::lit(",")) >> qi::lit(",") >> stateFormula > qi::lit(")"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createQuantileFormula, phoenix::ref(*this), qi::_1, qi::_2)]; + quantileFormula.name("Quantile formula"); + + stateFormula = (orStateFormula | multiFormula | quantileFormula); + stateFormula.name("state formula"); + formulaName = qi::lit("\"") >> identifier >> qi::lit("\"") >> qi::lit(":"); formulaName.name("formula name"); @@ -419,6 +424,20 @@ namespace storm { } } + std::pair FormulaParserGrammar::createQuantileBoundVariables(storm::solver::OptimizationDirection const& dir, std::string const& variableName) { + STORM_LOG_ASSERT(manager, "Mutable expression manager required to define quantile bound variable."); + STORM_LOG_THROW(!manager->hasVariable(variableName), storm::exceptions::WrongFormatException, "Invalid quantile variable name '" << variableName << "' in property: variable already exists."); + + storm::expressions::Variable var = manager->declareRationalVariable(variableName); + addIdentifierExpression(variableName, var); + std::pair result(dir, var); + return result; + } + + std::shared_ptr FormulaParserGrammar::createQuantileFormula(std::vector> const& boundVariables, std::shared_ptr const& subformula) { + return std::shared_ptr(new storm::logic::QuantileFormula(boundVariables, subformula)); + } + std::set FormulaParserGrammar::getUndefinedConstants(std::shared_ptr const& formula) const { std::set result; std::set usedVariables = formula->getUsedVariables(); diff --git a/src/storm-parsers/parser/FormulaParserGrammar.h b/src/storm-parsers/parser/FormulaParserGrammar.h index 75012aaf4..e582abe40 100644 --- a/src/storm-parsers/parser/FormulaParserGrammar.h +++ b/src/storm-parsers/parser/FormulaParserGrammar.h @@ -50,7 +50,8 @@ namespace storm { ("F", 5) ("G", 6) ("X", 7) - ("multi", 8); + ("multi", 8) + ("quantile", 9); } }; @@ -196,6 +197,8 @@ namespace storm { qi::rule(), Skipper> longRunAverageRewardFormula; qi::rule(), Skipper> multiFormula; + qi::rule(), qi::locals, Skipper> quantileBoundVariable; + qi::rule(), Skipper> quantileFormula; // Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser). boost::spirit::qi::real_parser> strict_double; @@ -229,6 +232,8 @@ namespace storm { std::shared_ptr createBinaryBooleanStateFormula(std::shared_ptr const& leftSubformula, std::shared_ptr const& rightSubformula, storm::logic::BinaryBooleanStateFormula::OperatorType operatorType); std::shared_ptr createUnaryBooleanStateFormula(std::shared_ptr const& subformula, boost::optional const& operatorType); std::shared_ptr createMultiFormula(std::vector> const& subformulas); + std::pair createQuantileBoundVariables(storm::solver::OptimizationDirection const& dir, std::string const& variableName); + std::shared_ptr createQuantileFormula(std::vector> const& boundVariables, std::shared_ptr const& subformula); std::set getUndefinedConstants(std::shared_ptr const& formula) const; storm::jani::Property createProperty(boost::optional const& propertyName, storm::modelchecker::FilterType const& filterType, std::shared_ptr const& formula, std::shared_ptr const& states);