Browse Source

First try on parsing of rational functions

Former-commit-id: 63a6ae0d14
tempestpy_adaptions
Mavo 9 years ago
parent
commit
f38eeff1ef
  1. 2
      src/builder/ExplicitDFTModelBuilder.cpp
  2. 69
      src/parser/DFTGalileoParser.cpp
  3. 25
      src/parser/DFTGalileoParser.h
  4. 38
      src/parser/ExpressionParser.cpp
  5. 18
      src/parser/ExpressionParser.h
  6. 6
      src/storage/dft/DFTElements.h
  7. 36
      src/storm-dyftee.cpp

2
src/builder/ExplicitDFTModelBuilder.cpp

@ -79,7 +79,7 @@ namespace storm {
while (!stateQueue.empty()) { while (!stateQueue.empty()) {
// Initialization // Initialization
outgoingTransitions.clear(); outgoingTransitions.clear();
ValueType sum = 0;
ValueType sum = storm::utility::zero<ValueType>();
// Consider next state // Consider next state
storm::storage::DFTState<ValueType> state = stateQueue.front(); storm::storage::DFTState<ValueType> state = stateQueue.front();

69
src/parser/DFTGalileoParser.cpp

@ -4,9 +4,10 @@
#include <fstream> #include <fstream>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <src/exceptions/NotImplementedException.h>
#include "../exceptions/FileIoException.h"
#include "../exceptions/NotSupportedException.h"
#include "src/storage/expressions/ExpressionManager.h"
#include "src/exceptions/NotImplementedException.h"
#include "src/exceptions/FileIoException.h"
#include "src/exceptions/NotSupportedException.h"
#include "src/utility/macros.h" #include "src/utility/macros.h"
namespace storm { namespace storm {
@ -15,7 +16,7 @@ namespace storm {
template<typename ValueType> template<typename ValueType>
storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename) { storm::storage::DFT<ValueType> DFTGalileoParser<ValueType>::parseDFT(const std::string& filename) {
if(readFile(filename)) { if(readFile(filename)) {
storm::storage::DFT<ValueType> dft = mBuilder.build();
storm::storage::DFT<ValueType> dft = builder.build();
STORM_LOG_DEBUG("Elements:" << std::endl << dft.getElementsString()); STORM_LOG_DEBUG("Elements:" << std::endl << dft.getElementsString());
STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString()); STORM_LOG_DEBUG("Spare Modules:" << std::endl << dft.getSpareModulesString());
return dft; return dft;
@ -43,6 +44,7 @@ namespace storm {
// constants // constants
std::string toplevelToken = "toplevel"; std::string toplevelToken = "toplevel";
std::string toplevelId; std::string toplevelId;
std::string parametricToken = "param";
std::ifstream file; std::ifstream file;
file.exceptions ( std::ifstream::failbit ); file.exceptions ( std::ifstream::failbit );
@ -73,8 +75,16 @@ namespace storm {
if(boost::starts_with(line, toplevelToken)) { if(boost::starts_with(line, toplevelToken)) {
toplevelId = stripQuotsFromName(line.substr(toplevelToken.size() + 1)); toplevelId = stripQuotsFromName(line.substr(toplevelToken.size() + 1));
} }
else
{
else if (boost::starts_with(line, parametricToken)) {
if (!std::is_same<ValueType, storm::RationalFunction>::value) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters only allowed when using rational functions.");
}
std::string parameter = stripQuotsFromName(line.substr(parametricToken.size() + 1));
storm::expressions::Variable var = manager->declareRationalVariable(parameter);
identifierMapping.emplace(var.getName(), var);
parser.setIdentifierMapping(identifierMapping);
STORM_LOG_TRACE("Added parameter: " << var.getName());
} else {
std::vector<std::string> tokens; std::vector<std::string> tokens;
boost::split(tokens, line, boost::is_any_of(" ")); boost::split(tokens, line, boost::is_any_of(" "));
std::string name(stripQuotsFromName(tokens[0])); std::string name(stripQuotsFromName(tokens[0]));
@ -84,28 +94,19 @@ namespace storm {
childNames.push_back(stripQuotsFromName(tokens[i])); childNames.push_back(stripQuotsFromName(tokens[i]));
} }
if(tokens[1] == "and") { if(tokens[1] == "and") {
success = mBuilder.addAndElement(name, childNames);
success = builder.addAndElement(name, childNames);
} else if(tokens[1] == "or") { } else if(tokens[1] == "or") {
success = mBuilder.addOrElement(name, childNames);
success = builder.addOrElement(name, childNames);
} else if(boost::starts_with(tokens[1], "vot")) { } else if(boost::starts_with(tokens[1], "vot")) {
success = mBuilder.addVotElement(name, boost::lexical_cast<unsigned>(tokens[1].substr(3)), childNames);
success = builder.addVotElement(name, boost::lexical_cast<unsigned>(tokens[1].substr(3)), childNames);
} else if(tokens[1] == "pand") { } else if(tokens[1] == "pand") {
success = mBuilder.addPandElement(name, childNames);
success = builder.addPandElement(name, childNames);
} else if(tokens[1] == "wsp" || tokens[1] == "csp") { } else if(tokens[1] == "wsp" || tokens[1] == "csp") {
success = mBuilder.addSpareElement(name, childNames);
success = builder.addSpareElement(name, childNames);
} else if(boost::starts_with(tokens[1], "lambda=")) { } else if(boost::starts_with(tokens[1], "lambda=")) {
ValueType failureRate = 0;
ValueType dormancyFactor = 0;
if (std::is_same<ValueType, double>::value) {
failureRate = boost::lexical_cast<double>(tokens[1].substr(7));
dormancyFactor = boost::lexical_cast<double>(tokens[2].substr(5));
} else {
// TODO Matthias: Parse RationalFunction
failureRate;
dormancyFactor;
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Parsing into rational function not supported.");
}
success = mBuilder.addBasicElement(name, failureRate, dormancyFactor);
ValueType failureRate = parseRationalExpression(tokens[1].substr(7));
ValueType dormancyFactor = parseRationalExpression(tokens[2].substr(5));
success = builder.addBasicElement(name, failureRate, dormancyFactor);
} else { } else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " + tokens[1] + " not recognized."); STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Type name: " + tokens[1] + " not recognized.");
success = false; success = false;
@ -115,17 +116,37 @@ namespace storm {
generalSuccess = success; generalSuccess = success;
} }
} }
if(!mBuilder.setTopLevel(toplevelId)) {
if(!builder.setTopLevel(toplevelId)) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown."); STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown.");
} }
file.close(); file.close();
return generalSuccess; return generalSuccess;
} }
template<typename ValueType>
ValueType DFTGalileoParser<ValueType>::parseRationalExpression(std::string const& expr) {
assert(false);
}
template<>
double DFTGalileoParser<double>::parseRationalExpression(std::string const& expr) {
return boost::lexical_cast<double>(expr);
}
// Explicitly instantiate the class. // Explicitly instantiate the class.
template class DFTGalileoParser<double>; template class DFTGalileoParser<double>;
#ifdef STORM_HAVE_CARL #ifdef STORM_HAVE_CARL
template<>
storm::RationalFunction DFTGalileoParser<storm::RationalFunction>::parseRationalExpression(std::string const& expr) {
STORM_LOG_TRACE("Translating expression: " << expr);
storm::expressions::Expression expression = parser.parseFromString(expr);
STORM_LOG_TRACE("Expression: " << expression);
storm::RationalFunction rationalFunction = evaluator.asRational(expression);
STORM_LOG_TRACE("Parsed expression: " << rationalFunction);
return rationalFunction;
}
template class DFTGalileoParser<RationalFunction>; template class DFTGalileoParser<RationalFunction>;
#endif #endif

25
src/parser/DFTGalileoParser.h

@ -1,8 +1,11 @@
#ifndef DFTGALILEOPARSER_H #ifndef DFTGALILEOPARSER_H
#define DFTGALILEOPARSER_H #define DFTGALILEOPARSER_H
#include "../storage/dft/DFT.h"
#include "../storage/dft/DFTBuilder.h"
#include "src/storage/dft/DFT.h"
#include "src/storage/dft/DFTBuilder.h"
#include "src/storage/expressions/ExpressionManager.h"
#include "src/parser/ExpressionParser.h"
#include "src/storage/expressions/ExpressionEvaluator.h"
#include <map> #include <map>
@ -11,16 +14,30 @@ namespace storm {
template<typename ValueType> template<typename ValueType>
class DFTGalileoParser { class DFTGalileoParser {
storm::storage::DFTBuilder<ValueType> mBuilder;
storm::storage::DFTBuilder<ValueType> builder;
std::shared_ptr<storm::expressions::ExpressionManager> manager;
storm::parser::ExpressionParser parser;
storm::expressions::ExpressionEvaluator<ValueType> evaluator;
std::unordered_map<std::string, storm::expressions::Expression> identifierMapping;
public: public:
DFTGalileoParser() : manager(new storm::expressions::ExpressionManager()), parser(*manager), evaluator(*manager) {
}
storm::storage::DFT<ValueType> parseDFT(std::string const& filename); storm::storage::DFT<ValueType> parseDFT(std::string const& filename);
private: private:
bool readFile(std::string const& filename); bool readFile(std::string const& filename);
std::string stripQuotsFromName(std::string const& name); std::string stripQuotsFromName(std::string const& name);
ValueType parseRationalExpression(std::string const& expr);
}; };
}
}
} }
#endif /* DFTGALILEOPARSER_H */ #endif /* DFTGALILEOPARSER_H */

