Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
CompositionInformationVisitor.cpp
Go to the documentation of this file.
2
5
8
9namespace storm {
10namespace jani {
11
12CompositionInformation::CompositionInformation() : nonStandardParallelComposition(false), nestedParallelComposition(false), parallelComposition(false) {
13 // Intentionally left empty.
14}
15
16void CompositionInformation::increaseAutomatonMultiplicity(std::string const& automatonName, uint64_t count) {
17 automatonNameToMultiplicity[automatonName] += count;
18}
19
20std::map<std::string, uint64_t> const& CompositionInformation::getAutomatonToMultiplicityMap() const {
21 return automatonNameToMultiplicity;
22}
23
24void CompositionInformation::addMultiplicityMap(std::map<std::string, uint64_t> const& multiplicityMap) {
25 automatonNameToMultiplicity = joinMultiplicityMaps(automatonNameToMultiplicity, multiplicityMap);
26}
27
28std::map<std::string, uint64_t> CompositionInformation::joinMultiplicityMaps(std::map<std::string, uint64_t> const& first,
29 std::map<std::string, uint64_t> const& second) {
30 std::map<std::string, uint64_t> result = first;
31 for (auto const& element : second) {
32 result[element.first] += element.second;
33 }
34 return result;
35}
36
38 nonStandardParallelComposition = value;
39}
40
42 return nonStandardParallelComposition;
43}
44
46 nestedParallelComposition = value;
47}
48
50 return nestedParallelComposition;
51}
52
54 parallelComposition = value;
55}
56
58 return parallelComposition;
59}
60
61std::string const& CompositionInformation::getActionName(uint64_t index) const {
62 return indexToNameMap.at(index);
63}
64
65uint64_t CompositionInformation::getActionIndex(std::string const& name) const {
66 return nameToIndexMap.at(name);
67}
68
70 nonSilentActionIndices.insert(index);
71}
72
73void CompositionInformation::addNonSilentActionIndices(std::set<uint64_t> const& indices) {
74 nonSilentActionIndices.insert(indices.begin(), indices.end());
75}
76
78 return nonSilentActionIndices.find(index) != nonSilentActionIndices.end();
79}
80
82 inputEnabledActionIndices.insert(index);
83}
84
85std::set<uint64_t> const& CompositionInformation::getNonSilentActionIndices() const {
86 return nonSilentActionIndices;
87}
88
90 return inputEnabledActionIndices;
91}
92
93void CompositionInformation::setMappings(std::map<uint64_t, std::string> const& indexToNameMap, std::map<std::string, uint64_t> const& nameToIndexMap) {
94 this->indexToNameMap = indexToNameMap;
95 this->nameToIndexMap = nameToIndexMap;
96}
97
99 : model(model), composition(composition), nextFreeActionIndex(0) {
100 // Determine the next free index we can give out to a new action.
101 for (auto const& action : model.getActions()) {
102 uint64_t actionIndex = model.getActionIndex(action.getName());
103
104 nameToIndexMap[action.getName()] = model.getActionIndex(action.getName());
105 indexToNameMap[actionIndex] = action.getName();
106
107 nextFreeActionIndex = std::max(nextFreeActionIndex, model.getActionIndex(action.getName()));
108 }
109 ++nextFreeActionIndex;
110}
111
113 CompositionInformation result = boost::any_cast<CompositionInformation>(composition.accept(*this, model));
114 result.setMappings(indexToNameMap, nameToIndexMap);
115 return result;
116}
117
118boost::any CompositionInformationVisitor::visit(AutomatonComposition const& composition, boost::any const& data) {
119 Model const& model = boost::any_cast<Model const&>(data);
120 Automaton const& automaton = model.getAutomaton(composition.getAutomatonName());
121
124 for (auto const& actionIndex : automaton.getActionIndices()) {
125 if (actionIndex != storm::jani::Model::SILENT_ACTION_INDEX) {
126 result.addNonSilentActionIndex(actionIndex);
127 }
128 }
129 for (auto const& action : composition.getInputEnabledActions()) {
130 auto it = nameToIndexMap.find(action);
131 STORM_LOG_THROW(it != nameToIndexMap.end(), storm::exceptions::WrongFormatException,
132 "Illegal action name '" << action << "' in when input-enabling automaton '" << composition.getAutomatonName() << "'.");
133 uint64_t actionIndex = it->second;
135 result.hasNonSilentActionIndex(actionIndex), storm::exceptions::WrongFormatException,
136 "Cannot make automaton '" << composition.getAutomatonName() << "' input enabled for action " << action << ", because it has no such action.");
137 result.addInputEnabledActionIndex(actionIndex);
138 }
139 return result;
140}
141
142boost::any CompositionInformationVisitor::visit(ParallelComposition const& composition, boost::any const& data) {
144
145 std::vector<CompositionInformation> subinformation;
146
147 std::set<uint64_t> nonsilentSubActionIndices;
148 for (auto const& subcomposition : composition.getSubcompositions()) {
149 subinformation.push_back(boost::any_cast<CompositionInformation>(subcomposition->accept(*this, data)));
150 nonsilentSubActionIndices.insert(subinformation.back().getNonSilentActionIndices().begin(), subinformation.back().getNonSilentActionIndices().end());
151 }
152
153 bool containsNonStandardParallelComposition = false;
154 bool containsSubParallelComposition = false;
155
156 for (auto const& subinfo : subinformation) {
157 containsNonStandardParallelComposition |= subinfo.containsNonStandardParallelComposition();
158 containsSubParallelComposition |= subinfo.containsParallelComposition();
159 result.addMultiplicityMap(subinfo.getAutomatonToMultiplicityMap());
160 }
161
162 // Keep track of the synchronization vectors that are effective, meaning that the subcompositions all have
163 // the non-silent actions that are referred to.
164 std::set<uint64_t> effectiveSynchVectors;
165 for (uint64_t synchVectorIndex = 0; synchVectorIndex < composition.getNumberOfSynchronizationVectors(); ++synchVectorIndex) {
166 effectiveSynchVectors.insert(synchVectorIndex);
167 }
168
169 // Now compute non-silent actions.
170 std::set<uint64_t> nonSilentActionIndices;
171 for (uint_fast64_t infoIndex = 0; infoIndex < subinformation.size(); ++infoIndex) {
172 auto const& subinfo = subinformation[infoIndex];
173
174 std::set<uint64_t> enabledSynchVectors;
175 std::set<uint64_t> actionsInSynch;
176 for (uint64_t synchVectorIndex = 0; synchVectorIndex < composition.getNumberOfSynchronizationVectors(); ++synchVectorIndex) {
177 auto const& synchVector = composition.getSynchronizationVector(synchVectorIndex);
178 if (synchVector.getInput(infoIndex) != SynchronizationVector::NO_ACTION_INPUT) {
179 for (auto const& nonSilentActionIndex : subinfo.getNonSilentActionIndices()) {
180 std::string const& nonSilentAction = indexToNameMap.at(nonSilentActionIndex);
181 if (synchVector.getInput(infoIndex) == nonSilentAction) {
182 enabledSynchVectors.insert(synchVectorIndex);
183 actionsInSynch.insert(nonSilentActionIndex);
184 }
185 }
186 } else {
187 enabledSynchVectors.insert(synchVectorIndex);
188 }
189 }
190
191 std::set_difference(subinfo.getNonSilentActionIndices().begin(), subinfo.getNonSilentActionIndices().end(), actionsInSynch.begin(),
192 actionsInSynch.end(), std::inserter(nonSilentActionIndices, nonSilentActionIndices.begin()));
193
194 std::set<uint64_t> newEffectiveSynchVectors;
195 std::set_intersection(effectiveSynchVectors.begin(), effectiveSynchVectors.end(), enabledSynchVectors.begin(), enabledSynchVectors.end(),
196 std::inserter(newEffectiveSynchVectors, newEffectiveSynchVectors.begin()));
197 effectiveSynchVectors = std::move(newEffectiveSynchVectors);
198 }
199
200 // Now add all outputs of effective synchronization vectors.
201 for (auto const& synchVectorIndex : effectiveSynchVectors) {
202 auto const& synchVector = composition.getSynchronizationVector(synchVectorIndex);
203 if (synchVector.getOutput() != storm::jani::Model::SILENT_ACTION_NAME) {
204 nonSilentActionIndices.insert(addOrGetActionIndex(synchVector.getOutput()));
205 }
206 }
207
208 // Finally check whether it's a non-standard parallel composition. We do that by first constructing a set of
209 // all effective synchronization vectors and then checking whether this set is fully contained within the
210 // set of expected synchronization vectors.
211
212 std::set<storm::jani::SynchronizationVector, storm::jani::SynchronizationVectorLexicographicalLess> synchVectorSet;
213 for (auto synchVectorIndex : effectiveSynchVectors) {
214 synchVectorSet.insert(composition.getSynchronizationVector(synchVectorIndex));
215 }
216
217 // Construct the set of expected synchronization vectors.
218 std::set<storm::jani::SynchronizationVector, storm::jani::SynchronizationVectorLexicographicalLess> expectedSynchVectorSetUnderApprox;
219 std::set<storm::jani::SynchronizationVector, storm::jani::SynchronizationVectorLexicographicalLess> expectedSynchVectorSetOverApprox;
220 for (auto actionIndex : nonsilentSubActionIndices) {
221 std::string const& actionName = indexToNameMap.at(actionIndex);
222 std::vector<std::string> input;
223 uint64_t numberOfParticipatingAutomata = 0;
224 for (auto const& subcomposition : subinformation) {
225 if (subcomposition.getNonSilentActionIndices().find(actionIndex) != subcomposition.getNonSilentActionIndices().end()) {
226 input.push_back(actionName);
227 ++numberOfParticipatingAutomata;
228 } else {
230 }
231 }
232
233 storm::jani::SynchronizationVector newSynchVector(input, actionName);
234 expectedSynchVectorSetOverApprox.insert(newSynchVector);
235 if (numberOfParticipatingAutomata > 1) {
236 expectedSynchVectorSetUnderApprox.insert(newSynchVector);
237 }
238 }
239
240 containsNonStandardParallelComposition |= !std::includes(expectedSynchVectorSetOverApprox.begin(), expectedSynchVectorSetOverApprox.end(),
241 synchVectorSet.begin(), synchVectorSet.end(), SynchronizationVectorLexicographicalLess());
242
243 containsNonStandardParallelComposition |= !std::includes(synchVectorSet.begin(), synchVectorSet.end(), expectedSynchVectorSetUnderApprox.begin(),
244 expectedSynchVectorSetUnderApprox.end(), SynchronizationVectorLexicographicalLess());
245
246 result.setContainsNonStandardParallelComposition(containsNonStandardParallelComposition);
248 result.setContainsNestedParallelComposition(containsSubParallelComposition);
249
250 result.addNonSilentActionIndices(nonSilentActionIndices);
251 return result;
252}
253
254uint64_t CompositionInformationVisitor::addOrGetActionIndex(std::string const& name) {
255 auto it = nameToIndexMap.find(name);
256 if (it != nameToIndexMap.end()) {
257 return it->second;
258 } else {
259 nameToIndexMap[name] = nextFreeActionIndex;
260 indexToNameMap[nextFreeActionIndex] = name;
261 return nextFreeActionIndex++;
262 }
263}
264
265} // namespace jani
266} // namespace storm
std::string const & getAutomatonName() const
Retrieves the name of the automaton this composition element refers to.
std::set< std::string > const & getInputEnabledActions() const
std::set< uint64_t > getActionIndices() const
Retrieves the set of action indices that are labels of edges of this automaton.
virtual boost::any accept(CompositionVisitor &visitor, boost::any const &data) const =0
std::map< std::string, uint64_t > const & getAutomatonToMultiplicityMap() const
void increaseAutomatonMultiplicity(std::string const &automatonName, uint64_t count=1)
std::string const & getActionName(uint64_t index) const
std::set< uint64_t > const & getNonSilentActionIndices() 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::set< uint64_t > const & getInputEnabledActionIndices() const
void setMappings(std::map< uint64_t, std::string > const &indexToNameMap, std::map< std::string, uint64_t > const &nameToIndexMap)
void addMultiplicityMap(std::map< std::string, uint64_t > const &multiplicityMap)
uint64_t getActionIndex(std::string const &name) const
void addNonSilentActionIndices(std::set< uint64_t > const &indices)
virtual boost::any visit(AutomatonComposition const &composition, boost::any const &data) override
CompositionInformationVisitor(Model const &model, Composition const &composition)
static const uint64_t SILENT_ACTION_INDEX
The index of the silent action.
Definition Model.h:642
std::vector< Action > const & getActions() const
Retrieves the actions of the model.
Definition Model.cpp:646
static const std::string SILENT_ACTION_NAME
The name of the silent action.
Definition Model.h:639
Automaton & getAutomaton(std::string const &name)
Retrieves the automaton with the given name.
Definition Model.cpp:888
uint64_t getActionIndex(std::string const &name) const
Get the index of the action.
Definition Model.cpp:636
std::size_t getNumberOfSynchronizationVectors() const
Retrieves the number of synchronization vectors.
SynchronizationVector const & getSynchronizationVector(uint64_t index) const
Retrieves the synchronization vector with the given index.
std::vector< std::shared_ptr< Composition > > const & getSubcompositions() const
Retrieves the subcompositions of the parallel composition.
static const std::string NO_ACTION_INPUT
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
LabParser.cpp.
Definition cli.cpp:18