BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
Scenario.cpp
Go to the documentation of this file.
1#include "Scenario.h"
5#include <limits>
6
7using namespace BPMNOS::Model;
8
9Scenario::Scenario(const Model* model, BPMNOS::number inception, BPMNOS::number completion, const DataInput& attributes, const std::unordered_map< const Attribute*, BPMNOS::number >& globalValueMap, unsigned int index)
10 : index(index)
11 , model(model)
12 , attributes(attributes)
13 , inception(inception)
14 , completion(completion)
15{
16 globals.resize(model->attributes.size());
17 for ( auto& [ attribute, value ] : globalValueMap ) {
18 globals[attribute->index] = value;
19 }
20}
21
22Scenario::Scenario(const Scenario& other, unsigned int index)
23 : index(index)
24 , model(other.model)
25 , attributes(other.attributes)
26 , inception(other.inception)
27 , completion(other.completion)
28{
29 // Implement deep copy logic for the 'instances' map and its elements
30 for (auto& [identifier, instance] : other.instances) {
31 std::unordered_map< const Attribute*, Data > data;
32 for ( auto& [attribute, attributeData] : instance.data ) {
33 data[attribute] = attributeData;
34 }
35 instances[(long unsigned int)identifier] = {instance.process,instance.id,instance.instantiation,data};
36 }
37}
38
39void Scenario::addInstance(const BPMN::Process* process, const BPMNOS::number instanceId, Scenario::Data instantiation ) {
40 // add instance
41 instances[(long unsigned int)instanceId] = {process,(long unsigned int)instanceId,instantiation,{}};
42 auto& instanceData = instances[(long unsigned int)instanceId];
43 // initialize all attribute data
44 assert( attributes.contains(process) );
45 for ( auto& [id,attribute] : attributes.at(process) ) {
46 instanceData.data[attribute] = { {}, std::nullopt };
47 }
48
49}
50
52 auto& instanceData = instances[(long unsigned int)instanceId];
53 if ( instanceData.instantiation.realization ) {
54 throw std::runtime_error("Scenario: illegal removal of instance '" + BPMNOS::to_string(instanceId,STRING) + "'with known realization");
55 }
56 instances.erase((long unsigned int)instanceId);
57}
58
60 if ( data.anticipations.size() && data.anticipations.back().disclosure >= anticipation.disclosure ) {
61 throw std::runtime_error("Scenario: disclosures must be provided in strictly increasing order");
62 }
63 data.anticipations.push_back(anticipation);
64}
65
67 data.realization = realization;
68}
69
70const Model* Scenario::getModel() const {
71 return model;
72}
73
77
78bool Scenario::isCompleted(const BPMNOS::number currentTime) const {
79 return currentTime > completion;
80}
81
82
83std::vector< const Scenario::InstanceData* > Scenario::getCreatedInstances(const BPMNOS::number currentTime) const {
84 std::vector< const Scenario::InstanceData* > knownInstances;
85
86 for ( auto& [id, instance] : instances ) {
87 if ( instance.instantiation.realization
88 && instance.instantiation.realization->disclosure <= currentTime
89 && instance.instantiation.realization->value.value() <= currentTime
90 ) {
91 knownInstances.push_back(&instance);
92 }
93 }
94 return knownInstances;
95}
96
97std::vector< const Scenario::InstanceData* > Scenario::getKnownInstances(const BPMNOS::number currentTime) const {
98 std::vector< const Scenario::InstanceData* > knownInstances;
99
100 for ( auto& [id, instance] : instances ) {
101 if ( instance.instantiation.realization
102 && instance.instantiation.realization->disclosure <= currentTime
103 ) {
104 knownInstances.push_back(&instance);
105 }
106 }
107 return knownInstances;
108}
109
110std::vector< const Scenario::InstanceData* > Scenario::getAnticipatedInstances(const BPMNOS::number currentTime) const {
111 std::vector< const Scenario::InstanceData* > anticipatedInstances;
112
113 for ( auto& [id, instance] : instances ) {
114 if ( instance.instantiation.realization
115 && instance.instantiation.realization->disclosure <= currentTime
116 ) {
117 // instance is already known
118 continue;
119 }
120 else if ( instance.instantiation.anticipations.size()
121 && instance.instantiation.anticipations.front().disclosure <= currentTime
122 ) {
123 anticipatedInstances.push_back(&instance);
124 }
125 }
126 return anticipatedInstances;
127}
128
129std::vector< std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values> > Scenario::getCurrentInstantiations(const BPMNOS::number currentTime) const {
130 std::vector< std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values> > instantiations;
131
132 for ( auto& [id, instance] : instances ) {
133 if ( instance.instantiation.realization
134 && instance.instantiation.realization->value.value() == currentTime
135 ) {
136 // return instantiations known to occurr at current time
137 instantiations.push_back({instance.process, getKnownInitialStatus(&instance,currentTime), getKnownInitialData(&instance,currentTime)});
138 }
139 }
140 return instantiations;
141}
142
143std::vector< std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values> > Scenario::getAnticipatedInstantiations(const BPMNOS::number currentTime, const BPMNOS::number assumedTime) const {
144 std::vector< std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values> > instantiations;
145
146 for ( auto& [id, instance] : instances ) {
147 if ( instance.instantiation.realization
148 && instance.instantiation.realization->disclosure <= currentTime
149 && instance.instantiation.realization->value.value() == assumedTime
150 ) {
151 // return known instantiations if realization is already disclosed at current time
152 instantiations.push_back({instance.process, getKnownInitialStatus(&instance,currentTime), getKnownInitialData(&instance,currentTime)});
153 }
154 else if ( instance.instantiation.anticipations.size()
155 && instance.instantiation.anticipations.front().disclosure <= currentTime
156 && getLatestDisclosure(instance.instantiation.anticipations,currentTime).value.value() == assumedTime
157 ) {
158 // return anticipated instantiations if anticipation is already disclosed at current time
159 instantiations.push_back({ instance.process, getAnticipatedInitialStatus(&instance, currentTime), getAnticipatedInitialData(&instance, currentTime) });
160 }
161
162 }
163 return instantiations;
164}
165
167 BPMNOS::Values initalStatus;
168 for ( auto& attribute : instance->process->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->attributes ) {
169 assert( instance->data.contains(attribute.get()) );
170 auto& data = instance->data.at(attribute.get());
171 if ( data.realization.has_value() && data.realization.value().disclosure > currentTime ) {
172 throw std::runtime_error("Scenario: cannot instantiate '" + BPMNOS::to_string(instance->id,STRING) + "' because data attribute '"+ attribute->id +"' is not yet known at time " + BPMNOS::to_string(currentTime,INTEGER) );
173 }
174
175 initalStatus.push_back( getKnownValue(instance,attribute.get(),currentTime) );
176 }
177 return initalStatus;
178}
179
181 BPMNOS::Values initalData;
182 for ( auto& attribute : instance->process->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->data ) {
183 assert( instance->data.contains(attribute.get()) );
184 auto& data = instance->data.at(attribute.get());
185 if ( data.realization.has_value() && data.realization.value().disclosure > currentTime ) {
186 throw std::runtime_error("Scenario: cannot instantiate '" + BPMNOS::to_string(instance->id,STRING) + "' because data attribute '"+ attribute->id +"' is not yet known at time " + BPMNOS::to_string(currentTime,INTEGER) );
187 }
188
189 initalData.push_back( getKnownValue(instance,attribute.get(),currentTime) );
190 }
191 return initalData;
192}
193
194std::optional<BPMNOS::number> Scenario::getKnownValue(const Scenario::InstanceData* instance, const BPMNOS::Model::Attribute* attribute, const BPMNOS::number currentTime) const {
195 auto& data = instance->data.at(attribute);
196
197 if ( data.realization.has_value() ) {
198 auto realization = data.realization.value();
199 if ( realization.disclosure > currentTime ) {
200 // value not yet disclosed
201 return std::nullopt;
202 }
203 else {
204 return realization.value;
205 }
206 }
207
208 // value will never be provided
209 return std::nullopt;
210}
211
212std::optional<BPMNOS::number> Scenario::getKnownValue(const BPMNOS::number instanceId, const BPMNOS::Model::Attribute* attribute, const BPMNOS::number currentTime) const {
213 auto& instanceData = instances.at((size_t)instanceId);
214 return getKnownValue(&instanceData,attribute,currentTime);
215}
216
217
218std::optional<BPMNOS::Values> Scenario::getKnownValues(const BPMNOS::number instanceId, const BPMN::Node* node, const BPMNOS::number currentTime) const {
219 auto& instanceData = instances.at((size_t)instanceId);
220
221 Values values;
222 for ( auto& attribute : node->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->attributes ) {
223 assert( instanceData.data.contains(attribute.get()) );
224 values.push_back( getKnownValue(&instanceData,attribute.get(),currentTime) );
225 }
226
227 return values;
228}
229
230
231std::optional<BPMNOS::Values> Scenario::getKnownData(const BPMNOS::number instanceId, const BPMN::Node* node, const BPMNOS::number currentTime) const {
232 auto& instanceData = instances.at((size_t)instanceId);
233
234 Values values;
235 for ( auto& attribute : node->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->data ) {
236 assert( instanceData.data.contains(attribute.get()) );
237 values.push_back( getKnownValue(&instanceData,attribute.get(),currentTime) );
238 }
239
240 return values;
241}
242
243std::optional<BPMNOS::number> Scenario::getAnticipatedValue(const Scenario::InstanceData* instance, const BPMNOS::Model::Attribute* attribute, const BPMNOS::number currentTime) const {
244 auto& data = instance->data.at(attribute);
245 if ( data.realization && data.realization->disclosure <= currentTime ) {
246 // return the realized value
247 return data.realization->value;
248 }
249 else if ( data.anticipations.size() && data.anticipations.front().disclosure <= currentTime ) {
250 // return the currently anticipated value
251 return getLatestDisclosure(data.anticipations,currentTime).value;
252 }
253
254 // return undefined value
255 return std::nullopt;
256}
257
258std::optional<BPMNOS::number> Scenario::getAnticipatedValue(const BPMNOS::number instanceId, const BPMNOS::Model::Attribute* attribute, const BPMNOS::number currentTime) const {
259 auto& instanceData = instances.at((size_t)instanceId);
260 return getAnticipatedValue(&instanceData,attribute,currentTime);
261}
262
264 BPMNOS::Values initalStatus;
265 for ( auto& attribute : instance->process->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->attributes ) {
266 assert( instance->data.contains(attribute.get()) );
267 initalStatus.push_back( getAnticipatedValue(instance,attribute.get(),currentTime) );
268 }
269 return initalStatus;
270}
271
273 BPMNOS::Values initalData;
274 for ( auto& attribute : instance->process->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->data ) {
275 assert( instance->data.contains(attribute.get()) );
276 initalData.push_back( getAnticipatedValue(instance,attribute.get(),currentTime) );
277 }
278 return initalData;
279}
280
281
282BPMNOS::Values Scenario::getAnticipatedValues(const BPMNOS::number instanceId, const BPMN::Node* node, const BPMNOS::number currentTime) const {
283 auto& instanceData = instances.at((size_t)instanceId);
284
285
286 Values values;
287 for ( auto& attribute : node->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->attributes ) {
288 assert( instanceData.data.contains(attribute.get()) );
289 values.push_back( getAnticipatedValue(&instanceData,attribute.get(),currentTime) );
290 }
291 return values;
292}
293
294BPMNOS::Values Scenario::getAnticipatedData(const BPMNOS::number instanceId, const BPMN::Node* node, const BPMNOS::number currentTime) const {
295 auto& instanceData = instances.at((size_t)instanceId);
296
297 Values values;
298 for ( auto& attribute : node->extensionElements->as<const BPMNOS::Model::ExtensionElements>()->data ) {
299 values.push_back( getAnticipatedValue(&instanceData,attribute.get(),currentTime) );
300 }
301 return values;
302}
303
304const Scenario::Disclosure& Scenario::getLatestDisclosure(const std::vector<Scenario::Disclosure>& data, const BPMNOS::number currentTime) const {
305 // find the first element with a disclosure time larger than the given time
306 auto it = std::upper_bound(data.begin(), data.end(), currentTime,
307 [](BPMNOS::number t, const Disclosure& element) -> bool { return (element.disclosure > t); }
308 );
309 if (it == data.begin()) {
310 throw std::runtime_error("Scenario: illegal request for latest disclosure");
311 }
312 // the preceding element is the last element with a disclosure time smaller or equal to the given time
313 it--;
314 return *it;
315}
316
317
319 auto& instanceData = instances[(size_t)instanceId];
320 return instanceData.instantiation;
321}
322
324 auto& instanceData = instances[(size_t)instanceId];
325 return instanceData.data[attribute];
326}
327
Class holding extension elements representing execution data for nodes.
std::vector< std::unique_ptr< Attribute > > attributes
Vector containing new status attributes declared for the node.
std::vector< std::unique_ptr< Attribute > > data
Vector containing data attributes declared for data objects within the node's scope.
Represents a BPMN model with all its processes.
Definition Model.h:21
std::vector< std::unique_ptr< Attribute > > attributes
Vector containing new global attributes declared for the model.
Definition Model.h:70
The Scenario class holds data for all BPMN instances.
Definition Scenario.h:20
BPMNOS::number inception
Time earliest time in execution.
Definition Scenario.h:187
std::vector< std::tuple< const BPMN::Process *, BPMNOS::Values, BPMNOS::Values > > getCurrentInstantiations(const BPMNOS::number currentTime) const
Method returning a vector of all instances that are known to be instantiated at the given time.
Definition Scenario.cpp:129
Values getKnownInitialStatus(const InstanceData *, const BPMNOS::number time) const
Method returning the initial status of a known instantiation at the given time.
Definition Scenario.cpp:166
Values getKnownInitialData(const InstanceData *, const BPMNOS::number time) const
Method returning the initial data attributes of a known instantiation at the given time.
Definition Scenario.cpp:180
std::optional< BPMNOS::number > getAnticipatedValue(const Scenario::InstanceData *instance, const BPMNOS::Model::Attribute *attribute, const BPMNOS::number currentTime) const
Method returning disclosed value of an attribute.
Definition Scenario.cpp:243
std::vector< const InstanceData * > getCreatedInstances(const BPMNOS::number currentTime) const
Method returning a vector of all instances that have been created until the given time.
Definition Scenario.cpp:83
std::optional< BPMNOS::Values > getKnownData(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const
Method returning all known values of new attributes.
Definition Scenario.cpp:231
Data & getAttributeData(const BPMNOS::number instanceId, const Attribute *attribute)
Definition Scenario.cpp:323
const DataInput & attributes
Map holding all attributes in the model with keys being the process and attribute id.
Definition Scenario.h:184
BPMNOS::number completion
The latest time in execution at which an instantiation can happen.
Definition Scenario.h:188
const Scenario::Disclosure & getLatestDisclosure(const std::vector< Scenario::Disclosure > &data, const BPMNOS::number currentTime) const
Definition Scenario.cpp:304
bool isCompleted(const BPMNOS::number currentTime) const
Method returning true if the currentTime exceeds the completion time.
Definition Scenario.cpp:78
std::unordered_map< size_t, InstanceData > instances
Map of instances with key being the instance id.
Definition Scenario.h:185
BPMNOS::Values getAnticipatedInitialStatus(const InstanceData *, const BPMNOS::number currentTime) const
Method returning the initial status of an anticipated instantiation at the given time.
Definition Scenario.cpp:263
void setRealization(Data &data, Disclosure realization)
Definition Scenario.cpp:66
const Model * getModel() const
Definition Scenario.cpp:70
Scenario(const Model *model, BPMNOS::number inception, BPMNOS::number completion, const DataInput &attributes, const std::unordered_map< const Attribute *, BPMNOS::number > &globalValueMap, unsigned int index=0)
Constructor for Scenario.
Definition Scenario.cpp:9
void removeAnticipatedInstance(const BPMNOS::number instanceId)
Definition Scenario.cpp:51
std::optional< BPMNOS::Values > getKnownValues(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const
Method returning all known values of new attributes.
Definition Scenario.cpp:218
void addAnticipation(Data &data, Disclosure anticipation)
Definition Scenario.cpp:59
Data & getInstantiationData(const BPMNOS::number instanceId)
Definition Scenario.cpp:318
void addInstance(const BPMN::Process *process, const BPMNOS::number instanceId, Data instantiation)
Definition Scenario.cpp:39
std::vector< const InstanceData * > getAnticipatedInstances(const BPMNOS::number currentTime) const
Method returning a vector of all instances that are anticipated and not known for sure at the given t...
Definition Scenario.cpp:110
std::vector< const InstanceData * > getKnownInstances(const BPMNOS::number currentTime) const
Method returning a vector of all instances that have been created or are known for sure until the giv...
Definition Scenario.cpp:97
std::vector< std::tuple< const BPMN::Process *, BPMNOS::Values, BPMNOS::Values > > getAnticipatedInstantiations(const BPMNOS::number currentTime, const BPMNOS::number assumedTime) const
Method returning a vector of all instances that are anticipated to be instantiated at the assumed tim...
Definition Scenario.cpp:143
BPMNOS::Values getAnticipatedInitialData(const InstanceData *, const BPMNOS::number currentTime) const
Method returning the initial data attributes of an anticipated instantiation at the given time.
Definition Scenario.cpp:272
BPMNOS::Values getAnticipatedData(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const
Method returning the disclosed values of new attributes.
Definition Scenario.cpp:294
std::optional< BPMNOS::number > getKnownValue(const Scenario::InstanceData *instance, const BPMNOS::Model::Attribute *attribute, const BPMNOS::number currentTime) const
Method returning a known value of an attribute.
Definition Scenario.cpp:194
BPMNOS::Values getAnticipatedValues(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const
Method returning the disclosed values of new attributes.
Definition Scenario.cpp:282
const Model * model
Pointer to the BPMN model.
Definition Scenario.h:182
BPMNOS::Values globals
Definition Scenario.h:181
BPMNOS::number getInception() const
Method returning the time of the earliest instantiation.
Definition Scenario.cpp:74
std::unique_ptr< ExtensionElements > extensionElements
Definition bpmn++.h:16299
Base class for all nodes in a BPMN model.
Definition bpmn++.h:16444
std::unordered_map< const BPMN::Process *, std::unordered_map< std::string, const Attribute * > > DataInput
Definition Scenario.h:15
std::string to_string(number numericValue, const ValueType &type)
Converts a number to a string.
Definition Number.cpp:150
BPMNOS_NUMBER_TYPE number
Definition Number.h:42
@ INTEGER
Definition Value.h:9
@ STRING
Definition Value.h:9
std::optional< Disclosure > realization
Definition Scenario.h:29
std::vector< Disclosure > anticipations
Definition Scenario.h:28
BPMNOS::number disclosure
Time at which the value is disclosed.
Definition Scenario.h:23
std::optional< BPMNOS::number > value
Value that the attribute takes at the time of disclosed.
Definition Scenario.h:24
std::unordered_map< const Attribute *, Data > data
Data regarding attribute values.
Definition Scenario.h:36
const BPMN::Process * process
Definition Scenario.h:33
size_t id
Instance identifier.
Definition Scenario.h:34