3#include <boost/algorithm/string.hpp> 
    4#include <boost/algorithm/string/replace.hpp> 
   17template<
typename ValueType>
 
   23    const std::regex commentRegex(
"(/\\*([^*]|(\\*+[^*/]))*\\*+/)|(//.*)");
 
   30    std::string toplevelId = 
"";
 
   38                size_t commentEnd = line.find(
"*/");
 
   39                if (commentEnd == std::string::npos) {
 
   43                    line = line.substr(commentEnd + 2);
 
   48            line = std::regex_replace(line, commentRegex, 
"");
 
   50            size_t commentStart = line.find(
"/*");
 
   51            if (commentStart != std::string::npos) {
 
   53                line = line.substr(0, commentStart);
 
   64            STORM_LOG_THROW(line.back() == 
';', storm::exceptions::WrongFormatException, 
"Semicolon expected at the end of line " << lineNo << 
".");
 
   69            std::vector<std::string> tokens;
 
   70            boost::split(tokens, line, boost::is_any_of(
" \t"), boost::token_compress_on);
 
   73            if (tokens[0] == 
"toplevel") {
 
   75                STORM_LOG_THROW(toplevelId.empty(), storm::exceptions::WrongFormatException, 
"Toplevel element already defined.");
 
   76                STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, 
"Expected unique element id after 'toplevel'.");
 
   77                toplevelId = parseName(tokens[1]);
 
   78            } 
else if (tokens[0] == 
"param") {
 
   80                STORM_LOG_THROW(tokens.size() == 2, storm::exceptions::WrongFormatException, 
"Expected unique parameter name after 'param'.");
 
   81                STORM_LOG_THROW((std::is_same<ValueType, storm::RationalFunction>::value), storm::exceptions::NotSupportedException,
 
   82                                "Parameters are only allowed when using rational functions.");
 
   86                std::string name = parseName(tokens[0]);
 
   88                std::vector<std::string> childNames;
 
   89                for (
size_t i = 2; i < tokens.size(); ++i) {
 
   90                    childNames.push_back(parseName(tokens[i]));
 
   94                std::string type = tokens[1];
 
   97                } 
else if (type == 
"or") {
 
   99                } 
else if (boost::starts_with(type, 
"vot")) {
 
  100                    size_t threshold = storm::parser::parseNumber<size_t>(type.substr(3));
 
  102                } 
else if (type.find(
"of") != std::string::npos) {
 
  103                    size_t pos = type.find(
"of");
 
  104                    size_t threshold = storm::parser::parseNumber<size_t>(type.substr(0, pos));
 
  105                    size_t count = storm::parser::parseNumber<size_t>(type.substr(pos + 2));
 
  106                    STORM_LOG_THROW(count == childNames.size(), storm::exceptions::WrongFormatException,
 
  107                                    "Voting gate number " << count << 
" does not correspond to number of children " << childNames.size() << 
".");
 
  109                } 
else if (type == 
"pand") {
 
  111                } 
else if (type == 
"pand-incl" || type == 
"pand<=") {
 
  113                } 
else if (type == 
"pand-excl" || type == 
"pand<") {
 
  115                } 
else if (type == 
"por") {
 
  117                } 
else if (type == 
"por-incl" || type == 
"por<=") {
 
  119                } 
else if (type == 
"por-excl" || type == 
"por<") {
 
  121                } 
else if (type == 
"wsp" || type == 
"csp" || type == 
"hsp" || type == 
"spare") {
 
  123                } 
else if (type == 
"seq") {
 
  125                } 
else if (type == 
"mutex") {
 
  127                } 
else if (type == 
"fdep") {
 
  128                    builder.
addPdep(name, childNames, storm::utility::one<ValueType>());
 
  129                } 
else if (boost::starts_with(type, 
"pdep=")) {
 
  130                    ValueType probability = valueParser.
parseValue(type.substr(5));
 
  131                    builder.
addPdep(name, childNames, probability);
 
  132                } 
else if (type.find(
"=") != std::string::npos) {
 
  135                    std::regex regexName(
"\"?" + tokens[0] + 
"\"?");
 
  136                    std::string remaining_line = std::regex_replace(line, regexName, 
"");
 
  137                    parseBasicElement(name, remaining_line, builder, valueParser);
 
  138                } 
else if (type.find(
"insp") != std::string::npos) {
 
  140                    STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException, 
"Inspections are not supported.");
 
  142                    STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException, 
"Type name '" << type << 
"' not recognized.");
 
  147        STORM_LOG_THROW(
false, storm::exceptions::FileIoException, 
"A parsing exception occurred in line " << lineNo << 
": " << exception.
what());
 
  153    return builder.
build();
 
 
  156template<
typename ValueType>
 
  158    size_t firstQuots = name.find(
"\"");
 
  159    if (firstQuots != std::string::npos) {
 
  161        size_t secondQuots = name.find(
"\"", firstQuots + 1);
 
  162        STORM_LOG_THROW(secondQuots != std::string::npos, storm::exceptions::WrongFormatException, 
"No ending quotation mark found in " << name);
 
  163        return name.substr(firstQuots + 1, secondQuots - 1);
 
 
  169template<
typename ValueType>
 
  172    std::regex nameRegex(name + 
"\\s*=\\s*([^\\s]*)");
 
  174    if (std::regex_search(line, match, nameRegex)) {
 
  176        std::string value = match.str(1);
 
  177        line = std::regex_replace(line, nameRegex, 
"");
 
  185template<
typename ValueType>
 
  192    std::optional<BEType> distribution;
 
  193    std::optional<ValueType> prob;
 
  194    std::optional<ValueType> lambda;
 
  195    std::optional<size_t> phases;
 
  196    std::optional<ValueType> shape;
 
  197    std::optional<ValueType> rate;
 
  198    std::optional<ValueType> mean;
 
  199    std::optional<ValueType> stddev;
 
  200    std::optional<ValueType> dorm;
 
  204    std::string value = parseValue(
"prob", input);
 
  205    if (!value.empty()) {
 
  207        distribution = BEType::PROBABILITY;
 
  211    value = parseValue(
"lambda", input);
 
  212    if (!value.empty()) {
 
  214            !distribution.has_value(), storm::exceptions::WrongFormatException,
 
  215            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::EXPONENTIAL) << 
" are defined for BE '" << name << 
"'.");
 
  217        distribution = BEType::EXPONENTIAL;
 
  222    value = parseValue(
"phases", input);
 
  223    if (!value.empty()) {
 
  225            !distribution.has_value() || distribution.value() == BEType::EXPONENTIAL, storm::exceptions::WrongFormatException,
 
  226            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::ERLANG) << 
" are defined for BE '" << name << 
"'.");
 
  227        phases = storm::parser::parseNumber<size_t>(value);
 
  228        distribution = BEType::ERLANG;
 
  232    value = parseValue(
"shape", input);
 
  233    if (!value.empty()) {
 
  235            !distribution.has_value(), storm::exceptions::WrongFormatException,
 
  236            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::WEIBULL) << 
" are defined for BE '" << name << 
"'.");
 
  238        distribution = BEType::WEIBULL;
 
  240    value = parseValue(
"rate", input);
 
  241    if (!value.empty()) {
 
  243            !distribution.has_value() || distribution.value() == BEType::WEIBULL, storm::exceptions::WrongFormatException,
 
  244            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::WEIBULL) << 
" are defined for BE '" << name << 
"'.");
 
  249    value = parseValue(
"mean", input);
 
  250    if (!value.empty()) {
 
  252            !distribution.has_value(), storm::exceptions::WrongFormatException,
 
  253            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::LOGNORMAL) << 
