Browse Source

fixes for array expressions, support to translate properties that consider array expressions, translating array models in cli

tempestpy_adaptions
TimQu 6 years ago
parent
commit
7c61a16d91
  1. 2
      src/storm-cli-utilities/CMakeLists.txt
  2. 10
      src/storm-cli-utilities/model-handling.h
  3. 20
      src/storm/builder/BuilderOptions.cpp
  4. 10
      src/storm/builder/BuilderOptions.h
  5. 3
      src/storm/builder/DdJaniModelBuilder.cpp
  6. 15
      src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp
  7. 10
      src/storm/generator/JaniNextStateGenerator.cpp
  8. 6
      src/storm/generator/NextStateGenerator.cpp
  9. 99
      src/storm/logic/ExpressionSubstitutionVisitor.cpp
  10. 33
      src/storm/logic/ExpressionSubstitutionVisitor.h
  11. 12
      src/storm/logic/Formula.cpp
  12. 1
      src/storm/logic/Formula.h
  13. 9
      src/storm/storage/jani/ArrayEliminator.cpp
  14. 3
      src/storm/storage/jani/ArrayEliminator.h
  15. 3
      src/storm/storage/jani/Model.cpp
  16. 4
      src/storm/storage/jani/ModelFeatures.cpp
  17. 3
      src/storm/storage/jani/ModelFeatures.h
  18. 4
      src/storm/storage/jani/Property.cpp
  19. 9
      src/storm/storage/jani/Property.h

2
src/storm-cli-utilities/CMakeLists.txt

@ -17,7 +17,7 @@ set_target_properties(storm-cli-utilities PROPERTIES DEFINE_SYMBOL "")
list(APPEND STORM_TARGETS storm-cli-utilities)
set(STORM_TARGETS ${STORM_TARGETS} PARENT_SCOPE)
target_link_libraries(storm-cli-utilities PUBLIC storm storm-counterexamples storm-parsers)
target_link_libraries(storm-cli-utilities PUBLIC storm storm-counterexamples storm-parsers storm-conv)
# Install storm headers to include directory.
foreach(HEADER ${STORM_CLI_UTIL_HEADERS})

10
src/storm-cli-utilities/model-handling.h

@ -4,6 +4,7 @@
#include "storm-counterexamples/api/counterexamples.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm-conv/api/storm-conv.h"
#include "storm/utility/resources.h"
#include "storm/utility/file.h"
@ -154,6 +155,15 @@ namespace storm {
}
}
if (output.model && output.model.get().isJaniModel()) {
storm::converter::JaniConversionOptions options;
options.allowFunctions = false;
options.allowArrays = coreSettings.getEngine() == storm::settings::modules::CoreSettings::Engine::Sparse && !buildSettings.isJitSet();
options.standardCompliant = false;
options.flatten = false;
output.preprocessedProperties = output.properties;
storm::api::transformJani(output.model.get().asJaniModel(), output.preprocessedProperties.get(), options);
}
return output;
}

20
src/storm/builder/BuilderOptions.cpp

@ -129,7 +129,7 @@ namespace storm {
return labelNames;
}
std::vector<storm::expressions::Expression> const& BuilderOptions::getExpressionLabels() const {
std::vector<std::pair<std::string, storm::expressions::Expression>> const& BuilderOptions::getExpressionLabels() const {
return expressionLabels;
}
@ -211,7 +211,9 @@ namespace storm {
}
BuilderOptions& BuilderOptions::addLabel(storm::expressions::Expression const& expression) {
expressionLabels.emplace_back(expression);
std::stringstream stream;
stream << expression;
expressionLabels.emplace_back(stream.str(), expression);
return *this;
}
@ -261,5 +263,19 @@ namespace storm {
return *this;
}
BuilderOptions& BuilderOptions::substituteExpressions(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) {
for (auto& e : expressionLabels) {
e.second = substitutionFunction(e.second);
}
for (auto& t : terminalStates) {
if (t.first.isExpression()) {
t.first = LabelOrExpression(substitutionFunction(t.first.getExpression()));
}
}
return *this;
}
}
}

