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() || ( token->state == Token::State::EXITING ) ); // loop activities may re-enter
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 extensionElements->fullScopeRestrictionsSatisfied(status,data,globals);
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 return extensionElements->feasibleExit(status,data,globals);
58}
59
60bool LocalEvaluator::updateValues(ChoiceDecision* decision, Values& status, Values& data, Values& globals) {
61 auto token = decision->token;
62 // make sure that timestamp used for evaluation is up to date
63 auto now = token->owner->systemState->getTime();
64 if ( status[BPMNOS::Model::ExtensionElements::Index::Timestamp].value() < now ) {
66 }
67 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
68 assert(extensionElements);
69 extensionElements->applyOperators(status,data,globals);
70 return extensionElements->feasibleCompletion(status,data,globals);
71}
72
73bool LocalEvaluator::updateValues(MessageDeliveryDecision* decision, Values& status, Values& data, Values& globals) {
74 auto token = decision->token;
75 // make sure that timestamp used for evaluation is up to date
76 auto now = token->owner->systemState->getTime();
77 if ( status[BPMNOS::Model::ExtensionElements::Index::Timestamp].value() < now ) {
79 }
80 assert( token->node );
81 assert( token->node->parent );
82 auto extensionElements =
83 token->node->represents<BPMN::MessageStartEvent>() ?
85 token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>()
86 ;
87 assert(extensionElements);
88 assert( dynamic_cast<const MessageDeliveryEvent*>(decision) );
89 auto message = static_cast<const MessageDeliveryEvent*>(decision)->message.lock();
90 message->apply(token->node,token->getAttributeRegistry(),status,data,globals);
91 extensionElements->applyOperators(status,data,globals);
92
93 // check feasibility
94 if ( token->node->represents<BPMN::ReceiveTask>() ) {
95 return extensionElements->feasibleCompletion(status,data,globals);
96 }
97 else if ( token->node->represents<BPMN::MessageStartEvent>() ) {
98 return extensionElements->feasibleEntry(status,data,globals);
99 }
100 else {
101 return extensionElements->satisfiesInheritedRestrictions(status,data,globals);
102 }
103}
104
105std::optional<double> LocalEvaluator::evaluate(EntryDecision* decision) {
106 auto token = decision->token;
107 assert( token->ready() || ( token->state == Token::State::EXITING ) ); // loop activities may re-enter
108 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
109 assert(extensionElements);
110 Values status = token->status;
111 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
112 Values data(*token->data);
113 Values globals = token->globals;
114 double evaluation = (double)extensionElements->getObjective(status,data,globals);
115//std::cerr << "Initial local evaluation at node " << token->node->id << ": " << evaluation << std::endl;
116
117 bool feasible = updateValues(decision,status,data,globals);
118 if ( !feasible ) {
119 return std::nullopt;
120 }
121 // return evaluation of entry
122//std::cerr << "Updated local evaluation: " << extensionElements->getObjective(status,data,globals) << std::endl;
123 return extensionElements->getObjective(status,data,globals) - evaluation;
124}
125
126std::optional<double> LocalEvaluator::evaluate(ExitDecision* decision) {
127 auto token = decision->token;
128 assert( token->completed() );
129 Values status = token->status;
130 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
131 Values data(*token->data);
132 Values globals = token->globals;
133 bool feasible = updateValues(decision,status,data,globals);
134 if ( !feasible ) {
135 return std::nullopt;
136 }
137 return 0;
138}
139
140std::optional<double> LocalEvaluator::evaluate(ChoiceDecision* decision) {
141 auto token = decision->token;
142 assert( token->busy() );
143 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
144 assert(extensionElements);
145 assert( extensionElements->choices.size() == decision->choices.size() );
146 auto evaluation = (double)extensionElements->getObjective(token->status, *token->data, token->globals);
147
148 assert( dynamic_cast<const ChoiceEvent*>(decision) );
149 Values status(token->status);
150 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
151 Values data(*token->data);
152 Values globals = token->globals;
153 // apply choices
154 for (size_t i = 0; i < extensionElements->choices.size(); i++) {
155 extensionElements->attributeRegistry.setValue( extensionElements->choices[i]->attribute, status, data, globals, decision->choices[i] );
156 }
157
158 bool feasible = updateValues(decision,status,data,globals);
159 if ( !feasible ) {
160 return std::nullopt;
161 }
162
163 return extensionElements->getObjective(status,data,globals) - evaluation;
164}
165
166std::optional<double> LocalEvaluator::evaluate(MessageDeliveryDecision* decision) {
167 auto token = decision->token;
168 assert( token->busy() );
169
170 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
171 assert(extensionElements);
172 Values status = token->status;
173 status[BPMNOS::Model::ExtensionElements::Index::Timestamp] = token->owner->systemState->currentTime;
174 Values data(*token->data);
175 Values globals = token->globals;
176 double evaluation = (double)extensionElements->getObjective(status,data,globals);
177
178 bool feasible = updateValues(decision,status,data,globals);
179 if ( !feasible ) {
180 return std::nullopt;
181 }
182
183 return extensionElements->getObjective(status,data,globals) - evaluation;
184}
185
186
187std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(EntryDecision* decision) {
188 std::set<const BPMNOS::Model::Attribute*> dependencies;
189
190 auto token = decision->token;
191 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
192 assert(extensionElements);
193
194 if (
195 token->node->represents<BPMN::Activity>() &&
196 !token->node->represents<BPMN::Task>()
197 ) {
198 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
199 }
200
201 dependencies.insert(extensionElements->entryDependencies.begin(), extensionElements->entryDependencies.end());
202
203 if ( token->node->represents<BPMN::Task>() &&
204 !token->node->represents<BPMN::ReceiveTask>() &&
206 ) {
207 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
208 }
209 return dependencies;
210}
211
212std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(ExitDecision* decision) {
213 std::set<const BPMNOS::Model::Attribute*> dependencies;
214
215 auto token = decision->token;
216 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
217 assert(extensionElements);
218
219 dependencies.insert(extensionElements->exitDependencies.begin(), extensionElements->exitDependencies.end());
220
221 return dependencies;
222}
223
224std::set<const BPMNOS::Model::Attribute*> LocalEvaluator::getDependencies(ChoiceDecision* decision) {
225 auto token = decision->token;
226 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
227 assert(extensionElements);
228
229
230 std::set<const BPMNOS::Model::Attribute*> dependencies = extensionElements->operatorDependencies;
231
232 dependencies.insert(extensionElements->completionDependencies.begin(), extensionElements->completionDependencies.end());
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/*
247 // THIS SHOULD NOT BE NEEDED
248 if ( token->node->represents<BPMN::SendTask>() ) {
249 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
250 assert(extensionElements);
251 dependencies.insert(extensionElements->completionDependencies.begin(), extensionElements->completionDependencies.end());
252 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
253 }
254*/
255 if ( token->node->represents<BPMN::ReceiveTask>() ) {
256 auto extensionElements = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>();
257 assert(extensionElements);
258 dependencies.insert(extensionElements->completionDependencies.begin(), extensionElements->completionDependencies.end());
259 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
260 }
261 else if ( token->node->represents<BPMN::MessageStartEvent>() ) {
262 auto eventSubProcess = token->node->parent;
263 auto extensionElements = eventSubProcess->extensionElements->as<BPMNOS::Model::ExtensionElements>();
264 assert(extensionElements);
265 dependencies.insert(extensionElements->entryDependencies.begin(), extensionElements->entryDependencies.end());
266 dependencies.insert(extensionElements->operatorDependencies.begin(), extensionElements->operatorDependencies.end());
267 }
268 return dependencies;
269
270}
271
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 current time.
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
Scope * parent
Reference to the parent node.
Definition bpmn++.h:16592
T * as()
Casts the element to the specified type T.
Definition bpmn++.h:16253
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
std::vector< number > choices
Definition ChoiceEvent.h:18
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.