Browse Source

Constants in formulas appear to be working

main
dehnert 9 years ago
parent
commit
b4381a7c48
  1. 31
      src/storm/cli/cli.cpp
  2. 4
      src/storm/counterexamples/SMTMinimalCommandSetGenerator.h
  3. 31
      src/storm/logic/BoundedUntilFormula.cpp
  4. 30
      src/storm/logic/BoundedUntilFormula.h
  5. 66
      src/storm/logic/CumulativeRewardFormula.cpp
  6. 26
      src/storm/logic/CumulativeRewardFormula.h
  7. 62
      src/storm/logic/InstantaneousRewardFormula.cpp
  8. 31
      src/storm/logic/InstantaneousRewardFormula.h
  9. 19
      src/storm/logic/TimeBound.cpp
  10. 21
      src/storm/logic/TimeBound.h
  11. 12
      src/storm/logic/TimeBoundType.h
  12. 24
      src/storm/logic/VariableSubstitutionVisitor.cpp
  13. 3
      src/storm/logic/VariableSubstitutionVisitor.h
  14. 8
      src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp
  15. 6
      src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp
  16. 6
      src/storm/modelchecker/multiobjective/pcaa/SparsePcaaPreprocessor.cpp
  17. 8
      src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp
  18. 8
      src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp
  19. 8
      src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp
  20. 28
      src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp
  21. 8
      src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp
  22. 8
      src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp
  23. 8
      src/storm/parser/FormulaParser.cpp
  24. 1
      src/storm/parser/FormulaParser.h
  25. 80
      src/storm/parser/FormulaParserGrammar.cpp
  26. 28
      src/storm/parser/FormulaParserGrammar.h
  27. 12
      src/storm/parser/JaniParser.cpp
  28. 36
      src/storm/storage/SymbolicModelDescription.cpp
  29. 5
      src/storm/storage/SymbolicModelDescription.h
  30. 5
      src/storm/storage/jani/Model.cpp
  31. 6
      src/storm/storage/prism/Program.cpp
  32. 65
      src/storm/utility/cli.cpp
  33. 16
      src/storm/utility/cli.h
  34. 55
      src/storm/utility/jani.cpp
  35. 7
      src/storm/utility/jani.h
  36. 60
      src/storm/utility/prism.cpp
  37. 2
      src/storm/utility/prism.h
  38. 5
      src/storm/utility/storm.cpp
  39. 1
      src/storm/utility/storm.h
  40. 6
      src/test/modelchecker/NativeHybridDtmcPrctlModelCheckerTest.cpp

31
src/storm/cli/cli.cpp

@ -247,19 +247,30 @@ 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<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
if (storm::settings::getModule<storm::settings::modules::GeneralSettings>().isPropertySet()) {
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
if (model.isJaniModel()) {
for(auto const& formula : storm::parseFormulasForJaniModel(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getProperty(), model.asJaniModel())) {
properties.emplace_back(std::to_string(i), formula);
++i;
}
formulas = storm::parseFormulasForJaniModel(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getProperty(), model.asJaniModel());
} else {
for(auto const& formula :storm::parseFormulasForPrismProgram(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getProperty(), model.asPrismProgram())) {
properties.emplace_back(std::to_string(i), formula);
++i;
}
formulas = storm::parseFormulasForPrismProgram(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getProperty(), model.asPrismProgram());
}
constantDefinitions = model.parseConstantDefinitions(constantDefinitionString);
formulas = substituteConstantsInFormulas(formulas, constantDefinitions);
for (auto const& formula : formulas) {
properties.emplace_back(std::to_string(i), formula);
++i;
}
} else {
constantDefinitions = model.parseConstantDefinitions(constantDefinitionString);
}
model = model.preprocess(constantDefinitions);
if (model.isJaniModel() && storm::settings::getModule<storm::settings::modules::JaniExportSettings>().isJaniFileSet()) {
exportJaniModel(model.asJaniModel(), properties, storm::settings::getModule<storm::settings::modules::JaniExportSettings>().getJaniFilename());
@ -269,10 +280,6 @@ namespace storm {
return;
}
// Get the string that assigns values to the unknown currently undefined constants in the model.
std::string constantDefinitionString = ioSettings.getConstantDefinitionString();
model = model.preprocess(constantDefinitionString);
STORM_LOG_TRACE("Building and checking symbolic model.");
if (storm::settings::getModule<storm::settings::modules::GeneralSettings>().isParametricSet()) {
#ifdef STORM_HAVE_CARL

4
src/storm/counterexamples/SMTMinimalCommandSetGenerator.h

@ -14,7 +14,7 @@
#include "storm/settings/modules/CoreSettings.h"
#include "storm/utility/counterexamples.h"
#include "storm/utility/prism.h"
#include "storm/utility/cli.h"
namespace storm {
namespace counterexamples {
@ -1612,7 +1612,7 @@ namespace storm {
auto analysisClock = std::chrono::high_resolution_clock::now();
decltype(std::chrono::high_resolution_clock::now() - analysisClock) totalAnalysisTime(0);
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions = storm::utility::prism::parseConstantDefinitionString(program, constantDefinitionString);
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions = storm::utility::cli::parseConstantDefinitionString(program.getManager(), constantDefinitionString);
storm::prism::Program preparedProgram = program.defineUndefinedConstants(constantDefinitions);
preparedProgram = preparedProgram.substituteConstants();

31
src/storm/logic/BoundedUntilFormula.cpp

@ -6,22 +6,11 @@
#include "storm/logic/FormulaVisitor.h"
#include "storm/exceptions/InvalidPropertyException.h"
#include "storm/exceptions/InvalidOperationException.h"
namespace storm {
namespace logic {
UntilBound::UntilBound(bool strict, storm::expressions::Expression const& bound) : strict(strict), bound(bound) {
// Intentionally left empty.
}
storm::expressions::Expression const& UntilBound::getBound() const {
return bound;
}
bool UntilBound::isStrict() const {
return strict;
}
BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, boost::optional<UntilBound> const& lowerBound, boost::optional<UntilBound> const& upperBound, BoundedType const& boundedType) : BinaryPathFormula(leftSubformula, rightSubformula), boundedType(boundedType), lowerBound(lowerBound), upperBound(upperBound) {
BoundedUntilFormula::BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, boost::optional<TimeBound> const& lowerBound, boost::optional<TimeBound> const& upperBound, TimeBoundType const& timeBoundType) : BinaryPathFormula(leftSubformula, rightSubformula), timeBoundType(timeBoundType), lowerBound(lowerBound), upperBound(upperBound) {
STORM_LOG_THROW(lowerBound || upperBound, storm::exceptions::InvalidArgumentException, "Bounded until formula requires at least one bound.");
}
@ -37,12 +26,16 @@ namespace storm {
return visitor.visit(*this, data);
}
TimeBoundType const& BoundedUntilFormula::getTimeBoundType() const {
return timeBoundType;
}
bool BoundedUntilFormula::isStepBounded() const {
return boundedType == BoundedType::Steps;
return timeBoundType == TimeBoundType::Steps;
}
bool BoundedUntilFormula::isTimeBounded() const {
return boundedType == BoundedType::Time;
return timeBoundType == TimeBoundType::Time;
}
bool BoundedUntilFormula::isLowerBoundStrict() const {
@ -79,6 +72,7 @@ namespace storm {
template <>
double BoundedUntilFormula::getLowerBound() const {
checkNoVariablesInBound(this->getLowerBound());
double bound = this->getLowerBound().evaluateAsDouble();
STORM_LOG_THROW(bound >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return bound;
@ -86,6 +80,7 @@ namespace storm {
template <>
double BoundedUntilFormula::getUpperBound() const {
checkNoVariablesInBound(this->getUpperBound());
double bound = this->getUpperBound().evaluateAsDouble();
STORM_LOG_THROW(bound >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return bound;
@ -93,6 +88,7 @@ namespace storm {
template <>
uint64_t BoundedUntilFormula::getLowerBound() const {
checkNoVariablesInBound(this->getLowerBound());
int_fast64_t bound = this->getLowerBound().evaluateAsInt();
STORM_LOG_THROW(bound >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return static_cast<uint64_t>(bound);
@ -100,11 +96,16 @@ namespace storm {
template <>
uint64_t BoundedUntilFormula::getUpperBound() const {
checkNoVariablesInBound(this->getUpperBound());
int_fast64_t bound = this->getUpperBound().evaluateAsInt();
STORM_LOG_THROW(bound >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return static_cast<uint64_t>(bound);
}
void BoundedUntilFormula::checkNoVariablesInBound(storm::expressions::Expression const& bound) {
STORM_LOG_THROW(!bound.containsVariables(), storm::exceptions::InvalidOperationException, "Cannot evaluate time-bound '" << bound << "' as it contains undefined constants.");
}
std::ostream& BoundedUntilFormula::writeToStream(std::ostream& out) const {
this->getLeftSubformula().writeToStream(out);

30
src/storm/logic/BoundedUntilFormula.h

@ -5,28 +5,14 @@
#include "storm/logic/BinaryPathFormula.h"
#include "storm/logic/TimeBound.h"
#include "storm/logic/TimeBoundType.h"
namespace storm {
namespace logic {
class UntilBound {
public:
UntilBound(bool strict, storm::expressions::Expression const& bound);
storm::expressions::Expression const& getBound() const;
bool isStrict() const;
private:
bool strict;
storm::expressions::Expression bound;
};
class BoundedUntilFormula : public BinaryPathFormula {
public:
enum class BoundedType {
Steps,
Time
};
BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, boost::optional<UntilBound> const& lowerBound, boost::optional<UntilBound> const& upperBound, BoundedType const& boundedType = BoundedType::Time);
BoundedUntilFormula(std::shared_ptr<Formula const> const& leftSubformula, std::shared_ptr<Formula const> const& rightSubformula, boost::optional<TimeBound> const& lowerBound, boost::optional<TimeBound> const& upperBound, TimeBoundType const& timeBoundType = TimeBoundType::Time);
virtual bool isBoundedUntilFormula() const override;
@ -34,6 +20,7 @@ namespace storm {
virtual boost::any accept(FormulaVisitor const& visitor, boost::any const& data) const override;
TimeBoundType const& getTimeBoundType() const;
bool isStepBounded() const;
bool isTimeBounded() const;
@ -57,10 +44,11 @@ namespace storm {
virtual std::ostream& writeToStream(std::ostream& out) const override;
private:
BoundedType boundedType;
static void checkNoVariablesInBound(storm::expressions::Expression const& bound);
boost::optional<UntilBound> lowerBound;
boost::optional<UntilBound> upperBound;
TimeBoundType timeBoundType;
boost::optional<TimeBound> lowerBound;
boost::optional<TimeBound> upperBound;
};
}
}

66
src/storm/logic/CumulativeRewardFormula.cpp

@ -2,16 +2,16 @@
#include "storm/logic/FormulaVisitor.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidPropertyException.h"
#include "storm/exceptions/InvalidOperationException.h"
namespace storm {
namespace logic {
CumulativeRewardFormula::CumulativeRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
// Intentionally left empty.
}
CumulativeRewardFormula::CumulativeRewardFormula(double timeBound) : timeBound(timeBound) {
CumulativeRewardFormula::CumulativeRewardFormula(TimeBound const& bound, TimeBoundType const& timeBoundType) : timeBoundType(timeBoundType), bound(bound) {
// Intentionally left empty.
}
bool CumulativeRewardFormula::isCumulativeRewardFormula() const {
return true;
}
@ -24,32 +24,52 @@ namespace storm {
return visitor.visit(*this, data);
}
bool CumulativeRewardFormula::hasDiscreteTimeBound() const {
return timeBound.which() == 0;
TimeBoundType const& CumulativeRewardFormula::getTimeBoundType() const {
return timeBoundType;
}
bool CumulativeRewardFormula::isStepBounded() const {
return timeBoundType == TimeBoundType::Steps;
}
bool CumulativeRewardFormula::isTimeBounded() const {
return timeBoundType == TimeBoundType::Time;
}
bool CumulativeRewardFormula::isBoundStrict() const {
return bound.isStrict();
}
uint_fast64_t CumulativeRewardFormula::getDiscreteTimeBound() const {
return boost::get<uint_fast64_t>(timeBound);
bool CumulativeRewardFormula::hasIntegerBound() const {
return bound.getBound().hasIntegerType();
}
bool CumulativeRewardFormula::hasContinuousTimeBound() const {
return timeBound.which() == 1;
storm::expressions::Expression const& CumulativeRewardFormula::getBound() const {
return bound.getBound();
}
template <>
double CumulativeRewardFormula::getBound() const {
checkNoVariablesInBound(bound.getBound());
double value = bound.getBound().evaluateAsDouble();
STORM_LOG_THROW(value >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return value;
}
template <>
uint64_t CumulativeRewardFormula::getBound() const {
checkNoVariablesInBound(bound.getBound());
uint64_t value = bound.getBound().evaluateAsInt();
STORM_LOG_THROW(value >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return value;
}
double CumulativeRewardFormula::getContinuousTimeBound() const {
if (this->hasDiscreteTimeBound()) {
return this->getDiscreteTimeBound();
} else {
return boost::get<double>(timeBound);
}
void CumulativeRewardFormula::checkNoVariablesInBound(storm::expressions::Expression const& bound) {
STORM_LOG_THROW(!bound.containsVariables(), storm::exceptions::InvalidOperationException, "Cannot evaluate time-bound '" << bound << "' as it contains undefined constants.");
}
std::ostream& CumulativeRewardFormula::writeToStream(std::ostream& out) const {
if (this->hasDiscreteTimeBound()) {
out << "C<=" << this->getDiscreteTimeBound();
} else {
out << "C<=" << this->getContinuousTimeBound();
}
out << "C<=" << this->getBound();
return out;
}
}

26
src/storm/logic/CumulativeRewardFormula.h

@ -1,17 +1,16 @@
#ifndef STORM_LOGIC_CUMULATIVEREWARDFORMULA_H_
#define STORM_LOGIC_CUMULATIVEREWARDFORMULA_H_
#include <boost/variant.hpp>
#include "storm/logic/PathFormula.h"
#include "storm/logic/TimeBound.h"
#include "storm/logic/TimeBoundType.h"
namespace storm {
namespace logic {
class CumulativeRewardFormula : public PathFormula {
public:
CumulativeRewardFormula(uint_fast64_t timeBound);
CumulativeRewardFormula(double timeBound);
CumulativeRewardFormula(TimeBound const& bound, TimeBoundType const& timeBoundType = TimeBoundType::Time);
virtual ~CumulativeRewardFormula() {
// Intentionally left empty.
@ -24,16 +23,23 @@ namespace storm {
virtual std::ostream& writeToStream(std::ostream& out) const override;
bool hasDiscreteTimeBound() const;
TimeBoundType const& getTimeBoundType() const;
bool isStepBounded() const;
bool isTimeBounded() const;
uint_fast64_t getDiscreteTimeBound() const;
bool isBoundStrict() const;
bool hasIntegerBound() const;
bool hasContinuousTimeBound() const;
storm::expressions::Expression const& getBound() const;
double getContinuousTimeBound() const;
template <typename ValueType>
ValueType getBound() const;
private:
boost::variant<uint_fast64_t, double> timeBound;
static void checkNoVariablesInBound(storm::expressions::Expression const& bound);
TimeBoundType timeBoundType;
TimeBound bound;
};
}
}

62
src/storm/logic/InstantaneousRewardFormula.cpp

@ -2,16 +2,16 @@
#include "storm/logic/FormulaVisitor.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidPropertyException.h"
#include "storm/exceptions/InvalidOperationException.h"
namespace storm {
namespace logic {
InstantaneousRewardFormula::InstantaneousRewardFormula(uint_fast64_t timeBound) : timeBound(timeBound) {
InstantaneousRewardFormula::InstantaneousRewardFormula(storm::expressions::Expression const& bound, TimeBoundType const& timeBoundType) : timeBoundType(timeBoundType), bound(bound) {
// Intentionally left empty.
}
InstantaneousRewardFormula::InstantaneousRewardFormula(double timeBound) : timeBound(timeBound) {
// Intentionally left empty.
}
bool InstantaneousRewardFormula::isInstantaneousRewardFormula() const {
return true;
}
@ -24,32 +24,48 @@ namespace storm {
return visitor.visit(*this, data);
}
bool InstantaneousRewardFormula::hasDiscreteTimeBound() const {
return timeBound.which() == 0;
TimeBoundType const& InstantaneousRewardFormula::getTimeBoundType() const {
return timeBoundType;
}
bool InstantaneousRewardFormula::isStepBounded() const {
return timeBoundType == TimeBoundType::Steps;
}
bool InstantaneousRewardFormula::isTimeBounded() const {
return timeBoundType == TimeBoundType::Time;
}
bool InstantaneousRewardFormula::hasIntegerBound() const {
return bound.hasIntegerType();
}
uint_fast64_t InstantaneousRewardFormula::getDiscreteTimeBound() const {
return boost::get<uint_fast64_t>(timeBound);
storm::expressions::Expression const& InstantaneousRewardFormula::getBound() const {
return bound;
}
bool InstantaneousRewardFormula::hasContinuousTimeBound() const {
return timeBound.which() == 1;
template <>
double InstantaneousRewardFormula::getBound() const {
checkNoVariablesInBound(bound);
double value = bound.evaluateAsDouble();
STORM_LOG_THROW(value >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return value;
}
double InstantaneousRewardFormula::getContinuousTimeBound() const {
if (this->hasDiscreteTimeBound()) {
return this->getDiscreteTimeBound();
} else {
return boost::get<double>(timeBound);
}
template <>
uint64_t InstantaneousRewardFormula::getBound() const {
checkNoVariablesInBound(bound);
uint64_t value = bound.evaluateAsInt();
STORM_LOG_THROW(value >= 0, storm::exceptions::InvalidPropertyException, "Time-bound must not evaluate to negative number.");
return value;
}
void InstantaneousRewardFormula::checkNoVariablesInBound(storm::expressions::Expression const& bound) {
STORM_LOG_THROW(!bound.containsVariables(), storm::exceptions::InvalidOperationException, "Cannot evaluate time-instant '" << bound << "' as it contains undefined constants.");
}
std::ostream& InstantaneousRewardFormula::writeToStream(std::ostream& out) const {
if (this->hasDiscreteTimeBound()) {
out << "I=" << this->getDiscreteTimeBound();
} else {
out << "I=" << this->getContinuousTimeBound();
}
out << "I=" << this->getBound();
return out;
}
}

31
src/storm/logic/InstantaneousRewardFormula.h

@ -1,18 +1,17 @@
#ifndef STORM_LOGIC_INSTANTANEOUSREWARDFORMULA_H_
#define STORM_LOGIC_INSTANTANEOUSREWARDFORMULA_H_
#include <boost/variant.hpp>
#include "storm/logic/PathFormula.h"
#include "storm/logic/TimeBoundType.h"
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace logic {
class InstantaneousRewardFormula : public PathFormula {
public:
InstantaneousRewardFormula(uint_fast64_t timeBound);
InstantaneousRewardFormula(double timeBound);
InstantaneousRewardFormula(storm::expressions::Expression const& bound, TimeBoundType const& timeBoundType = TimeBoundType::Time);
virtual ~InstantaneousRewardFormula() {
// Intentionally left empty.
}
@ -25,16 +24,22 @@ namespace storm {
virtual std::ostream& writeToStream(std::ostream& out) const override;
bool hasDiscreteTimeBound() const;
TimeBoundType const& getTimeBoundType() const;
bool isStepBounded() const;
bool isTimeBounded() const;
uint_fast64_t getDiscreteTimeBound() const;
bool hasContinuousTimeBound() const;
bool hasIntegerBound() const;
storm::expressions::Expression const& getBound() const;
template <typename ValueType>
ValueType getBound() const;
double getContinuousTimeBound() const;
private:
boost::variant<uint_fast64_t, double> timeBound;
static void checkNoVariablesInBound(storm::expressions::Expression const& bound);
TimeBoundType timeBoundType;
storm::expressions::Expression bound;
};
}
}

19
src/storm/logic/TimeBound.cpp

@ -0,0 +1,19 @@
#include "storm/logic/TimeBound.h"
namespace storm {
namespace logic {
TimeBound::TimeBound(bool strict, storm::expressions::Expression const& bound) : strict(strict), bound(bound) {
// Intentionally left empty.
}
storm::expressions::Expression const& TimeBound::getBound() const {
return bound;
}
bool TimeBound::isStrict() const {
return strict;
}
}
}

21
src/storm/logic/TimeBound.h

@ -0,0 +1,21 @@
#pragma once
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace logic {
class TimeBound {
public:
TimeBound(bool strict, storm::expressions::Expression const& bound);
storm::expressions::Expression const& getBound() const;
bool isStrict() const;
private:
bool strict;
storm::expressions::Expression bound;
};
}
}

12
src/storm/logic/TimeBoundType.h

@ -0,0 +1,12 @@
#pragma once
namespace storm {
namespace logic {
enum class TimeBoundType {
Steps,
Time
};
}
}

24
src/storm/logic/VariableSubstitutionVisitor.cpp

@ -14,6 +14,30 @@ namespace storm {
return boost::any_cast<std::shared_ptr<Formula>>(result);
}
boost::any VariableSubstitutionVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
auto left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
auto right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
boost::optional<TimeBound> lowerBound;
if (f.hasLowerBound()) {
lowerBound = TimeBound(f.isLowerBoundStrict(), f.getLowerBound().substitute(substitution));
}
boost::optional<TimeBound> upperBound;
if (f.hasUpperBound()) {
upperBound = TimeBound(f.isUpperBoundStrict(), f.getUpperBound().substitute(substitution));
}
return std::static_pointer_cast<Formula>(std::make_shared<BoundedUntilFormula>(left, right, lowerBound, upperBound, f.getTimeBoundType()));
}
boost::any VariableSubstitutionVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
return std::static_pointer_cast<Formula>(std::make_shared<CumulativeRewardFormula>(storm::logic::TimeBound(f.isBoundStrict(), f.getBound().substitute(substitution)), f.getTimeBoundType()));
}
boost::any VariableSubstitutionVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
return std::static_pointer_cast<Formula>(std::make_shared<InstantaneousRewardFormula>(f.getBound().substitute(substitution), f.getTimeBoundType()));
}
boost::any VariableSubstitutionVisitor::visit(AtomicExpressionFormula const& f, boost::any const&) const {
return std::static_pointer_cast<Formula>(std::make_shared<AtomicExpressionFormula>(f.getExpression().substitute(substitution)));
}

3
src/storm/logic/VariableSubstitutionVisitor.h

@ -16,6 +16,9 @@ namespace storm {
std::shared_ptr<Formula> substitute(Formula const& f) const;
virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override;
virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(InstantaneousRewardFormula const& f, boost::any const& data) const override;
virtual boost::any visit(AtomicExpressionFormula const& f, boost::any const& data) const override;
private:

8
src/storm/modelchecker/csl/HybridCtmcCslModelChecker.cpp

@ -88,13 +88,17 @@ namespace storm {
template<typename ModelType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getContinuousTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported.");
return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory);
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridCtmcCslModelChecker<ModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getContinuousTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported.");
return storm::modelchecker::helper::HybridCtmcCslHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory);
}
template<typename ModelType>

6
src/storm/modelchecker/csl/SparseCtmcCslModelChecker.cpp

@ -99,14 +99,16 @@ namespace storm {
template <typename SparseCtmcModelType>
std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getContinuousTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeInstantaneousRewards(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
template <typename SparseCtmcModelType>
std::unique_ptr<CheckResult> SparseCtmcCslModelChecker<SparseCtmcModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getContinuousTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(!rewardPathFormula.isStepBounded(), storm::exceptions::NotImplementedException, "Currently step-bounded properties on CTMCs are not supported.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseCtmcCslHelper::computeCumulativeRewards(this->getModel().getTransitionMatrix(), this->getModel().getExitRateVector(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<double>(), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}

6
src/storm/modelchecker/multiobjective/pcaa/SparsePcaaPreprocessor.cpp

@ -314,9 +314,9 @@ namespace storm {
template<typename SparseModelType>
void SparsePcaaPreprocessor<SparseModelType>::preprocessCumulativeRewardFormula(storm::logic::CumulativeRewardFormula const& formula, ReturnType& result, PcaaObjective<ValueType>& currentObjective, boost::optional<std::string> const& optionalRewardModelName) {
STORM_LOG_THROW(result.originalModel.isOfType(storm::models::ModelType::Mdp), storm::exceptions::InvalidPropertyException, "Cumulative reward formulas are not supported for the given model type.");
STORM_LOG_THROW(formula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Expected a cumulativeRewardFormula with a discrete time bound but got " << formula << ".");
STORM_LOG_THROW(formula.getDiscreteTimeBound()>0, storm::exceptions::InvalidPropertyException, "Expected a cumulativeRewardFormula with a positive discrete time bound but got " << formula << ".");
currentObjective.upperTimeBound = storm::utility::convertNumber<ValueType>(formula.getDiscreteTimeBound());
STORM_LOG_THROW(!formula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Expected a cumulativeRewardFormula with a discrete time bound but got " << formula << ".");
// FIXME: really convert to value type?
currentObjective.upperTimeBound = storm::utility::convertNumber<ValueType>(formula.getBound<uint64_t>());
RewardModelType objectiveRewards = result.preprocessedModel.getRewardModel(optionalRewardModelName ? optionalRewardModelName.get() : "");
objectiveRewards.reduceToStateBasedRewards(result.preprocessedModel.getTransitionMatrix(), false);

8
src/storm/modelchecker/prctl/HybridDtmcPrctlModelChecker.cpp

@ -82,15 +82,15 @@ namespace storm {
template<typename ModelType>
std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ull), *this->linearEquationSolverFactory);
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory);
}
template<typename ModelType>

8
src/storm/modelchecker/prctl/HybridMdpPrctlModelChecker.cpp

@ -81,16 +81,16 @@ namespace storm {
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<ModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ll), *this->linearEquationSolverFactory);
}
template<typename ModelType>
std::unique_ptr<CheckResult> HybridMdpPrctlModelChecker<ModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::HybridMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory);
}
template<typename ModelType>

8
src/storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.cpp

@ -85,16 +85,16 @@ namespace storm {
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeCumulativeRewards(this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ull), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
template<typename SparseDtmcModelType>
std::unique_ptr<CheckResult> SparseDtmcPrctlModelChecker<SparseDtmcModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeInstantaneousRewards(this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *linearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}

28
src/storm/modelchecker/prctl/SparseMdpPrctlModelChecker.cpp

@ -26,7 +26,7 @@
#include "storm/storage/MaximalEndComponentDecomposition.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/exceptions/InvalidPropertyException.h"
namespace storm {
namespace modelchecker {
@ -57,7 +57,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeBoundedUntilProbabilities(CheckTask<storm::logic::BoundedUntilFormula, ValueType> const& checkTask) {
storm::logic::BoundedUntilFormula const& pathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(!pathFormula.hasLowerBound() && pathFormula.hasUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have single upper time bound.");
STORM_LOG_THROW(pathFormula.hasIntegerUpperBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have discrete upper time bound.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
@ -71,7 +71,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeNextProbabilities(CheckTask<storm::logic::NextFormula, ValueType> const& checkTask) {
storm::logic::NextFormula const& pathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(pathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeNextProbabilities(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory);
@ -81,7 +81,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeUntilProbabilities(CheckTask<storm::logic::UntilFormula, ValueType> const& checkTask) {
storm::logic::UntilFormula const& pathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> leftResultPointer = this->check(pathFormula.getLeftSubformula());
std::unique_ptr<CheckResult> rightResultPointer = this->check(pathFormula.getRightSubformula());
ExplicitQualitativeCheckResult const& leftResult = leftResultPointer->asExplicitQualitativeCheckResult();
@ -97,7 +97,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeGloballyProbabilities(CheckTask<storm::logic::GloballyFormula, ValueType> const& checkTask) {
storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(pathFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
auto ret = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeGloballyProbabilities(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
@ -107,7 +107,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeConditionalProbabilities(CheckTask<storm::logic::ConditionalFormula, ValueType> const& checkTask) {
storm::logic::ConditionalFormula const& conditionalFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(this->getModel().getInitialStates().getNumberOfSetBits() == 1, storm::exceptions::InvalidPropertyException, "Cannot compute conditional probabilities on MDPs with more than one initial state.");
STORM_LOG_THROW(conditionalFormula.getSubformula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
STORM_LOG_THROW(conditionalFormula.getConditionFormula().isEventuallyFormula(), storm::exceptions::InvalidPropertyException, "Illegal conditional probability formula.");
@ -123,25 +123,25 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *minMaxLinearEquationSolverFactory);
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ull), *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidArgumentException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *minMaxLinearEquationSolverFactory);
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *minMaxLinearEquationSolverFactory);
return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
}
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeReachabilityRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::EventuallyFormula, ValueType> const& checkTask) {
storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(eventuallyFormula.getSubformula());
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeReachabilityRewards(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), *minMaxLinearEquationSolverFactory);
@ -151,7 +151,7 @@ namespace storm {
template<typename SparseMdpModelType>
std::unique_ptr<CheckResult> SparseMdpPrctlModelChecker<SparseMdpModelType>::computeLongRunAverageProbabilities(CheckTask<storm::logic::StateFormula, ValueType> const& checkTask) {
storm::logic::StateFormula const& stateFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
std::unique_ptr<CheckResult> subResultPointer = this->check(stateFormula);
ExplicitQualitativeCheckResult const& subResult = subResultPointer->asExplicitQualitativeCheckResult();
std::vector<ValueType> numericResult = storm::modelchecker::helper::SparseMdpPrctlHelper<ValueType>::computeLongRunAverageProbabilities(checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), *minMaxLinearEquationSolverFactory);

8
src/storm/modelchecker/prctl/SymbolicDtmcPrctlModelChecker.cpp

@ -83,16 +83,16 @@ namespace storm {
template<typename ModelType>
std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeCumulativeRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ull), *this->linearEquationSolverFactory);
return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult));
}
template<typename ModelType>
std::unique_ptr<CheckResult> SymbolicDtmcPrctlModelChecker<ModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
storm::dd::Add<DdType> numericResult = storm::modelchecker::helper::SymbolicDtmcPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory);
return std::unique_ptr<SymbolicQuantitativeCheckResult<DdType>>(new SymbolicQuantitativeCheckResult<DdType>(this->getModel().getReachableStates(), numericResult));
}

8
src/storm/modelchecker/prctl/SymbolicMdpPrctlModelChecker.cpp

@ -83,16 +83,16 @@ namespace storm {
std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<ModelType>::computeCumulativeRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::CumulativeRewardFormula, ValueType> const& checkTask) {
storm::logic::CumulativeRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeCumulativeRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>() + (rewardPathFormula.isBoundStrict() ? 1ull : 0ull), *this->linearEquationSolverFactory);
}
template<typename ModelType>
std::unique_ptr<CheckResult> SymbolicMdpPrctlModelChecker<ModelType>::computeInstantaneousRewards(storm::logic::RewardMeasureType, CheckTask<storm::logic::InstantaneousRewardFormula, ValueType> const& checkTask) {
storm::logic::InstantaneousRewardFormula const& rewardPathFormula = checkTask.getFormula();
STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidArgumentException, "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
STORM_LOG_THROW(rewardPathFormula.hasDiscreteTimeBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getDiscreteTimeBound(), *this->linearEquationSolverFactory);
STORM_LOG_THROW(rewardPathFormula.hasIntegerBound(), storm::exceptions::InvalidPropertyException, "Formula needs to have a discrete time bound.");
return storm::modelchecker::helper::SymbolicMdpPrctlHelper<DdType, ValueType>::computeInstantaneousRewards(checkTask.getOptimizationDirection(), this->getModel(), this->getModel().getTransitionMatrix(), checkTask.isRewardModelSet() ? this->getModel().getRewardModel(checkTask.getRewardModel()) : this->getModel().getRewardModel(""), rewardPathFormula.getBound<uint64_t>(), *this->linearEquationSolverFactory);
}
template<typename ModelType>

8
src/storm/parser/FormulaParser.cpp

@ -17,16 +17,18 @@
namespace storm {
namespace parser {
FormulaParser::FormulaParser() : manager(new storm::expressions::ExpressionManager()), grammar(new FormulaParserGrammar(manager)) {
// Intentionally left empty.
}
FormulaParser::FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : manager(manager), grammar(new FormulaParserGrammar(manager)) {
// Intentionally left empty.
}
FormulaParser::FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager> const& manager) : manager(manager), grammar(new FormulaParserGrammar(manager)) {
// Intentionally left empty.
}
FormulaParser::FormulaParser(storm::prism::Program const& program) : manager(program.getManager().getSharedPointer()), grammar(new FormulaParserGrammar(manager)) {
// Make the formulas of the program available to the parser.
for (auto const& formula : program.getFormulas()) {

1
src/storm/parser/FormulaParser.h

@ -23,6 +23,7 @@ namespace storm {
public:
FormulaParser();
explicit FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager);
explicit FormulaParser(std::shared_ptr<storm::expressions::ExpressionManager> const& manager);
explicit FormulaParser(storm::prism::Program const& program);
FormulaParser(FormulaParser const& other);

80
src/storm/parser/FormulaParserGrammar.cpp

@ -4,7 +4,15 @@
namespace storm {
namespace parser {
FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : FormulaParserGrammar::base_type(start), manager(manager), expressionParser(*manager, keywords_, true, true) {
FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), expressionParser(*manager, keywords_, true, true) {
initialize();
}
FormulaParserGrammar::FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager> const& manager) : FormulaParserGrammar::base_type(start), constManager(manager), manager(manager), expressionParser(*manager, keywords_, true, true) {
initialize();
}
void FormulaParserGrammar::initialize() {
// Register all variables so we can parse them in the expressions.
for (auto variableTypePair : *manager) {
identifiers_.add(variableTypePair.first.getName(), variableTypePair.first);
@ -15,10 +23,10 @@ namespace storm {
longRunAverageRewardFormula = (qi::lit("LRA") | qi::lit("S"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createLongRunAverageRewardFormula, phoenix::ref(*this))];
longRunAverageRewardFormula.name("long run average reward formula");
instantaneousRewardFormula = (qi::lit("I=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("I=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)];
instantaneousRewardFormula = (qi::lit("I=") > expressionParser)[qi::_val = phoenix::bind(&FormulaParserGrammar::createInstantaneousRewardFormula, phoenix::ref(*this), qi::_1)];
instantaneousRewardFormula.name("instantaneous reward formula");
cumulativeRewardFormula = (qi::lit("C<=") >> strict_double)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)] | (qi::lit("C<=") > qi::uint_)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1)];
cumulativeRewardFormula = ((qi::lit("C<=")[qi::_a = false] | qi::lit("C<")[qi::_a = true]) > expressionParser)[qi::_val = phoenix::bind(&FormulaParserGrammar::createCumulativeRewardFormula, phoenix::ref(*this), qi::_1, qi::_a)];
cumulativeRewardFormula.name("cumulative reward formula");
totalRewardFormula = (qi::lit("C"))[qi::_val = phoenix::bind(&FormulaParserGrammar::createTotalRewardFormula, phoenix::ref(*this))];
@ -105,12 +113,19 @@ namespace storm {
stateFormula = (orStateFormula | multiObjectiveFormula);
stateFormula.name("state formula");
start = qi::eps > (stateFormula % +(qi::char_("\n;"))) >> qi::skip(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - (qi::eol | qi::eoi)))[qi::eps] >> qi::eoi;
identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_') | qi::char_('.')) >> *(qi::alnum | qi::char_('_')))]]];
identifier.name("identifier");
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.name("start");
//Enable the following lines to print debug output for most the rules.
// Enable the following lines to print debug output for most the rules.
/*
debug(start);
debug(constantDefinition);
debug(stateFormula);
debug(orStateFormula);
debug(andStateFormula);
@ -167,38 +182,41 @@ namespace storm {
this->identifiers_.add(identifier, expression);
}
std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>> FormulaParserGrammar::createTimeBoundFromInterval(storm::expressions::Expression const& lowerBound, storm::expressions::Expression const& upperBound) const {
storm::logic::UntilBound lower(false, lowerBound);
storm::logic::UntilBound upper(false, upperBound);
void FormulaParserGrammar::addConstant(std::string const& name, bool integer) {
STORM_LOG_ASSERT(manager, "Mutable expression manager required to define new constants.");
storm::expressions::Variable newVariable;
if (integer) {
newVariable = manager->declareIntegerVariable(name);
} else {
newVariable = manager->declareRationalVariable(name);
}
addIdentifierExpression(name, newVariable);
}
bool FormulaParserGrammar::areConstantDefinitionsAllowed() const {
return static_cast<bool>(manager);
}
std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>> FormulaParserGrammar::createTimeBoundFromInterval(storm::expressions::Expression const& lowerBound, storm::expressions::Expression const& upperBound) const {
storm::logic::TimeBound lower(false, lowerBound);
storm::logic::TimeBound upper(false, upperBound);
return std::make_pair(lower, upper);
}
std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>> FormulaParserGrammar::createTimeBoundFromSingleBound(storm::expressions::Expression const& bound, bool upperBound, bool strict) const {
std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>> FormulaParserGrammar::createTimeBoundFromSingleBound(storm::expressions::Expression const& bound, bool upperBound, bool strict) const {
if (upperBound) {
return std::make_pair(boost::none, storm::logic::UntilBound(strict, bound));
return std::make_pair(boost::none, storm::logic::TimeBound(strict, bound));
} else {
return std::make_pair(storm::logic::UntilBound(strict, bound), boost::none);
return std::make_pair(storm::logic::TimeBound(strict, bound), boost::none);
}
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
if (timeBound.which() == 0) {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::InstantaneousRewardFormula(static_cast<uint_fast64_t>(boost::get<unsigned>(timeBound))));
} else {
double timeBoundAsDouble = boost::get<double>(timeBound);
STORM_LOG_THROW(timeBoundAsDouble >= 0, storm::exceptions::WrongFormatException, "Instantaneous reward property must have non-negative bound.");
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::InstantaneousRewardFormula(timeBoundAsDouble));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createInstantaneousRewardFormula(storm::expressions::Expression const& timeBound) const {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::InstantaneousRewardFormula(timeBound));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const {
if (timeBound.which() == 0) {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::CumulativeRewardFormula(static_cast<uint_fast64_t>(boost::get<unsigned>(timeBound))));
} else {
double timeBoundAsDouble = boost::get<double>(timeBound);
STORM_LOG_THROW(timeBoundAsDouble >= 0, storm::exceptions::WrongFormatException, "Cumulative reward property must have non-negative bound.");
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::CumulativeRewardFormula(static_cast<uint_fast64_t>(timeBoundAsDouble)));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createCumulativeRewardFormula(storm::expressions::Expression const& timeBound, bool strict) const {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::CumulativeRewardFormula(storm::logic::TimeBound(strict, timeBound)));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createTotalRewardFormula() const {
@ -222,9 +240,9 @@ namespace storm {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::AtomicLabelFormula(label));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createEventuallyFormula(boost::optional<std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula const> const& subformula) const {
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createEventuallyFormula(boost::optional<std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula const> const& subformula) const {
if (timeBound) {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, timeBound.get().first, timeBound.get().second, storm::logic::BoundedUntilFormula::BoundedType::Time));
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, timeBound.get().first, timeBound.get().second, storm::logic::TimeBoundType::Time));
} else {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::EventuallyFormula(subformula, context));
}
@ -238,9 +256,9 @@ namespace storm {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::NextFormula(subformula));
}
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createUntilFormula(std::shared_ptr<storm::logic::Formula const> const& leftSubformula, boost::optional<std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>>> const& timeBound, std::shared_ptr<storm::logic::Formula const> const& rightSubformula) {
std::shared_ptr<storm::logic::Formula const> FormulaParserGrammar::createUntilFormula(std::shared_ptr<storm::logic::Formula const> const& leftSubformula, boost::optional<std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>>> const& timeBound, std::shared_ptr<storm::logic::Formula const> const& rightSubformula) {
if (timeBound) {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::BoundedUntilFormula(leftSubformula, rightSubformula, timeBound.get().first, timeBound.get().second, storm::logic::BoundedUntilFormula::BoundedType::Time));
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::BoundedUntilFormula(leftSubformula, rightSubformula, timeBound.get().first, timeBound.get().second, storm::logic::TimeBoundType::Time));
} else {
return std::shared_ptr<storm::logic::Formula const>(new storm::logic::UntilFormula(leftSubformula, rightSubformula));
}

28
src/storm/parser/FormulaParserGrammar.h

@ -20,6 +20,7 @@ namespace storm {
class FormulaParserGrammar : public qi::grammar<Iterator, std::vector<std::shared_ptr<storm::logic::Formula const>>(), Skipper> {
public:
FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager const> const& manager);
FormulaParserGrammar(std::shared_ptr<storm::expressions::ExpressionManager> const& manager);
FormulaParserGrammar(FormulaParserGrammar const& other) = default;
FormulaParserGrammar& operator=(FormulaParserGrammar const& other) = default;
@ -34,6 +35,8 @@ namespace storm {
void addIdentifierExpression(std::string const& identifier, storm::expressions::Expression const& expression);
private:
void initialize();
struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
keywordsStruct() {
add
@ -108,7 +111,8 @@ namespace storm {
rewardMeasureTypeStruct rewardMeasureType_;
// The manager used to parse expressions.
std::shared_ptr<storm::expressions::ExpressionManager const> manager;
std::shared_ptr<storm::expressions::ExpressionManager const> constManager;
std::shared_ptr<storm::expressions::ExpressionManager> manager;
// Parser and manager used for recognizing expressions.
storm::parser::ExpressionParser expressionParser;
@ -119,6 +123,9 @@ namespace storm {
qi::rule<Iterator, std::vector<std::shared_ptr<storm::logic::Formula const>>(), Skipper> start;
qi::rule<Iterator, qi::unused_type(), qi::locals<bool>, Skipper> constantDefinition;
qi::rule<Iterator, std::string(), Skipper> identifier;
qi::rule<Iterator, storm::logic::OperatorInformation(), qi::locals<boost::optional<storm::OptimizationDirection>, boost::optional<storm::logic::ComparisonType>, boost::optional<storm::expressions::Expression>>, Skipper> operatorInformation;
qi::rule<Iterator, storm::logic::RewardMeasureType(), Skipper> rewardMeasureType;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> probabilityOperator;
@ -149,10 +156,10 @@ namespace storm {
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(storm::logic::FormulaContext), Skipper> globallyFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(storm::logic::FormulaContext), Skipper> untilFormula;
qi::rule<Iterator, std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>>(), qi::locals<bool, bool>, Skipper> timeBound;
qi::rule<Iterator, std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>>(), qi::locals<bool, bool>, Skipper> timeBound;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> rewardPathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> cumulativeRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), qi::locals<bool>, Skipper> cumulativeRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> totalRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> instantaneousRewardFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula const>(), Skipper> longRunAverageRewardFormula;
@ -162,21 +169,24 @@ namespace storm {
// Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>> createTimeBoundFromInterval(storm::expressions::Expression const& lowerBound, storm::expressions::Expression const& upperBound) const;
std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>> createTimeBoundFromSingleBound(storm::expressions::Expression const& bound, bool upperBound, bool strict) const;
bool areConstantDefinitionsAllowed() const;
void addConstant(std::string const& name, bool integer);
std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>> createTimeBoundFromInterval(storm::expressions::Expression const& lowerBound, storm::expressions::Expression const& upperBound) const;
std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>> createTimeBoundFromSingleBound(storm::expressions::Expression const& bound, bool upperBound, bool strict) const;
// Methods that actually create the expression objects.
std::shared_ptr<storm::logic::Formula const> createInstantaneousRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula const> createCumulativeRewardFormula(boost::variant<unsigned, double> const& timeBound) const;
std::shared_ptr<storm::logic::Formula const> createInstantaneousRewardFormula(storm::expressions::Expression const& timeBound) const;
std::shared_ptr<storm::logic::Formula const> createCumulativeRewardFormula(storm::expressions::Expression const& timeBound, bool strict) const;
std::shared_ptr<storm::logic::Formula const> createTotalRewardFormula() const;
std::shared_ptr<storm::logic::Formula const> createLongRunAverageRewardFormula() const;
std::shared_ptr<storm::logic::Formula const> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
std::shared_ptr<storm::logic::Formula const> createBooleanLiteralFormula(bool literal) const;
std::shared_ptr<storm::logic::Formula const> createAtomicLabelFormula(std::string const& label) const;
std::shared_ptr<storm::logic::Formula const> createEventuallyFormula(boost::optional<std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula const> const& subformula) const;
std::shared_ptr<storm::logic::Formula const> createEventuallyFormula(boost::optional<std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>>> const& timeBound, storm::logic::FormulaContext context, std::shared_ptr<storm::logic::Formula const> const& subformula) const;
std::shared_ptr<storm::logic::Formula const> createGloballyFormula(std::shared_ptr<storm::logic::Formula const> const& subformula) const;
std::shared_ptr<storm::logic::Formula const> createNextFormula(std::shared_ptr<storm::logic::Formula const> const& subformula) const;
std::shared_ptr<storm::logic::Formula const> createUntilFormula(std::shared_ptr<storm::logic::Formula const> const& leftSubformula, boost::optional<std::pair<boost::optional<storm::logic::UntilBound>, boost::optional<storm::logic::UntilBound>>> const& timeBound, std::shared_ptr<storm::logic::Formula const> const& rightSubformula);
std::shared_ptr<storm::logic::Formula const> createUntilFormula(std::shared_ptr<storm::logic::Formula const> const& leftSubformula, boost::optional<std::pair<boost::optional<storm::logic::TimeBound>, boost::optional<storm::logic::TimeBound>>> const& timeBound, std::shared_ptr<storm::logic::Formula const> const& rightSubformula);
std::shared_ptr<storm::logic::Formula const> createConditionalFormula(std::shared_ptr<storm::logic::Formula const> const& leftSubformula, std::shared_ptr<storm::logic::Formula const> const& rightSubformula, storm::logic::FormulaContext context) const;
storm::logic::OperatorInformation createOperatorInformation(boost::optional<storm::OptimizationDirection> const& optimizationDirection, boost::optional<storm::logic::ComparisonType> const& comparisonType, boost::optional<storm::expressions::Expression> const& threshold) const;
std::shared_ptr<storm::logic::Formula const> createLongRunAverageOperatorFormula(storm::logic::OperatorInformation const& operatorInformation, std::shared_ptr<storm::logic::Formula const> const& subformula) const;

12
src/storm/parser/JaniParser.cpp

@ -256,14 +256,14 @@ namespace storm {
if(!accTime && !accSteps) {
if (rewExpr.isVariable()) {
std::string rewardName = rewExpr.getVariables().begin()->getName();
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::InstantaneousRewardFormula>(static_cast<uint64_t>(stepInstant)), rewardName, opInfo);
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::InstantaneousRewardFormula>(stepInstantExpr, storm::logic::TimeBoundType::Steps), rewardName, opInfo);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only simple reward expressions are currently supported");
}
} else {
if (rewExpr.isVariable()) {
std::string rewardName = rewExpr.getVariables().begin()->getName();
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::CumulativeRewardFormula>(static_cast<uint64_t>(stepInstant)), rewardName, opInfo);
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::CumulativeRewardFormula>(storm::logic::TimeBound(false, stepInstantExpr), storm::logic::TimeBoundType::Steps), rewardName, opInfo);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only simple reward expressions are currently supported");
}
@ -276,14 +276,14 @@ namespace storm {
if(!accTime && !accSteps) {
if (rewExpr.isVariable()) {
std::string rewardName = rewExpr.getVariables().begin()->getName();
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::InstantaneousRewardFormula>(timeInstant), rewardName, opInfo);
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::InstantaneousRewardFormula>(timeInstantExpr, storm::logic::TimeBoundType::Time), rewardName, opInfo);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only simple reward expressions are currently supported");
}
} else {
if (rewExpr.isVariable()) {
std::string rewardName = rewExpr.getVariables().begin()->getName();
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::CumulativeRewardFormula>(timeInstant), rewardName, opInfo);
return std::make_shared<storm::logic::RewardOperatorFormula>(std::make_shared<storm::logic::CumulativeRewardFormula>(storm::logic::TimeBound(false, timeInstantExpr), storm::logic::TimeBoundType::Time), rewardName, opInfo);
} else {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Only simple reward expressions are currently supported");
}
@ -345,7 +345,7 @@ namespace storm {
upperBound--;
}
STORM_LOG_THROW(upperBound >= 0, storm::exceptions::InvalidJaniException, "Step-bounds cannot be negative");
return std::make_shared<storm::logic::BoundedUntilFormula const>(args[0], args[1], storm::logic::UntilBound(pi.lowerBoundStrict, pi.lowerBound), storm::logic::UntilBound(pi.upperBoundStrict, pi.upperBound), storm::logic::BoundedUntilFormula::BoundedType::Steps);
return std::make_shared<storm::logic::BoundedUntilFormula const>(args[0], args[1], storm::logic::TimeBound(pi.lowerBoundStrict, pi.lowerBound), storm::logic::TimeBound(pi.upperBoundStrict, pi.upperBound), storm::logic::TimeBoundType::Steps);
} else if (propertyStructure.count("time-bounds") > 0) {
storm::jani::PropertyInterval pi = parsePropertyInterval(propertyStructure.at("time-bounds"));
STORM_LOG_THROW(pi.hasUpperBound(), storm::exceptions::NotSupportedException, "Storm only supports time-bounded until with an upper bound.");
@ -356,7 +356,7 @@ namespace storm {
double upperBound = pi.upperBound.evaluateAsDouble();
STORM_LOG_THROW(lowerBound >= 0, storm::exceptions::InvalidJaniException, "(Lower) time-bounds cannot be negative");
STORM_LOG_THROW(upperBound >= 0, storm::exceptions::InvalidJaniException, "(Upper) time-bounds cannot be negative");
return std::make_shared<storm::logic::BoundedUntilFormula const>(args[0], args[1], storm::logic::UntilBound(pi.lowerBoundStrict, pi.lowerBound), storm::logic::UntilBound(pi.upperBoundStrict, pi.upperBound), storm::logic::BoundedUntilFormula::BoundedType::Time);
return std::make_shared<storm::logic::BoundedUntilFormula const>(args[0], args[1], storm::logic::TimeBound(pi.lowerBoundStrict, pi.lowerBound), storm::logic::TimeBound(pi.upperBoundStrict, pi.upperBound), storm::logic::TimeBoundType::Time);
} else if (propertyStructure.count("reward-bounds") > 0 ) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Reward bounded properties are not supported by Storm");

36
src/storm/storage/SymbolicModelDescription.cpp

@ -1,5 +1,6 @@
#include "storm/storage/SymbolicModelDescription.h"
#include "storm/utility/cli.h"
#include "storm/utility/prism.h"
#include "storm/utility/jani.h"
@ -84,12 +85,22 @@ namespace storm {
STORM_LOG_THROW(isJaniModel(), storm::exceptions::InvalidOperationException, "Cannot retrieve JANI model, because the symbolic description has a different type.");
return boost::get<storm::jani::Model>(modelDescription.get());
}
storm::jani::Model& SymbolicModelDescription::asJaniModel() {
STORM_LOG_THROW(isJaniModel(), storm::exceptions::InvalidOperationException, "Cannot retrieve JANI model, because the symbolic description has a different type.");
return boost::get<storm::jani::Model>(modelDescription.get());
}
storm::prism::Program const& SymbolicModelDescription::asPrismProgram() const {
STORM_LOG_THROW(isPrismProgram(), storm::exceptions::InvalidOperationException, "Cannot retrieve JANI model, because the symbolic description has a different type.");
return boost::get<storm::prism::Program>(modelDescription.get());
}
storm::prism::Program& SymbolicModelDescription::asPrismProgram() {
STORM_LOG_THROW(isPrismProgram(), storm::exceptions::InvalidOperationException, "Cannot retrieve JANI model, because the symbolic description has a different type.");
return boost::get<storm::prism::Program>(modelDescription.get());
}
std::vector<std::string> SymbolicModelDescription::getParameterNames() const {
std::vector<std::string> result;
if (isJaniModel()) {
@ -116,17 +127,34 @@ namespace storm {
}
SymbolicModelDescription SymbolicModelDescription::preprocess(std::string const& constantDefinitionString) const {
std::map<storm::expressions::Variable, storm::expressions::Expression> substitution = parseConstantDefinitions(constantDefinitionString);
if (this->isJaniModel()) {
std::map<storm::expressions::Variable, storm::expressions::Expression> substitution = storm::utility::jani::parseConstantDefinitionString(this->asJaniModel(), constantDefinitionString);
storm::jani::Model preparedModel = this->asJaniModel().defineUndefinedConstants(substitution).substituteConstants();
return SymbolicModelDescription(preparedModel);
} else if (this->isPrismProgram()) {
std::map<storm::expressions::Variable, storm::expressions::Expression> substitution = storm::utility::prism::parseConstantDefinitionString(this->asPrismProgram(), constantDefinitionString);
return SymbolicModelDescription(this->asPrismProgram().defineUndefinedConstants(substitution).substituteConstants());
}
return *this;
}
SymbolicModelDescription SymbolicModelDescription::preprocess(std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantDefinitions) const {
if (this->isJaniModel()) {
storm::jani::Model preparedModel = this->asJaniModel().defineUndefinedConstants(constantDefinitions).substituteConstants();
return SymbolicModelDescription(preparedModel);
} else if (this->isPrismProgram()) {
return SymbolicModelDescription(this->asPrismProgram().defineUndefinedConstants(constantDefinitions).substituteConstants());
}
return *this;
}
std::map<storm::expressions::Variable, storm::expressions::Expression> SymbolicModelDescription::parseConstantDefinitions(std::string const& constantDefinitionString) const {
if (this->isJaniModel()) {
return storm::utility::cli::parseConstantDefinitionString(this->asJaniModel().getManager(), constantDefinitionString);
} else {
return storm::utility::cli::parseConstantDefinitionString(this->asPrismProgram().getManager(), constantDefinitionString);
}
}
void SymbolicModelDescription::requireNoUndefinedConstants() const {
if (this->isJaniModel()) {
storm::utility::jani::requireNoUndefinedConstants(this->asJaniModel());

5
src/storm/storage/SymbolicModelDescription.h

@ -32,13 +32,18 @@ namespace storm {
void setModel(storm::prism::Program const& program);
storm::jani::Model const& asJaniModel() const;
storm::jani::Model& asJaniModel();
storm::prism::Program const& asPrismProgram() const;
storm::prism::Program& asPrismProgram();
std::vector<std::string> getParameterNames() const;
SymbolicModelDescription toJani(bool makeVariablesGlobal = true) const;
SymbolicModelDescription preprocess(std::string const& constantDefinitionString = "") const;
SymbolicModelDescription preprocess(std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantDefinitions) const;
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitions(std::string const& constantDefinitionString) const;
void requireNoUndefinedConstants() const;

5
src/storm/storage/jani/Model.cpp

@ -825,11 +825,6 @@ namespace storm {
}
}
// As a sanity check, we make sure that the given mapping does not contain any definitions for identifiers
// that are not undefined constants.
for (auto const& constantExpressionPair : constantDefinitions) {
STORM_LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidOperationException, "Unable to define non-existant constant '" << constantExpressionPair.first.getName() << "'.");
}
return result;
}

6
src/storm/storage/prism/Program.cpp

@ -760,12 +760,6 @@ namespace storm {
}
}
// As a sanity check, we make sure that the given mapping does not contain any definitions for identifiers
// that are not undefined constants.
for (auto const& constantExpressionPair : constantDefinitions) {
STORM_LOG_THROW(definedUndefinedConstants.find(constantExpressionPair.first) != definedUndefinedConstants.end(), storm::exceptions::InvalidArgumentException, "Unable to define non-existant constant.");
}
return Program(this->manager, this->getModelType(), newConstants, this->getGlobalBooleanVariables(), this->getGlobalIntegerVariables(), this->getFormulas(), this->getModules(), this->getActionNameToIndexMapping(), this->getRewardModels(), this->getLabels(), this->getOptionalInitialConstruct(), this->getOptionalSystemCompositionConstruct());
}

65
src/storm/utility/cli.cpp

@ -0,0 +1,65 @@
#include "storm/utility/cli.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/WrongFormatException.h"
namespace storm {
namespace utility {
namespace cli {
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::expressions::ExpressionManager const& manager, std::string const& constantDefinitionString) {
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
std::set<storm::expressions::Variable> definedConstants;
if (!constantDefinitionString.empty()) {
// Parse the string that defines the undefined constants of the model and make sure that it contains exactly
// one value for each undefined constant of the model.
std::vector<std::string> definitions;
boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
for (auto& definition : definitions) {
boost::trim(definition);
// Check whether the token could be a legal constant definition.
std::size_t positionOfAssignmentOperator = definition.find('=');
STORM_LOG_THROW(positionOfAssignmentOperator != std::string::npos, storm::exceptions::WrongFormatException, "Illegal constant definition string: syntax error.");
// Now extract the variable name and the value from the string.
std::string constantName = definition.substr(0, positionOfAssignmentOperator);
boost::trim(constantName);
std::string value = definition.substr(positionOfAssignmentOperator + 1);
boost::trim(value);
// Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
if (manager.hasVariable(constantName)) {
// Get the actual constant and check whether it's in fact undefined.
auto const& variable = manager.getVariable(constantName);
STORM_LOG_THROW(definedConstants.find(variable) == definedConstants.end(), storm::exceptions::WrongFormatException, "Illegally trying to define constant '" << constantName <<"' twice.");
definedConstants.insert(variable);
if (variable.hasBooleanType()) {
if (value == "true") {
constantDefinitions[variable] = manager.boolean(true);
} else if (value == "false") {
constantDefinitions[variable] = manager.boolean(false);
} else {
throw storm::exceptions::WrongFormatException() << "Illegal value for boolean constant: " << value << ".";
}
} else if (variable.hasIntegerType()) {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[variable] = manager.integer(integerValue);
} else if (variable.hasRationalType()) {
double doubleValue = std::stod(value);
constantDefinitions[variable] = manager.rational(doubleValue);
}
} else {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Illegal constant definition string: unknown undefined constant '" << constantName << "'.");
}
}
}
return constantDefinitions;
}
}
}
}

16
src/storm/utility/cli.h

@ -0,0 +1,16 @@
#pragma once
#include <map>
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace utility {
namespace cli {
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::expressions::ExpressionManager const& manager, std::string const& constantDefinitionString);
}
}
}

55
src/storm/utility/jani.cpp

@ -11,61 +11,6 @@
namespace storm {
namespace utility {
namespace jani {
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::jani::Model const& model, std::string const& constantDefinitionString) {
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
std::set<storm::expressions::Variable> definedConstants;
if (!constantDefinitionString.empty()) {
// Parse the string that defines the undefined constants of the model and make sure that it contains exactly
// one value for each undefined constant of the model.
std::vector<std::string> definitions;
boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
for (auto& definition : definitions) {
boost::trim(definition);
// Check whether the token could be a legal constant definition.
std::size_t positionOfAssignmentOperator = definition.find('=');
STORM_LOG_THROW(positionOfAssignmentOperator != std::string::npos, storm::exceptions::InvalidArgumentException, "Illegal constant definition string: syntax error.");
// Now extract the variable name and the value from the string.
std::string constantName = definition.substr(0, positionOfAssignmentOperator);
boost::trim(constantName);
std::string value = definition.substr(positionOfAssignmentOperator + 1);
boost::trim(value);
// Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
if (model.hasConstant(constantName)) {
// Get the actual constant and check whether it's in fact undefined.
auto const& constant = model.getConstant(constantName);
storm::expressions::Variable variable = constant.getExpressionVariable();
STORM_LOG_THROW(!constant.isDefined(), storm::exceptions::InvalidArgumentException, "Illegally trying to define already defined constant '" << constantName <<"'.");
STORM_LOG_THROW(definedConstants.find(variable) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
definedConstants.insert(variable);
if (constant.getType().isBooleanType()) {
if (value == "true") {
constantDefinitions[variable] = model.getExpressionManager().boolean(true);
} else if (value == "false") {
constantDefinitions[variable] = model.getExpressionManager().boolean(false);
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
}
} else if (constant.getType().isIntegerType()) {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[variable] = model.getExpressionManager().integer(integerValue);
} else if (constant.getType().isRationalType()) {
double doubleValue = std::stod(value);
constantDefinitions[variable] = model.getExpressionManager().rational(doubleValue);
}
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Illegal constant definition string: unknown undefined constant '" << constantName << "'.");
}
}
}
return constantDefinitions;
}
void requireNoUndefinedConstants(storm::jani::Model const& model) {
if (model.hasUndefinedConstants()) {

7
src/storm/utility/jani.h

@ -3,11 +3,6 @@
#include <map>
namespace storm {
namespace expressions {
class Variable;
class Expression;
}
namespace jani {
class Model;
}
@ -15,8 +10,6 @@ namespace storm {
namespace utility {
namespace jani {
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::jani::Model const& model, std::string const& constantDefinitionString);
void requireNoUndefinedConstants(storm::jani::Model const& model);
}
}

60
src/storm/utility/prism.cpp

@ -5,6 +5,7 @@
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/storage/prism/Program.h"
#include "storm/utility/cli.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidArgumentException.h"
@ -22,64 +23,7 @@ namespace storm {
}
storm::prism::Program preprocess(storm::prism::Program const& program, std::string const& constantDefinitionString) {
return preprocess(program, parseConstantDefinitionString(program, constantDefinitionString));
}
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::prism::Program const& program, std::string const& constantDefinitionString) {
std::map<storm::expressions::Variable, storm::expressions::Expression> constantDefinitions;
std::set<storm::expressions::Variable> definedConstants;
if (!constantDefinitionString.empty()) {
// Parse the string that defines the undefined constants of the model and make sure that it contains exactly
// one value for each undefined constant of the model.
std::vector<std::string> definitions;
boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
for (auto& definition : definitions) {
boost::trim(definition);
// Check whether the token could be a legal constant definition.
uint_fast64_t positionOfAssignmentOperator = definition.find('=');
if (positionOfAssignmentOperator == std::string::npos) {
throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: syntax error.";
}
// Now extract the variable name and the value from the string.
std::string constantName = definition.substr(0, positionOfAssignmentOperator);
boost::trim(constantName);
std::string value = definition.substr(positionOfAssignmentOperator + 1);
boost::trim(value);
// Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
if (program.hasConstant(constantName)) {
// Get the actual constant and check whether it's in fact undefined.
auto const& constant = program.getConstant(constantName);
storm::expressions::Variable variable = constant.getExpressionVariable();
STORM_LOG_THROW(!constant.isDefined(), storm::exceptions::InvalidArgumentException, "Illegally trying to define already defined constant '" << constantName <<"'.");
STORM_LOG_THROW(definedConstants.find(variable) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
definedConstants.insert(variable);
if (constant.getType().isBooleanType()) {
if (value == "true") {
constantDefinitions[variable] = program.getManager().boolean(true);
} else if (value == "false") {
constantDefinitions[variable] = program.getManager().boolean(false);
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
}
} else if (constant.getType().isIntegerType()) {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[variable] = program.getManager().integer(integerValue);
} else if (constant.getType().isRationalType()) {
double doubleValue = std::stod(value);
constantDefinitions[variable] = program.getManager().rational(doubleValue);
}
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Illegal constant definition string: unknown undefined constant " << constantName << ".");
}
}
}
return constantDefinitions;
return preprocess(program, storm::utility::cli::parseConstantDefinitionString(program.getManager(), constantDefinitionString));
}
void requireNoUndefinedConstants(storm::prism::Program const& program) {

2
src/storm/utility/prism.h

@ -20,8 +20,6 @@ namespace storm {
namespace utility {
namespace prism {
std::map<storm::expressions::Variable, storm::expressions::Expression> parseConstantDefinitionString(storm::prism::Program const& program, std::string const& constantDefinitionString);
storm::prism::Program preprocess(storm::prism::Program const& program, std::map<storm::expressions::Variable, storm::expressions::Expression> const& constantDefinitions);
storm::prism::Program preprocess(storm::prism::Program const& program, std::string const& constantDefinitionString);

5
src/storm/utility/storm.cpp

@ -47,7 +47,7 @@ namespace storm{
* @param FormulaParser
* @return The formulas.
*/
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulas(storm::parser::FormulaParser & formulaParser, std::string const& inputString) {
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulas(storm::parser::FormulaParser& formulaParser, std::string const& inputString) {
// 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.
if (inputString.find(".") != std::string::npos && std::ifstream(inputString).good()) {
@ -65,6 +65,7 @@ namespace storm{
std::vector<std::shared_ptr<storm::logic::Formula const>> substituteConstantsInFormulas(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) {
std::vector<std::shared_ptr<storm::logic::Formula const>> preprocessedFormulas;
for (auto const& formula : formulas) {
preprocessedFormulas.emplace_back(formula->substitute(substitution));
}
@ -78,7 +79,7 @@ namespace storm{
}
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulasForPrismProgram(std::string const& inputString, storm::prism::Program const& program) {
storm::parser::FormulaParser formulaParser(program);
storm::parser::FormulaParser formulaParser(program.getManager().getSharedPointer());
auto formulas = parseFormulas(formulaParser, inputString);
return substituteConstantsInFormulas(formulas, program.getConstantsSubstitution());
}

1
src/storm/utility/storm.h

@ -108,6 +108,7 @@ namespace storm {
std::vector<std::shared_ptr<storm::logic::Formula const>> formulasInProperties(std::vector<storm::jani::Property> const& properties);
std::pair<storm::jani::Model, std::map<std::string, storm::jani::Property>> parseJaniModel(std::string const& path);
storm::prism::Program parseProgram(std::string const& path);
std::vector<std::shared_ptr<storm::logic::Formula const>> substituteConstantsInFormulas(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas, std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution);
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulasForExplicit(std::string const& inputString);
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulasForPrismProgram(std::string const& inputString, storm::prism::Program const& program);
std::vector<std::shared_ptr<storm::logic::Formula const>> parseFormulasForJaniModel(std::string const& inputString, storm::jani::Model const& model);

6
src/test/modelchecker/NativeHybridDtmcPrctlModelCheckerTest.cpp

@ -18,7 +18,7 @@
#include "storm/settings/modules/GmmxxEquationSolverSettings.h"
#include "storm/settings/modules/NativeEquationSolverSettings.h"
TEST(NativeHybridDtmcPrctlModelCheckerTest, Die_CUDD) {
TEST(NativeHybridDtmcPrctlModelCheckerTest, Die_Cudd) {
storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm");
storm::prism::Program program = modelDescription.preprocess().asPrismProgram();
@ -142,7 +142,7 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Die_Sylvan) {
EXPECT_NEAR(3.6666646003723145, quantitativeResult4.getMax(), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
}
TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds_CUDD) {
TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds_Cudd) {
storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/crowds-5-5.pm");
storm::prism::Program program = modelDescription.preprocess().asPrismProgram();
@ -232,7 +232,7 @@ TEST(NativeHybridDtmcPrctlModelCheckerTest, Crowds_Sylvan) {
EXPECT_NEAR(0.32153900158185761, quantitativeResult3.getMax(), storm::settings::getModule<storm::settings::modules::GmmxxEquationSolverSettings>().getPrecision());
}
TEST(NativeHybridDtmcPrctlModelCheckerTest, SynchronousLeader_CUDD) {
TEST(NativeHybridDtmcPrctlModelCheckerTest, SynchronousLeader_Cudd) {
storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/leader-3-5.pm");
storm::prism::Program program = modelDescription.preprocess().asPrismProgram();

Loading…
Cancel
Save