10
src/storm/builder/BuilderOptions.h

@ -96,7 +96,7 @@ namespace storm {
* Which expression labels are built
* @return
*/
std::vector<storm::expressions::Expression> const& getExpressionLabels() const;
std::vector<std::pair<std::string, storm::expressions::Expression>> const& getExpressionLabels() const;
std::vector<std::pair<LabelOrExpression, bool>> const& getTerminalStates() const;
bool hasTerminalStates() const;
void clearTerminalStates();
@ -179,7 +179,11 @@ namespace storm {
*/
BuilderOptions& setAddOverlappingGuardsLabel(bool newValue = true);
/**
* Substitutes all expressions occurring in these options.
*/
BuilderOptions& substituteExpressions(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction);
private:
/// A flag that indicates whether all reward models are to be built. In this case, the reward model names are
/// to be ignored.
@ -195,7 +199,7 @@ namespace storm {
std::set<std::string> labelNames;
/// The expression that are to be used for creating the state labeling.
std::vector<storm::expressions::Expression> expressionLabels;
std::vector<std::pair<std::string, storm::expressions::Expression>> expressionLabels;
/// If one of these labels/expressions evaluates to the given bool, the builder can abort the exploration.
std::vector<std::pair<LabelOrExpression, bool>> terminalStates;

3
src/storm/builder/DdJaniModelBuilder.cpp

@ -1986,6 +1986,9 @@ namespace storm {
}
STORM_LOG_THROW(!model.usesAssignmentLevels(), storm::exceptions::WrongFormatException, "The symbolic JANI model builder currently does not support assignment levels.");
auto features = model.getModelFeatures();
features.remove(storm::jani::ModelFeature::DerivedOperators);
STORM_LOG_THROW(features.empty(), storm::exceptions::InvalidSettingsException, "The dd jani model builder does not support the following model feature(s): " << features.toString() << ".");
storm::jani::Model preparedModel = model;

15
src/storm/builder/jit/ExplicitJitJaniModelBuilder.cpp

@ -107,10 +107,6 @@ namespace storm {
transientVariables.insert(variable.getExpressionVariable());
}
if (this->model.containsArrayVariables()) {
this->model.eliminateArrays();
}
// Construct vector of the automata to be put in parallel.
storm::jani::Composition const& topLevelComposition = this->model.getSystemComposition();
if (topLevelComposition.isAutomatonComposition()) {
@ -151,6 +147,10 @@ namespace storm {
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "The input model contains undefined constants that influence the graph structure of the underlying model, which is not allowed.");
}
#endif
auto features = model.getModelFeatures();
features.remove(storm::jani::ModelFeature::DerivedOperators);
STORM_LOG_THROW(features.empty(), storm::exceptions::InvalidArgumentException, "The jit model builder does not support the following model feature(s): " << features.toString() << ".");
//STORM_LOG_THROW(!model.reusesActionsInComposition(), storm::exceptions::InvalidArgumentException, "The jit JANI model builder currently does not support reusing actions in parallel composition");
// Comment this in to print the JANI model for debugging purposes.
@ -1562,11 +1562,12 @@ namespace storm {
}
std::set<std::string> expressionLabelStrings;
for (auto const& expression : this->options.getExpressionLabels()) {
for (auto const& expressionLabel : this->options.getExpressionLabels()) {
cpptempl::data_map label;
std::string expressionLabelString = expression.toString();
std::string const& expressionLabelString = expressionLabel.first;
auto const& expression = expressionLabel.second;
if(expressionLabelStrings.count(expressionLabelString) == 0) {
label["name"] = expression.toString();
label["name"] = expressionLabelString;
label["predicate"] = expressionTranslator.translate(shiftVariablesWrtLowerBound(expression), storm::expressions::ToCppTranslationOptions(variablePrefixes, variableToName, storm::expressions::ToCppTranslationMode::CastDouble));
labels.push_back(label);
expressionLabelStrings.insert(expressionLabelString);

10
src/storm/generator/JaniNextStateGenerator.cpp

@ -3,7 +3,6 @@
#include "storm/models/sparse/StateLabeling.h"
#include "storm/storage/expressions/SimpleValuation.h"
#include "storm/solver/SmtSolver.h"
#include "storm/storage/jani/Edge.h"
@ -15,6 +14,7 @@
#include "storm/storage/jani/ParallelComposition.h"
#include "storm/storage/jani/CompositionInformationVisitor.h"
#include "storm/storage/jani/traverser/AssignmentLevelFinder.h"
#include "storm/storage/jani/traverser/ArrayExpressionFinder.h"
#include "storm/storage/sparse/JaniChoiceOrigins.h"
@ -42,10 +42,15 @@ namespace storm {
STORM_LOG_THROW(!model.hasNonGlobalTransientVariable(), storm::exceptions::InvalidSettingsException, "The explicit next-state generator currently does not support automata-local transient variables.");
STORM_LOG_THROW(!this->options.isBuildChoiceLabelsSet(), storm::exceptions::InvalidSettingsException, "JANI next-state generator cannot generate choice labels.");
auto features = model.getModelFeatures();
features.remove(storm::jani::ModelFeature::DerivedOperators);
// Eliminate arrays if necessary.
if (this->model.containsArrayVariables()) {
if (features.hasArrays()) {
arrayEliminatorData = this->model.eliminateArrays(true);
this->options.substituteExpressions([this](storm::expressions::Expression const& exp) {return arrayEliminatorData.transformExpression(exp);});
features.remove(storm::jani::ModelFeature::Arrays);
}
STORM_LOG_THROW(features.empty(), storm::exceptions::InvalidSettingsException, "The explicit next-state generator does not support the following model feature(s): " << features.toString() << ".");
// Lift the transient edge destinations of the first assignment level.
uint64_t lowestAssignmentLevel = storm::jani::AssignmentLevelFinder().getLowestAssignmentLevel(this->model);
@ -809,7 +814,6 @@ namespace storm {
for (auto const& element : transientVariableToExpressionMap) {
transientVariableExpressions.push_back(std::make_pair(element.first.getName(), element.second));
}
return NextStateGenerator<ValueType, StateType>::label(stateStorage, initialStateIndices, deadlockStateIndices, transientVariableExpressions);
}

6
src/storm/generator/NextStateGenerator.cpp

@ -67,11 +67,7 @@ namespace storm {
template<typename ValueType, typename StateType>
storm::models::sparse::StateLabeling NextStateGenerator<ValueType, StateType>::label(storm::storage::sparse::StateStorage<StateType> const& stateStorage, std::vector<StateType> const& initialStateIndices, std::vector<StateType> const& deadlockStateIndices, std::vector<std::pair<std::string, storm::expressions::Expression>> labelsAndExpressions) {
for (auto const& expression : this->options.getExpressionLabels()) {
std::stringstream stream;
stream << expression;
labelsAndExpressions.push_back(std::make_pair(stream.str(), expression));
}
labelsAndExpressions.insert(labelsAndExpressions.end(), this->options.getExpressionLabels().begin(), this->options.getExpressionLabels().end());
// Make the labels unique.
std::sort(labelsAndExpressions.begin(), labelsAndExpressions.end(), [] (std::pair<std::string, storm::expressions::Expression> const& a, std::pair<std::string, storm::expressions::Expression> const& b) { return a.first < b.first; } );

99
src/storm/logic/ExpressionSubstitutionVisitor.cpp

@ -0,0 +1,99 @@
#include "storm/logic/ExpressionSubstitutionVisitor.h"
#include "storm/logic/Formulas.h"
namespace storm {
namespace logic {
std::shared_ptr<Formula> ExpressionSubstitutionVisitor::substitute(Formula const& f, std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) const {
boost::any result = f.accept(*this, &substitutionFunction);
return boost::any_cast<std::shared_ptr<Formula>>(result);
}
OperatorInformation substituteOperatorInformation(OperatorInformation const& operatorInformation, std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) {
boost::optional<Bound> bound;
if(operatorInformation.bound) {
bound = Bound(operatorInformation.bound->comparisonType, substitutionFunction(operatorInformation.bound->threshold));
}
return OperatorInformation(operatorInformation.optimalityType, bound);
}
boost::any ExpressionSubstitutionVisitor::visit(TimeOperatorFormula const& f, boost::any const& data) const {
std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
return std::static_pointer_cast<Formula>(std::make_shared<TimeOperatorFormula>(subformula, substituteOperatorInformation(f.getOperatorInformation(), substitutionFunction)));
}
boost::any ExpressionSubstitutionVisitor::visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
return std::static_pointer_cast<Formula>(std::make_shared<LongRunAverageOperatorFormula>(subformula, substituteOperatorInformation(f.getOperatorInformation(), substitutionFunction)));
}
boost::any ExpressionSubstitutionVisitor::visit(ProbabilityOperatorFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
return std::static_pointer_cast<Formula>(std::make_shared<ProbabilityOperatorFormula>(subformula, substituteOperatorInformation(f.getOperatorInformation(), substitutionFunction)));
}
boost::any ExpressionSubstitutionVisitor::visit(RewardOperatorFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
std::shared_ptr<Formula> subformula = boost::any_cast<std::shared_ptr<Formula>>(f.getSubformula().accept(*this, data));
return std::static_pointer_cast<Formula>(std::make_shared<RewardOperatorFormula>(subformula, f.getOptionalRewardModelName(), substituteOperatorInformation(f.getOperatorInformation(), substitutionFunction)));
}
boost::any ExpressionSubstitutionVisitor::visit(BoundedUntilFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
std::vector<boost::optional<TimeBound>> lowerBounds, upperBounds;
std::vector<TimeBoundReference> timeBoundReferences;
for (uint64_t i = 0; i < f.getDimension(); ++i) {
if (f.hasLowerBound(i)) {
lowerBounds.emplace_back(TimeBound(f.isLowerBoundStrict(i), substitutionFunction(f.getLowerBound(i))));
} else {
lowerBounds.emplace_back();
}
if (f.hasUpperBound(i)) {
upperBounds.emplace_back(TimeBound(f.isUpperBoundStrict(i), substitutionFunction(f.getUpperBound(i))));
} else {
upperBounds.emplace_back();
}
timeBoundReferences.push_back(f.getTimeBoundReference(i));
}
if (f.hasMultiDimensionalSubformulas()) {
std::vector<std::shared_ptr<Formula const>> leftSubformulas, rightSubformulas;
for (uint64_t i = 0; i < f.getDimension(); ++i) {
leftSubformulas.push_back(boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula(i).accept(*this, data)));
rightSubformulas.push_back(boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula(i).accept(*this, data)));
}
return std::static_pointer_cast<Formula>(std::make_shared<BoundedUntilFormula>(leftSubformulas, rightSubformulas, lowerBounds, upperBounds, timeBoundReferences));
} else {
std::shared_ptr<Formula> left = boost::any_cast<std::shared_ptr<Formula>>(f.getLeftSubformula().accept(*this, data));
std::shared_ptr<Formula> right = boost::any_cast<std::shared_ptr<Formula>>(f.getRightSubformula().accept(*this, data));
return std::static_pointer_cast<Formula>(std::make_shared<BoundedUntilFormula>(left, right, lowerBounds, upperBounds, timeBoundReferences));
}
}
boost::any ExpressionSubstitutionVisitor::visit(CumulativeRewardFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
std::vector<TimeBound> bounds;
std::vector<TimeBoundReference> timeBoundReferences;
for (uint64_t i = 0; i < f.getDimension(); ++i) {
bounds.emplace_back(TimeBound(f.isBoundStrict(i), substitutionFunction(f.getBound(i))));
timeBoundReferences.push_back(f.getTimeBoundReference(i));
}
return std::static_pointer_cast<Formula>(std::make_shared<CumulativeRewardFormula>(bounds, timeBoundReferences));
}
boost::any ExpressionSubstitutionVisitor::visit(InstantaneousRewardFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
return std::static_pointer_cast<Formula>(std::make_shared<InstantaneousRewardFormula>(substitutionFunction(f.getBound()), f.getTimeBoundType()));
}
boost::any ExpressionSubstitutionVisitor::visit(AtomicExpressionFormula const& f, boost::any const& data) const {
auto const& substitutionFunction = *boost::any_cast<std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const*>(data);
return std::static_pointer_cast<Formula>(std::make_shared<AtomicExpressionFormula>(substitutionFunction(f.getExpression())));
}
}
}

33
src/storm/logic/ExpressionSubstitutionVisitor.h

@ -0,0 +1,33 @@
#pragma once
#include <map>
#include <functional>
#include "storm/logic/CloneVisitor.h"
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace logic {
class ExpressionSubstitutionVisitor : public CloneVisitor {
public:
ExpressionSubstitutionVisitor() = default;
std::shared_ptr<Formula> substitute(Formula const& f, std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) const;
virtual boost::any visit(TimeOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(LongRunAverageOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(ProbabilityOperatorFormula const& f, boost::any const& data) const override;
virtual boost::any visit(RewardOperatorFormula 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(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;
};
}
}

12
src/storm/logic/Formula.cpp

@ -3,7 +3,8 @@
#include "storm/logic/FragmentChecker.h"
#include "storm/logic/FormulaInformationVisitor.h"
#include "storm/logic/VariableSubstitutionVisitor.h"
#include "storm/storage/jani/expressions/JaniExpressionSubstitutionVisitor.h"
#include "storm/logic/ExpressionSubstitutionVisitor.h"
#include "storm/logic/LabelSubstitutionVisitor.h"
#include "storm/logic/ToExpressionVisitor.h"
@ -438,8 +439,13 @@ namespace storm {
}
std::shared_ptr<Formula> Formula::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const {
VariableSubstitutionVisitor visitor(substitution);
return visitor.substitute(*this);
storm::expressions::JaniExpressionSubstitutionVisitor<std::map<storm::expressions::Variable, storm::expressions::Expression>> v(substitution);
return substitute([&v](storm::expressions::Expression const& exp) {return v.substitute(exp);});
}
std::shared_ptr<Formula> Formula::substitute(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& expressionSubstitution) const {
ExpressionSubstitutionVisitor visitor;
return visitor.substitute(*this, expressionSubstitution);
}
std::shared_ptr<Formula> Formula::substitute(std::map<std::string, storm::expressions::Expression> const& labelSubstitution) const {

1
src/storm/logic/Formula.h

@ -198,6 +198,7 @@ namespace storm {
std::shared_ptr<Formula const> asSharedPointer() const;
std::shared_ptr<Formula> substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
std::shared_ptr<Formula> substitute(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& expressionSubstitution) const;
std::shared_ptr<Formula> substitute(std::map<std::string, storm::expressions::Expression> const& labelSubstitution) const;
std::shared_ptr<Formula> substitute(std::map<std::string, std::string> const& labelSubstitution) const;

9
src/storm/storage/jani/ArrayEliminator.cpp

@ -578,15 +578,20 @@ namespace storm {
return eliminator.eliminate(arrayExpression);
}
void ArrayEliminatorData::transformProperty(storm::jani::Property& property) const {
property = property.substitute([this](storm::expressions::Expression const& exp) {return transformExpression(exp);});
}
ArrayEliminatorData ArrayEliminator::eliminate(Model& model, bool keepNonTrivialArrayAccess) {
auto sizes = detail::MaxArraySizeDeterminer().getMaxSizes(model);
ArrayEliminatorData result = detail::ArrayVariableReplacer(model.getExpressionManager(), keepNonTrivialArrayAccess, sizes).replace(model);
if (!keepNonTrivialArrayAccess) {
model.getModelFeatures().remove(ModelFeature::Arrays);
}
model.finalize();
STORM_LOG_ASSERT(!containsArrayExpression(model), "the model still contains array expressions.");
return result;
}
}
}

3
src/storm/storage/jani/ArrayEliminator.h

@ -4,6 +4,7 @@
#include <boost/any.hpp>
#include "storm/storage/jani/traverser/JaniTraverser.h"
#include "storm/storage/jani/Property.h"
namespace storm {
namespace jani {
@ -14,6 +15,8 @@ namespace storm {
// Transforms the given expression (which might contain array expressions) to an equivalent expression without array variables.
storm::expressions::Expression transformExpression(storm::expressions::Expression const& arrayExpression) const;
// Transforms the given property (which might contain array expressions) to an equivalent property without array variables.
void transformProperty(storm::jani::Property& property) const;
};
class ArrayEliminator {

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

@ -16,7 +16,7 @@
#include "storm/storage/jani/CompositionInformationVisitor.h"
#include "storm/storage/jani/Compositions.h"
#include "storm/storage/jani/JSONExporter.h"
#include "storm/storage/jani/traverser/ArrayEliminator.h"
#include "storm/storage/jani/ArrayEliminator.h"
#include "storm/storage/jani/expressions/JaniExpressionSubstitutionVisitor.h"
#include "storm/storage/expressions/LinearityCheckVisitor.h"
@ -69,6 +69,7 @@ namespace storm {
if (this != &other) {
this->name = other.name;
this->modelType = other.modelType;
this->modelFeatures = other.modelFeatures;
this->version = other.version;
this->expressionManager = other.expressionManager;
this->actions = other.actions;

4
src/storm/storage/jani/ModelFeatures.cpp

@ -44,6 +44,10 @@ namespace storm {
return features.count(ModelFeature::StateExitRewards) > 0;
}
bool ModelFeatures::empty() const {
return features.empty();
}
void ModelFeatures::add(ModelFeature const& modelFeature) {
features.insert(modelFeature);
}

3
src/storm/storage/jani/ModelFeatures.h

@ -19,6 +19,9 @@ namespace storm {
bool hasDerivedOperators() const;
bool hasStateExitRewards() const;
// Returns true, if no model feature is enabled.
bool empty() const;
void add(ModelFeature const& modelFeature);
void remove(ModelFeature const& modelFeature);

4
src/storm/storage/jani/Property.cpp

@ -30,6 +30,10 @@ namespace storm {
return Property(name, filterExpression.substitute(substitution), comment);
}
Property Property::substitute(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) const {
return Property(name, filterExpression.substitute(substitutionFunction), comment);
}
Property Property::substituteLabels(std::map<std::string, std::string> const& substitution) const {
return Property(name, filterExpression.substituteLabels(substitution), comment);
}

9
src/storm/storage/jani/Property.h

@ -1,5 +1,7 @@
#pragma once
#include <functional>
#include "storm/modelchecker/results/FilterType.h"
#include "storm/logic/Formulas.h"
#include "storm/logic/FragmentSpecification.h"
@ -54,10 +56,14 @@ namespace storm {
return FilterExpression(formula->substitute(substitution), ft, statesFormula->substitute(substitution));
}
FilterExpression substitute(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) const {
return FilterExpression(formula->substitute(substitutionFunction), ft, statesFormula->substitute(substitutionFunction));
}
FilterExpression substituteLabels(std::map<std::string, std::string> const& labelSubstitution) const {
return FilterExpression(formula->substitute(labelSubstitution), ft, statesFormula->substitute(labelSubstitution));
}
private:
// For now, we assume that the states are always the initial states.
std::shared_ptr<storm::logic::Formula const> formula;
@ -103,6 +109,7 @@ namespace storm {
std::string const& getComment() const;
Property substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) const;
Property substitute(std::function<storm::expressions::Expression(storm::expressions::Expression const&)> const& substitutionFunction) const;
Property substituteLabels(std::map<std::string, std::string> const& labelSubstitution) const;
FilterExpression const& getFilter() const;

Loading…
Cancel
Save