7
//#include "../PQL/PQL.h"
9
namespace PetriEngine {
10
namespace Simplification {
11
enum Trivial { False=0, True=1, Indeterminate=2 };
12
enum MemberType { Constant, Input, Output, Regular };
14
std::vector<int> _variables;
16
bool _canAnalyze = false;
20
Member(std::vector<int>&& vec, int constant, bool canAnalyze = true)
21
: _variables(vec), _constant(constant), _canAnalyze(canAnalyze) {
23
Member(int constant, bool canAnalyse = true)
24
: _constant(constant), _canAnalyze(canAnalyse) {
30
int constant() const { return _constant; };
31
bool canAnalyze() const { return _canAnalyze; };
32
size_t size() const { return _variables.size(); }
33
std::vector<int>& variables() { return _variables; }
34
const std::vector<int>& variables() const { return _variables; }
36
Member& operator+=(const Member& m) {
37
auto tc = _constant + m._constant;
38
auto ca = _canAnalyze && m._canAnalyze;
45
Member& operator-=(const Member& m) {
46
auto tc = _constant - m._constant;
47
auto ca = _canAnalyze && m._canAnalyze;
54
Member& operator*=(const Member& m) {
55
if(!isZero() && !m.isZero()){
60
auto tc = _constant * m._constant;
61
auto ca = _canAnalyze && m._canAnalyze;
69
bool substrationIsZero(const Member& m2) const
71
uint32_t min = std::min(_variables.size(), m2._variables.size());
74
if(_variables[i] != m2._variables[i]) return false;
77
for(; i < _variables.size(); ++i)
79
if(_variables[i] != 0) return false;
82
for(; i < m2._variables.size(); ++i)
84
if(m2._variables[i] != 0) return false;
90
for(const int& v : _variables){
91
if(v != 0) return false;
96
MemberType getType() const {
97
bool isConstant = true;
100
for(const int& v : _variables){
109
if(isConstant) return MemberType::Constant;
110
else if(isInput) return MemberType::Input;
111
else if(isOutput) return MemberType::Output;
112
else return MemberType::Regular;
115
bool operator==(const Member& m) const {
116
size_t min = std::min(_variables.size(), m.size());
117
size_t max = std::max(_variables.size(), m.size());
118
if(memcmp(_variables.data(), m._variables.data(), sizeof(int)*min) != 0)
122
for (uint32_t i = min; i < max; i++) {
123
if (i >= _variables.size()) {
124
if(m._variables[i] != 0) return false;
125
} else if (i >= m._variables.size()) {
126
if(_variables[i] != 0) return false;
129
if(_variables[i] - m._variables[i] != 0) return false;
135
Trivial operator<(const Member& m) const {
136
return trivialLessThan(m, std::less<int>());
138
Trivial operator<=(const Member& m) const {
139
return trivialLessThan(m, std::less_equal<int>());
141
Trivial operator>(const Member& m) const {
142
return m.trivialLessThan(*this, std::less<int>());
144
Trivial operator>=(const Member& m) const {
145
return m.trivialLessThan(*this, std::less_equal<int>());
149
void addVariables(const Member& m2) {
150
uint32_t size = std::max(_variables.size(), m2._variables.size());
151
_variables.resize(size, 0);
153
for (uint32_t i = 0; i < size; i++) {
154
if (i >= m2._variables.size()) {
157
_variables[i] += m2._variables[i];
162
void subtractVariables(const Member& m2) {
163
uint32_t size = std::max(_variables.size(), m2._variables.size());
164
_variables.resize(size, 0);
166
for (uint32_t i = 0; i < size; i++) {
167
if (i >= m2._variables.size()) {
170
_variables[i] -= m2._variables[i];
175
void multiply(const Member& m2) {
177
if (isZero() != m2.isZero()){
179
for(auto& v : _variables) v *= m2._constant;
181
} else if (!m2.isZero()){
182
_variables = m2._variables;
183
for(auto& v : _variables) v *= _constant;
190
Trivial trivialLessThan(const Member& m2, std::function<bool (int, int)> compare) const {
191
MemberType type1 = getType();
192
MemberType type2 = m2.getType();
196
return compare(_constant, m2._constant) ? Trivial::True : Trivial::False;
198
// constant < constant/input/output
199
if (type1 == MemberType::Constant){
200
if(type2 == MemberType::Constant){
201
return compare(_constant, m2._constant) ? Trivial::True : Trivial::False;
203
else if(type2 == MemberType::Input && !compare(_constant, m2._constant)){
204
return Trivial::False;
206
else if(type2 == MemberType::Output && compare(_constant, m2._constant)){
207
return Trivial::True;
210
// input < output/constant
211
else if (type1 == MemberType::Input
212
&& (type2 == MemberType::Constant || type2 == MemberType::Output)
213
&& compare(_constant, m2._constant)) {
214
return Trivial::True;
216
// output < input/constant
217
else if (type1 == MemberType::Output
218
&& (type2 == MemberType::Constant || type2 == MemberType::Input)
219
&& !compare(_constant, m2._constant)) {
220
return Trivial::False;
222
return Trivial::Indeterminate;
229
#endif /* MEMBER_H */