38
src/parser/ExpressionParser.cpp

@ -5,7 +5,7 @@
namespace storm { namespace storm {
namespace parser { namespace parser {
ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), powerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), trueFalse_(manager), manager(manager.getSharedPointer()), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
ExpressionParser::ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking) : ExpressionParser::base_type(expression), orOperator_(), andOperator_(), equalityOperator_(), relationalOperator_(), plusOperator_(), multiplicationOperator_(), powerOperator_(), unaryOperator_(), floorCeilOperator_(), minMaxOperator_(), trueFalse_(manager), manager(manager.getSharedPointer()), createExpressions(false), acceptDoubleLiterals(true), deleteIdentifierMapping(false), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&ExpressionParser::isValidIdentifier, phoenix::ref(*this), qi::_1)]; identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&ExpressionParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
identifier.name("identifier"); identifier.name("identifier");
@ -126,9 +126,23 @@ namespace storm {
this->identifiers_ = nullptr; this->identifiers_ = nullptr;
} }
} }
void ExpressionParser::setIdentifierMapping(std::unordered_map<std::string, storm::expressions::Expression> const& identifierMapping) {
unsetIdentifierMapping();
this->createExpressions = true;
this->identifiers_ = new qi::symbols<char, storm::expressions::Expression>();
for (auto const& identifierExpressionPair : identifierMapping) {
this->identifiers_->add(identifierExpressionPair.first, identifierExpressionPair.second);
}
deleteIdentifierMapping = true;
}
void ExpressionParser::unsetIdentifierMapping() { void ExpressionParser::unsetIdentifierMapping() {
this->createExpressions = false; this->createExpressions = false;
if (deleteIdentifierMapping) {
delete this->identifiers_;
deleteIdentifierMapping = false;
}
this->identifiers_ = nullptr; this->identifiers_ = nullptr;
} }
@ -346,5 +360,25 @@ namespace storm {
} }
return true; return true;
} }
storm::expressions::Expression ExpressionParser::parseFromString(std::string const& expressionString) const {
PositionIteratorType first(expressionString.begin());
PositionIteratorType iter = first;
PositionIteratorType last(expressionString.end());
// Create empty result;
storm::expressions::Expression result;
try {
// Start parsing.
bool succeeded = qi::phrase_parse(iter, last, *this, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)) >> (qi::eol | qi::eoi), result);
STORM_LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Could not parse expression.");
STORM_LOG_DEBUG("Parsed expression successfully.");
} catch (qi::expectation_failure<PositionIteratorType> const& e) {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, e.what_);
}
return result;
}
} }
} }

