BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
Guidance.cpp
Go to the documentation of this file.
1#include "Guidance.h"
9//#include <iostream>
10
11using namespace BPMNOS::Model;
12
14 : element(guidance)
15 , attributeRegistry(attributeRegistry)
16{
17 if ( guidance->type.value.value == "message" ) {
18 type = Type::MessageDelivery;
19 }
20 else if ( guidance->type.value.value == "entry" ) {
21 type = Type::Entry;
22 }
23 else if ( guidance->type.value.value == "exit" ) {
24 type = Type::Exit;
25 }
26 else if ( guidance->type.value.value == "choice" ) {
27 type = Type::Choice;
28 }
29
30 // add all attributes
31 if ( guidance->attributes.has_value() ) {
32 for ( XML::bpmnos::tAttribute& attributeElement : guidance->attributes.value().get().attribute ) {
33 try {
34 auto attribute = std::make_unique<Attribute>(&attributeElement, Attribute::Category::STATUS, this->attributeRegistry);
35 if ( attribute->expression ) {
36 for ( auto input : attribute->expression->inputs ) {
37 dependencies.insert(input);
38 }
39 }
40 attributes.push_back(std::move(attribute));
41 }
42 catch ( const std::exception &error ){
43 throw std::runtime_error("Guidance: illegal expression for attribute '" + (std::string)attributeElement.id.value + "'\n" + error.what() );
44 }
45 }
46 }
47 // add all restrictions
48 if ( guidance->restrictions.has_value() ) {
49 for ( XML::bpmnos::tRestriction& restriction : guidance->restrictions.value().get().restriction ) {
50 try {
51 restrictions.push_back(std::make_unique<Restriction>(&restriction,this->attributeRegistry));
52 for ( auto input : restrictions.back()->expression.inputs ) {
53 dependencies.insert(input);
54 }
55 }
56 catch ( const std::exception &error ){
57 throw std::runtime_error("Guidance: illegal expression for restriction '" + (std::string)restriction.id.value + "'\n" + error.what() );
58 }
59 }
60 }
61 // add all operators
62 if ( guidance->operators.has_value() ) {
63 for ( XML::bpmnos::tOperator& operator_ : guidance->operators.value().get().operator_ ) {
64 try {
65 operators.push_back(std::make_unique<Operator>(&operator_,this->attributeRegistry));
66 for ( auto input : operators.back()->expression.inputs ) {
67 dependencies.insert(input);
68 }
69 }
70 catch ( const std::exception &error ){
71 throw std::runtime_error("Guidance: illegal expression for operator '" + (std::string)operator_.id.value + "'" + "'\n" + error.what() );
72 }
73 }
74 }
75}
76
77template <typename DataType>
78BPMNOS::number Guidance::getObjective(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
79 BPMNOS::number objective = 0;
80 for ( auto& [name, attribute] : attributeRegistry.statusAttributes ) {
81 auto value = attributeRegistry.getValue(attribute,status,data,globals);
82 if ( value.has_value() && attribute->weight ) {
83//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
84 objective += attribute->weight * value.value();
85 }
86 }
87 for ( auto& [name, attribute] : attributeRegistry.dataAttributes ) {
88 auto value = attributeRegistry.getValue(attribute,status,data,globals);
89 if ( value.has_value() && attribute->weight ) {
90//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
91 objective += attribute->weight * value.value();
92 }
93 }
94 for ( auto& [name, attribute] : attributeRegistry.globalAttributes ) {
95 auto value = attributeRegistry.getValue(attribute,status,data,globals);
96 if ( value.has_value() ) {
97//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
98 objective += attribute->weight * value.value();
99 }
100 }
101 return objective;
102}
103
104template BPMNOS::number Guidance::getObjective<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
105//template BPMNOS::number Guidance::getObjective<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
106
107template <typename DataType>
108bool Guidance::restrictionsSatisfied(const BPMN::FlowNode* node, const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
109 for ( auto& restriction : restrictions ) {
110 if ( !restriction->isSatisfied(status,data,globals) ) {
111 return false;
112 }
113 }
114
115 // TODO: do we need to check node restrictions?
116 return true;
117}
118
119template bool Guidance::restrictionsSatisfied<BPMNOS::Values>(const BPMN::FlowNode* node, const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
120//template bool Guidance::restrictionsSatisfied<BPMNOS::SharedValues>(const BPMN::FlowNode* node, const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
121
122
123template <typename DataType>
124void Guidance::apply(const Scenario* scenario, BPMNOS::number currentTime, const BPMNOS::number instanceId, const BPMN::FlowNode* node, BPMNOS::Values& status, DataType& data, BPMNOS::Values& globals) const {
125
126 for ( auto& attribute : attributes ) {
127 status.push_back( scenario->getKnownValue(instanceId, attribute.get(), currentTime ) );
128 if ( attribute->expression ) {
129 // compute initial value
130 status.back() = attribute->expression->execute(status,data,globals);
131 }
132 }
133
134 // apply operators
135 for ( auto& operator_ : operators ) {
136 operator_->apply(status,data,globals);
137 }
138}
139
140template void Guidance::apply<BPMNOS::Values>(const Scenario* scenario, BPMNOS::number currentTime, const BPMNOS::number instanceId, const BPMN::FlowNode* node, BPMNOS::Values& status, BPMNOS::Values& data, BPMNOS::Values& globals) const;
141//template void Guidance::apply<BPMNOS::SharedValues>(const Scenario* scenario, BPMNOS::number currentTime, const BPMNOS::number instanceId, const BPMN::FlowNode* node, BPMNOS::Values& status, BPMNOS::SharedValues& data, BPMNOS::Values& globals) const;
142
std::map< std::string, Attribute * > dataAttributes
std::map< std::string, Attribute * > globalAttributes
std::map< std::string, Attribute * > statusAttributes
std::optional< BPMNOS::number > getValue(const Attribute *attribute, const Values &status, const Values &data, const Values &globals) const
BPMNOS::number getObjective(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Definition Guidance.cpp:78
std::vector< std::unique_ptr< Attribute > > attributes
Definition Guidance.h:27
void apply(const Scenario *scenario, BPMNOS::number currentTime, const BPMNOS::number instanceId, const BPMN::FlowNode *node, BPMNOS::Values &status, DataType &data, BPMNOS::Values &globals) const
Definition Guidance.cpp:124
std::vector< std::unique_ptr< Operator > > operators
Definition Guidance.h:29
AttributeRegistry attributeRegistry
Registry allowing to look up attributes by their names.
Definition Guidance.h:23
bool restrictionsSatisfied(const BPMN::FlowNode *node, const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Definition Guidance.cpp:108
Guidance(XML::bpmnos::tGuidance *guidance, const AttributeRegistry &attributeRegistry)
Definition Guidance.cpp:13
std::vector< std::unique_ptr< Restriction > > restrictions
Definition Guidance.h:28
The Scenario class holds data for all BPMN instances.
Definition Scenario.h:20
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
Base class for BPMN elements that may contain incoming and outgoing sequence flows.
Definition bpmn++.h:16670
Attribute & type
Attribute value can be expected to be of type 'std::string'.
Definition tGuidance.h:51
std::optional< std::reference_wrapper< tAttributes > > attributes
Definition tGuidance.h:52
BPMNOS_NUMBER_TYPE number
Definition Number.h:42
Value value
Definition bpmn++.h:78
std::string value
Definition bpmn++.h:50