BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
CPModel.h
Go to the documentation of this file.
1#ifndef BPMNOS_Execution_CPModel_H
2#define BPMNOS_Execution_CPModel_H
3
4#ifdef USE_CP
5
6#include <bpmn++.h>
7#include "FlattenedGraph.h"
13#include <cp/cp.h>
14#include <unordered_map>
15#include <utility>
16#include <memory>
17
18namespace BPMNOS::Execution {
19
20class CPSolution;
21
22/**
23 * @brief A controller dispatching decisions obtained from a solution of a constraint program
24 */
25class CPModel {
26friend class CPSolutionObserver;
27friend class CPController;
28public:
29 using Vertex = FlattenedGraph::Vertex;
30
31 struct Config {
32 bool instantEntry = false; // instant entry is not supported
33 bool instantChoices = true; // non-instant choices are not supported
34 bool instantExit = true; // non-instant exit is not supported
35 };
36 static Config default_config() { return {}; } // Work around for compiler bug see: https://stackoverflow.com/questions/53408962/try-to-understand-compiler-error-message-default-member-initializer-required-be/75691051#75691051
37 CPModel(const BPMNOS::Execution::FlattenedGraph* flattenedGraph, Config config = default_config());
38
39 const CP::Model& getModel() const { return model; }
40 const BPMNOS::Model::Scenario* scenario;
41protected:
42 Config config;
43public:
44 const FlattenedGraph* flattenedGraph;
45 std::vector<const Vertex*> vertices; /// Vertices sorted for CP model
46 std::unordered_map< const Vertex*, size_t > indexMap; /// Index in sortedVertices for each vertex
47protected:
48 CP::Model model;
49 LIMEX::Handle<CP::Expression,CP::Expression> limexHandle;
50
51 void createCP(); /// Method creating the constraint program
52 void createGlobalVariables();
53 void createMessageFlowVariables();
54 void createMessagingConstraints();
55 void createMessageHeader(const Vertex* vertex);
56 void createMessageContent(const Vertex* vertex);
57 void createVertexVariables(const Vertex* vertex);
58 void createEntryVariables(const Vertex* vertex);
59 void createExitVariables(const Vertex* vertex);
60 void createSequenceFlowVariables(const Vertex* source, const Vertex* target, const BPMNOS::Model::Gatekeeper* gatekeeper = nullptr);
61 void createStatusFlowVariables(const Vertex* source, const Vertex* target);
62
63 void createSequenceConstraints(const Vertex* vertex);
64 void createRestrictions(const Vertex* vertex);
65 CP::Expression createExpression(const Vertex* vertex, const Model::Expression& expression);
66
67 void createGlobalIndexVariable(const Vertex* vertex);
68 void createDataVariables(const Vertex* vertex);
69 void createDataIndexVariables(const Vertex* vertex);
70
71 void constrainGlobalVariables();
72 void constrainDataVariables(const FlattenedGraph::Vertex* vertex);
73 void constrainSequentialActivities();
74 void constrainEventBasedGateway(const FlattenedGraph::Vertex* gateway);
75 void constrainTypedStartEvent(const FlattenedGraph::Vertex* startEvent);
76
77 struct AttributeVariables {
78 const CP::Variable& defined;
79 const CP::Variable& value;
80 // Constructor
81 AttributeVariables(const CP::Variable& defined, const CP::Variable& value)
82 : defined(defined), value(value) {}
83 // Copy Constructor
84 AttributeVariables(const AttributeVariables& other)
85 : defined(other.defined), value(other.value) {}
86 // Assignment Operator
87 AttributeVariables operator=(const AttributeVariables& other) {
88 return AttributeVariables(other.defined,other.value);
89 }
90 };
91
92 struct IndexedAttributeVariables {
93 CP::IndexedVariables& defined;
94 CP::IndexedVariables& value;
95 };
96
97 void addToObjective(const BPMNOS::Model::Attribute* attribute, const CP::Variable& variable);
98 void addObjectiveCoefficients(const Vertex* vertex);
99
100 struct AttributeEvaluation {
101 AttributeEvaluation(std::expected< double, std::string > defined, std::expected< double, std::string > value) : _defined(defined), _value(value) {}
102 inline bool defined() const { return (bool)_defined.value(); }
103 inline double value() const { return _value.value(); }
104 // bool cast operator
105 explicit operator bool() const {
106 return static_cast<bool>(_defined) && static_cast<bool>(_value);
107 }
108 private:
109 std::expected< double, std::string > _defined;
110 std::expected< double, std::string > _value;
111 };
112
113 void createStatus(const Vertex* vertex);
114 void addAttributes(const Vertex* vertex, std::vector<AttributeVariables>& variables, const BPMNOS::Model::Attribute* loopIndex = nullptr);
115 void createEntryStatus(const Vertex* vertex);
116 void createExitStatus(const Vertex* vertex);
117 void createLocalAttributeVariables(const Vertex* vertex);
118 CP::Expression createOperatorExpression( const Model::Expression& operator_, std::tuple< std::vector<AttributeVariables>, std::vector<AttributeVariables>, std::vector<AttributeVariables> >& localVariables );
119 std::pair< CP::Expression, CP::Expression > getLocalAttributeVariables( const Model::Attribute* attribute, std::tuple< std::vector<AttributeVariables>, std::vector<AttributeVariables>, std::vector<AttributeVariables> >& localVariables );
120
121 const BPMNOS::Model::Choice* findChoice(const std::vector< std::unique_ptr<BPMNOS::Model::Choice> >& choices, const BPMNOS::Model::Attribute* attribute) const;
122
123 const BPMNOS::Model::Content* findContent(const BPMNOS::Model::MessageDefinition* messageDefinition, const BPMNOS::Model::Attribute* attribute) const;
124
125 std::vector<CPModel::AttributeVariables> createUniquelyDeducedEntryStatus(const Vertex* vertex, const BPMNOS::Model::AttributeRegistry& attributeRegistry, std::vector<AttributeVariables>& inheritedStatus);
126 std::vector<AttributeVariables> createAlternativeEntryStatus(const Vertex* vertex, const BPMNOS::Model::AttributeRegistry& attributeRegistry, std::vector< std::pair<const CP::Variable&, std::vector<AttributeVariables>& > > alternatives);
127 std::vector<AttributeVariables> createMergedStatus(const Vertex* vertex, const BPMNOS::Model::AttributeRegistry& attributeRegistry, std::vector< std::pair<const CP::Variable&, std::vector<AttributeVariables>& > > inputs);
128 CP::Expression getLoopIndex(const Vertex* vertex);
129 void createLoopEntryStatus(const Vertex* vertex);
130 std::vector<CPModel::AttributeVariables> createLoopExitStatus(const Vertex* vertex);
131
132 struct pair_hash {
133 template <class T1, class T2>
134 std::size_t operator () (const std::pair<T1,T2> &p) const {
135 auto h1 = std::hash<T1>{}(p.first);
136 auto h2 = std::hash<T2>{}(p.second);
137 // Mainly for demonstration purposes, i.e. works but is overly simple
138 // In the real world, use sth. like boost.hash_combine
139 // return h1 ^ h2;
140 // return h1 * 31 + h2; // Prime multiplication
141 return h1 ^ (h2 * 2654435761u); // Uses a large prime for better distribution
142 }
143 };
144
145 std::vector<const Vertex*> messageRecipients; /// Container of all (exit) vertices catching a message
146 std::vector<const Vertex*> messageSenders; /// Container of all (entry) vertices throwing a message
147
148 std::unordered_map< const Vertex*, const CP::Variable& > position; /// Variables holding sequence positions for all vertices
149 std::unordered_map< const Vertex*, const CP::Variable& > visit; /// Variables indicating whether the a token enters or leaves a vertex
150
151 std::unordered_map< std::pair< const Vertex*, const Vertex* >, const CP::Variable&, pair_hash > tokenFlow; /// Variables indicating whether the a token flows from one vertex to another
152 std::unordered_map< std::pair< const Vertex*, const Vertex* >, const CP::Variable&, pair_hash > messageFlow; /// Variables indicating whether a message is sent from one vertex to another
153
154 std::unordered_map< const Vertex*, std::unordered_map< std::string, AttributeVariables> > messageHeader; /// Variables representing the header of a message originating at a vertex
155 std::unordered_map< const Vertex*, std::unordered_map< std::string, AttributeVariables> > messageContent; /// Variables representing the content of a message originating at a vertex
156
157 std::vector< IndexedAttributeVariables > globals; /// Variables representing global attributes after i-th modification
158 std::unordered_map< const Vertex*, const CP::Variable& > globalIndex; /// Variables representing an index representing the state of the global attributes
159
160 std::unordered_map< std::pair< const Vertex*, const Model::Attribute*>, IndexedAttributeVariables, pair_hash > data; /// Variables representing data attributes after i-th modification
161 std::unordered_map< const Vertex*, CP::reference_vector< const CP::Variable > > dataIndex; /// Variables representing an index representing the state of the data attributes for each data owner
162
163 std::unordered_map< const Vertex*, std::vector<AttributeVariables> > status; /// Variables representing status attributes of a vertex
164 std::unordered_map< const Vertex*, std::vector< std::tuple< std::vector<AttributeVariables>, std::vector<AttributeVariables>, std::vector<AttributeVariables> > > > locals; /// Variables representing status, data, globals attributes of a vertex after the i-th operator
165
166 std::unordered_map< std::pair< const Vertex*, const Model::Attribute*>, const CP::Variable&, pair_hash > discretizerMap; /// Variables representing discretizers for choices with multipleOf constraint
167
168 std::unordered_map< std::pair< const Vertex*, const Vertex* >, std::vector<AttributeVariables>, pair_hash > statusFlow; /// Variables representing status attributes flowing from one vertex to another
169
170 std::optional< BPMN::Activity::LoopCharacteristics > getLoopCharacteristics(const Vertex* vertex) const;
171 std::optional< BPMNOS::number > getTimestamp( const Vertex* vertex ) const;
172 std::pair< CP::Expression, CP::Expression > getAttributeVariables( const Vertex* vertex, const Model::Attribute* attribute);
173public:
174 std::string stringify() const { return model.stringify(); };
175
176 const Vertex* entry(const Vertex* vertex) const { return flattenedGraph->entry(vertex); };
177 const Vertex* exit(const Vertex* vertex) const { return flattenedGraph->exit(vertex); };
178};
179
180} // namespace BPMNOS::Execution
181
182#endif // USE_CP
183
184#endif // BPMNOS_Execution_CPModel_H
185
Represents a graph containing all BPMN nodes that may receive a token during execution of a scenario.
const Vertex * exit(const Vertex *vertex) const
const Vertex * entry(const Vertex *vertex) const
Class representing a choice to be made within a BPMNOS::Model::DecisionTask.
Definition Choice.h:21
Class holding extension elements representing gatekeeper conditions for sequence flows.
Definition Gatekeeper.h:17
Abstract base class for scenarios holding data for all BPMN instances.
Definition Scenario.h:21