" are defined for BE '" << name << 
"'.");
 
  255        distribution = BEType::LOGNORMAL;
 
  257    value = parseValue(
"stddev", input);
 
  258    if (!value.empty()) {
 
  260            !distribution.has_value() || distribution.value() == BEType::LOGNORMAL, storm::exceptions::WrongFormatException,
 
  261            "Two distributions " << 
toString(distribution.value()) << 
" and " << 
toString(BEType::LOGNORMAL) << 
" are defined for BE '" << name << 
"'.");
 
  266    value = parseValue(
"dorm", input);
 
  267    if (!value.empty()) {
 
  272    value = parseValue(
"cov", input);
 
  273    if (!value.empty()) {
 
  274        STORM_LOG_WARN(
"Coverage is not supported and will be ignored for basic element '" << name << 
"'.");
 
  276    value = parseValue(
"res", input);
 
  277    if (!value.empty()) {
 
  278        STORM_LOG_WARN(
"Restoration is not supported and will be ignored for basic element '" << name << 
"'.");
 
  280    value = parseValue(
"repl", input);
 
  281    if (!value.empty()) {
 
  282        size_t replication = storm::parser::parseNumber<size_t>(value);
 
  283        STORM_LOG_THROW(replication == 1, storm::exceptions::NotSupportedException, 
"Replication > 1 is not supported for basic element '" << name << 
"'.");
 
  285    value = parseValue(
"interval", input);
 
  286    if (!value.empty()) {
 
  287        STORM_LOG_WARN(
"Interval is not supported and will be ignored for basic element '" << name << 
"'.");
 
  289    value = parseValue(
"repair", input);
 
  290    if (!value.empty()) {
 
  291        STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException, 
"Repairs are not supported and will be ignored for basic element '" << name << 
"'.");
 
  296        STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException, 
"Unknown arguments for basic element '" << name << 
"': " << input);
 
  300    STORM_LOG_THROW(distribution.has_value(), storm::exceptions::WrongFormatException, 
"No failure distribution is defined for BE '" << name << 
"'.");
 
  301    switch (distribution.value()) {
 
  302        case BEType::PROBABILITY:
 
  303            STORM_LOG_THROW(prob.has_value(), storm::exceptions::WrongFormatException,
 
  304                            "Distribution " << 
toString(BEType::PROBABILITY) << 
" requires parameter 'prob' for BE '" << name << 
"'.");
 
  305            if (!dorm.has_value()) {
 
  306                STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name << 
"'. Assuming dormancy factor of 1.");
 
  307                dorm = storm::utility::one<ValueType>();
 
  311        case BEType::EXPONENTIAL:
 
  312            STORM_LOG_THROW(lambda.has_value(), storm::exceptions::WrongFormatException,
 
  313                            "Distribution " << 
toString(BEType::EXPONENTIAL) << 
" requires parameter 'lambda' for BE '" << name << 
"'.");
 
  314            if (!dorm.has_value()) {
 
  315                STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name << 
"'. Assuming dormancy factor of 1.");
 
  316                dorm = storm::utility::one<ValueType>();
 
  321            STORM_LOG_THROW(lambda.has_value(), storm::exceptions::WrongFormatException,
 
  322                            "Distribution " << 
toString(BEType::ERLANG) << 
" requires parameter 'lambda' for BE '" << name << 
"'.");
 
  323            STORM_LOG_THROW(phases.has_value(), storm::exceptions::WrongFormatException,
 
  324                            "Distribution " << 
toString(BEType::ERLANG) << 
" requires parameter 'phases' for BE '" << name << 
"'.");
 
  325            if (!dorm.has_value()) {
 
  326                STORM_LOG_WARN(
"No dormancy factor was provided for basic element '" << name << 
"'. Assuming dormancy factor of 1.");
 
  327                dorm = storm::utility::one<ValueType>();
 
  331        case BEType::WEIBULL:
 
  332            STORM_LOG_THROW(shape.has_value(), storm::exceptions::WrongFormatException,
 
  333                            "Distribution " << 
toString(BEType::WEIBULL) << 
" requires parameter 'shape' for BE '" << name << 
"'.");
 
  334            STORM_LOG_THROW(rate.has_value(), storm::exceptions::WrongFormatException,
 
  335                            "Distribution " << 
toString(BEType::WEIBULL) << 
" requires parameter 'rate' for BE '" << name << 
"'.");
 
  338        case BEType::LOGNORMAL:
 
  339            STORM_LOG_THROW(mean.has_value(), storm::exceptions::WrongFormatException,
 
  340                            "Distribution " << 
toString(BEType::LOGNORMAL) << 
" requires parameter 'mean' for BE '" << name << 
"'.");
 
  341            STORM_LOG_THROW(stddev.has_value(), storm::exceptions::WrongFormatException,
 
  342                            "Distribution " << 
toString(BEType::WEIBULL) << 
" requires parameter 'stddev' for BE '" << name << 
"'.");
 
  346            STORM_LOG_THROW(
false, storm::exceptions::WrongFormatException, 
"No distribution defined for basic element '" << name << 
"'.");
 
  352template class DFTGalileoParser<double>;
 
  353template class DFTGalileoParser<RationalFunction>;
 
void addPdep(std::string const &name, std::vector< std::string > const &children, ValueType probability)
Create (probabilistic) dependency (PDEP) and add it to DFT.
 
void addOrGate(std::string const &name, std::vector< std::string > const &children)
Create OR-gate and add it to DFT.
 
void addVotingGate(std::string const &name, unsigned threshold, std::vector< std::string > const &children)
Create VOTing-gate and add it to DFT.
 
void addBasicElementErlang(std::string const &name, ValueType rate, unsigned phases, ValueType dormancyFactor)
Create BE with Erlang distribution and add it to DFT.
 
void addSpareGate(std::string const &name, std::vector< std::string > const &children)
Create SPARE-gate and add it to DFT.
 
storm::dft::storage::DFT< ValueType > build()
Create DFT.
 
void addAndGate(std::string const &name, std::vector< std::string > const &children)
Create AND-gate and add it to DFT.
 
void addBasicElementProbability(std::string const &name, ValueType probability, ValueType dormancyFactor)
Create BE with constant (Bernoulli) distribution and add it to DFT.
 
void setTopLevel(std::string const &tle)
Set top level element.
 
void addBasicElementExponential(std::string const &name, ValueType rate, ValueType dormancyFactor, bool transient=false)
Create BE with exponential distribution and add it to DFT.
 
void addPorGate(std::string const &name, std::vector< std::string > const &children, bool inclusive=true)
Create POR-gate and add it to DFT.
 
void addSequenceEnforcer(std::string const &name, std::vector< std::string > const &children)
Create sequence enforcer (SEQ) and add it to DFT.
 
void addPandGate(std::string const &name, std::vector< std::string > const &children, bool inclusive=true)
Create PAND-gate and add it to DFT.
 
void addBasicElementWeibull(std::string const &name, ValueType shape, ValueType rate)
Create BE with Weibull distribution and add it to DFT.
 
void addBasicElementLogNormal(std::string const &name, ValueType mean, ValueType standardDeviation)
Create BE with log-normal distribution and add it to DFT.
 
void addMutex(std::string const &name, std::vector< std::string > const &children)
Create mutual exclusion-gate (MUTEX) and add it to DFT.
 
Parser for DFT in the Galileo format.
 
static storm::dft::storage::DFT< ValueType > parseDFT(std::string const &filename)
Parse DFT in Galileo format and build DFT.
 
static std::string parseName(std::string const &name)
Parse element name (strip quotation marks, etc.).
 
Represents a Dynamic Fault Tree.
 
This class represents the base class of all exception classes.
 
virtual const char * what() const noexcept override
Retrieves the message associated with this exception.
 
Parser for values according to their ValueType.
 
void addParameter(std::string const ¶meter)
Add declaration of parameter.
 
ValueType parseValue(std::string const &value) const
Parse ValueType from string.
 
#define STORM_LOG_WARN(message)
 
#define STORM_LOG_THROW(cond, exception, message)
 
std::string toString(DFTElementType const &type)
 
std::basic_istream< CharT, Traits > & getline(std::basic_istream< CharT, Traits > &input, std::basic_string< CharT, Traits, Allocator > &str)
Overloaded getline function which handles different types of newline (  and \r).
 
void closeFile(std::ofstream &stream)
Close the given file after writing.
 
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.