18
src/parser/ExpressionParser.h

@ -25,7 +25,7 @@ namespace storm {
* points it would typically allow. This can, for example, be used to prevent errors if the outer grammar * points it would typically allow. This can, for example, be used to prevent errors if the outer grammar
* also parses boolean conjuncts that are erroneously consumed by the expression parser. * also parses boolean conjuncts that are erroneously consumed by the expression parser.
*/ */
ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_, bool allowBacktracking = false);
ExpressionParser(storm::expressions::ExpressionManager const& manager, qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_ = qi::symbols<char, uint_fast64_t>(), bool allowBacktracking = false);
ExpressionParser(ExpressionParser const& other) = default; ExpressionParser(ExpressionParser const& other) = default;
ExpressionParser& operator=(ExpressionParser const& other) = default; ExpressionParser& operator=(ExpressionParser const& other) = default;
@ -38,6 +38,15 @@ namespace storm {
* @param identifiers_ A pointer to a mapping from identifiers to expressions. * @param identifiers_ A pointer to a mapping from identifiers to expressions.
*/ */
void setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_); void setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_);
/*!
* Sets an identifier mapping that is used to determine valid variables in the expression. The mapped-to
* expressions will be substituted wherever the key value appears in the parsed expression. After setting
* this, the parser will generate expressions.
*
* @param identifierMapping A mapping from identifiers to expressions.
*/
void setIdentifierMapping(std::unordered_map<std::string, storm::expressions::Expression> const& identifierMapping);
/*! /*!
* Unsets a previously set identifier mapping. This will make the parser not generate expressions any more * Unsets a previously set identifier mapping. This will make the parser not generate expressions any more
@ -51,7 +60,9 @@ namespace storm {
* @param flag If set to true, double literals are accepted. * @param flag If set to true, double literals are accepted.
*/ */
void setAcceptDoubleLiterals(bool flag); void setAcceptDoubleLiterals(bool flag);
storm::expressions::Expression parseFromString(std::string const& expressionString) const;
private: private:
struct orOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> { struct orOperatorStruct : qi::symbols<char, storm::expressions::OperatorType> {
orOperatorStruct() { orOperatorStruct() {
@ -184,6 +195,9 @@ namespace storm {
// A flag that indicates whether double literals are accepted. // A flag that indicates whether double literals are accepted.
bool acceptDoubleLiterals; bool acceptDoubleLiterals;
// A flag that indicates whether the mapping must be deleted on unsetting.
bool deleteIdentifierMapping;
// The currently used mapping of identifiers to expressions. This is used if the parser is set to create // The currently used mapping of identifiers to expressions. This is used if the parser is set to create
// expressions. // expressions.
qi::symbols<char, storm::expressions::Expression> const* identifiers_; qi::symbols<char, storm::expressions::Expression> const* identifiers_;

6
src/storage/dft/DFTElements.h

@ -11,6 +11,8 @@
#include "DFTState.h" #include "DFTState.h"
#include "DFTStateSpaceGenerationQueues.h" #include "DFTStateSpaceGenerationQueues.h"
#include "src/utility/constants.h"
#include "src/adapters/CarlAdapter.h"
using std::size_t; using std::size_t;
@ -313,9 +315,9 @@ namespace storm {
} }
bool isColdBasicElement() const { bool isColdBasicElement() const {
return mPassiveFailureRate == 0;
return storm::utility::isZero(mPassiveFailureRate);
} }
virtual std::vector<size_t> independentUnit() const { virtual std::vector<size_t> independentUnit() const {
return {this->mId}; return {this->mId};
} }

36
src/storm-dyftee.cpp

@ -5,7 +5,7 @@
#include "modelchecker/results/CheckResult.h" #include "modelchecker/results/CheckResult.h"
#include "utility/storm.h" #include "utility/storm.h"
#define VALUE_TYPE double
#define VALUE_TYPE storm::RationalFunction
/* /*
* Entry point for the DyFTeE backend. * Entry point for the DyFTeE backend.
@ -15,6 +15,15 @@ int main(int argc, char** argv) {
std::cout << "Storm-DyFTeE should be called with a filename as argument." << std::endl; std::cout << "Storm-DyFTeE should be called with a filename as argument." << std::endl;
return 1; return 1;
} }
// Construct PCTL forumla
std::string inputFormula;
if (argc < 3) {
// Set explicit reachability formula
inputFormula = "Pmax=?[true U \"failed\"]";
} else {
// Read formula from input
inputFormula = argv[2];
}
storm::utility::setUp(); storm::utility::setUp();
log4cplus::LogLevel level = log4cplus::TRACE_LOG_LEVEL; log4cplus::LogLevel level = log4cplus::TRACE_LOG_LEVEL;
@ -24,33 +33,20 @@ int main(int argc, char** argv) {
std::cout << "Parsing DFT file..." << std::endl; std::cout << "Parsing DFT file..." << std::endl;
storm::parser::DFTGalileoParser<VALUE_TYPE> parser; storm::parser::DFTGalileoParser<VALUE_TYPE> parser;
storm::storage::DFT<VALUE_TYPE> dft = parser.parseDFT(argv[1]); storm::storage::DFT<VALUE_TYPE> dft = parser.parseDFT(argv[1]);
std::cout << "Built data structure" << std::endl; std::cout << "Built data structure" << std::endl;
// Verify the model as CTMC
std::cout << "Building CTMC..." << std::endl; std::cout << "Building CTMC..." << std::endl;
storm::builder::ExplicitDFTModelBuilder<VALUE_TYPE> builder(dft); storm::builder::ExplicitDFTModelBuilder<VALUE_TYPE> builder(dft);
std::shared_ptr<storm::models::sparse::Model<VALUE_TYPE>> model = builder.buildCTMC(); std::shared_ptr<storm::models::sparse::Model<VALUE_TYPE>> model = builder.buildCTMC();
std::cout << "Built CTMC" << std::endl; std::cout << "Built CTMC" << std::endl;
std::cout << "Model checking..." << std::endl; std::cout << "Model checking..." << std::endl;
// Construct PCTL forumla
std::string inputFormula;
if (argc < 3) {
// Set explicit reachability formula
inputFormula = "Pmax=?[true U \"failed\"]";
} else {
// Read formula from input
inputFormula = argv[2];
}
std::vector<std::shared_ptr<storm::logic::Formula>> formulas = storm::parseFormulasForExplicit(inputFormula); std::vector<std::shared_ptr<storm::logic::Formula>> formulas = storm::parseFormulasForExplicit(inputFormula);
assert(formulas.size() == 1); assert(formulas.size() == 1);
// Verify the model
std::unique_ptr<storm::modelchecker::CheckResult> result(storm::verifySparseModel(model, formulas[0]));
assert(result);
std::unique_ptr<storm::modelchecker::CheckResult> resultCtmc(storm::verifySparseModel(model, formulas[0]));
assert(resultCtmc);
std::cout << "Result (initial states): "; std::cout << "Result (initial states): ";
result->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates()));
std::cout << *result << std::endl;
std::cout << "Checked model" << std::endl;
resultCtmc->filter(storm::modelchecker::ExplicitQualitativeCheckResult(model->getInitialStates()));
std::cout << *resultCtmc << std::endl;
std::cout << "Checked CTMC" << std::endl;
} }
Loading…
Cancel
Save