Browse Source

Merge branch 'master' into chris_diss

main
dehnert 7 years ago
parent
commit
9aaf7e0bfb
  1. 8
      src/storm-cli-utilities/model-handling.h
  2. 16
      src/storm/api/export.cpp
  3. 31
      src/storm/settings/modules/JaniExportSettings.cpp
  4. 10
      src/storm/settings/modules/JaniExportSettings.h
  5. 10
      src/storm/solver/helper/SoundValueIterationHelper.cpp
  6. 2
      src/storm/storage/jani/Assignment.cpp
  7. 3
      src/storm/storage/jani/Assignment.h
  8. 4
      src/storm/storage/jani/Automaton.cpp
  9. 2
      src/storm/storage/jani/Automaton.h
  10. 39
      src/storm/storage/jani/JSONExporter.cpp
  11. 4
      src/storm/storage/jani/JSONExporter.h
  12. 121
      src/storm/storage/jani/JaniLocationExpander.cpp
  13. 26
      src/storm/storage/jani/JaniLocationExpander.h
  14. 4
      src/storm/storage/jani/Location.cpp
  15. 3
      src/storm/storage/jani/Location.h
  16. 10
      src/storm/storage/jani/Model.cpp
  17. 13
      src/storm/storage/jani/Model.h
  18. 8
      src/storm/storage/jani/OrderedAssignments.cpp
  19. 4
      src/storm/storage/jani/OrderedAssignments.h

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

