24 changed files with 663 additions and 216 deletions
-
261src/generator/JaniNextStateGenerator.cpp
-
134src/generator/JaniNextStateGenerator.h
-
59src/generator/PrismNextStateGenerator.cpp
-
73src/generator/VariableInformation.cpp
-
35src/generator/VariableInformation.h
-
7src/storage/jani/Automaton.cpp
-
5src/storage/jani/Automaton.h
-
4src/storage/jani/BoundedIntegerVariable.cpp
-
5src/storage/jani/BoundedIntegerVariable.h
-
92src/storage/jani/CompositionInformationVisitor.cpp
-
60src/storage/jani/CompositionInformationVisitor.h
-
1src/storage/jani/CompositionVisitor.h
-
3src/storage/jani/Compositions.h
-
14src/storage/jani/EdgeDestination.cpp
-
6src/storage/jani/EdgeDestination.h
-
13src/storage/jani/Model.cpp
-
5src/storage/jani/Model.h
-
4src/storage/prism/IntegerVariable.cpp
-
7src/storage/prism/IntegerVariable.h
-
19src/storage/prism/Module.cpp
-
16src/storage/prism/Module.h
-
34src/storage/prism/Program.cpp
-
14src/storage/prism/Program.h
-
8src/storage/prism/Update.cpp
@ -1,89 +1,172 @@ |
|||
//#include "src/generator/JaniNextStateGenerator.h"
|
|||
//
|
|||
//#include "src/models/sparse/StateLabeling.h"
|
|||
//
|
|||
//#include "src/storage/expressions/SimpleValuation.h"
|
|||
//
|
|||
//#include "src/utility/constants.h"
|
|||
//#include "src/utility/macros.h"
|
|||
//#include "src/exceptions/InvalidSettingsException.h"
|
|||
//#include "src/exceptions/WrongFormatException.h"
|
|||
//
|
|||
//namespace storm {
|
|||
// namespace generator {
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// JaniNextStateGenerator<ValueType, StateType>::JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options) : NextStateGenerator<ValueType, StateType>(options), model(model.substituteConstants()), variableInformation(this->model), evaluator(this->model.getManager()), state(nullptr), comparator() {
|
|||
// STORM_LOG_THROW(!this->model.hasDefaultComposition(), storm::exceptions::WrongFormatException, "The explicit next-state generator currently does not support custom system compositions.");
|
|||
// STORM_LOG_THROW(!this->options.isBuildAllRewardModelsSet() && this->options.getRewardModelNames().empty(), storm::exceptions::InvalidSettingsException, "The explicit next-state generator currently does not support building reward models.");
|
|||
//
|
|||
// // If there are terminal states we need to handle, we now need to translate all labels to expressions.
|
|||
// if (this->options.hasTerminalStates()) {
|
|||
// for (auto const& expressionOrLabelAndBool : this->options.getTerminalStates()) {
|
|||
// if (expressionOrLabelAndBool.first.isExpression()) {
|
|||
// terminalStates.push_back(std::make_pair(expressionOrLabelAndBool.first.getExpression(), expressionOrLabelAndBool.second));
|
|||
// } else {
|
|||
// STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Cannot make label terminal for JANI models.");
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// uint64_t JaniNextStateGenerator<ValueType, StateType>::getStateSize() const {
|
|||
// return variableInformation.getTotalBitOffset(true);
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// ModelType JaniNextStateGenerator<ValueType, StateType>::getModelType() const {
|
|||
// switch (model.getModelType()) {
|
|||
// case storm::jani::ModelType::DTMC: return ModelType::DTMC;
|
|||
// case storm::jani::ModelType::CTMC: return ModelType::CTMC;
|
|||
// case storm::jani::ModelType::MDP: return ModelType::MDP;
|
|||
// case storm::jani::ModelType::MA: return ModelType::MA;
|
|||
// default:
|
|||
// STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Invalid model type.");
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// bool JaniNextStateGenerator<ValueType, StateType>::isDeterministicModel() const {
|
|||
// return model.isDeterministicModel();
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// std::vector<StateType> JaniNextStateGenerator<ValueType, StateType>::getInitialStates(StateToIdCallback const& stateToIdCallback) {
|
|||
// // FIXME: This only works for models with exactly one initial state. We should make this more general.
|
|||
// CompressedState initialState(variableInformation.getTotalBitOffset());
|
|||
//
|
|||
// // We need to initialize the values of the variables to their initial value.
|
|||
// for (auto const& booleanVariable : variableInformation.booleanVariables) {
|
|||
// initialState.set(booleanVariable.bitOffset, booleanVariable.initialValue);
|
|||
// }
|
|||
// for (auto const& integerVariable : variableInformation.integerVariables) {
|
|||
// initialState.setFromInt(integerVariable.bitOffset, integerVariable.bitWidth, static_cast<uint_fast64_t>(integerVariable.initialValue - integerVariable.lowerBound));
|
|||
// }
|
|||
//
|
|||
// // Register initial state and return it.
|
|||
// StateType id = stateToIdCallback(initialState);
|
|||
// return {id};
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// void JaniNextStateGenerator<ValueType, StateType>::load(CompressedState const& state) {
|
|||
// // Since almost all subsequent operations are based on the evaluator, we load the state into it now.
|
|||
// unpackStateIntoEvaluator(state, variableInformation, evaluator);
|
|||
//
|
|||
// // Also, we need to store a pointer to the state itself, because we need to be able to access it when expanding it.
|
|||
// this->state = &state;
|
|||
// }
|
|||
//
|
|||
// template<typename ValueType, typename StateType>
|
|||
// bool JaniNextStateGenerator<ValueType, StateType>::satisfies(storm::expressions::Expression const& expression) const {
|
|||
// if (expression.isTrue()) {
|
|||
// return true;
|
|||
// }
|
|||
// return evaluator.asBool(expression);
|
|||
// }
|
|||
// }
|
|||
//}
|
|||
#include "src/generator/JaniNextStateGenerator.h"
|
|||
|
|||
#include "src/models/sparse/StateLabeling.h"
|
|||
|
|||
#include "src/storage/expressions/SimpleValuation.h"
|
|||
|
|||
#include "src/solver/SmtSolver.h"
|
|||
|
|||
#include "src/utility/constants.h"
|
|||
#include "src/utility/macros.h"
|
|||
#include "src/utility/solver.h"
|
|||
#include "src/exceptions/InvalidSettingsException.h"
|
|||
#include "src/exceptions/WrongFormatException.h"
|
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
JaniNextStateGenerator<ValueType, StateType>::JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options) : JaniNextStateGenerator(model.substituteConstants(), options, false) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
JaniNextStateGenerator<ValueType, StateType>::JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options, bool flag) : NextStateGenerator<ValueType, StateType>(model.getExpressionManager(), VariableInformation(model), options), model(model) { |
|||
STORM_LOG_THROW(!this->model.hasDefaultComposition(), storm::exceptions::WrongFormatException, "The explicit next-state generator currently does not support custom system compositions."); |
|||
STORM_LOG_THROW(!this->options.isBuildAllRewardModelsSet() && this->options.getRewardModelNames().empty(), storm::exceptions::InvalidSettingsException, "The explicit next-state generator currently does not support building reward models."); |
|||
|
|||
// If there are terminal states we need to handle, we now need to translate all labels to expressions.
|
|||
if (this->options.hasTerminalStates()) { |
|||
for (auto const& expressionOrLabelAndBool : this->options.getTerminalStates()) { |
|||
if (expressionOrLabelAndBool.first.isExpression()) { |
|||
this->terminalStates.push_back(std::make_pair(expressionOrLabelAndBool.first.getExpression(), expressionOrLabelAndBool.second)); |
|||
} else { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Cannot make label terminal for JANI models."); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
ModelType JaniNextStateGenerator<ValueType, StateType>::getModelType() const { |
|||
switch (model.getModelType()) { |
|||
case storm::jani::ModelType::DTMC: return ModelType::DTMC; |
|||
case storm::jani::ModelType::CTMC: return ModelType::CTMC; |
|||
case storm::jani::ModelType::MDP: return ModelType::MDP; |
|||
case storm::jani::ModelType::MA: return ModelType::MA; |
|||
default: |
|||
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Invalid model type."); |
|||
} |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
bool JaniNextStateGenerator<ValueType, StateType>::isDeterministicModel() const { |
|||
return model.isDeterministicModel(); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::vector<StateType> JaniNextStateGenerator<ValueType, StateType>::getInitialStates(StateToIdCallback const& stateToIdCallback) { |
|||
// Prepare an SMT solver to enumerate all initial states.
|
|||
storm::utility::solver::SmtSolverFactory factory; |
|||
std::unique_ptr<storm::solver::SmtSolver> solver = factory.create(model.getExpressionManager()); |
|||
|
|||
std::vector<storm::expressions::Expression> rangeExpressions = model.getAllRangeExpressions(); |
|||
for (auto const& expression : rangeExpressions) { |
|||
solver->add(expression); |
|||
} |
|||
solver->add(model.getInitialStatesExpression(true)); |
|||
|
|||
// Proceed ss long as the solver can still enumerate initial states.
|
|||
std::vector<StateType> initialStateIndices; |
|||
while (solver->check() == storm::solver::SmtSolver::CheckResult::Sat) { |
|||
// Create fresh state.
|
|||
CompressedState initialState(this->variableInformation.getTotalBitOffset()); |
|||
|
|||
// Read variable assignment from the solution of the solver. Also, create an expression we can use to
|
|||
// prevent the variable assignment from being enumerated again.
|
|||
storm::expressions::Expression blockingExpression; |
|||
std::shared_ptr<storm::solver::SmtSolver::ModelReference> model = solver->getModel(); |
|||
for (auto const& booleanVariable : this->variableInformation.booleanVariables) { |
|||
bool variableValue = model->getBooleanValue(booleanVariable.variable); |
|||
storm::expressions::Expression localBlockingExpression = variableValue ? !booleanVariable.variable : booleanVariable.variable; |
|||
blockingExpression = blockingExpression.isInitialized() ? blockingExpression || localBlockingExpression : localBlockingExpression; |
|||
initialState.set(booleanVariable.bitOffset, variableValue); |
|||
} |
|||
for (auto const& integerVariable : this->variableInformation.integerVariables) { |
|||
int_fast64_t variableValue = model->getIntegerValue(integerVariable.variable); |
|||
storm::expressions::Expression localBlockingExpression = integerVariable.variable != model->getManager().integer(variableValue); |
|||
blockingExpression = blockingExpression.isInitialized() ? blockingExpression || localBlockingExpression : localBlockingExpression; |
|||
initialState.setFromInt(integerVariable.bitOffset, integerVariable.bitWidth, static_cast<uint_fast64_t>(variableValue - integerVariable.lowerBound)); |
|||
} |
|||
|
|||
// Register initial state and return it.
|
|||
StateType id = stateToIdCallback(initialState); |
|||
initialStateIndices.push_back(id); |
|||
|
|||
// Block the current initial state to search for the next one.
|
|||
solver->add(blockingExpression); |
|||
} |
|||
|
|||
return initialStateIndices; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
CompressedState JaniNextStateGenerator<ValueType, StateType>::applyUpdate(CompressedState const& state, storm::jani::EdgeDestination const& destination) { |
|||
CompressedState newState(state); |
|||
|
|||
auto assignmentIt = destination.getAssignments().begin(); |
|||
auto assignmentIte = destination.getAssignments().end(); |
|||
|
|||
// Iterate over all boolean assignments and carry them out.
|
|||
auto boolIt = this->variableInformation.booleanVariables.begin(); |
|||
for (; assignmentIt != assignmentIte && assignmentIt->getAssignedExpression().hasBooleanType(); ++assignmentIt) { |
|||
while (assignmentIt->getExpressionVariable() != boolIt->variable) { |
|||
++boolIt; |
|||
} |
|||
newState.set(boolIt->bitOffset, this->evaluator.asBool(assignmentIt->getExpressionVariable())); |
|||
} |
|||
|
|||
// Iterate over all integer assignments and carry them out.
|
|||
auto integerIt = this->variableInformation.integerVariables.begin(); |
|||
for (; assignmentIt != assignmentIte && assignmentIt->getAssignedExpression().hasIntegerType(); ++assignmentIt) { |
|||
while (assignmentIt->getExpressionVariable() != integerIt->variable) { |
|||
++integerIt; |
|||
} |
|||
int_fast64_t assignedValue = this->evaluator.asInt(assignmentIt->getAssignedExpression()); |
|||
STORM_LOG_THROW(assignedValue <= integerIt->upperBound, storm::exceptions::WrongFormatException, "The update " << assignmentIt->getExpressionVariable().getName() << " := " << assignmentIt->getAssignedExpression() << " leads to an out-of-bounds value (" << assignedValue << ") for the variable '" << assignmentIt->getExpressionVariable().getName() << "'."); |
|||
newState.setFromInt(integerIt->bitOffset, integerIt->bitWidth, assignedValue - integerIt->lowerBound); |
|||
STORM_LOG_ASSERT(static_cast<int_fast64_t>(newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth)) + integerIt->lowerBound == assignedValue, "Writing to the bit vector bucket failed (read " << newState.getAsInt(integerIt->bitOffset, integerIt->bitWidth) << " but wrote " << assignedValue << ")."); |
|||
} |
|||
|
|||
// Check that we processed all assignments.
|
|||
STORM_LOG_ASSERT(assignmentIt == assignmentIte, "Not all assignments were consumed."); |
|||
|
|||
return newState; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
StateBehavior<ValueType, StateType> JaniNextStateGenerator<ValueType, StateType>::expand(StateToIdCallback const& stateToIdCallback) { |
|||
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::vector<Choice<ValueType>> JaniNextStateGenerator<ValueType, StateType>::getSilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback) { |
|||
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::vector<Choice<ValueType>> JaniNextStateGenerator<ValueType, StateType>::getNonsilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback) { |
|||
|
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
std::size_t JaniNextStateGenerator<ValueType, StateType>::getNumberOfRewardModels() const { |
|||
return 0; |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
RewardModelInformation JaniNextStateGenerator<ValueType, StateType>::getRewardModelInformation(uint64_t const& index) const { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "Cannot retrieve reward model information."); |
|||
return RewardModelInformation("", false, false, false); |
|||
} |
|||
|
|||
template<typename ValueType, typename StateType> |
|||
storm::models::sparse::StateLabeling JaniNextStateGenerator<ValueType, StateType>::label(storm::storage::BitVectorHashMap<StateType> const& states, std::vector<StateType> const& initialStateIndices) { |
|||
return NextStateGenerator<ValueType, StateType>::label(states, initialStateIndices, {}); |
|||
} |
|||
|
|||
template class JaniNextStateGenerator<double>; |
|||
template class JaniNextStateGenerator<storm::RationalFunction>; |
|||
|
|||
} |
|||
} |
@ -1,68 +1,66 @@ |
|||
//#pragma once |
|||
// |
|||
//#include "src/generator/NextStateGenerator.h" |
|||
//#include "src/generator/VariableInformation.h" |
|||
// |
|||
//#include "src/storage/jani/Model.h" |
|||
//#include "src/storage/expressions/ExpressionEvaluator.h" |
|||
// |
|||
//#include "src/utility/ConstantsComparator.h" |
|||
// |
|||
//namespace storm { |
|||
// namespace generator { |
|||
// |
|||
// template<typename ValueType, typename StateType = uint32_t> |
|||
// class JaniNextStateGenerator : public NextStateGenerator<ValueType, StateType> { |
|||
// public: |
|||
// typedef typename NextStateGenerator<ValueType, StateType>::StateToIdCallback StateToIdCallback; |
|||
// |
|||
// JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options = NextStateGeneratorOptions()); |
|||
// |
|||
// virtual uint64_t getStateSize() const override; |
|||
// virtual ModelType getModelType() const override; |
|||
// virtual bool isDeterministicModel() const override; |
|||
// virtual std::vector<StateType> getInitialStates(StateToIdCallback const& stateToIdCallback) override; |
|||
// |
|||
// virtual void load(CompressedState const& state) override; |
|||
// virtual StateBehavior<ValueType, StateType> expand(StateToIdCallback const& stateToIdCallback) override; |
|||
// virtual bool satisfies(storm::expressions::Expression const& expression) const override; |
|||
// |
|||
// virtual std::size_t getNumberOfRewardModels() const override; |
|||
// virtual RewardModelInformation getRewardModelInformation(uint64_t const& index) const override; |
|||
// |
|||
// virtual storm::expressions::SimpleValuation toValuation(CompressedState const& state) const override; |
|||
// |
|||
// virtual storm::models::sparse::StateLabeling label(storm::storage::BitVectorHashMap<StateType> const& states, std::vector<StateType> const& initialStateIndices = {}) override; |
|||
// |
|||
// private: |
|||
// /*! |
|||
// * Applies an update to the state currently loaded into the evaluator and applies the resulting values to |
|||
// * the given compressed state. |
|||
// * @params state The state to which to apply the new values. |
|||
// * @params update The update to apply. |
|||
// * @return The resulting state. |
|||
// */ |
|||
// CompressedState applyUpdate(CompressedState const& state, storm::jani::EdgeDestination const& update); |
|||
// |
|||
// /*! |
|||
// * Retrieves all choices labeled with the silent action possible from the given state. |
|||
// * |
|||
// * @param state The state for which to retrieve the silent choices. |
|||
// * @return The silent action choices of the state. |
|||
// */ |
|||
// std::vector<Choice<ValueType>> getSilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback); |
|||
// |
|||
// /*! |
|||
// * Retrieves all choices labeled with some non-silent action possible from the given state. |
|||
// * |
|||
// * @param state The state for which to retrieve the non-silent choices. |
|||
// * @return The non-silent action choices of the state. |
|||
// */ |
|||
// std::vector<Choice<ValueType>> getNonsilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback); |
|||
// |
|||
// // The model used for the generation of next states. |
|||
// storm::jani::Model model; |
|||
// }; |
|||
// |
|||
// } |
|||
//} |
|||
#pragma once |
|||
|
|||
#include "src/generator/NextStateGenerator.h" |
|||
|
|||
#include "src/storage/jani/Model.h" |
|||
|
|||
namespace storm { |
|||
namespace generator { |
|||
|
|||
template<typename ValueType, typename StateType = uint32_t> |
|||
class JaniNextStateGenerator : public NextStateGenerator<ValueType, StateType> { |
|||
public: |
|||
typedef typename NextStateGenerator<ValueType, StateType>::StateToIdCallback StateToIdCallback; |
|||
|
|||
JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options = NextStateGeneratorOptions()); |
|||
|
|||
virtual ModelType getModelType() const override; |
|||
virtual bool isDeterministicModel() const override; |
|||
virtual std::vector<StateType> getInitialStates(StateToIdCallback const& stateToIdCallback) override; |
|||
|
|||
virtual StateBehavior<ValueType, StateType> expand(StateToIdCallback const& stateToIdCallback) override; |
|||
|
|||
virtual std::size_t getNumberOfRewardModels() const override; |
|||
virtual RewardModelInformation getRewardModelInformation(uint64_t const& index) const override; |
|||
|
|||
virtual storm::models::sparse::StateLabeling label(storm::storage::BitVectorHashMap<StateType> const& states, std::vector<StateType> const& initialStateIndices = {}) override; |
|||
|
|||
private: |
|||
/*! |
|||
* A delegate constructor that is used to preprocess the model before the constructor of the superclass is |
|||
* being called. The last argument is only present to distinguish the signature of this constructor from the |
|||
* public one. |
|||
*/ |
|||
JaniNextStateGenerator(storm::jani::Model const& model, NextStateGeneratorOptions const& options, bool flag); |
|||
|
|||
/*! |
|||
* Applies an update to the state currently loaded into the evaluator and applies the resulting values to |
|||
* the given compressed state. |
|||
* @params state The state to which to apply the new values. |
|||
* @params update The update to apply. |
|||
* @return The resulting state. |
|||
*/ |
|||
CompressedState applyUpdate(CompressedState const& state, storm::jani::EdgeDestination const& update); |
|||
|
|||
/*! |
|||
* Retrieves all choices labeled with the silent action possible from the given state. |
|||
* |
|||
* @param state The state for which to retrieve the silent choices. |
|||
* @return The silent action choices of the state. |
|||
*/ |
|||
std::vector<Choice<ValueType>> getSilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback); |
|||
|
|||
/*! |
|||
* Retrieves all choices labeled with some non-silent action possible from the given state. |
|||
* |
|||
* @param state The state for which to retrieve the non-silent choices. |
|||
* @return The non-silent action choices of the state. |
|||
*/ |
|||
std::vector<Choice<ValueType>> getNonsilentActionChoices(CompressedState const& state, StateToIdCallback stateToIdCallback); |
|||
|
|||
// The model used for the generation of next states. |
|||
storm::jani::Model model; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,92 @@ |
|||
#include "src/storage/jani/CompositionInformationVisitor.h"
|
|||
|
|||
#include "src/storage/jani/Model.h"
|
|||
#include "src/storage/jani/Compositions.h"
|
|||
|
|||
namespace storm { |
|||
namespace jani { |
|||
|
|||
CompositionInformation::CompositionInformation(std::map<std::string, uint64_t> const& automatonNameToMultiplicity, std::set<std::string> const& nonsilentActions, bool containsRenameComposition, bool containsRestrictedParallelComposition) : automatonNameToMultiplicity(automatonNameToMultiplicity), nonsilentActions(nonsilentActions), renameComposition(containsRenameComposition), restrictedParallelComposition(containsRestrictedParallelComposition) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
void CompositionInformation::increaseAutomatonMultiplicity(std::string const& automatonName, uint64_t count) { |
|||
automatonNameToMultiplicity[automatonName] += count; |
|||
} |
|||
|
|||
void CompositionInformation::addNonsilentAction(std::string const& actionName) { |
|||
// FIXME
|
|||
} |
|||
|
|||
std::set<std::string> const& CompositionInformation::getNonsilentActions() const { |
|||
// FIXME
|
|||
} |
|||
|
|||
void CompositionInformation::renameNonsilentActions(std::map<std::string, std::string> const& renaming) { |
|||
// FIXME
|
|||
} |
|||
|
|||
void CompositionInformation::setContainsRenameComposition() { |
|||
renameComposition = true; |
|||
} |
|||
|
|||
bool CompositionInformation::containsRenameComposition() const { |
|||
return renameComposition; |
|||
} |
|||
|
|||
void CompositionInformation::setContainsRestrictedParallelComposition() { |
|||
restrictedParallelComposition = true; |
|||
} |
|||
|
|||
bool CompositionInformation::containsRestrictedParallelComposition() const { |
|||
return restrictedParallelComposition; |
|||
} |
|||
|
|||
std::map<std::string, uint64_t> CompositionInformation::joinMultiplicityMaps(std::map<std::string, uint64_t> const& first, std::map<std::string, uint64_t> const& second) { |
|||
std::map<std::string, uint64_t> result = first; |
|||
for (auto const& element : second) { |
|||
result[element.first] += element.second; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
std::map<std::string, uint64_t> const& CompositionInformation::getAutomatonToMultiplicityMap() const { |
|||
return automatonNameToMultiplicity; |
|||
} |
|||
|
|||
CompositionInformation CompositionInformationVisitor::getInformation(Composition const& composition, Model const& model) { |
|||
return boost::any_cast<CompositionInformation>(composition.accept(*this, model)); |
|||
} |
|||
|
|||
boost::any CompositionInformationVisitor::visit(AutomatonComposition const& composition, boost::any const& data) { |
|||
CompositionInformation result; |
|||
result.increaseAutomatonMultiplicity(composition.getAutomatonName()); |
|||
return result; |
|||
} |
|||
|
|||
boost::any CompositionInformationVisitor::visit(RenameComposition const& composition, boost::any const& data) { |
|||
CompositionInformation subresult = boost::any_cast<CompositionInformation>(composition.getSubcomposition().accept(*this, data)); |
|||
subresult.setContainsRenameComposition(); |
|||
return subresult; |
|||
} |
|||
|
|||
boost::any CompositionInformationVisitor::visit(ParallelComposition const& composition, boost::any const& data) { |
|||
Model const& model = boost::any_cast<Model const&>(data); |
|||
CompositionInformation left = boost::any_cast<CompositionInformation>(composition.getLeftSubcomposition().accept(*this, data)); |
|||
CompositionInformation right = boost::any_cast<CompositionInformation>(composition.getRightSubcomposition().accept(*this, data)); |
|||
|
|||
// Join the information from both sides.
|
|||
bool containsRenameComposition = left.containsRenameComposition() || right.containsRenameComposition(); |
|||
bool containsRestrictedParallelComposition = left.containsRestrictedParallelComposition() || right.containsRestrictedParallelComposition(); |
|||
std::map<std::string, uint64_t> joinedAutomatonToMultiplicity = CompositionInformation::joinMultiplicityMaps(left.getAutomatonToMultiplicityMap(), right.getAutomatonToMultiplicityMap()); |
|||
|
|||
// If there was no restricted parallel composition yet, maybe the current composition is one, so check it.
|
|||
if (!containsRestrictedParallelComposition) { |
|||
// FIXME.
|
|||
} |
|||
|
|||
return CompositionInformation(joinedAutomatonToMultiplicity, containsRenameComposition, containsRestrictedParallelComposition); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
#pragma once |
|||
|
|||
#include <map> |
|||
#include <set> |
|||
#include <cstdint> |
|||
|
|||
#include "src/storage/jani/CompositionVisitor.h" |
|||
|
|||
namespace storm { |
|||
namespace jani { |
|||
|
|||
class Model; |
|||
|
|||
class CompositionInformation { |
|||
public: |
|||
CompositionInformation() = default; |
|||
CompositionInformation(std::map<std::string, uint64_t> const& automatonNameToMultiplicity, std::set<std::string> const& nonsilentActions, bool containsRenaming, bool containsRestrictedParallelComposition); |
|||
|
|||
void increaseAutomatonMultiplicity(std::string const& automatonName, uint64_t count = 1); |
|||
|
|||
void addNonsilentAction(std::string const& actionName); |
|||
std::set<std::string> const& getNonsilentActions() const; |
|||
void renameNonsilentActions(std::map<std::string, std::string> const& renaming); |
|||
|
|||
void setContainsRenameComposition(); |
|||
bool containsRenameComposition() const; |
|||
|
|||
void setContainsRestrictedParallelComposition(); |
|||
bool containsRestrictedParallelComposition() const; |
|||
|
|||
static std::map<std::string, uint64_t> joinMultiplicityMaps(std::map<std::string, uint64_t> const& first, std::map<std::string, uint64_t> const& second); |
|||
std::map<std::string, uint64_t> const& getAutomatonToMultiplicityMap() const; |
|||
|
|||
private: |
|||
/// A mapping from the automata's names to the amount of times they occur in the composition. |
|||
std::map<std::string, uint64_t> automatonNameToMultiplicity; |
|||
|
|||
/// The set of non-silent actions contained in the composition. |
|||
std::set<std::string> nonsilentActions; |
|||
|
|||
/// A flag indicating whether the composition contains a renaming composition. |
|||
bool renameComposition; |
|||
|
|||
/// A flag indicating whether the composition contains |
|||
bool restrictedParallelComposition; |
|||
}; |
|||
|
|||
class CompositionInformationVisitor : public CompositionVisitor { |
|||
public: |
|||
CompositionInformationVisitor() = default; |
|||
|
|||
CompositionInformation getInformation(Composition const& composition, Model const& model); |
|||
|
|||
virtual boost::any visit(AutomatonComposition const& composition, boost::any const& data) override; |
|||
virtual boost::any visit(RenameComposition const& composition, boost::any const& data) override; |
|||
virtual boost::any visit(ParallelComposition const& composition, boost::any const& data) override; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
#include "src/storage/jani/AutomatonComposition.h" |
|||
#include "src/storage/jani/RenameComposition.h" |
|||
#include "src/storage/jani/ParallelComposition.h" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue