diff --git a/src/storm-parsers/parser/FormulaParser.cpp b/src/storm-parsers/parser/FormulaParser.cpp index 37dad72d3..485a4bb18 100644 --- a/src/storm-parsers/parser/FormulaParser.cpp +++ b/src/storm-parsers/parser/FormulaParser.cpp @@ -60,7 +60,7 @@ namespace storm { storm::utility::openFile(filename, inputFileStream); std::vector properties; - + // Now try to parse the contents of the file. try { std::string fileContent((std::istreambuf_iterator(inputFileStream)), (std::istreambuf_iterator())); @@ -70,7 +70,7 @@ namespace storm { storm::utility::closeFile(inputFileStream); throw e; } - + // Close the stream in case everything went smoothly and return result. storm::utility::closeFile(inputFileStream); return properties; diff --git a/src/storm/logic/CloneVisitor.cpp b/src/storm/logic/CloneVisitor.cpp index 103c47fc0..57c8ce377 100644 --- a/src/storm/logic/CloneVisitor.cpp +++ b/src/storm/logic/CloneVisitor.cpp @@ -28,6 +28,34 @@ namespace storm { return std::static_pointer_cast(std::make_shared(f)); } + boost::any CloneVisitor::visit(BoundedGloballyFormula const& f, boost::any const& data) const { + std::vector> lowerBounds, upperBounds; + std::vector timeBoundReferences; + for (uint64_t i = 0; i < f.getDimension(); ++i) { + if (f.hasLowerBound(i)) { + lowerBounds.emplace_back(TimeBound(f.isLowerBoundStrict(i), f.getLowerBound(i))); + } else { + lowerBounds.emplace_back(); + } + if (f.hasUpperBound(i)) { + upperBounds.emplace_back(TimeBound(f.isUpperBoundStrict(i), f.getUpperBound(i))); + } else { + upperBounds.emplace_back(); + } + timeBoundReferences.push_back(f.getTimeBoundReference(i)); + } + if (f.hasMultiDimensionalSubformulas()) { + std::vector> subformulas; + for (uint64_t i = 0; i < f.getDimension(); ++i) { + subformulas.push_back(boost::any_cast>(f.getSubformula(i).accept(*this, data))); + } + return std::static_pointer_cast(std::make_shared(subformulas, lowerBounds, upperBounds, timeBoundReferences)); + } else { + std::shared_ptr subformula = boost::any_cast>(f.getSubformula().accept(*this, data)); + return std::static_pointer_cast(std::make_shared(subformula, lowerBounds, upperBounds, timeBoundReferences)); + } + } + boost::any CloneVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const { std::vector> lowerBounds, upperBounds; std::vector timeBoundReferences; diff --git a/src/storm/logic/CloneVisitor.h b/src/storm/logic/CloneVisitor.h index 5ff29e816..61578bdca 100644 --- a/src/storm/logic/CloneVisitor.h +++ b/src/storm/logic/CloneVisitor.h @@ -16,6 +16,7 @@ namespace storm { virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override; virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override; virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedGloballyFormula const& f, boost::any const& data) const override; virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override; virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override; diff --git a/src/storm/logic/Formula.cpp b/src/storm/logic/Formula.cpp index 70379b8ba..b4e6c13bc 100644 --- a/src/storm/logic/Formula.cpp +++ b/src/storm/logic/Formula.cpp @@ -377,7 +377,6 @@ namespace storm { return dynamic_cast(*this); } - // TODO: find out why these casts are not valid BoundedGloballyFormula& Formula::asBoundedGloballyFormula() { return dynamic_cast(*this); } diff --git a/src/storm/logic/Formulas.h b/src/storm/logic/Formulas.h index f054794e7..cc59b93b6 100644 --- a/src/storm/logic/Formulas.h +++ b/src/storm/logic/Formulas.h @@ -5,6 +5,7 @@ #include "storm/logic/BinaryPathFormula.h" #include "storm/logic/BinaryStateFormula.h" #include "storm/logic/BooleanLiteralFormula.h" +#include "storm/logic/BoundedGloballyFormula.h" #include "storm/logic/BoundedUntilFormula.h" #include "storm/logic/CumulativeRewardFormula.h" #include "storm/logic/EventuallyFormula.h" diff --git a/src/storm/logic/LiftableTransitionRewardsVisitor.cpp b/src/storm/logic/LiftableTransitionRewardsVisitor.cpp index ce17bb60e..a61dccf7c 100644 --- a/src/storm/logic/LiftableTransitionRewardsVisitor.cpp +++ b/src/storm/logic/LiftableTransitionRewardsVisitor.cpp @@ -30,6 +30,24 @@ namespace storm { return true; } + boost::any LiftableTransitionRewardsVisitor::visit(BoundedGloballyFormula const& f, boost::any const& data) const { + for (unsigned i = 0; i < f.getDimension(); ++i) { + if (f.getTimeBoundReference(i).isRewardBound() && rewardModelHasTransitionRewards(f.getTimeBoundReference(i).getRewardName())) { + return false; + } + } + + bool result = true; + if (f.hasMultiDimensionalSubformulas()) { + for (unsigned i = 0; i < f.getDimension(); ++i) { + result = result && boost::any_cast(f.getSubformula(i).accept(*this, data)); + } + } else { + result = result && boost::any_cast(f.getSubformula().accept(*this, data)); + } + return result; + } + boost::any LiftableTransitionRewardsVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const { for (unsigned i = 0; i < f.getDimension(); ++i) { if (f.getTimeBoundReference(i).isRewardBound() && rewardModelHasTransitionRewards(f.getTimeBoundReference(i).getRewardName())) { diff --git a/src/storm/logic/LiftableTransitionRewardsVisitor.h b/src/storm/logic/LiftableTransitionRewardsVisitor.h index bbac6b7c2..52a791237 100644 --- a/src/storm/logic/LiftableTransitionRewardsVisitor.h +++ b/src/storm/logic/LiftableTransitionRewardsVisitor.h @@ -22,6 +22,7 @@ namespace storm { virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override; virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override; virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedGloballyFormula const& f, boost::any const& data) const override; virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override; virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override; diff --git a/src/storm/logic/ToExpressionVisitor.cpp b/src/storm/logic/ToExpressionVisitor.cpp index 8eb8444fc..1e6852d84 100644 --- a/src/storm/logic/ToExpressionVisitor.cpp +++ b/src/storm/logic/ToExpressionVisitor.cpp @@ -47,6 +47,10 @@ namespace storm { return result; } + boost::any ToExpressionVisitor::visit(BoundedGloballyFormula const&, boost::any const&) const { + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot assemble expression from formula that contains illegal elements."); + } + boost::any ToExpressionVisitor::visit(BoundedUntilFormula const&, boost::any const&) const { STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Cannot assemble expression from formula that contains illegal elements."); } diff --git a/src/storm/logic/ToExpressionVisitor.h b/src/storm/logic/ToExpressionVisitor.h index 675dbbcba..b68b5c438 100644 --- a/src/storm/logic/ToExpressionVisitor.h +++ b/src/storm/logic/ToExpressionVisitor.h @@ -16,6 +16,7 @@ namespace storm { virtual boost::any visit(AtomicLabelFormula const& f, boost::any const& data) const override; virtual boost::any visit(BinaryBooleanStateFormula const& f, boost::any const& data) const override; virtual boost::any visit(BooleanLiteralFormula const& f, boost::any const& data) const override; + virtual boost::any visit(BoundedGloballyFormula const& f, boost::any const& data) const override; virtual boost::any visit(BoundedUntilFormula const& f, boost::any const& data) const override; virtual boost::any visit(ConditionalFormula const& f, boost::any const& data) const override; virtual boost::any visit(CumulativeRewardFormula const& f, boost::any const& data) const override; diff --git a/src/storm/storage/jani/JSONExporter.cpp b/src/storm/storage/jani/JSONExporter.cpp index 586c81051..84b0ed3c9 100644 --- a/src/storm/storage/jani/JSONExporter.cpp +++ b/src/storm/storage/jani/JSONExporter.cpp @@ -212,6 +212,54 @@ namespace storm { ExportJsonType opDecl(f.isTrueFormula() ? true : false); return opDecl; } + boost::any FormulaToJaniJson::visit(storm::logic::BoundedGloballyFormula const& f, boost::any const& data) const { + STORM_LOG_THROW(!f.hasMultiDimensionalSubformulas(), storm::exceptions::NotSupportedException, "Jani export of multi-dimensional bounded globally formulas is not supported."); + ExportJsonType opDecl; + opDecl["op"] = "G"; + opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data)); + + bool hasStepBounds(false), hasTimeBounds(false); + std::vector rewardBounds; + + for (uint64_t i = 0; i < f.getDimension(); ++i) { + boost::optional lower, upper; + boost::optional lowerExclusive, upperExclusive; + if (f.hasLowerBound(i)) { + lower = f.getLowerBound(i); + lowerExclusive = f.isLowerBoundStrict(i); + } + if (f.hasUpperBound(i)) { + upper = f.getUpperBound(i); + upperExclusive = f.isUpperBoundStrict(i); + } + ExportJsonType propertyInterval = constructPropertyInterval(lower, lowerExclusive, upper, upperExclusive); + + auto tbr = f.getTimeBoundReference(i); + if (tbr.isStepBound() || (model.isDiscreteTimeModel() && tbr.isTimeBound())) { + STORM_LOG_THROW(!hasStepBounds, storm::exceptions::NotSupportedException, "Jani export of until formulas with multiple step bounds is not supported."); + hasStepBounds = true; + opDecl["step-bounds"] = propertyInterval; + } else if(tbr.isRewardBound()) { + ExportJsonType rewbound; + rewbound["exp"] = buildExpression(model.getRewardModelExpression(tbr.getRewardName()), model.getConstants(), model.getGlobalVariables()); + if (tbr.hasRewardAccumulation()) { + rewbound["accumulate"] = constructRewardAccumulation(tbr.getRewardAccumulation(), tbr.getRewardName()); + } else { + rewbound["accumulate"] = constructStandardRewardAccumulation(tbr.getRewardName()); + } + rewbound["bounds"] = propertyInterval; + rewardBounds.push_back(std::move(rewbound)); + } else { + STORM_LOG_THROW(!hasTimeBounds, storm::exceptions::NotSupportedException, "Jani export of globally formulas with multiple time bounds is not supported."); + hasTimeBounds = true; + opDecl["time-bounds"] = propertyInterval; + } + } + if (!rewardBounds.empty()) { + opDecl["reward-bounds"] = ExportJsonType(rewardBounds); + } + return opDecl; + } boost::any FormulaToJaniJson::visit(storm::logic::BoundedUntilFormula const& f, boost::any const& data) const { STORM_LOG_THROW(!f.hasMultiDimensionalSubformulas(), storm::exceptions::NotSupportedException, "Jani export of multi-dimensional bounded until formulas is not supported."); ExportJsonType opDecl; diff --git a/src/storm/storage/jani/JSONExporter.h b/src/storm/storage/jani/JSONExporter.h index 9408cff82..437c10c6c 100644 --- a/src/storm/storage/jani/JSONExporter.h +++ b/src/storm/storage/jani/JSONExporter.h @@ -52,6 +52,7 @@ namespace storm { virtual boost::any visit(storm::logic::AtomicLabelFormula const& f, boost::any const& data) const; virtual boost::any visit(storm::logic::BinaryBooleanStateFormula const& f, boost::any const& data) const; virtual boost::any visit(storm::logic::BooleanLiteralFormula const& f, boost::any const& data) const; + virtual boost::any visit(storm::logic::BoundedGloballyFormula const& f, boost::any const& data) const; virtual boost::any visit(storm::logic::BoundedUntilFormula const& f, boost::any const& data) const; virtual boost::any visit(storm::logic::ConditionalFormula const& f, boost::any const& data) const; virtual boost::any visit(storm::logic::CumulativeRewardFormula const& f, boost::any const& data) const;