@ -186,11 +186,15 @@ namespace storm {
template <typename ValueType>
std::shared_ptr<storm::models::ModelBase> buildModelSparse(SymbolicInput const& input, storm::settings::modules::BuildSettings const& buildSettings) {
auto counterexampleGeneratorSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
storm::builder::BuilderOptions options(createFormulasToRespect(input.properties));
options.setBuildChoiceLabels(buildSettings.isBuildChoiceLabelsSet());
options.setBuildStateValuations(buildSettings.isBuildStateValuationsSet());
options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
if (storm::settings::manager().hasModule(storm::settings::modules::CounterexampleGeneratorSettings::moduleName)) {
auto counterexampleGeneratorSettings = storm::settings::getModule<storm::settings::modules::CounterexampleGeneratorSettings>();
options.setBuildChoiceOrigins(counterexampleGeneratorSettings.isMinimalCommandSetGenerationSet());
} else {
options.setBuildChoiceOrigins(false);
}
options.setBuildAllLabels(buildSettings.isBuildFullModelSet());
options.setBuildAllRewardModels(buildSettings.isBuildFullModelSet());
options.setAddOutOfBoundsState(buildSettings.isBuildOutOfBoundsStateSet());

16
src/storm/api/export.cpp

@ -1,17 +1,27 @@
#include "storm/api/export.h"
#include "storm/storage/jani/JaniLocationExpander.h"
namespace storm {
namespace api {
void exportJaniModel(storm::jani::Model const& model, std::vector<storm::jani::Property> const& properties, std::string const& filename) {
auto janiSettings = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
storm::jani::Model exportModel = model;
if (janiSettings.isLocationVariablesSet()) {
for(auto const& pair : janiSettings.getLocationVariables()) {
storm::jani::JaniLocationExpander expander(exportModel);
expander.transform(pair.first, pair.second);
exportModel = expander.getResult();
}
}
if (janiSettings.isExportAsStandardJaniSet()) {
storm::jani::Model normalisedModel = model;
storm::jani::Model normalisedModel = exportModel;
normalisedModel.makeStandardJaniCompliant();
storm::jani::JsonExporter::toFile(normalisedModel, properties, filename);
} else {
storm::jani::JsonExporter::toFile(model, properties, filename);
storm::jani::JsonExporter::toFile(exportModel, properties, filename);
}
}

31
src/storm/settings/modules/JaniExportSettings.cpp

@ -7,6 +7,8 @@
#include "storm/settings/ArgumentBuilder.h"
#include "storm/settings/Argument.h"
#include <boost/algorithm/string.hpp>
namespace storm {
namespace settings {
namespace modules {
@ -16,11 +18,16 @@ namespace storm {
const std::string JaniExportSettings::janiFileOptionShortName = "output";
const std::string JaniExportSettings::standardCompliantOptionName = "standard-compliant";
const std::string JaniExportSettings::standardCompliantOptionShortName = "standard";
const std::string JaniExportSettings::exportFlattenOptionName = "flatten";
const std::string JaniExportSettings::locationVariablesOptionName = "location-variables";
JaniExportSettings::JaniExportSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, janiFileOptionName, false, "Destination for the jani model.").setShortName(janiFileOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "path to file").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, locationVariablesOptionName, true, "Variables to export in the location").addArgument(storm::settings::ArgumentBuilder::createStringArgument("variables", "A comma separated list with local variables.").setDefaultValueString("").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, standardCompliantOptionName, false, "Export in standard compliant variant.").setShortName(standardCompliantOptionShortName).build());
this->addOption(storm::settings::OptionBuilder(moduleName, exportFlattenOptionName, true, "Export in standard compliant variant.").build());
}
bool JaniExportSettings::isJaniFileSet() const {
@ -34,7 +41,29 @@ namespace storm {
bool JaniExportSettings::isExportAsStandardJaniSet() const {
return this->getOption(standardCompliantOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isExportFlattenedSet() const {
return this->getOption(exportFlattenOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isLocationVariablesSet() const {
return this->getOption(locationVariablesOptionName).getHasOptionBeenSet();
}
std::vector<std::pair<std::string, std::string>> JaniExportSettings::getLocationVariables() const {
std::string argument = this->getOption(locationVariablesOptionName).getArgumentByName("variables").getValueAsString();
std::vector<std::string> arguments;
boost::split( arguments, argument, boost::is_any_of(","));
std::vector<std::pair<std::string, std::string>> result;
for (auto const& pair : arguments) {
std::vector<std::string> keyvaluepair;
boost::split( keyvaluepair, pair, boost::is_any_of("."));
STORM_LOG_THROW(keyvaluepair.size() == 2, storm::exceptions::IllegalArgumentException, "Expected a name of the form AUTOMATON.VARIABLE (with no further dots) but got " << pair);
result.emplace_back(keyvaluepair.at(0), keyvaluepair.at(1));
}
return result;
}
void JaniExportSettings::finalize() {
}

10
src/storm/settings/modules/JaniExportSettings.h

@ -25,7 +25,13 @@ namespace storm {
std::string getJaniFilename() const;
bool isExportAsStandardJaniSet() const;
bool isExportFlattenedSet() const;
bool isLocationVariablesSet() const;
std::vector<std::pair<std::string, std::string>> getLocationVariables() const;
bool check() const override;
void finalize() override;
@ -36,6 +42,8 @@ namespace storm {
static const std::string janiFileOptionShortName;
static const std::string standardCompliantOptionName;
static const std::string standardCompliantOptionShortName;
static const std::string exportFlattenOptionName;
static const std::string locationVariablesOptionName;
};
}

10
src/storm/solver/helper/SoundValueIterationHelper.cpp

@ -301,14 +301,14 @@ namespace storm {
storm::utility::vector::applyPointwise(x, y, x, [&meanBound] (ValueType const& xi, ValueType const& yi) -> ValueType { return xi + yi * meanBound; });
STORM_LOG_INFO("Sound Value Iteration terminated with lower value bound "
STORM_LOG_INFO("Sound Value Iteration terminated with lower bound (over all states) "
<< (hasLowerBound ? lowerBound : storm::utility::zero<ValueType>()) << (hasLowerBound ? "" : "(none)")
<< " and upper value bound "
<< (hasUpperBound ? upperBound : storm::utility::zero<ValueType>()) << (hasUpperBound ? "" : "(none)")
<< " and upper bound (over all states)"
<< (hasUpperBound ? upperBound : storm::utility::infinity<ValueType>()) << (hasUpperBound ? "" : "(none)")
<< ". Decision value is "
<< (hasDecisionValue ? decisionValue : storm::utility::zero<ValueType>()) << (hasDecisionValue ? "" : "(none)")
<< (hasDecisionValue ? decisionValue : -storm::utility::infinity<ValueType>()) << (hasDecisionValue ? "" : "(none)")
<< ".");
}
}
template<typename ValueType>
bool SoundValueIterationHelper<ValueType>::checkCustomTerminationCondition(storm::solver::TerminationCondition<ValueType> const& condition) {

2
src/storm/storage/jani/Assignment.cpp

@ -37,7 +37,7 @@ namespace storm {
}
void Assignment::substitute(std::map<storm::expressions::Variable, storm::expressions::Expression> const& substitution) {
this->setAssignedExpression(this->getAssignedExpression().substitute(substitution));
this->setAssignedExpression(this->getAssignedExpression().substitute(substitution).simplify());
}
int64_t Assignment::getLevel() const {

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

@ -14,7 +14,8 @@ namespace storm {
* Creates an assignment of the given expression to the given variable.
*/
Assignment(storm::jani::Variable const& variable, storm::expressions::Expression const& expression, uint64_t index = 0);
Assignment(Assignment const&) = default;
bool operator==(Assignment const& other) const;
/*!

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

@ -54,6 +54,10 @@ namespace storm {
return variables.addVariable(variable);
}
bool Automaton::hasVariable(std::string const& name) const {
return variables.hasVariable(name);
}
VariableSet& Automaton::getVariables() {
return variables;
}

2
src/storm/storage/jani/Automaton.h

@ -79,6 +79,8 @@ namespace storm {
* Retrieves the variables of this automaton.
*/
VariableSet const& getVariables() const;
bool hasVariable(std::string const& name) const;
/*!
* Retrieves all expression variables used by this automaton.

39
src/storm/storage/jani/JSONExporter.cpp

@ -35,6 +35,7 @@ namespace storm {
modernjson::json buildExpression(storm::expressions::Expression const& exp, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables = VariableSet(), VariableSet const& localVariables = VariableSet()) {
STORM_LOG_TRACE("Exporting " << exp);
return ExpressionToJson::translate(exp, constants, globalVariables, localVariables);
}
@ -680,7 +681,7 @@ namespace storm {
}
modernjson::json buildAssignmentArray(storm::jani::OrderedAssignments const& orderedAssignments, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables) {
modernjson::json buildAssignmentArray(storm::jani::OrderedAssignments const& orderedAssignments, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
std::vector<modernjson::json> assignmentDeclarations;
bool addIndex = orderedAssignments.hasMultipleLevels();
for(auto const& assignment : orderedAssignments) {
@ -691,18 +692,21 @@ namespace storm {
assignmentEntry["index"] = assignment.getLevel();
}
assignmentDeclarations.push_back(assignmentEntry);
if (commentExpressions) {
assignmentEntry["comment"] = assignment.getVariable().getName() + " <- " + assignment.getAssignedExpression().toString();
}
}
return modernjson::json(assignmentDeclarations);
}
modernjson::json buildLocationsArray(std::vector<storm::jani::Location> const& locations, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables) {
modernjson::json buildLocationsArray(std::vector<storm::jani::Location> const& locations, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
std::vector<modernjson::json> locationDeclarations;
for(auto const& location : locations) {
modernjson::json locEntry;
locEntry["name"] = location.getName();
// TODO support invariants?
if (!location.getAssignments().empty()) {
locEntry["transient-values"] = buildAssignmentArray(location.getAssignments(), constants, globalVariables, localVariables);
locEntry["transient-values"] = buildAssignmentArray(location.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
}
locationDeclarations.push_back(locEntry);
}
@ -717,7 +721,7 @@ namespace storm {
return modernjson::json(names);
}
modernjson::json buildDestinations(std::vector<EdgeDestination> const& destinations, std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables) {
modernjson::json buildDestinations(std::vector<EdgeDestination> const& destinations, std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
assert(destinations.size() > 0);
std::vector<modernjson::json> destDeclarations;
for(auto const& destination : destinations) {
@ -731,16 +735,19 @@ namespace storm {
}
if (!prob1) {
destEntry["probability"]["exp"] = buildExpression(destination.getProbability(), constants, globalVariables, localVariables);
if (commentExpressions) {
destEntry["probability"]["comment"] = destination.getProbability().toString();
}
}
if (!destination.getOrderedAssignments().empty()) {
destEntry["assignments"] = buildAssignmentArray(destination.getOrderedAssignments(), constants, globalVariables, localVariables);
destEntry["assignments"] = buildAssignmentArray(destination.getOrderedAssignments(), constants, globalVariables, localVariables, commentExpressions);
}
destDeclarations.push_back(destEntry);
}
return modernjson::json(destDeclarations);
}
modernjson::json buildEdges(std::vector<Edge> const& edges , std::map<uint64_t, std::string> const& actionNames, std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables) {
modernjson::json buildEdges(std::vector<Edge> const& edges , std::map<uint64_t, std::string> const& actionNames, std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
std::vector<modernjson::json> edgeDeclarations;
for(auto const& edge : edges) {
if (edge.getGuard().isFalse()) {
@ -754,13 +761,19 @@ namespace storm {
}
if(edge.hasRate()) {
edgeEntry["rate"]["exp"] = buildExpression(edge.getRate(), constants, globalVariables, localVariables);
if (commentExpressions) {
edgeEntry["rate"]["comment"] = edge.getRate().toString();
}
}
if (!edge.getGuard().isTrue()) {
edgeEntry["guard"]["exp"] = buildExpression(edge.getGuard(), constants, globalVariables, localVariables);
if (commentExpressions) {
edgeEntry["guard"]["comment"] = edge.getGuard().toString();
}
}
edgeEntry["destinations"] = buildDestinations(edge.getDestinations(), locationNames, constants, globalVariables, localVariables);
edgeEntry["destinations"] = buildDestinations(edge.getDestinations(), locationNames, constants, globalVariables, localVariables, commentExpressions);
if (!edge.getAssignments().empty()) {
edgeEntry["assignments"] = buildAssignmentArray(edge.getAssignments(), constants, globalVariables, localVariables);
edgeEntry["assignments"] = buildAssignmentArray(edge.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
}
edgeDeclarations.push_back(edgeEntry);
@ -768,7 +781,7 @@ namespace storm {
return modernjson::json(edgeDeclarations);
}
modernjson::json buildAutomataArray(std::vector<storm::jani::Automaton> const& automata, std::map<uint64_t, std::string> const& actionNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables) {
modernjson::json buildAutomataArray(std::vector<storm::jani::Automaton> const& automata, std::map<uint64_t, std::string> const& actionNames, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, bool commentExpressions) {
std::vector<modernjson::json> automataDeclarations;
for(auto const& automaton : automata) {
modernjson::json autoEntry;
@ -777,16 +790,16 @@ namespace storm {
if(automaton.hasRestrictedInitialStates()) {
autoEntry["restrict-initial"]["exp"] = buildExpression(automaton.getInitialStatesRestriction(), constants, globalVariables, automaton.getVariables());
}
autoEntry["locations"] = buildLocationsArray(automaton.getLocations(), constants, globalVariables, automaton.getVariables());
autoEntry["locations"] = buildLocationsArray(automaton.getLocations(), constants, globalVariables, automaton.getVariables(), commentExpressions);
autoEntry["initial-locations"] = buildInitialLocations(automaton);
autoEntry["edges"] = buildEdges(automaton.getEdges(), actionNames, automaton.buildIdToLocationNameMap(), constants, globalVariables, automaton.getVariables());
autoEntry["edges"] = buildEdges(automaton.getEdges(), actionNames, automaton.buildIdToLocationNameMap(), constants, globalVariables, automaton.getVariables(), commentExpressions);
automataDeclarations.push_back(autoEntry);
}
return modernjson::json(automataDeclarations);
}
void JsonExporter::convertModel(storm::jani::Model const& janiModel) {
void JsonExporter::convertModel(storm::jani::Model const& janiModel, bool commentExpressions) {
jsonStruct["jani-version"] = janiModel.getJaniVersion();
jsonStruct["name"] = janiModel.getName();
jsonStruct["type"] = to_string(janiModel.getModelType());
@ -794,7 +807,7 @@ namespace storm {
jsonStruct["constants"] = buildConstantsArray(janiModel.getConstants());
jsonStruct["variables"] = buildVariablesArray(janiModel.getGlobalVariables(), janiModel.getConstants(), janiModel.getGlobalVariables());
jsonStruct["restrict-initial"]["exp"] = buildExpression(janiModel.getInitialStatesRestriction(), janiModel.getConstants(), janiModel.getGlobalVariables());
jsonStruct["automata"] = buildAutomataArray(janiModel.getAutomata(), janiModel.getActionIndexToNameMap(), janiModel.getConstants(), janiModel.getGlobalVariables());
jsonStruct["automata"] = buildAutomataArray(janiModel.getAutomata(), janiModel.getActionIndexToNameMap(), janiModel.getConstants(), janiModel.getGlobalVariables(), commentExpressions);
jsonStruct["system"] = CompositionJsonExporter::translate(janiModel.getSystemComposition());
std::vector<std::string> standardFeatureVector = {"derived-operators"};
jsonStruct["features"] = standardFeatureVector;

4
src/storm/storage/jani/JSONExporter.h

@ -3,7 +3,7 @@
#include "storm/storage/expressions/ExpressionVisitor.h"
#include "storm/logic/FormulaVisitor.h"
#include "Model.h"
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Property.h"
#include "storm/adapters/RationalNumberAdapter.h"
// JSON parser
@ -80,7 +80,7 @@ namespace storm {
private:
void convertModel(storm::jani::Model const& model);
void convertModel(storm::jani::Model const& model, bool commentExpressions = true);
void convertProperties(std::vector<storm::jani::Property> const& formulas, storm::jani::Model const& model);
void appendVariableDeclaration(storm::jani::Variable const& variable);

121
src/storm/storage/jani/JaniLocationExpander.cpp

@ -0,0 +1,121 @@
#include "storm/storage/jani/JaniLocationExpander.h"
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/exceptions/IllegalArgumentException.h"
namespace storm {
namespace jani {
JaniLocationExpander::JaniLocationExpander(Model const& origModel) : original(origModel) {
}
void JaniLocationExpander::transform(std::string const& automatonName, std::string const& variableName) {
STORM_LOG_THROW(original.hasAutomaton(automatonName), storm::exceptions::IllegalArgumentException, "Model has no automaton with name " << automatonName << ". ");
STORM_LOG_THROW(original.getAutomaton(automatonName).hasVariable(variableName), storm::exceptions::IllegalArgumentException, "Automaton " << automatonName << " has no variable with name " << variableName << ". ");
newModel = original;
newModel.replaceAutomaton(newModel.getAutomatonIndex(automatonName), transformAutomaton(original.getAutomaton(automatonName), variableName));
}
Model const& JaniLocationExpander::getResult() const {
return newModel;
}
Automaton JaniLocationExpander::transformAutomaton(Automaton const& automaton, std::string const& variableName) {
Automaton newAutomaton(automaton.getName(), automaton.getLocationExpressionVariable());
int64_t initialVariableValue;
int64_t variableLowerBound;
int64_t variableUpperBound;
storm::expressions::Variable eliminatedExpressionVariable;
const storm::jani::Variable* variable;
for (auto const& var : automaton.getVariables()) {
if (var.getName() == variableName) {
// This variable will be eliminated in the new automaton.
STORM_LOG_THROW(var.hasInitExpression(), storm::exceptions::IllegalArgumentException, "Variable to be eliminated has to have an initexpression.");
STORM_LOG_THROW(var.isBoundedIntegerVariable(), storm::exceptions::IllegalArgumentException, "Variable to be eliminated has to be an bounded integer variable.");
STORM_LOG_THROW(!var.isTransient(), storm::exceptions::IllegalArgumentException, "Cannot eliminate transient variable");
variableUpperBound = var.asBoundedIntegerVariable().getUpperBound().evaluateAsInt();
variableLowerBound = var.asBoundedIntegerVariable().getLowerBound().evaluateAsInt();
initialVariableValue = var.getInitExpression().evaluateAsInt();
variable = &var;
eliminatedExpressionVariable = var.getExpressionVariable();
} else {
// Other variables are just copied.
newAutomaton.addVariable(var);
}
}
STORM_LOG_THROW(!automaton.getInitialStatesRestriction().containsVariable({eliminatedExpressionVariable}), storm::exceptions::NotSupportedException, "Elimination of variable that occurs in the initial state restriction is not allowed");
newAutomaton.setInitialStatesRestriction(automaton.getInitialStatesRestriction());
std::map<storm::expressions::Variable, storm::expressions::Expression> substitutionMap;
std::map<std::string, std::vector<std::string>> locationNames;
std::map<uint64_t, std::map<int64_t, uint64_t>> locationVariableValueMap;
for (auto const& loc : automaton.getLocations()) {
locationNames[loc.getName()] = std::vector<std::string>();
uint64_t origIndex = automaton.getLocationIndex(loc.getName());
for (int64_t i = variableLowerBound; i <= variableUpperBound; i++) {
std::string newLocationName = loc.getName() + "_" + variableName + "_" + std::to_string(i);
substitutionMap[eliminatedExpressionVariable] = original.getExpressionManager().integer(i);
std::cout << "eliminate " << eliminatedExpressionVariable.getName() << " with " << i << std::endl;
OrderedAssignments newAssignments = loc.getAssignments().clone();
newAssignments.substitute(substitutionMap);
std::cout << newAssignments << std::endl;
uint64_t newLocationIndex = newAutomaton.addLocation(Location(newLocationName, newAssignments));
locationVariableValueMap[origIndex][i] = newLocationIndex;
locationNames[loc.getName()].push_back(newLocationName);
}
}
for (auto const& edge : automaton.getEdges()) {
for (auto const& newValueAndLocation : locationVariableValueMap[edge.getSourceLocationIndex()]) {
substitutionMap[eliminatedExpressionVariable] = original.getExpressionManager().integer(newValueAndLocation.first);
uint64_t newSourceIndex = newValueAndLocation.second;
storm::expressions::Expression newGuard = edge.getGuard().substitute(substitutionMap).simplify();
if (!newGuard.containsVariables() && !newGuard.evaluateAsBool()) {
continue;
}
std::shared_ptr<storm::jani::TemplateEdge> templateEdge = std::make_shared<storm::jani::TemplateEdge>(newGuard);
STORM_LOG_THROW(edge.getAssignments().empty(), storm::exceptions::NotImplementedException, "Support for edge-assignments is not implemented");
std::vector<std::pair<uint64_t, storm::expressions::Expression>> destinationLocationsAndProbabilities;
for (auto const& destination : edge.getDestinations()) {
OrderedAssignments oa(destination.getOrderedAssignments().clone());
oa.substitute(substitutionMap);
int64_t value;
for (auto const& assignment : oa) {
if (assignment.getVariable() == *variable) {
oa.remove(assignment);
value = assignment.getAssignedExpression().evaluateAsInt();
break;
}
}
TemplateEdgeDestination ted(oa);
templateEdge->addDestination(ted);
destinationLocationsAndProbabilities.emplace_back(locationVariableValueMap[destination.getLocationIndex()][value], destination.getProbability().substitute((substitutionMap)));
}
newAutomaton.addEdge(storm::jani::Edge(newSourceIndex, edge.getActionIndex(), edge.hasRate() ? boost::optional<storm::expressions::Expression>(edge.getRate().substitute(substitutionMap)) : boost::none, templateEdge, destinationLocationsAndProbabilities));
}
}
return newAutomaton;
}
}
}

26
src/storm/storage/jani/JaniLocationExpander.h

@ -0,0 +1,26 @@
#pragma once
#include "storm/storage/jani/Model.h"
#include "storm/storage/jani/Automaton.h"
namespace storm {
namespace jani {
class JaniLocationExpander {
public:
JaniLocationExpander(Model const& original);
void transform(std::string const& automatonName, std::string const& variableName);
Model const& getResult() const;
private:
Model const& original;
Model newModel;
Automaton transformAutomaton(Automaton const& automaton, std::string const& variableName);
};
}
}

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

@ -10,6 +10,10 @@ namespace storm {
Location::Location(std::string const& name, std::vector<Assignment> const& transientAssignments) : name(name), assignments(transientAssignments) {
// Intentionally left empty.
}
Location::Location(std::string const& name, OrderedAssignments const& assignments) : name(name), assignments(assignments) {
// Intentionally left empty.
}
std::string const& Location::getName() const {
return name;

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

@ -18,7 +18,8 @@ namespace storm {
* Creates a new location.
*/
Location(std::string const& name, std::vector<Assignment> const& transientAssignments = {});
Location(std::string const& name, OrderedAssignments const& assignments);
/*!
* Retrieves the name of the location.
*/

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

@ -711,7 +711,15 @@ namespace storm {
std::vector<Automaton> const& Model::getAutomata() const {
return automata;
}
bool Model::hasAutomaton(std::string const& name) const {
return automatonToIndex.find(name) != automatonToIndex.end();
}
void Model::replaceAutomaton(uint64_t index, Automaton const& automaton) {
automata[index] = automaton;
}
Automaton& Model::getAutomaton(std::string const& name) {
auto it = automatonToIndex.find(name);
STORM_LOG_THROW(it != automatonToIndex.end(), storm::exceptions::InvalidOperationException, "Unable to retrieve unknown automaton '" << name << "'.");

13
src/storm/storage/jani/Model.h

@ -245,6 +245,19 @@ namespace storm {
*/
std::vector<Automaton> const& getAutomata() const;
/**
* Replaces the automaton at index with a new automaton.
* @param index
* @param newAutomaton
*/
void replaceAutomaton(uint64_t index, Automaton const& newAutomaton);
/*!
* Rerieves whether there exists an automaton with the given name.
* @param name
* @return
*/
bool hasAutomaton(std::string const& name) const;
/*!
* Retrieves the automaton with the given name.
*/

8
src/storm/storage/jani/OrderedAssignments.cpp

@ -16,6 +16,14 @@ namespace storm {
OrderedAssignments::OrderedAssignments(Assignment const& assignment) {
add(assignment);
}
OrderedAssignments OrderedAssignments::clone() const {
OrderedAssignments result;
for (auto const& assignment : allAssignments) {
result.add(Assignment(*assignment));
}
return result;
}
bool OrderedAssignments::add(Assignment const& assignment, bool addToExisting) {
// If the element is contained in this set of assignment, nothing needs to be added.

4
src/storm/storage/jani/OrderedAssignments.h

@ -142,7 +142,9 @@ namespace storm {
bool areLinear() const;
friend std::ostream& operator<<(std::ostream& stream, OrderedAssignments const& assignments);
OrderedAssignments clone() const;
private:
uint64_t isReadBeforeAssignment(Variable const& var, uint64_t assignmentNumber, uint64_t start = 0) const;
uint64_t isWrittenBeforeAssignment(Variable const& var, uint64_t assignmentNumber, uint64_t start = 0) const;

Loading…
Cancel
Save