5 changed files with 190 additions and 5 deletions
			
			
		- 
					16src/storm/api/export.cpp
- 
					27src/storm/settings/modules/JaniExportSettings.cpp
- 
					5src/storm/settings/modules/JaniExportSettings.h
- 
					121src/storm/storage/jani/JaniLocationExpander.cpp
- 
					26src/storm/storage/jani/JaniLocationExpander.h
| @ -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; | |||
| 
 | |||
| 
 | |||
|         } | |||
| 
 | |||
| 
 | |||
|     } | |||
| } | |||
| @ -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); | |||
| 
 | |||
| 
 | |||
| 
 | |||
|         }; | |||
|     } | |||
| 
 | |||
| } | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue