BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
Choice.cpp
Go to the documentation of this file.
1#include "Choice.h"
3#include <cmath>
4#include <strutil.h>
7
8using namespace BPMNOS::Model;
9
10Choice::Choice(XML::bpmnos::tDecision* decision, const AttributeRegistry& attributeRegistry)
11 : element(decision)
12 , attributeRegistry(attributeRegistry)
13 , attribute(nullptr)
14{
15 std::string attributeName;
16 auto input = encodeQuotedStrings(decision->condition.value.value);
17 strutil::replace_all( input, "∈", " in ");
18
19 // check whether condition provides bounds or enumeration
20 auto conditions = strutil::split(input,'<');
21 if ( conditions.size() == 3 ) {
22 // condition has two inequalities
23 if ( conditions[1][0] == '=' ) {
24 // inequality, remove '=' and trim
25 conditions[1].erase(0, 1);
26 strictness.first = false;
27 }
28 else {
29 // strict inequality
30 strictness.first = true;
31 }
32 lowerBound.emplace( strutil::trim_copy(conditions[0]), attributeRegistry);
33 for ( auto dependency : lowerBound.value().inputs ) {
34 dependencies.insert(dependency);
35 }
36
37 // determine attribute
38 attributeName = strutil::trim_copy(conditions[1]);
39
40 if ( conditions[2][0] == '=' ) {
41 // inequality, remove '=' and trim
42 conditions[2].erase(0, 1);
43 strictness.second = false;
44 }
45 else {
46 // strict inequality
47 strictness.second = true;
48 }
49
50 upperBound.emplace( strutil::trim_copy(conditions[2]), attributeRegistry);
51 for ( auto dependency : upperBound.value().inputs ) {
52 dependencies.insert(dependency);
53 }
54
55 }
56 else if ( auto parts = strutil::split(input," in "); parts.size() == 2 ) {
57
58 attributeName = strutil::trim_copy(parts.front());
59 auto rhs = strutil::trim_copy(parts.back());
60
61 if ( (rhs.front() == '[' && rhs.back() == ']') || (rhs.front() == '{' && rhs.back() == '}') ) {
62 auto alternatives = strutil::split( encodeCollection( rhs.substr(1, rhs.size()-2) ), ',' );
63 for ( auto& alternative : alternatives ) {
64 enumeration.emplace_back( strutil::trim_copy(alternative), attributeRegistry);
65 for ( auto dependency : enumeration.back().inputs ) {
66 dependencies.insert(dependency);
67 }
68 }
69 if ( enumeration.empty() ) {
70 throw std::runtime_error("Choice: empty enumeration");
71 }
72 }
73 else {
74 throw std::runtime_error("Choice: invalid enumeration '" + rhs + "'");
75 }
76 }
77 else {
78 attributeName = strutil::trim_copy(input);
79 lowerBound.emplace("false", attributeRegistry);
80 upperBound.emplace("true", attributeRegistry);
81 }
82
83 if ( attributeName == "" ) {
84 throw std::runtime_error("Choice: unable to determine attribute name");
85 }
86
87 attribute = attributeRegistry[ attributeName ];
88
89 if ( attribute->type == STRING && enumeration.empty() ) {
90 throw std::runtime_error("Choice: no enumeration provided for string");
91 }
92 if ( attribute->type == COLLECTION ) {
93 throw std::runtime_error("Choice: attribute is a collection");
94 }
95
96 attribute->isImmutable = false;
97}
98
99template <typename DataType>
100std::pair<BPMNOS::number,BPMNOS::number> Choice::getBounds(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
101 assert( attribute->type != STRING );
102 assert( lowerBound.has_value() );
103 assert( upperBound.has_value() );
104 BPMNOS::number min = lowerBound.value().execute(status,data,globals).value_or(std::numeric_limits<BPMNOS::number>::min());
105 if ( strictness.first ) {
107 }
108 BPMNOS::number max = upperBound.value().execute(status,data,globals).value_or(std::numeric_limits<BPMNOS::number>::max());
109 if ( strictness.second ) {
111 }
112 if ( attribute->type != DECIMAL ) {
113 min = std::ceil((double)min);
114 max = std::floor((double)max);
115 }
116
117 return {min,max};
118}
119
120template std::pair<BPMNOS::number,BPMNOS::number> Choice::getBounds<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
121template std::pair<BPMNOS::number,BPMNOS::number> Choice::getBounds<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
122
123
124template <typename DataType>
125std::vector<BPMNOS::number> Choice::getEnumeration(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
126 assert( enumeration.size() );
127 std::vector<BPMNOS::number> allowedValues;
128 for ( auto& alternative : enumeration ) {
129 auto allowedValue = alternative.execute(status,data,globals);
130 if ( allowedValue.has_value() ) {
131 allowedValues.push_back( allowedValue.value() );
132 }
133 }
134
135 return allowedValues;
136}
137
138template std::vector<BPMNOS::number> Choice::getEnumeration<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
139template std::vector<BPMNOS::number> Choice::getEnumeration<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
140
#define BPMNOS_NUMBER_PRECISION
Definition Number.h:32
bool isImmutable
Flag indicating whether attribute value may be changed by operator, choice, or intermediate catch eve...
Definition Attribute.h:38
std::optional< Expression > upperBound
Definition Choice.h:29
std::set< const Attribute * > dependencies
Definition Choice.h:31
Choice(XML::bpmnos::tDecision *decision, const AttributeRegistry &attributeRegistry)
Definition Choice.cpp:10
std::pair< BPMNOS::number, BPMNOS::number > getBounds(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Returns the minimal and maximal value the attribute may take.
Definition Choice.cpp:100
std::vector< BPMNOS::number > getEnumeration(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Returns the allowed values the attribute may take.
Definition Choice.cpp:125
Attribute * attribute
Definition Choice.h:26
const AttributeRegistry & attributeRegistry
Definition Choice.h:25
std::optional< Expression > lowerBound
Definition Choice.h:28
std::vector< Expression > enumeration
Definition Choice.h:30
std::pair< bool, bool > strictness
Definition Choice.h:27
Attribute & condition
Attribute value can be expected to be of type 'std::string'.
Definition tDecision.h:45
std::string encodeQuotedStrings(std::string text)
std::string encodeCollection(std::string text)
Function to replace a collection that is not preceded by an alphanumeric or underscore.
BPMNOS_NUMBER_TYPE number
Definition Number.h:42
@ STRING
Definition Value.h:9
@ COLLECTION
Definition Value.h:9
@ DECIMAL
Definition Value.h:9
Value value
Definition bpmn++.h:78
std::string value
Definition bpmn++.h:50