Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 59.5% 66 / 0 / 111
Functions: -% 0 / 1 / 1
Branches: 62.1% 41 / 0 / 66

OMCompiler/Compiler/NFFrontEnd/NFOperator.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated uniontype NFOperator
37 protected
38 import Operator = NFOperator;
39 import Util;
40
41 public
42 import Type = NFType;
43 import Absyn;
44 import AbsynUtil;
45 import DAE;
46 import JSON;
47
48 type Op = enumeration(
49 // Basic arithmetic operators.
50 ADD, // 1: +
51 SUB, // 2: -
52 MUL, // 3: *
53 DIV, // 4: /
54 POW, // 5: ^
55 // Element-wise arithmetic operators. These are only used until the type
56 // checking, then replaced with a more specific operator.
57 ADD_EW, // 6: .+
58 SUB_EW, // 7: .-
59 MUL_EW, // 8: .*
60 DIV_EW, // 9: ./
61 POW_EW, // 10: .^
62 // Scalar-Array and Array-Scalar arithmetic operators.
63 ADD_SCALAR_ARRAY, // 11: scalar + array
64 ADD_ARRAY_SCALAR, // 12: array + scalar
65 SUB_SCALAR_ARRAY, // 13: scalar - array
66 SUB_ARRAY_SCALAR, // 14: array - scalar
67 MUL_SCALAR_ARRAY, // 15: scalar * array
68 MUL_ARRAY_SCALAR, // 16: array * scalar
69 MUL_VECTOR_MATRIX, // 17: vector * matrix
70 MUL_MATRIX_VECTOR, // 18: matrix * vector
71 SCALAR_PRODUCT, // 19: vector * vector
72 MATRIX_PRODUCT, // 20: matrix * matrix
73 DIV_SCALAR_ARRAY, // 21: scalar / array
74 DIV_ARRAY_SCALAR, // 22: array / scalar
75 POW_SCALAR_ARRAY, // 23: scalar ^ array
76 POW_ARRAY_SCALAR, // 24: array ^ scalar
77 POW_MATRIX, // 25: matrix ^ Integer
78 // Unary arithmetic operators.
79 UMINUS, // 26: -
80 // Logic operators.
81 AND, // 27: and
82 OR, // 28: or
83 NOT, // 29: not
84 // Relational operators.
85 LESS, // 30: <
86 LESSEQ, // 31: <=
87 GREATER, // 32: >
88 GREATEREQ, // 33: >=
89 EQUAL, // 34: ==
90 NEQUAL, // 35: <>
91 USERDEFINED // 36: Overloaded operator.
92 );
93
94 record OPERATOR
95 Type ty;
96 Op op;
97 end OPERATOR;
98
99 function compare
100 input Operator op1;
101 input Operator op2;
102 output Integer comp;
103 protected
104 Op o1 = op1.op, o2 = op2.op;
105 algorithm
106 // TODO: Compare the types instead if both operators are USERDEFINED.
107 55564 comp := Util.intCompare(Integer(o1), Integer(o2));
108 end compare;
109
110 function invert
111 input output Operator operator;
112 algorithm
113 operator.op := match operator.op
114 case Op.ADD then Op.SUB;
115 case Op.SUB then Op.ADD;
116 case Op.MUL then Op.DIV;
117 case Op.DIV then Op.MUL;
118 case Op.ADD_EW then Op.SUB_EW;
119 case Op.SUB_EW then Op.ADD_EW;
120 case Op.MUL_EW then Op.DIV_EW;
121 case Op.DIV_EW then Op.MUL_EW;
122 case Op.ADD_SCALAR_ARRAY then Op.SUB_SCALAR_ARRAY;
123 case Op.ADD_ARRAY_SCALAR then Op.SUB_ARRAY_SCALAR;
124 case Op.SUB_SCALAR_ARRAY then Op.ADD_SCALAR_ARRAY;
125 case Op.SUB_ARRAY_SCALAR then Op.ADD_ARRAY_SCALAR;
126 case Op.MUL_SCALAR_ARRAY then Op.DIV_SCALAR_ARRAY;
127 case Op.MUL_ARRAY_SCALAR then Op.DIV_ARRAY_SCALAR;
128 case Op.DIV_SCALAR_ARRAY then Op.MUL_SCALAR_ARRAY;
129 case Op.DIV_ARRAY_SCALAR then Op.MUL_ARRAY_SCALAR;
130 case Op.LESS then Op.GREATEREQ;
131 case Op.LESSEQ then Op.GREATER;
132 case Op.GREATER then Op.LESSEQ;
133 case Op.GREATEREQ then Op.LESS;
134 case Op.EQUAL then Op.EQUAL;
135 case Op.NEQUAL then Op.NEQUAL;
136 // ToDo: should POW return POW? exponent should be negated
137 else algorithm
138 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + "Failed! Don't know how to invert: " + symbol(operator)});
139 ✗ then fail();
140 end match;
141 end invert;
142
143 function negate
144 "the logical negation of a relational operator, e.g. < to >= and == to <>"
145 input output Operator operator;
146 algorithm
147 operator.op := match operator.op
148 case Op.LESS then Op.GREATEREQ;
149 case Op.LESSEQ then Op.GREATER;
150 case Op.GREATER then Op.LESSEQ;
151 case Op.GREATEREQ then Op.LESS;
152 case Op.EQUAL then Op.NEQUAL;
153 case Op.NEQUAL then Op.EQUAL;
154 else algorithm
155 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed! Don't know how to negate: " + symbol(operator)});
156 ✗ then fail();
157 end match;
158 end negate;
159
160 type TypeRestriction = enumeration(SCALAR, VECTOR, MATRIX, ARRAY, OTHER);
161
162 function typeRestriction
163 input Type ty;
164 output TypeRestriction restriction;
165 algorithm
166
2/2
✓ Branch 1 taken 743 times.
✓ Branch 2 taken 106436 times.
107179 if Type.isScalar(ty) then
167 restriction := TypeRestriction.SCALAR;
168 elseif Type.isVector(ty) then
169 restriction := TypeRestriction.VECTOR;
170 elseif Type.isMatrix(ty) then
171 restriction := TypeRestriction.MATRIX;
172 elseif Type.isArray(ty) then
173 restriction := TypeRestriction.ARRAY;
174 else
175 restriction := TypeRestriction.OTHER;
176 end if;
177 end typeRestriction;
178
179 function repairMultary
180 input output Operator operator;
181 input list<Type> types;
182 protected
183 MathClassification mc = getMathClassification(operator);
184 SizeClassification sc;
185 list<tuple<TypeRestriction, Type>> lst;
186 tuple<TypeRestriction, Type> min_, max_;
187 Type ty;
188 function tplLt
189 input tuple<TypeRestriction, Type> tpl1;
190 input tuple<TypeRestriction, Type> tpl2;
191 output Boolean b = Util.tuple21(tpl1) < Util.tuple21(tpl2);
192 end tplLt;
193 algorithm
194
4/4
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 211 times.
✓ Branch 2 taken 425 times.
✓ Branch 3 taken 211 times.
636 lst := list((typeRestriction(t), t) for t in types);
195 211 min_ := List.minElement(lst, tplLt);
196 211 max_ := List.maxElement(lst, tplLt);
197 (sc, ty) := match (min_, max_)
198 case ((TypeRestriction.SCALAR, _), (TypeRestriction.SCALAR, ty)) then (SizeClassification.SCALAR, ty);
199 case ((TypeRestriction.SCALAR, _), (_ ,ty)) then (SizeClassification.SCALAR_ARRAY, ty);
200 case ((TypeRestriction.VECTOR, _), (TypeRestriction.VECTOR, ty)) then (SizeClassification.ELEMENT_WISE, ty);
201 case ((TypeRestriction.VECTOR, _), (TypeRestriction.MATRIX, ty)) then (SizeClassification.VECTOR_MATRIX, ty);
202 case ((TypeRestriction.MATRIX, _), (TypeRestriction.MATRIX, ty)) then (SizeClassification.ELEMENT_WISE, ty);
203 case ((TypeRestriction.ARRAY, _), (TypeRestriction.ARRAY, ty)) then (SizeClassification.ELEMENT_WISE, ty);
204 else algorithm
205 ✗ Error.terminate(getInstanceName() + " failed because the multary arguments have incompatible sizes: "
206 + List.toString(types, Type.toString), sourceInfo());
207 ✗ then fail();
208 end match;
209 211 operator := fromClassification((mc, sc), ty);
210 end repairMultary;
211
212 function repairBinary
213 input output Operator operator;
214 input Type ty1;
215 input Type ty2;
216 protected
217 MathClassification mc = getMathClassification(operator);
218 SizeClassification sc;
219 Type ty;
220 algorithm
221 (sc, ty) := match (typeRestriction(ty1), typeRestriction(ty2))
222 local
223 TypeRestriction r1, r2;
224 case (TypeRestriction.SCALAR, TypeRestriction.SCALAR) then (SizeClassification.SCALAR, ty1);
225 case (TypeRestriction.SCALAR, r2) guard(r2>TypeRestriction.SCALAR) then (SizeClassification.SCALAR_ARRAY, ty2);
226 case (r1, TypeRestriction.SCALAR) guard(r1>TypeRestriction.SCALAR) then (SizeClassification.ARRAY_SCALAR, ty1);
227 case (TypeRestriction.VECTOR, TypeRestriction.MATRIX) then (SizeClassification.VECTOR_MATRIX, ty1);
228 case (TypeRestriction.MATRIX, TypeRestriction.VECTOR) then (SizeClassification.MATRIX_VECTOR, ty2);
229 222 case (r1, r2) guard(r1 == r2) then (getSizeClassification(operator), ty1);
230 else algorithm
231 ✗ Error.terminate(getInstanceName() + " failed because the binary arguments have incompatible sizes: "
232 + Type.toString(ty1) + ", " + Type.toString(ty2), sourceInfo());
233 ✗ then fail();
234 end match;
235 53377 operator := fromClassification((mc, sc), ty);
236 end repairBinary;
237
238 function isLogical
239 input Operator operator;
240 output Boolean b;
241 algorithm
242 b := match operator.op
243 case Op.AND then true;
244 case Op.OR then true;
245 case Op.NOT then true;
246 else false;
247 end match;
248 end isLogical;
249
250 function isRelational
251 input Operator operator;
252 output Boolean b;
253 algorithm
254 b := match operator.op
255 case Op.LESS then true;
256 case Op.LESSEQ then true;
257 case Op.GREATER then true;
258 case Op.GREATEREQ then true;
259 case Op.EQUAL then true;
260 case Op.NEQUAL then true;
261 else false;
262 end match;
263 end isRelational;
264
265 function isScalarProduct
266 input Operator operator;
267 output Boolean b;
268 algorithm
269 b := match operator.op
270 case Op.SCALAR_PRODUCT then true;
271 else false;
272 end match;
273 end isScalarProduct;
274
275 function fromAbsyn
276 input Absyn.Operator inOperator;
277 output Operator outOperator;
278 protected
279 Op op;
280 algorithm
281 op := match inOperator
282 case Absyn.ADD() then Op.ADD;
283 case Absyn.SUB() then Op.SUB;
284 case Absyn.MUL() then Op.MUL;
285 case Absyn.DIV() then Op.DIV;
286 case Absyn.POW() then Op.POW;
287 case Absyn.ADD_EW() then Op.ADD_EW;
288 case Absyn.SUB_EW() then Op.SUB_EW;
289 case Absyn.MUL_EW() then Op.MUL_EW;
290 case Absyn.DIV_EW() then Op.DIV_EW;
291 case Absyn.POW_EW() then Op.POW_EW;
292 case Absyn.UPLUS() then Op.ADD;
293 case Absyn.UPLUS_EW() then Op.ADD;
294 case Absyn.UMINUS() then Op.UMINUS;
295 case Absyn.UMINUS_EW() then Op.UMINUS;
296 case Absyn.AND() then Op.AND;
297 case Absyn.OR() then Op.OR;
298 case Absyn.NOT() then Op.NOT;
299 case Absyn.LESS() then Op.LESS;
300 case Absyn.LESSEQ() then Op.LESSEQ;
301 case Absyn.GREATER() then Op.GREATER;
302 case Absyn.GREATEREQ() then Op.GREATEREQ;
303 case Absyn.EQUAL() then Op.EQUAL;
304 case Absyn.NEQUAL() then Op.NEQUAL;
305 end match;
306
307 1101057 outOperator := OPERATOR(Type.UNKNOWN(), op);
308 end fromAbsyn;
309
310 function toAbsyn
311 input Operator op;
312 output Absyn.Operator aop;
313 algorithm
314 aop := match op.op
315 ✗ case Op.ADD then if Type.isArray(op.ty) then Absyn.Operator.ADD_EW() else Absyn.Operator.ADD();
316 ✗ case Op.SUB then if Type.isArray(op.ty) then Absyn.Operator.SUB_EW() else Absyn.Operator.SUB();
317 ✗ case Op.MUL then if Type.isArray(op.ty) then Absyn.Operator.MUL_EW() else Absyn.Operator.MUL();
318 ✗ case Op.DIV then if Type.isArray(op.ty) then Absyn.Operator.DIV_EW() else Absyn.Operator.DIV();
319 ✗ case Op.POW then if Type.isArray(op.ty) then Absyn.Operator.POW_EW() else Absyn.Operator.POW();
320 case Op.ADD_EW then Absyn.Operator.ADD_EW();
321 case Op.SUB_EW then Absyn.Operator.SUB_EW();
322 case Op.MUL_EW then Absyn.Operator.MUL_EW();
323 case Op.DIV_EW then Absyn.Operator.DIV_EW();
324 case Op.POW_EW then Absyn.Operator.POW_EW();
325 case Op.ADD_SCALAR_ARRAY then Absyn.Operator.ADD();
326 case Op.ADD_ARRAY_SCALAR then Absyn.Operator.ADD();
327 case Op.SUB_SCALAR_ARRAY then Absyn.Operator.SUB();
328 case Op.SUB_ARRAY_SCALAR then Absyn.Operator.SUB();
329 case Op.MUL_SCALAR_ARRAY then Absyn.Operator.MUL();
330 case Op.MUL_ARRAY_SCALAR then Absyn.Operator.MUL();
331 case Op.MUL_VECTOR_MATRIX then Absyn.Operator.MUL();
332 case Op.MUL_MATRIX_VECTOR then Absyn.Operator.MUL();
333 case Op.SCALAR_PRODUCT then Absyn.Operator.MUL();
334 case Op.MATRIX_PRODUCT then Absyn.Operator.MUL();
335 case Op.DIV_SCALAR_ARRAY then Absyn.Operator.DIV();
336 case Op.DIV_ARRAY_SCALAR then Absyn.Operator.DIV();
337 case Op.POW_SCALAR_ARRAY then Absyn.Operator.POW();
338 case Op.POW_ARRAY_SCALAR then Absyn.Operator.POW();
339 case Op.POW_MATRIX then Absyn.Operator.POW();
340 ✗ case Op.UMINUS then if Type.isArray(op.ty) then Absyn.Operator.UMINUS_EW() else Absyn.Operator.UMINUS();
341 case Op.AND then Absyn.Operator.AND();
342 case Op.OR then Absyn.Operator.OR();
343 case Op.NOT then Absyn.Operator.NOT();
344 case Op.LESS then Absyn.Operator.LESS();
345 case Op.LESSEQ then Absyn.Operator.LESSEQ();
346 case Op.GREATER then Absyn.Operator.GREATER();
347 case Op.EQUAL then Absyn.Operator.EQUAL();
348 case Op.NEQUAL then Absyn.Operator.NEQUAL();
349 else
350 algorithm
351 ✗ Error.terminate(getInstanceName() + " got unknown type.", sourceInfo());
352 ✗ then
353 fail();
354 end match;
355 end toAbsyn;
356
357 function toDAE
358 input Operator op;
359 output DAE.Operator daeOp;
360 output Boolean swapArguments = false "The DAE structure only has array*scalar, not scalar*array, etc";
361 output Boolean negate = false "The second argument should be negated.";
362 protected
363 DAE.Type ty;
364 algorithm
365 761477 ty := Type.toDAE(op.ty);
366 daeOp := match op.op
367
2/2
✓ Branch 1 taken 1956 times.
✓ Branch 2 taken 161506 times.
163462 case Op.ADD then if Type.isArray(op.ty) then DAE.ADD_ARR(ty) else DAE.ADD(ty);
368
2/2
✓ Branch 1 taken 395 times.
✓ Branch 2 taken 116671 times.
117066 case Op.SUB then if Type.isArray(op.ty) then DAE.SUB_ARR(ty) else DAE.SUB(ty);
369
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 359465 times.
359465 case Op.MUL then if Type.isArray(op.ty) then DAE.MUL_ARR(ty) else DAE.MUL(ty);
370
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 45167 times.
45168 case Op.DIV then if Type.isArray(op.ty) then DAE.DIV_ARR(ty) else DAE.DIV(ty);
371
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 23120 times.
23120 case Op.POW then if Type.isArray(op.ty) then DAE.POW_ARR2(ty) else DAE.POW(ty);
372 ✗ case Op.ADD_SCALAR_ARRAY algorithm swapArguments := true; then DAE.ADD_ARRAY_SCALAR(ty);
373 3 case Op.ADD_ARRAY_SCALAR then DAE.ADD_ARRAY_SCALAR(ty);
374 1 case Op.SUB_SCALAR_ARRAY then DAE.SUB_SCALAR_ARRAY(ty);
375 // array .- scalar is handled as array .+ (-scalar)
376 1 case Op.SUB_ARRAY_SCALAR algorithm negate := true; then DAE.ADD_ARRAY_SCALAR(ty);
377 346 case Op.MUL_SCALAR_ARRAY algorithm swapArguments := true; then DAE.MUL_ARRAY_SCALAR(ty);
378 159 case Op.MUL_ARRAY_SCALAR then DAE.MUL_ARRAY_SCALAR(ty);
379 ✗ case Op.MUL_VECTOR_MATRIX then DAE.MUL_MATRIX_PRODUCT(ty);
380 68 case Op.MUL_MATRIX_VECTOR then DAE.MUL_MATRIX_PRODUCT(ty);
381 405 case Op.SCALAR_PRODUCT then DAE.MUL_SCALAR_PRODUCT(ty);
382 8 case Op.ADD_EW then DAE.ADD_ARR(ty);
383 44 case Op.SUB_EW then DAE.SUB_ARR(ty);
384 38 case Op.MUL_EW then DAE.MUL_ARR(ty);
385 ✗ case Op.DIV_EW then DAE.DIV_ARR(ty);
386 156 case Op.MATRIX_PRODUCT then DAE.MUL_MATRIX_PRODUCT(ty);
387 ✗ case Op.DIV_SCALAR_ARRAY then DAE.DIV_SCALAR_ARRAY(ty);
388 215 case Op.DIV_ARRAY_SCALAR then DAE.DIV_ARRAY_SCALAR(ty);
389 ✗ case Op.POW_SCALAR_ARRAY then DAE.POW_SCALAR_ARRAY(ty);
390 18 case Op.POW_ARRAY_SCALAR then DAE.POW_ARRAY_SCALAR(ty);
391 4 case Op.POW_MATRIX then DAE.POW_ARR(ty);
392
2/2
✓ Branch 1 taken 328 times.
✓ Branch 2 taken 27115 times.
27443 case Op.UMINUS then if Type.isArray(op.ty) then DAE.UMINUS_ARR(ty) else DAE.UMINUS(ty);
393 2669 case Op.AND then DAE.AND(ty);
394 1133 case Op.OR then DAE.OR(ty);
395 920 case Op.NOT then DAE.NOT(ty);
396 4657 case Op.LESS then DAE.LESS(ty);
397 2324 case Op.LESSEQ then DAE.LESSEQ(ty);
398 5411 case Op.GREATER then DAE.GREATER(ty);
399 3458 case Op.GREATEREQ then DAE.GREATEREQ(ty);
400 3028 case Op.EQUAL then DAE.EQUAL(ty);
401 687 case Op.NEQUAL then DAE.NEQUAL(ty);
402 else
403 algorithm
404 ✗ Error.terminate(getInstanceName() + " got unknown type: " + opToString(op.op), sourceInfo());
405 ✗ then
406 fail();
407 end match;
408 end toDAE;
409
410 function typeOf
411 input Operator op;
412 output Type ty = op.ty;
413 end typeOf;
414
415 function setType
416 input Type ty;
417 input output Operator op;
418 algorithm
419 122733 op.ty := ty;
420 end setType;
421
422 function scalarize
423 input output Operator op;
424 algorithm
425 51364 op.ty := Type.arrayElementType(op.ty);
426 end scalarize;
427
428 function unlift
429 input output Operator op;
430 algorithm
431 995 op.ty := Type.unliftArray(op.ty);
432 end unlift;
433
434 function symbol
435 input Operator op;
436 input String spacing = " ";
437 output String symbol;
438 algorithm
439 symbol := match op.op
440 case Op.ADD then "+";
441 case Op.SUB then "-";
442 case Op.MUL then "*";
443 case Op.DIV then "/";
444 case Op.POW then "^";
445 case Op.ADD_EW then ".+";
446 case Op.SUB_EW then ".-";
447 case Op.MUL_EW then ".*";
448 case Op.DIV_EW then "./";
449 case Op.POW_EW then ".^";
450 case Op.ADD_SCALAR_ARRAY then ".+";
451 case Op.ADD_ARRAY_SCALAR then ".+";
452 case Op.SUB_SCALAR_ARRAY then ".-";
453 case Op.SUB_ARRAY_SCALAR then ".-";
454 case Op.MUL_SCALAR_ARRAY then "*";
455 case Op.MUL_ARRAY_SCALAR then ".*";
456 case Op.MUL_VECTOR_MATRIX then "*";
457 case Op.MUL_MATRIX_VECTOR then "*";
458 case Op.SCALAR_PRODUCT then "*";
459 case Op.MATRIX_PRODUCT then "*";
460 case Op.DIV_SCALAR_ARRAY then "./";
461 case Op.DIV_ARRAY_SCALAR then "/";
462 case Op.POW_SCALAR_ARRAY then ".^";
463 case Op.POW_ARRAY_SCALAR then ".^";
464 case Op.POW_MATRIX then "^";
465 case Op.UMINUS then "-";
466 case Op.AND then "and";
467 case Op.OR then "or";
468 case Op.NOT then "not";
469 case Op.LESS then "<";
470 case Op.LESSEQ then "<=";
471 case Op.GREATER then ">";
472 case Op.GREATEREQ then ">=";
473 case Op.EQUAL then "==";
474 case Op.NEQUAL then "<>";
475 //case Op.USERDEFINED then "Userdefined:" + AbsynUtil.pathString(op.fqName);
476 else
477 algorithm
478 ✗ Error.terminate(getInstanceName() + " got unknown type.", sourceInfo());
479 ✗ then
480 fail();
481 end match;
482
483 72920 symbol := spacing + symbol + spacing;
484 end symbol;
485
486 function toJSON
487 input Operator operator;
488 output JSON json;
489 protected
490 constant array<JSON> symbols = MetaModelica.Dangerous.listArrayLiteral({
491 JSON.STRING("+"),
492 JSON.STRING("-"),
493 JSON.STRING("*"),
494 JSON.STRING("/"),
495 JSON.STRING("^"),
496 JSON.STRING(".+"),
497 JSON.STRING(".-"),
498 JSON.STRING(".*"),
499 JSON.STRING("./"),
500 JSON.STRING(".^"),
501 JSON.STRING(".+"),
502 JSON.STRING(".+"),
503 JSON.STRING(".-"),
504 JSON.STRING(".-"),
505 JSON.STRING("*"),
506 JSON.STRING(".*"),
507 JSON.STRING("*"),
508 JSON.STRING("*"),
509 JSON.STRING("*"),
510 JSON.STRING("*"),
511 JSON.STRING("./"),
512 JSON.STRING("/"),
513 JSON.STRING(".^"),
514 JSON.STRING(".^"),
515 JSON.STRING("^"),
516 JSON.STRING("-"),
517 JSON.STRING("and"),
518 JSON.STRING("or"),
519 JSON.STRING("not"),
520 JSON.STRING("<"),
521 JSON.STRING("<="),
522 JSON.STRING(">"),
523 JSON.STRING(">="),
524 JSON.STRING("=="),
525 JSON.STRING("<>")
526 });
527
528 Op op = operator.op;
529 algorithm
530 3 json := symbols[Integer(op)];
531 end toJSON;
532
533 function priority
534 input Operator op;
535 input Boolean lhs;
536 output Integer priority;
537 algorithm
538 priority := match op.op
539
2/2
✓ Branch 0 taken 17547 times.
✓ Branch 1 taken 3573 times.
21120 case Op.ADD then if lhs then 5 else 6;
540 case Op.SUB then 5;
541 case Op.MUL then 2;
542 case Op.DIV then 2;
543 case Op.POW then 1;
544
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 case Op.ADD_EW then if lhs then 5 else 6;
545 case Op.SUB_EW then 5;
546
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 case Op.MUL_EW then if lhs then 2 else 3;
547 case Op.DIV_EW then 2;
548 case Op.POW_EW then 1;
549 ✗ case Op.ADD_SCALAR_ARRAY then if lhs then 5 else 6;
550 ✗ case Op.ADD_ARRAY_SCALAR then if lhs then 5 else 6;
551 case Op.SUB_SCALAR_ARRAY then 5;
552 case Op.SUB_ARRAY_SCALAR then 5;
553
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 case Op.MUL_SCALAR_ARRAY then if lhs then 2 else 3;
554
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 case Op.MUL_ARRAY_SCALAR then if lhs then 2 else 3;
555 ✗ case Op.MUL_VECTOR_MATRIX then if lhs then 2 else 3;
556
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 case Op.MUL_MATRIX_VECTOR then if lhs then 2 else 3;
557
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 54 times.
120 case Op.SCALAR_PRODUCT then if lhs then 2 else 3;
558
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
17 case Op.MATRIX_PRODUCT then if lhs then 2 else 3;
559 case Op.DIV_SCALAR_ARRAY then 2;
560 case Op.DIV_ARRAY_SCALAR then 2;
561 case Op.POW_SCALAR_ARRAY then 1;
562 case Op.POW_ARRAY_SCALAR then 1;
563 case Op.POW_MATRIX then 1;
564 case Op.AND then 8;
565 case Op.OR then 9;
566 else 0;
567 end match;
568 end priority;
569
570 function isAssociative
571 input Operator op;
572 output Boolean isAssociative;
573 algorithm
574 isAssociative := match op.op
575 case Op.ADD then true;
576 case Op.ADD_EW then true;
577 //case ADD_ARRAY_SCALAR() then true;
578 case Op.MUL_EW then true;
579 //case MUL_ARRAY_SCALAR() then true;
580 else false;
581 end match;
582 end isAssociative;
583
584 function isNonAssociative
585 input Operator op;
586 output Boolean isNonAssociative;
587 algorithm
588 isNonAssociative := match op.op
589 case Op.POW then true;
590 case Op.POW_EW then true;
591 case Op.POW_SCALAR_ARRAY then true;
592 case Op.POW_ARRAY_SCALAR then true;
593 case Op.POW_MATRIX then true;
594 else false;
595 end match;
596 end isNonAssociative;
597
598 function makeAdd
599 input Type ty;
600 output Operator op = OPERATOR(ty, Op.ADD);
601 end makeAdd;
602
603 function makeSub
604 input Type ty;
605 output Operator op = OPERATOR(ty, Op.SUB);
606 end makeSub;
607
608 function makeMul
609 input Type ty;
610 output Operator op = OPERATOR(ty, Op.MUL);
611 end makeMul;
612
613 function makeScalarProduct
614 input Type ty;
615 output Operator op = OPERATOR(ty, Op.SCALAR_PRODUCT);
616 end makeScalarProduct;
617
618 function makeDiv
619 input Type ty;
620 output Operator op = OPERATOR(ty, Op.DIV);
621 end makeDiv;
622
623 function makePow
624 input Type ty;
625 output Operator op = OPERATOR(ty, Op.POW);
626 end makePow;
627
628 function makeAddEW
629 input Type ty;
630 output Operator op = OPERATOR(ty, Op.ADD_EW);
631 end makeAddEW;
632
633 function makeSubEW
634 input Type ty;
635 output Operator op = OPERATOR(ty, Op.SUB_EW);
636 end makeSubEW;
637
638 function makeMulEW
639 input Type ty;
640 output Operator op = OPERATOR(ty, Op.MUL_EW);
641 end makeMulEW;
642
643 function makeDivEW
644 input Type ty;
645 output Operator op = OPERATOR(ty, Op.DIV_EW);
646 end makeDivEW;
647
648 function makeUMinus
649 input Type ty;
650 output Operator op = OPERATOR(ty, Op.UMINUS);
651 end makeUMinus;
652
653 function makeAnd
654 input Type ty;
655 output Operator op = OPERATOR(ty, Op.AND);
656 end makeAnd;
657
658 function makeOr
659 input Type ty;
660 output Operator op = OPERATOR(ty, Op.OR);
661 end makeOr;
662
663 function makeNot
664 input Type ty;
665 output Operator op = OPERATOR(ty, Op.NOT);
666 end makeNot;
667
668 function makeLess
669 input Type ty;
670 output Operator op = OPERATOR(ty, Op.LESS);
671 end makeLess;
672
673 function makeLessEq
674 input Type ty;
675 output Operator op = OPERATOR(ty, Op.LESSEQ);
676 end makeLessEq;
677
678 function makeGreater
679 input Type ty;
680 output Operator op = OPERATOR(ty, Op.GREATER);
681 end makeGreater;
682
683 function makeGreaterEq
684 input Type ty;
685 output Operator op = OPERATOR(ty, Op.GREATEREQ);
686 end makeGreaterEq;
687
688 function makeEqual
689 input Type ty;
690 output Operator op = OPERATOR(ty, Op.EQUAL);
691 end makeEqual;
692
693 function makeNotEqual
694 input Type ty;
695 output Operator op = OPERATOR(ty, Op.NEQUAL);
696 end makeNotEqual;
697
698 function makeScalarArray
699 input Type ty;
700 input Op op;
701 output Operator outOp;
702 protected
703 Op o;
704 algorithm
705 o := match op
706 case Op.ADD then Op.ADD_SCALAR_ARRAY;
707 case Op.SUB then Op.SUB_SCALAR_ARRAY;
708 case Op.MUL then Op.MUL_SCALAR_ARRAY;
709 case Op.DIV then Op.DIV_SCALAR_ARRAY;
710 case Op.POW then Op.POW_SCALAR_ARRAY;
711 end match;
712
713 13 outOp := OPERATOR(ty, o);
714 end makeScalarArray;
715
716 function makeArrayScalar
717 input Type ty;
718 input Op op;
719 output Operator outOp;
720 protected
721 Op o;
722 algorithm
723 o := match op
724 case Op.ADD then Op.ADD_ARRAY_SCALAR;
725 case Op.SUB then Op.SUB_ARRAY_SCALAR;
726 case Op.MUL then Op.MUL_ARRAY_SCALAR;
727 case Op.DIV then Op.DIV_ARRAY_SCALAR;
728 case Op.POW then Op.POW_ARRAY_SCALAR;
729 end match;
730
731 12 outOp := OPERATOR(ty, o);
732 end makeArrayScalar;
733
734 function makeEW
735 input output Operator op;
736 algorithm
737 () := match op.op
738 ✗ case Op.ADD algorithm op.op := Op.ADD_EW; then ();
739 ✗ case Op.SUB algorithm op.op := Op.SUB_EW; then ();
740 111 case Op.MUL algorithm op.op := Op.MUL_EW; then ();
741 ✗ case Op.DIV algorithm op.op := Op.DIV_EW; then ();
742 ✗ case Op.POW algorithm op.op := Op.POW_EW; then ();
743 else ();
744 end match;
745 end makeEW;
746
747 function stripEW
748 input output Operator op;
749 algorithm
750 () := match op.op
751 ✗ case Op.ADD_EW algorithm op.op := Op.ADD; then ();
752 ✗ case Op.SUB_EW algorithm op.op := Op.SUB; then ();
753 8 case Op.MUL_EW algorithm op.op := Op.MUL; then ();
754 ✗ case Op.DIV_EW algorithm op.op := Op.DIV; then ();
755 ✗ case Op.POW_EW algorithm op.op := Op.POW; then ();
756 else ();
757 end match;
758 end stripEW;
759
760 function isElementWise
761 input Operator op;
762 output Boolean ew;
763 algorithm
764 ew := match op.op
765 case Op.ADD_EW then true;
766 case Op.SUB_EW then true;
767 case Op.MUL_EW then true;
768 case Op.DIV_EW then true;
769 case Op.POW_EW then true;
770 else false;
771 end match;
772 end isElementWise;
773
774 type MathClassification = enumeration(ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION, POWER, LOGICAL, RELATION);
775 type SizeClassification = enumeration(SCALAR, ELEMENT_WISE, ARRAY_SCALAR, SCALAR_ARRAY, MATRIX, VECTOR_MATRIX, MATRIX_VECTOR, LOGICAL, RELATION);
776 type Classification = tuple<MathClassification, SizeClassification>;
777
778 function mathSymbol
779 input MathClassification mcl;
780 output String str;
781 algorithm
782 str := match mcl
783 case MathClassification.ADDITION then "+";
784 case MathClassification.SUBTRACTION then "-";
785 case MathClassification.MULTIPLICATION then "*";
786 case MathClassification.DIVISION then "/";
787 case MathClassification.POWER then "^";
788 case MathClassification.LOGICAL then "L";
789 case MathClassification.RELATION then "R";
790 else fail();
791 end match;
792 end mathSymbol;
793
794 function classificationString
795 input Classification cla;
796 output String str;
797 protected
798 MathClassification mcl;
799 SizeClassification scl;
800 algorithm
801 ✗ (mcl, scl) := cla;
802 ✗ str := mathClassificationString(mcl) + sizeClassificationString(scl);
803 end classificationString;
804
805 function mathClassificationString
806 input MathClassification mcl;
807 output String str;
808 algorithm
809 str := match mcl
810 case MathClassification.ADDITION then "[ADD]";
811 case MathClassification.SUBTRACTION then "[SUB]";
812 case MathClassification.MULTIPLICATION then "[MUL]";
813 case MathClassification.DIVISION then "[DIV]";
814 case MathClassification.POWER then "[POW]";
815 case MathClassification.LOGICAL then "[LOG]";
816 case MathClassification.RELATION then "[REL]";
817 else fail();
818 end match;
819 end mathClassificationString;
820
821 function sizeClassificationString
822 input SizeClassification scl;
823 output String str;
824 algorithm
825 str := match scl
826 case SizeClassification.SCALAR then "[SCALAR]";
827 case SizeClassification.ELEMENT_WISE then "[ELMWIS]";
828 case SizeClassification.ARRAY_SCALAR then "[ARR-SC]";
829 case SizeClassification.SCALAR_ARRAY then "[SC-ARR]";
830 case SizeClassification.MATRIX then "[MATRIX]";
831 case SizeClassification.VECTOR_MATRIX then "[VEC-MA]";
832 case SizeClassification.MATRIX_VECTOR then "[MA-VEC]";
833 case SizeClassification.LOGICAL then "[LOGICL]";
834 case SizeClassification.RELATION then "[RELATN]";
835 else fail();
836 end match;
837 end sizeClassificationString;
838
839 function classify
840 input Operator op;
841 output Classification cl;
842 algorithm
843 cl := match op.op
844 case Op.ADD then (MathClassification.ADDITION, SizeClassification.SCALAR);
845 case Op.SUB then (MathClassification.SUBTRACTION, SizeClassification.SCALAR);
846 case Op.MUL then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR);
847 case Op.DIV then (MathClassification.DIVISION, SizeClassification.SCALAR);
848 case Op.POW then (MathClassification.POWER, SizeClassification.SCALAR);
849 case Op.ADD_EW then (MathClassification.ADDITION, SizeClassification.ELEMENT_WISE);
850 case Op.SUB_EW then (MathClassification.SUBTRACTION, SizeClassification.ELEMENT_WISE);
851 case Op.MUL_EW then (MathClassification.MULTIPLICATION, SizeClassification.ELEMENT_WISE);
852 case Op.DIV_EW then (MathClassification.DIVISION, SizeClassification.ELEMENT_WISE);
853 case Op.POW_EW then (MathClassification.POWER, SizeClassification.ELEMENT_WISE);
854 case Op.MUL_ARRAY_SCALAR then (MathClassification.MULTIPLICATION, SizeClassification.ARRAY_SCALAR);
855 case Op.MUL_SCALAR_ARRAY then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR_ARRAY);
856 case Op.ADD_ARRAY_SCALAR then (MathClassification.ADDITION, SizeClassification.ARRAY_SCALAR);
857 case Op.ADD_SCALAR_ARRAY then (MathClassification.ADDITION, SizeClassification.SCALAR_ARRAY);
858 case Op.SUB_ARRAY_SCALAR then (MathClassification.SUBTRACTION, SizeClassification.ARRAY_SCALAR);
859 case Op.SUB_SCALAR_ARRAY then (MathClassification.SUBTRACTION, SizeClassification.SCALAR_ARRAY);
860 case Op.SCALAR_PRODUCT then (MathClassification.MULTIPLICATION, SizeClassification.SCALAR);
861 case Op.MATRIX_PRODUCT then (MathClassification.MULTIPLICATION, SizeClassification.MATRIX);
862 case Op.MUL_VECTOR_MATRIX then (MathClassification.MULTIPLICATION, SizeClassification.VECTOR_MATRIX);
863 case Op.MUL_MATRIX_VECTOR then (MathClassification.MULTIPLICATION, SizeClassification.MATRIX_VECTOR);
864 case Op.DIV_ARRAY_SCALAR then (MathClassification.DIVISION, SizeClassification.ARRAY_SCALAR);
865 case Op.DIV_SCALAR_ARRAY then (MathClassification.DIVISION, SizeClassification.SCALAR_ARRAY);
866 case Op.POW_ARRAY_SCALAR then (MathClassification.POWER, SizeClassification.ARRAY_SCALAR);
867 case Op.POW_SCALAR_ARRAY then (MathClassification.POWER, SizeClassification.SCALAR_ARRAY);
868 case Op.POW_MATRIX then (MathClassification.POWER, SizeClassification.MATRIX);
869 case Op.AND then (MathClassification.LOGICAL, SizeClassification.LOGICAL);
870 case Op.OR then (MathClassification.LOGICAL, SizeClassification.LOGICAL);
871 case Op.NOT then (MathClassification.LOGICAL, SizeClassification.LOGICAL);
872 case Op.LESS then (MathClassification.RELATION, SizeClassification.RELATION);
873 case Op.LESSEQ then (MathClassification.RELATION, SizeClassification.RELATION);
874 case Op.GREATER then (MathClassification.RELATION, SizeClassification.RELATION);
875 case Op.GREATEREQ then (MathClassification.RELATION, SizeClassification.RELATION);
876 case Op.EQUAL then (MathClassification.RELATION, SizeClassification.RELATION);
877 case Op.NEQUAL then (MathClassification.RELATION, SizeClassification.RELATION);
878 else algorithm
879 ✗ Error.addInternalError(getInstanceName() + ": Don't know how to handle " + String(op.op), sourceInfo());
880 ✗ then fail();
881 end match;
882 end classify;
883
884 function classifyAddition
885 "used to create an addition of the resulting type.
886 Note: not to be used for logical or relations"
887 input Operator op;
888 output SizeClassification sz = if Type.isScalar(op.ty) then SizeClassification.SCALAR else SizeClassification.ELEMENT_WISE;
889 end classifyAddition;
890
891 function fromClassification
892 "Only works for non-logical operators!"
893 input Classification cl "mathematical and size classification";
894 input Type ty "Type information";
895 output Operator result "Resulting operator";
896 protected
897 Op op;
898 algorithm
899 op := match cl
900 case (MathClassification.ADDITION, SizeClassification.SCALAR) then Op.ADD;
901 case (MathClassification.SUBTRACTION, SizeClassification.SCALAR) then Op.SUB;
902 case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR) then Op.MUL;
903 // this has to be done correctly. use type of the expressions?
904 //case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR) then Op.SCALAR_PRODUCT;
905 case (MathClassification.DIVISION, SizeClassification.SCALAR) then Op.DIV;
906 case (MathClassification.POWER, SizeClassification.SCALAR) then Op.POW;
907
908 case (MathClassification.ADDITION, SizeClassification.ELEMENT_WISE) then Op.ADD_EW;
909 case (MathClassification.SUBTRACTION, SizeClassification.ELEMENT_WISE) then Op.SUB_EW;
910 case (MathClassification.MULTIPLICATION, SizeClassification.ELEMENT_WISE) then Op.MUL_EW;
911 case (MathClassification.DIVISION, SizeClassification.ELEMENT_WISE) then Op.DIV_EW;
912 case (MathClassification.POWER, SizeClassification.ELEMENT_WISE) then Op.POW_EW;
913
914 case (MathClassification.ADDITION, SizeClassification.ARRAY_SCALAR) then Op.ADD_ARRAY_SCALAR;
915 case (MathClassification.SUBTRACTION, SizeClassification.ARRAY_SCALAR) then Op.SUB_ARRAY_SCALAR;
916 case (MathClassification.MULTIPLICATION, SizeClassification.ARRAY_SCALAR) then Op.MUL_ARRAY_SCALAR;
917 case (MathClassification.DIVISION, SizeClassification.ARRAY_SCALAR) then Op.DIV_ARRAY_SCALAR;
918 case (MathClassification.POWER, SizeClassification.ARRAY_SCALAR) then Op.POW_ARRAY_SCALAR;
919
920 case (MathClassification.ADDITION, SizeClassification.SCALAR_ARRAY) then Op.ADD_SCALAR_ARRAY;
921 case (MathClassification.SUBTRACTION, SizeClassification.SCALAR_ARRAY) then Op.SUB_SCALAR_ARRAY;
922 case (MathClassification.MULTIPLICATION, SizeClassification.SCALAR_ARRAY) then Op.MUL_SCALAR_ARRAY;
923 case (MathClassification.DIVISION, SizeClassification.SCALAR_ARRAY) then Op.DIV_SCALAR_ARRAY;
924 case (MathClassification.POWER, SizeClassification.SCALAR_ARRAY) then Op.POW_SCALAR_ARRAY;
925
926 case (MathClassification.ADDITION, SizeClassification.MATRIX) then Op.ADD_EW;
927 case (MathClassification.SUBTRACTION, SizeClassification.MATRIX) then Op.SUB_EW;
928 case (MathClassification.POWER, SizeClassification.MATRIX) then Op.POW_MATRIX;
929 case (MathClassification.MULTIPLICATION, SizeClassification.MATRIX) then Op.MATRIX_PRODUCT;
930 case (MathClassification.MULTIPLICATION, SizeClassification.VECTOR_MATRIX) then Op.MUL_VECTOR_MATRIX;
931 case (MathClassification.MULTIPLICATION, SizeClassification.MATRIX_VECTOR) then Op.MUL_MATRIX_VECTOR;
932 else algorithm
933 ✗ Error.addInternalError(getInstanceName() + ": Don't know how to handle math class and size class combination: " + classificationString(cl), sourceInfo());
934 ✗ then fail();
935 end match;
936 62288 result := OPERATOR(ty, op);
937 end fromClassification;
938
939 function getMathClassification
940 input Operator op;
941 output MathClassification mcl;
942 algorithm
943 189395 (mcl, _) := classify(op);
944 end getMathClassification;
945
946 function getSizeClassification
947 input Operator op;
948 output SizeClassification scl;
949 algorithm
950 681 (_, scl) := classify(op);
951 end getSizeClassification;
952
953 function combineSizeClassification
954 input SizeClassification scl1;
955 input SizeClassification scl2;
956 output SizeClassification scl;
957 algorithm
958 scl := match (scl1, scl2)
959 // Todo: more cases?
960 case (SizeClassification.ELEMENT_WISE, SizeClassification.SCALAR) then SizeClassification.ARRAY_SCALAR;
961 case (SizeClassification.SCALAR, SizeClassification.ELEMENT_WISE) then SizeClassification.SCALAR_ARRAY;
962 else scl1;
963 end match;
964 end combineSizeClassification;
965
966 function isDashClassification
967 input MathClassification mcl;
968 output Boolean b;
969 algorithm
970 b := match mcl
971 case MathClassification.ADDITION then true;
972 case MathClassification.SUBTRACTION then true;
973 else false;
974 end match;
975 end isDashClassification;
976
977 function isCommutative
978 "returns true for operators that are commutative"
979 input Operator operator;
980 output Boolean b;
981 algorithm
982 b := match Type.arrayElementType(operator.ty)
983 case Type.INTEGER() then true;
984 case Type.REAL() then true;
985 case Type.BOOLEAN() then true;
986 else false;
987 end match;
988 56 if not b then return; end if;
989
990 b := match operator.op
991 case Op.ADD then true;
992 case Op.MUL then true;
993 case Op.ADD_EW then true;
994 case Op.MUL_EW then true;
995 // the following might need adaption since they depend on argument ordering
996 // furthermore weird regarding more than two arguments in Expression.MULTARY()
997 case Op.ADD_SCALAR_ARRAY then true;
998 case Op.ADD_ARRAY_SCALAR then true;
999 case Op.MUL_SCALAR_ARRAY then true;
1000 case Op.MUL_ARRAY_SCALAR then true;
1001 else false;
1002 end match;
1003 end isCommutative;
1004
1005 function isSoftCommutative
1006 "returns true for operators that are not commutative but have an easy rule for swapping arguments"
1007 input Operator operator;
1008 output Boolean b;
1009 algorithm
1010 b := match operator.op
1011 case Op.SUB then true;
1012 case Op.DIV then true;
1013 case Op.SUB_EW then true;
1014 case Op.DIV_EW then true;
1015 // the following might need adaption since they depend on argument ordering
1016 // furthermore weird regarding more than two arguments in Expression.MULTARY()
1017 case Op.SUB_SCALAR_ARRAY then true;
1018 case Op.SUB_ARRAY_SCALAR then true;
1019 case Op.DIV_SCALAR_ARRAY then true;
1020 case Op.DIV_ARRAY_SCALAR then true;
1021 else false;
1022 end match;
1023 end isSoftCommutative;
1024
1025 function repetition
1026 input Operator operator;
1027 output tuple<Boolean, Boolean> b;
1028 algorithm
1029 b := match operator.op
1030 case Op.ADD_SCALAR_ARRAY then (true, false);
1031 case Op.ADD_ARRAY_SCALAR then (false, true);
1032 case Op.MUL_SCALAR_ARRAY then (true, false);
1033 case Op.MUL_ARRAY_SCALAR then (false, true);
1034 case Op.MUL_VECTOR_MATRIX then (true, true);
1035 case Op.MUL_MATRIX_VECTOR then (true, true);
1036 case Op.MATRIX_PRODUCT then (true, true);
1037 else (false, false);
1038 end match;
1039 end repetition;
1040
1041 function reduction
1042 input Operator operator;
1043 output Boolean b;
1044 algorithm
1045 b := match operator.op
1046 case Op.MUL_MATRIX_VECTOR then true;
1047 case Op.MUL_VECTOR_MATRIX then true;
1048 case Op.MATRIX_PRODUCT then true;
1049 case Op.SCALAR_PRODUCT then true;
1050 else false;
1051 end match;
1052 end reduction;
1053
1054 function isCombineable
1055 input Operator op1;
1056 input Operator op2;
1057 output Boolean b;
1058 protected
1059 MathClassification mcl1, mcl2;
1060 SizeClassification scl1, scl2;
1061 algorithm
1062 3466 (mcl1, scl1) := classify(op1);
1063 3466 (mcl2, scl2) := classify(op2);
1064
4/4
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 3425 times.
✓ Branch 4 taken 38 times.
✓ Branch 5 taken 3 times.
3466 b := isCombineableMath(mcl1, mcl2) and isCombineableSize(scl1, scl2);
1065 if b then
1066
3/4
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 24 times.
38 b := not (isScalarProduct(op1) or isScalarProduct(op2));
1067 end if;
1068 end isCombineable;
1069
1070 function isCombineableMath
1071 input MathClassification mcl1;
1072 input MathClassification mcl2;
1073 output Boolean b;
1074 algorithm
1075
6/6
✓ Branch 0 taken 3449 times.
✓ Branch 1 taken 17 times.
✓ Branch 3 taken 1861 times.
✓ Branch 4 taken 1588 times.
✓ Branch 6 taken 24 times.
✓ Branch 7 taken 1837 times.
3466 b := mcl1 == mcl2 or (isDashClassification(mcl1) and isDashClassification(mcl2));
1076 end isCombineableMath;
1077
1078 function isCombineableSize
1079 input SizeClassification scl1;
1080 input SizeClassification scl2;
1081 output Boolean b;
1082 algorithm
1083 41 b := scl1 == scl2;
1084 end isCombineableSize;
1085
1086 function toDebugString
1087 input Operator op;
1088 output String str;
1089 algorithm
1090 ✗ str := "OPERATOR(" + Type.toString(op.ty) + ", " + opToString(op.op) + ")";
1091 end toDebugString;
1092
1093 function opToString
1094 input Op op;
1095 output String str;
1096 algorithm
1097 str := match op
1098 case Op.ADD then "ADD";
1099 case Op.SUB then "SUB";
1100 case Op.MUL then "MUL";
1101 case Op.DIV then "DIV";
1102 case Op.POW then "POW";
1103 case Op.ADD_EW then "ADD_EW";
1104 case Op.SUB_EW then "SUB_EW";
1105 case Op.MUL_EW then "MUL_EW";
1106 case Op.DIV_EW then "DIV_EW";
1107 case Op.POW_EW then "POW_EW";
1108 case Op.ADD_SCALAR_ARRAY then "ADD_SCALAR_ARRAY";
1109 case Op.ADD_ARRAY_SCALAR then "ADD_ARRAY_SCALAR";
1110 case Op.SUB_SCALAR_ARRAY then "SUB_SCALAR_ARRAY";
1111 case Op.SUB_ARRAY_SCALAR then "SUB_ARRAY_SCALAR";
1112 case Op.MUL_SCALAR_ARRAY then "MUL_SCALAR_ARRAY";
1113 case Op.MUL_ARRAY_SCALAR then "MUL_ARRAY_SCALAR";
1114 case Op.MUL_VECTOR_MATRIX then "MUL_VECTOR_MATRIX";
1115 case Op.MUL_MATRIX_VECTOR then "MUL_MATRIX_VECTOR";
1116 case Op.SCALAR_PRODUCT then "SCALAR_PRODUCT";
1117 case Op.MATRIX_PRODUCT then "MATRIX_PRODUCT";
1118 case Op.DIV_SCALAR_ARRAY then "DIV_SCALAR_ARRAY";
1119 case Op.DIV_ARRAY_SCALAR then "DIV_ARRAY_SCALAR";
1120 case Op.POW_SCALAR_ARRAY then "POW_SCALAR_ARRAY";
1121 case Op.POW_ARRAY_SCALAR then "POW_ARRAY_SCALAR";
1122 case Op.POW_MATRIX then "POW_MATRIX";
1123 case Op.UMINUS then "UMINUS";
1124 case Op.AND then "AND";
1125 case Op.OR then "OR";
1126 case Op.NOT then "NOT";
1127 case Op.LESS then "LESS";
1128 case Op.LESSEQ then "LESSEQ";
1129 case Op.GREATER then "GREATER";
1130 case Op.GREATEREQ then "GREATEREQ";
1131 case Op.EQUAL then "EQUAL";
1132 case Op.NEQUAL then "NEQUAL";
1133 case Op.USERDEFINED then "USERDEFINED";
1134 else algorithm
1135 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + "failed. Unhanded enumeration."});
1136 ✗ then fail();
1137 end match;
1138 end opToString;
1139
1140 annotation(__OpenModelica_Interface="nf_frontend");
1141 end NFOperator;
1142