BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
LocalEvaluator.cpp
Go to the documentation of this file.
1#include "LocalEvaluator.h"
6
7using namespace BPMNOS::Execution;
8
9
10bool LocalEvaluator::updateValues(EntryDecision* decision, Values& status, Values& data, Values& globals) {
11 auto token = decision->token;
12 assert( token->ready() );
13 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
14 assert(extensionElements);
15
16 // make sure that all initial attribute values are up to date
17 extensionElements->computeInitialValues(token->owner->systemState->getTime(),status,data,globals);
18
19 // TODO: this shoud not be relevant
20 if ( token->node->represents<BPMN::EventSubProcess>() ) {
21assert(!"No entry for event-subprocesses");
22 // for event-subprocesses apply operators before checking entry restrictions
23 extensionElements->applyOperators(status,data,globals);
24 }
25
26 if ( !extensionElements->feasibleEntry(status,data,globals) ) {
27 // entry would be infeasible
28//std::cerr << "Local evaluator: std::nullopt" << std::endl;
29 return false;
30 }
31
32
33 if ( token->node->represents<BPMN::Task>() &&
34 !token->node->represents<BPMN::ReceiveTask>() &&
36 ) {
37 // apply operators after checking entry restrictions and before applying guidance
38 // receive tasks and decision tasks require further decision before operators are applied
39 extensionElements->applyOperators(status,data,globals);
40 }
41 return true;
42}
43
44bool LocalEvaluator::updateValues(ExitDecision* decision, Values& status, Values& data, Values& globals) {
45 auto token = decision->token;
46 assert( token->completed() );
47
48 // make sure that timestamp used for evaluation is up to date
49 auto now = token->owner->systemState->getTime();
50 if ( status[BPMNOS::Model::ExtensionElements::Index::Timestamp].value() < now ) {
52 }
53
54 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
55 assert(extensionElements);
56
57 if ( !extensionElements->feasibleExit(status,data,globals) ) {
58 // exit would be infeasible
59 return false;
60 }
61
62 return true;
63}
64
65bool LocalEvaluator::updateValues(ChoiceDecision* decision, Values& status, Values& data, Values& globals) {
66 auto token = decision->token;
67 // make sure that timestamp used for evaluation is up to date
68 auto now = token->owner->systemState->getTime();
69 if ( status[BPMNOS::Model::ExtensionElements::Index::Timestamp].value() < now ) {
71 }
72 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
73 assert(extensionElements);
74 extensionElements->applyOperators(status,data,globals);
75 // TODO: do we want to check feasibility here?
76 if ( !extensionElements->fullScopeRestrictionsSatisfied(status,data,globals) ) {
77 // exit would be infeasible
78 return false;
79 }
80
81 return true;
82}
83
84bool LocalEvaluator::updateValues(MessageDeliveryDecision* decision, Values& status, Values& data, Values& globals) {
85 auto token = decision->token;
86 // make sure that timestamp used for evaluation is up to date
87 auto now = token->owner->systemState->getTime();
88 if ( status[BPMNOS::Model::ExtensionElements::Index::Timestamp].value() < now ) {
90 }
91 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
92 assert(extensionElements);
93 assert( dynamic_cast<const MessageDeliveryEvent*>(decision) );
94 auto message = static_cast<const MessageDeliveryEvent*>(decision)->message.lock();
95 message->apply(token->node,token->getAttributeRegistry(),status,data,globals);
96 extensionElements->applyOperators(status,data,globals);
97
98 // TODO: do we want to check feasibility here?
99 if ( !extensionElements->fullScopeRestrictionsSatisfied(status,data,globals) ) {
100 // exit would be infeasible
101 return false;
102 }
103
104 return true;
105}
106
107std::optional<double> LocalEvaluator::evaluate(EntryDecision* decision) {
108 auto token = decision->token;
109 assert( token->ready() );
110 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
111 assert(extensionElements);
112 Values status = token->status;
113 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
114 Values data(*token->data);
115 Values globals = token->globals;
116 double evaluation = (double)extensionElements->getObjective(status,data,globals);
117//std::cerr << "Initial local evaluation at node " << token->node->id << ": " << evaluation << std::endl;
118
119 bool feasible = updateValues(decision,status,data,globals);
120 if ( !feasible ) {
121 return std::nullopt;
122 }
123 // return evaluation of entry
124//std::cerr << "Updated local evaluation: " << extensionElements->getObjective(status,data,globals) << std::endl;
125 return evaluation - extensionElements->getObjective(status,data,globals);
126}
127
128std::optional<double> LocalEvaluator::evaluate(ExitDecision* decision) {
129 auto token = decision->token;
130 assert( token->completed() );
131 Values status = token->status;
132 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
133 Values data(*token->data);
134 Values globals = token->globals;
135 bool feasible = updateValues(decision,status,data,globals);
136 if ( !feasible ) {
137 return std::nullopt;
138 }
139 return 0;
140}
141
142std::optional<double> LocalEvaluator::evaluate(ChoiceDecision* decision) {
143 auto token = decision->token;
144 assert( token->busy() );
145 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
146 assert(extensionElements);
147 assert( extensionElements->choices.size() == decision->choices.size() );
148 auto evaluation = (double)extensionElements->getObjective(token->status, *token->data, token->globals);
149
150 assert( dynamic_cast<const ChoiceEvent*>(decision) );
151 Values status(token->status);
152 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
153 Values data(*token->data);
154 Values globals = token->globals;
155 // apply choices
156 for (size_t i = 0; i < extensionElements->choices.size(); i++) {
157 extensionElements->attributeRegistry.setValue( extensionElements->choices[i]->attribute, status, data, globals, decision->choices[i] );
158 }
159
160 bool feasible = updateValues(decision,status,data,globals);
161 if ( !feasible ) {
162 return std::nullopt;
163 }
164
165 return evaluation - extensionElements->getObjective(status,data,globals);
166}
167
168std::optional<double> LocalEvaluator::evaluate(MessageDeliveryDecision* decision) {
169 auto token = decision->token;
170 assert( token->busy() );
171
172 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
173 assert(extensionElements);
174 Values status = token->status;
175 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
176 Values data(*token->data);
177 Values globals = token->globals;
178 double evaluation = (double)extensionElements->getObjective(status,data,globals);
179
180 bool feasible = updateValues(decision,status,data,globals);
181 if ( !feasible ) {
182 return std::nullopt;
183 }
184
185 return evaluation - extensionElements->getObjective(status,data,globals);
186}
187
188
189std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(EntryDecision* decision) {
190 std::set<const BPMNOS::Model::Attribute*> dependencies;
191
192 auto token = decision->token;
193 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
194 assert(extensionElements);
195
196 if (
197 token->node->represents<BPMN::Activity>() &&
198 !token->node->represents<BPMN::Task>()
199 ) {
200 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
201 }
202
203 dependencies.insert(extensionElements->entryDependencies.begin(), extensionElements->entryDependencies.end());
204
205 if ( token->node->represents<BPMN::Task>() &&
206 !token->node->represents<BPMN::ReceiveTask>() &&
208 ) {
209 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
210// dependencies.insert(extensionElements->exitDependencies.begin(), extensionElements->exitDependencies.end());
211 }
212 return dependencies;
213}
214
215std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(ExitDecision* decision) {
216 std::set<const BPMNOS::Model::Attribute*> dependencies;
217
218 auto token = decision->token;
219 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
220 assert(extensionElements);
221
222 dependencies.insert(extensionElements->exitDependencies.begin(), extensionElements->exitDependencies.end());
223
224 return dependencies;
225}
226
227std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(ChoiceDecision* decision) {
228 auto token = decision->token;
229 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
230 assert(extensionElements);
231
232 std::set<const BPMNOS::Model::Attribute*> dependencies = extensionElements->operatorDependencies;
233
234 // add expression dependencies
235 for ( auto& choice : extensionElements->choices ) {
236 dependencies.insert(choice->dependencies.begin(), choice->dependencies.end());
237 }
238
239 return dependencies;
240}
241
242std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(MessageDeliveryDecision* decision) {
243 std::set<const BPMNOS::Model::Attribute*> dependencies;
244 auto token = decision->token;
245
246 if ( token->node->represents<BPMN::SendTask>() ) {
247 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
248 assert(extensionElements);
249 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
250 }
251 else if ( token->node->represents<BPMN::MessageStartEvent>() ) {
252 auto eventSubProcess = token->node->parent;
253 auto extensionElements = eventSubProcess->extensionElements->as<BPMNOS::Model::ExtensionElements>();
254 assert(extensionElements);
255 dependencies.insert(extensionElements->entryDependencies.begin(), extensionElements->entryDependencies.end());
256 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
257 }
258 return dependencies;
259
260}
261
std::set< const BPMNOS::Model::Attribute * > getDependencies(EntryDecision *decision) override
virtual bool updateValues(EntryDecision *decision, Values &status, Values &data, Values &globals)
std::optional< double > evaluate(EntryDecision *decision) override
const SystemState * systemState
BPMNOS::number getTime() const
Function returning the assumed time time if available or the current time otherwise.
const BPMN::FlowNode * node
Definition Token.h:46
const StateMachine * owner
State machine owning the token.
Definition Token.h:44
Class representing a task in which one or more choices have to be made.
Class holding extension elements representing execution data for nodes.
std::unique_ptr< ExtensionElements > extensionElements
Definition bpmn++.h:16299
T * represents()
Attempts to cast the element to the specified type T.
Definition bpmn++.h:16236
Represents the event that choices are made for a DecisionTask.
Represents the event that choices are made for a DecisionTask.
Definition ChoiceEvent.h:15
Represents the event of a token entering a node.
const Token * token
Definition Event.h:18
Represents the event of a token exiting a node.
Represents the event of a message from the message pool being delivered.
Represents the event of a message from the message pool being delivered.