12 const std::unordered_map<const Attribute*, BPMNOS::number>& globalValueMap,
16 , earliestInstantiationTime(earliestInstantiationTime)
17 , latestInstantiationTime(latestInstantiationTime)
21 for (
auto& [attribute, value] : globalValueMap) {
22 globals[attribute->index] = value;
28 instances[(size_t)instanceId] = {process, (size_t)instanceId, instantiationTime, {}};
32 std::optional<BPMNOS::number> value) {
33 instances[(size_t)instanceId].values[attribute] = value;
38 disclosure[(size_t)instanceId][node] = disclosureTime;
63 const Values& globals)
const {
64 size_t id = (size_t)instanceId;
75 auto& randomGenerator =
getRng(
id, node);
81 for (
auto& arrivalExpression : nodeArrivalExpressions) {
82 auto value = arrivalExpression.expression->execute(status, data,
globals);
83 if (value.has_value() && arrivalExpression.attribute) {
84 instances.at(
id).values[arrivalExpression.attribute] = value.value();
95 auto key = std::make_pair(instanceId, node);
96 if (!
rngs.contains(key)) {
98 size_t nodeHash = std::hash<std::string>{}(node->
id);
99 size_t combinedSeed =
static_cast<size_t>(
scenarioSeed) ^ (instanceId * 31) ^ (nodeHash * 17);
100 rngs[key] = std::mt19937(combinedSeed);
115 std::vector<const Scenario::InstanceData*> result;
117 if (instance.instantiationTime <= currentTime) {
118 result.push_back(&instance);
126 std::vector<const Scenario::InstanceData*> result;
128 result.push_back(&instance);
133std::vector<std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values>>
135 std::vector<std::tuple<const BPMN::Process*, BPMNOS::Values, BPMNOS::Values>> result;
137 BPMNOS::number effectiveInstantiationTime = instance.instantiationTime;
138 if (
disclosure.contains(instance.id) &&
disclosure.at(instance.id).contains(instance.process)) {
139 effectiveInstantiationTime = std::max(effectiveInstantiationTime,
140 disclosure.at(instance.id).at(instance.process));
142 if (effectiveInstantiationTime == currentTime) {
144 if (effectiveInstantiationTime > instance.instantiationTime) {
147 result.push_back({instance.process, std::move(status),
getKnownInitialData(&instance, currentTime)});
157 result.push_back(
getKnownValue(instance, attribute.get(), currentTime));
166 result.push_back(
getKnownValue(instance, attribute.get(), currentTime));
176 std::vector<double> variableValues;
177 for (
auto input : attribute->
expression->variables) {
178 if (!input->isImmutable) {
182 if (!value.has_value()) {
185 variableValues.push_back((
double)value.value());
188 std::vector<std::vector<double>> collectionValues;
189 for (
auto input : attribute->
expression->collections) {
190 if (!input->isImmutable) {
193 collectionValues.push_back({});
194 auto collection =
getKnownValue(instance, input, currentTime);
195 if (!collection.has_value()) {
199 collectionValues.back().push_back(value);
203 return number(attribute->
expression->compiled.evaluate(variableValues, collectionValues));
206 if (instance->
values.contains(attribute)) {
207 return instance->
values.at(attribute);
224 auto& instance =
instances.at((
size_t)instanceId);
226 if (currentTime <
disclosure.at(instance.id).at(node)) {
232 result.push_back(
getKnownValue(&instance, attribute.get(), currentTime));
241 auto& instance =
instances.at((
size_t)instanceId);
243 if (currentTime <
disclosure.at(instance.id).at(node)) {
249 result.push_back(
getKnownValue(&instance, attribute.get(), currentTime));
259 size_t id = (size_t)instanceId;
274 for (
auto& attribute : extensionElements->data) {
275 if (instance.values.contains(attribute.get())) {
276 data.push_back(instance.values.at(attribute.get()));
279 data.push_back(std::nullopt);
284 auto& randomGenerator =
getRng(
id, task);
290 for (
auto& completionExpression : taskCompletionExpressions) {
291 auto value = completionExpression.expression->execute(status, data,
globals);
292 if (value.has_value() && completionExpression.attribute) {
295 for (
auto& attribute : extensionElements->attributes) {
296 if (attribute.get() == completionExpression.attribute) {
297 status[index] = value;
317 auto& instance =
instances.at(instanceId);
320 auto it = pendings.begin();
321 while (it != pendings.end()) {
322 if (currentTime >= it->disclosureTime) {
324 instance.values[it->attribute] = it->value;
326 it = pendings.erase(it);
CollectionRegistry collectionRegistry
std::unique_ptr< const Expression > expression
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.
std::vector< std::unique_ptr< Attribute > > attributes
Vector containing new global attributes declared for the model.
std::map< std::pair< size_t, const BPMN::Node * >, BPMNOS::Values > taskCompletionStatus
Stored completion status per (instanceId, task)
const Model * model
Pointer to the BPMN model.
std::unordered_map< size_t, std::vector< StochasticPendingDisclosure > > pendingDisclosures
Instance ID -> pending disclosures.
std::unordered_map< size_t, std::unordered_map< const BPMN::Node *, std::vector< ArrivalExpression > > > arrivalExpressions
Arrival expressions per (instance, node)
void revealData(BPMNOS::number currentTime) const
void setValue(const BPMNOS::number instanceId, const Attribute *attribute, std::optional< BPMNOS::number > value)
void addArrivalExpression(const BPMNOS::number instanceId, const BPMN::Node *node, ArrivalExpression &&expr)
void addInstance(const BPMN::Process *process, const BPMNOS::number instanceId, BPMNOS::number instantiationTime)
Values getKnownInitialData(const InstanceData *, const BPMNOS::number time) const override
Method returning the initial data attributes for process instantiation.
BPMNOS::number getEarliestInstantiationTime() const override
Method returning the time of the earliest instantiation.
std::vector< const InstanceData * > getCreatedInstances(const BPMNOS::number currentTime) const override
Method returning a vector of all instances that have been created until the given time.
BPMNOS::number earliestInstantiationTime
std::unordered_map< size_t, InstanceData > instances
void addPendingDisclosure(const BPMNOS::number instanceId, StochasticPendingDisclosure &&pending)
std::vector< const InstanceData * > getKnownInstances(const BPMNOS::number currentTime) const override
Method returning a vector of all instances that have been created or are known for sure until the giv...
void setTaskCompletionStatus(const BPMNOS::number instanceId, const BPMN::Node *task, BPMNOS::Values status) const override
Store the completion status when a task enters BUSY state.
BPMNOS::number latestInstantiationTime
std::vector< std::tuple< const BPMN::Process *, BPMNOS::Values, BPMNOS::Values > > getCurrentInstantiations(const BPMNOS::number currentTime) const override
Method returning a vector of all instances that are known to be instantiated at the given time.
void setDisclosure(const BPMNOS::number instanceId, const BPMN::Node *node, BPMNOS::number disclosureTime)
std::set< std::pair< size_t, const Attribute * > > disclosedAttributes
Track which attributes have been disclosed.
unsigned int scenarioSeed
std::optional< BPMNOS::Values > getKnownData(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const override
Method returning all known values of new attributes.
std::map< std::pair< size_t, const BPMN::Node * >, std::mt19937 > rngs
Per (instance, node) RNG for reproducibility.
Values getKnownInitialStatus(const InstanceData *, const BPMNOS::number time) const override
Method returning the initial status attributes for process instantiation.
bool isCompleted(const BPMNOS::number currentTime) const override
Method returning true if the currentTime exceeds the completion time.
RandomDistributionFactory * randomFactory
RandomDistributionFactory for expression evaluation (set by provider)
std::optional< BPMNOS::number > getKnownValue(const Scenario::InstanceData *instance, const BPMNOS::Model::Attribute *attribute, const BPMNOS::number currentTime) const override
Method returning a known value of an attribute.
std::optional< BPMNOS::Values > getKnownValues(const BPMNOS::number instanceId, const BPMN::Node *node, const BPMNOS::number currentTime) const override
Method returning all known values of new attributes.
std::mt19937 & getRng(size_t instanceId, const BPMN::Node *node) const
Get or create RNG for (instance, node) pair.
void initializeArrivalData(BPMNOS::number instanceId, const BPMN::Node *node, const Values &status, const Values &data, const Values &globals) const override
Initialize arrival data when a token arrives at an activity.
void addCompletionExpression(const BPMNOS::number instanceId, const BPMN::Node *task, CompletionExpression &&expr)
StochasticScenario(const Model *model, BPMNOS::number earliestInstantiationTime, BPMNOS::number latestInstantiationTime, const std::unordered_map< const Attribute *, BPMNOS::number > &globalValueMap, unsigned int seed=0)
std::unordered_map< size_t, std::unordered_map< const BPMN::Node *, BPMNOS::number > > disclosure
Instance ID -> Node -> disclosure time.
std::unordered_map< size_t, std::unordered_map< const BPMN::Node *, std::vector< CompletionExpression > > > completionExpressions
Completion expressions per (instance, node)
void setCurrentRng(std::mt19937 *rng)
Set the current RNG to use for expression evaluation.
std::unique_ptr< ExtensionElements > extensionElements
std::string id
Id of element.
Base class for all nodes in a BPMN model.
BPMNOS_NUMBER_TYPE number
Structure representing an arrival expression.
Structure representing a completion expression.
static constexpr size_t Timestamp
std::unordered_map< const Attribute *, std::optional< BPMNOS::number > > values
Attribute values.
const BPMN::Process * process
Structure representing a pending disclosure.