#include "src/storage/jani/CompositionInformationVisitor.h" #include "src/storage/jani/Model.h" #include "src/storage/jani/Compositions.h" namespace storm { namespace jani { CompositionInformation::CompositionInformation() : automatonNameToMultiplicity(), nonsilentActions(), renameComposition(false), restrictedParallelComposition(false) { // Intentionally left empty. } CompositionInformation::CompositionInformation(std::map const& automatonNameToMultiplicity, std::set 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) { nonsilentActions.insert(actionName); } std::set const& CompositionInformation::getNonsilentActions() const { return nonsilentActions; } std::set CompositionInformation::renameNonsilentActions(std::set const& nonsilentActions, std::map> const& renaming) { std::set newNonsilentActions; for (auto const& entry : nonsilentActions) { auto it = renaming.find(entry); if (it != renaming.end()) { if (it->second) { newNonsilentActions.insert(it->second.get()); } } else { newNonsilentActions.insert(entry); } } return newNonsilentActions; } void CompositionInformation::setContainsRenameComposition() { renameComposition = true; } bool CompositionInformation::containsRenameComposition() const { return renameComposition; } void CompositionInformation::setContainsRestrictedParallelComposition() { restrictedParallelComposition = true; } bool CompositionInformation::containsRestrictedParallelComposition() const { return restrictedParallelComposition; } std::map CompositionInformation::joinMultiplicityMaps(std::map const& first, std::map const& second) { std::map result = first; for (auto const& element : second) { result[element.first] += element.second; } return result; } std::map const& CompositionInformation::getAutomatonToMultiplicityMap() const { return automatonNameToMultiplicity; } CompositionInformation CompositionInformationVisitor::getInformation(Composition const& composition, Model const& model) { return boost::any_cast(composition.accept(*this, model)); } boost::any CompositionInformationVisitor::visit(AutomatonComposition const& composition, boost::any const& data) { Model const& model = boost::any_cast(data); Automaton const& automaton = model.getAutomaton(composition.getAutomatonName()); CompositionInformation result; result.increaseAutomatonMultiplicity(composition.getAutomatonName()); for (auto const& actionIndex : automaton.getActionIndices()) { if (actionIndex != model.getSilentActionIndex()) { result.addNonsilentAction(model.getAction(actionIndex).getName()); } } return result; } boost::any CompositionInformationVisitor::visit(RenameComposition const& composition, boost::any const& data) { CompositionInformation subresult = boost::any_cast(composition.getSubcomposition().accept(*this, data)); std::set nonsilentActions = CompositionInformation::renameNonsilentActions(subresult.getNonsilentActions(), composition.getRenaming()); return CompositionInformation(subresult.getAutomatonToMultiplicityMap(), nonsilentActions, true, subresult.containsRestrictedParallelComposition()); } boost::any CompositionInformationVisitor::visit(ParallelComposition const& composition, boost::any const& data) { CompositionInformation left = boost::any_cast(composition.getLeftSubcomposition().accept(*this, data)); CompositionInformation right = boost::any_cast(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 joinedAutomatonToMultiplicity = CompositionInformation::joinMultiplicityMaps(left.getAutomatonToMultiplicityMap(), right.getAutomatonToMultiplicityMap()); std::set nonsilentActions; std::set_union(left.getNonsilentActions().begin(), left.getNonsilentActions().end(), right.getNonsilentActions().begin(), right.getNonsilentActions().end(), std::inserter(nonsilentActions, nonsilentActions.begin())); // If there was no restricted parallel composition yet, maybe the current composition is one, so check it. if (!containsRestrictedParallelComposition) { std::set commonNonsilentActions; std::set_intersection(left.getNonsilentActions().begin(), left.getNonsilentActions().end(), right.getNonsilentActions().begin(), right.getNonsilentActions().end(), std::inserter(commonNonsilentActions, commonNonsilentActions.begin())); bool allCommonActionsIncluded = std::includes(commonNonsilentActions.begin(), commonNonsilentActions.end(), composition.getSynchronizationAlphabet().begin(), composition.getSynchronizationAlphabet().end()); containsRestrictedParallelComposition = !allCommonActionsIncluded; } return CompositionInformation(joinedAutomatonToMultiplicity, nonsilentActions, containsRenameComposition, containsRestrictedParallelComposition); } } }