Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 61.5% 75 / 0 / 122
Functions: -% 0 / 1 / 1
Branches: 46.7% 14 / 0 / 30

OMCompiler/Compiler/NFFrontEnd/NFDimension.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 NFDimension
37 protected
38 import Absyn;
39 import Dimension = NFDimension;
40 import DAE;
41 import Dump;
42 import Operator = NFOperator;
43 import Prefixes = NFPrefixes;
44 import List;
45 import SimplifyExp = NFSimplifyExp;
46 import Ceval = NFCeval;
47
48 public
49 import BaseModelica;
50 import Absyn.{Exp, Path, Subscript};
51 import Class = NFClass;
52 import Expression = NFExpression;
53 import NFInstNode.InstNode;
54 import NFInstNode;
55 import Type = NFType;
56 import ComponentRef = NFComponentRef;
57 import NFPrefixes.Variability;
58 import Inst = NFInst;
59 import NFCeval.EvalTarget;
60
61 record RAW_DIM
62 Absyn.Subscript dim;
63 NFInstNode.ScopeRef scope "Weakly: the class tree owns the scope this
64 dimension was written in.";
65 end RAW_DIM;
66
67 record UNTYPED
68 Expression dimension;
69 Boolean isProcessing;
70 end UNTYPED;
71
72 record INTEGER
73 Integer size;
74 Variability var;
75 end INTEGER;
76
77 record BOOLEAN
78 end BOOLEAN;
79
80 record ENUM
81 Type enumType;
82 end ENUM;
83
84 record EXP
85 Expression exp;
86 Variability var;
87 end EXP;
88
89 record RESIZABLE
90 "for all symbolic purposes this is INTEGER() for codegeneration it is EXP()
91 invoked by using annotation(__OpenModelica_resizable=true) on a parameter"
92 Integer size "the actual size defined by the user";
93 Option<Integer> opt_size "the optimal size determined by the backend";
94 Expression exp "the full expression (parameter)";
95 Variability var;
96 end RESIZABLE;
97
98 record UNKNOWN
99 end UNKNOWN;
100
101 function fromExp
102 input Expression exp;
103 input Variability var;
104 output Dimension dim;
105 algorithm
106 dim := match exp
107 local
108 Expression exp_simple, e1, e2;
109 Integer value, value_original;
110 Type ty;
111
112 179261 case Expression.INTEGER() then INTEGER(exp.value, var);
113
114 case Expression.TYPENAME(ty = Type.ARRAY(elementType = ty))
115 then
116 match ty
117 case Type.BOOLEAN() then BOOLEAN();
118 51 case Type.ENUMERATION() then ENUM(ty);
119 else
120 algorithm
121 ✗ Error.terminate(getInstanceName() + " got invalid typename", sourceInfo());
122 ✗ then
123 fail();
124 end match;
125
126 case Expression.ARRAY()
127 guard Expression.arrayAllEqual(exp)
128 ✗ then fromExp(Expression.arrayFirstScalar(exp), var);
129
130 case Expression.SUBSCRIPTED_EXP(split = true)
131 guard Expression.isArray(exp.exp) and Expression.arrayAllEqual(exp.exp)
132 1 then fromExp(Expression.arrayFirstScalar(exp.exp), var);
133
134 else algorithm
135 26305 exp_simple := SimplifyExp.simplify(exp);
136 then match exp_simple
137 // if it can be simplified to an integer its just an integer
138 559 case Expression.INTEGER(value) then INTEGER(value, var);
139 // if it can be simplified to an integer after replacing resizables its resizable
140 else algorithm
141 25746 e1 := Expression.map(exp_simple, Expression.replaceResizableParameter);
142 25746 e1 := SimplifyExp.simplify(e1);
143 then match e1
144 case Expression.INTEGER(value) algorithm
145 // if replacing the body with original yields another solution, it has already been resized
146 704 e2 := Expression.map(exp_simple, Expression.replaceResizableParameterWithOriginal);
147 704 e2 := SimplifyExp.simplify(e2);
148 then match e2
149 ✗ case Expression.INTEGER(value_original) guard(value <> value_original) then RESIZABLE(value_original, SOME(value), exp, var);
150 704 else RESIZABLE(value, NONE(), exp, var);
151 end match;
152 // otherwise it is just an expression
153 25042 else EXP(exp, var);
154 end match;
155 end match;
156 end match;
157 end fromExp;
158
159 function fromRange
160 input Expression range "needs to be RANGE()";
161 output Dimension dim;
162 protected
163 Integer start, step, stop;
164 algorithm
165 (start, step, stop) := match range
166 case Expression.RANGE(start = Expression.INTEGER(start),
167 step = NONE(),
168 stop = Expression.INTEGER(stop))
169 then (start, 1, stop);
170 case Expression.RANGE(start = Expression.INTEGER(start),
171 step = SOME(Expression.INTEGER(step)),
172 stop = Expression.INTEGER(stop))
173 then (start, step, stop);
174 else algorithm
175 ✗ Error.terminate(getInstanceName() + " got non-range expression: " + Expression.toString(range), sourceInfo());
176 ✗ then fail();
177 end match;
178
179 ✗ dim := INTEGER(intDiv(stop-start, step) + 1, NFPrefixes.Variability.CONSTANT);
180 end fromRange;
181
182 function fromInteger
183 input Integer n;
184 input Variability var = Variability.CONSTANT;
185 output Dimension dim = INTEGER(n, var);
186 end fromInteger;
187
188 function fromExpArray
189 input array<Expression> expl;
190 output Dimension dim = INTEGER(arrayLength(expl), Variability.CONSTANT);
191 end fromExpArray;
192
193 function fromExpList
194 input list<Expression> expl;
195 output Dimension dim = INTEGER(listLength(expl), Variability.CONSTANT);
196 end fromExpList;
197
198 function toRange
199 input Dimension dim;
200 output Expression range;
201 algorithm
202 32 range := Expression.RANGE(Type.liftArrayLeft(typeOf(dim), dim),
203 lowerBoundExp(dim), NONE(), upperBoundExp(dim));
204 end toRange;
205
206 function toDAE
207 input Dimension dim;
208 output DAE.Dimension daeDim;
209 algorithm
210 daeDim := match dim
211 local
212 Type ty;
213
214 1040923 case INTEGER() then DAE.DIM_INTEGER(dim.size);
215 case BOOLEAN() then DAE.DIM_BOOLEAN();
216 case ENUM(enumType = ty as Type.ENUMERATION())
217 1338 then DAE.DIM_ENUM(ty.typePath, ty.literals, listLength(ty.literals));
218 5300 case EXP() then DAE.DIM_EXP(Expression.toDAE(dim.exp));
219 2716 case RESIZABLE() then DAE.DIM_EXP(Expression.toDAE(dim.exp));
220 case UNKNOWN() then DAE.DIM_UNKNOWN();
221 end match;
222 end toDAE;
223
224 function add
225 input Dimension a, b;
226 output Dimension c;
227 protected
228 function addExp
229 input Expression e1;
230 input Expression e2;
231 output Expression res = Expression.BINARY(e1, Operator.OPERATOR(Type.INTEGER(), NFOperator.Op.ADD), e2);
232 end addExp;
233 function addOpt
234 input Option<Integer> s1;
235 input Option<Integer> s2;
236 output Option<Integer> res;
237 algorithm
238 res := match (s1, s2)
239 local
240 Integer i1, i2;
241 ✗ case (SOME(i1), SOME(i2)) then SOME(i1+i2);
242 else NONE();
243 end match;
244 end addOpt;
245 algorithm
246 c := match (a, b)
247 case (UNKNOWN(),_) then UNKNOWN();
248 case (_,UNKNOWN()) then UNKNOWN();
249 25172 case (INTEGER(),INTEGER()) then INTEGER(a.size+b.size, Prefixes.variabilityMax(a.var, b.var));
250 12 case (INTEGER(),EXP()) then EXP(addExp(b.exp, Expression.INTEGER(a.size)), b.var);
251 5 case (EXP(),INTEGER()) then EXP(addExp(a.exp, Expression.INTEGER(b.size)), a.var);
252 7 case (EXP(),EXP()) then EXP(addExp(a.exp, b.exp), Prefixes.variabilityMax(a.var, b.var));
253 ✗ case (INTEGER(),RESIZABLE()) then RESIZABLE(a.size+b.size, addOpt(SOME(a.size), b.opt_size), addExp(b.exp, Expression.INTEGER(a.size)), b.var);
254 ✗ case (RESIZABLE(),INTEGER()) then RESIZABLE(a.size+b.size, addOpt(a.opt_size, SOME(b.size)), addExp(a.exp, Expression.INTEGER(b.size)), a.var);
255 ✗ case (EXP(),RESIZABLE()) then EXP(addExp(a.exp, b.exp), Prefixes.variabilityMax(a.var, b.var));
256 ✗ case (RESIZABLE(),EXP()) then EXP(addExp(a.exp, b.exp), Prefixes.variabilityMax(a.var, b.var));
257 ✗ case (RESIZABLE(),RESIZABLE()) then RESIZABLE(a.size+b.size, addOpt(a.opt_size, b.opt_size), addExp(a.exp, b.exp), Prefixes.variabilityMax(a.var, b.var));
258 else UNKNOWN();
259 end match;
260 end add;
261
262 function size
263 input Dimension dim;
264 input Boolean resize = false;
265 output Integer size;
266 algorithm
267 size := match dim
268 local
269 Type ty;
270
271 1117021 case INTEGER() then dim.size;
272
2/2
✓ Branch 0 taken 3602 times.
✓ Branch 1 taken 1376 times.
4978 case RESIZABLE() then if resize then Util.getOptionOrDefault(dim.opt_size, dim.size) else dim.size;
273 case BOOLEAN() then 2;
274 67 case ENUM(enumType = ty as Type.ENUMERATION()) then listLength(ty.literals);
275 else algorithm
276
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
54 if Flags.isSet(Flags.FAILTRACE) then
277 ✗ Error.addCompilerWarning(getInstanceName() + " could not get size of: " + toString(dim));
278 end if;
279 54 then fail();
280 end match;
281 end size;
282
283 function sizes
284 "Returns the sizes of the given dimension sizes."
285 input list<Dimension> dims;
286 input Boolean resize = false;
287 output list<Integer> outSizes = list(Dimension.size(d, resize) for d in dims);
288 end sizes;
289
290 function sizesProduct
291 "Returns the product of the given dimension sizes."
292 input list<Dimension> dims;
293 input Boolean resize = false;
294 output Integer outSize = product(Dimension.size(d, resize) for d in dims);
295 end sizesProduct;
296
297 function isEqual
298 input Dimension dim1;
299 input Dimension dim2;
300 output Boolean isEqual;
301 algorithm
302 isEqual := match (dim1, dim2)
303 case (UNKNOWN(), _) then true;
304 case (_, UNKNOWN()) then true;
305 case (EXP(), _) then true;
306 case (_, EXP()) then true;
307 6 case (RESIZABLE(), RESIZABLE()) then isEqualResizableExp(dim1.exp, dim2.exp);
308 22427 else Dimension.size(dim1) == Dimension.size(dim2);
309 end match;
310 end isEqual;
311
312 function isEqualResizableExp
313 "resizable size expressions can be in different forms (e.g. BINARY and MULTARY)"
314 input Expression exp1;
315 input Expression exp2;
316 output Boolean b = Expression.isEqual(exp1, exp2) or Expression.isEqual(canonicalExp(exp1), canonicalExp(exp2));
317 end isEqualResizableExp;
318
319 function canonicalExp
320 input output Expression exp;
321 algorithm
322 30 exp := SimplifyExp.simplify(SimplifyExp.combineBinaries(exp));
323 end canonicalExp;
324
325 function isEqualKnown
326 input Dimension dim1;
327 input Dimension dim2;
328 output Boolean isEqual;
329 algorithm
330 isEqual := match (dim1, dim2)
331 case (UNKNOWN(), _) then false;
332 case (_, UNKNOWN()) then false;
333 884 case (EXP(), EXP()) then Expression.isEqual(dim1.exp, dim2.exp);
334 8 case (RESIZABLE(), RESIZABLE()) then isEqualResizableExp(dim1.exp, dim2.exp);
335 case (EXP(), _) then false;
336 case (_, EXP()) then false;
337 332265 else Dimension.size(dim1) == Dimension.size(dim2);
338 end match;
339 end isEqualKnown;
340
341 function isEqualKnownSize
342 "Same as isEqualKnown, but also takes the nodes and dimension indices that
343 the dimensions come from in order to check for equality when one dimension
344 is a size-expression that refers to the other dimension."
345 input Dimension dim1;
346 input InstNode node1;
347 input Integer index1;
348 input Dimension dim2;
349 input InstNode node2;
350 input Integer index2;
351 output Boolean isEqual;
352 algorithm
353 isEqual := match (dim1, dim2)
354 // dim1 is equal to dim2 if dim1 = size(node2, ...)
355 case (EXP(), _) guard isSizeOf(dim1, node2, index2) then true;
356
357 // dim2 is equal to dim1 if dim2 = size(node1, ...)
358 case (_, EXP()) guard isSizeOf(dim2, node1, index1) then true;
359
360 ✗ case (EXP(), EXP()) then Expression.isEqual(dim1.exp, dim2.exp);
361 ✗ case (RESIZABLE(), RESIZABLE()) then isEqualResizableExp(dim1.exp, dim2.exp);
362 case (UNKNOWN(), _) then false;
363 case (_, UNKNOWN()) then false;
364 5 else Dimension.size(dim1) == Dimension.size(dim2);
365 end match;
366 end isEqualKnownSize;
367
368 function isSame
369 input Dimension dim1;
370 input Dimension dim2;
371 output Boolean same;
372 algorithm
373 same := match (dim1, dim2)
374 case (RAW_DIM(), RAW_DIM())
375 ✗ then InstNode.isSame(InstNode.borrow(dim1.scope), InstNode.borrow(dim2.scope)) and
376 AbsynUtil.subscriptEqual(dim1.dim, dim2.dim);
377 ✗ case (UNTYPED(), UNTYPED()) then Expression.isEqual(dim1.dimension, dim2.dimension);
378 1782 case (INTEGER(), INTEGER()) then dim1.size == dim2.size;
379 case (BOOLEAN(), BOOLEAN()) then true;
380 ✗ case (ENUM(), ENUM()) then Type.isEqual(dim1.enumType, dim2.enumType);
381 ✗ case (EXP(), EXP()) then Expression.isEqual(dim1.exp, dim2.exp);
382 ✗ case (RESIZABLE(), RESIZABLE()) then isEqualResizableExp(dim1.exp, dim2.exp);
383 case (UNKNOWN(), UNKNOWN()) then true;
384 else false;
385 end match;
386 end isSame;
387
388 function isSizeOf
389 "Returns true if the dimension is size(node, index)."
390 input Dimension dim;
391 input InstNode node;
392 input Integer index;
393 output Boolean res;
394 protected
395 Expression cref_exp, index_exp;
396 algorithm
397 res := match dim
398 case EXP(exp = Expression.SIZE(exp = cref_exp as Expression.CREF(), dimIndex = SOME(index_exp)))
399 ✗ then InstNode.refEqual(ComponentRef.node(cref_exp.cref), node) and
400 Expression.isEqual(index_exp, Expression.INTEGER(index));
401
402 else false;
403 end match;
404 end isSizeOf;
405
406 function isResizable
407 input Dimension dim;
408 output Boolean b;
409 algorithm
410 b := match dim
411 case RESIZABLE() then true;
412 else false;
413 end match;
414 end isResizable;
415
416 function allEqualKnown
417 input list<Dimension> dims1;
418 input list<Dimension> dims2;
419 output Boolean allEqual = List.isEqualOnTrue(dims1, dims2, isEqualKnown);
420 end allEqualKnown;
421
422 function isKnown
423 input Dimension dim;
424 input Boolean allowExp = false;
425 output Boolean known;
426 algorithm
427 known := match dim
428 case INTEGER() then true;
429 case BOOLEAN() then true;
430 case ENUM() then true;
431 case RESIZABLE() then true;
432 case EXP() then allowExp;
433 else false;
434 end match;
435 end isKnown;
436
437 function isUnknown
438 input Dimension dim;
439 output Boolean isUnknown;
440 algorithm
441 isUnknown := match dim
442 case UNKNOWN() then true;
443 else false;
444 end match;
445 end isUnknown;
446
447 function isZero
448 input Dimension dim;
449 output Boolean isZero;
450 algorithm
451 isZero := match dim
452 429269 case INTEGER() then dim.size == 0;
453 11 case ENUM() then Type.enumSize(dim.enumType) == 0;
454 else false;
455 end match;
456 end isZero;
457
458 function isOne
459 input Dimension dim;
460 output Boolean isOne;
461 algorithm
462 isOne := match dim
463 2944 case INTEGER() then dim.size == 1;
464 ✗ case ENUM() then Type.enumSize(dim.enumType) == 1;
465 else false;
466 end match;
467 end isOne;
468
469 function subscriptType
470 "Returns the expected type of a subscript for the given dimension."
471 input Dimension dim;
472 output Type ty;
473 algorithm
474 ty := match dim
475 case INTEGER() then Type.INTEGER();
476 case BOOLEAN() then Type.BOOLEAN();
477 208 case ENUM() then dim.enumType;
478 3487 case EXP() then Expression.typeOf(dim.exp);
479 57 case RESIZABLE() then Expression.typeOf(dim.exp);
480 else Type.UNKNOWN();
481 end match;
482 end subscriptType;
483
484 function toString
485 input Dimension dim;
486 output String str;
487 algorithm
488 str := match dim
489 local
490 Type ty;
491
492 ✗ case RAW_DIM() then Dump.printSubscriptStr(dim.dim);
493 1611 case INTEGER() then String(dim.size);
494 case BOOLEAN() then "Boolean";
495 ✗ case ENUM(enumType = ty as Type.ENUMERATION()) then AbsynUtil.pathString(ty.typePath);
496 1 case EXP() then Expression.toString(dim.exp);
497 179 case RESIZABLE() then Expression.toString(dim.exp) + "(R)";
498 case UNKNOWN() then ":";
499 ✗ case UNTYPED() then Expression.toString(dim.dimension);
500 end match;
501 end toString;
502
503 function hashList
504 input list<Dimension> dims;
505 output Integer hash = Util.HASH_SEED;
506 algorithm
507
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 120 times.
263 for dim in dims loop
508 143 hash := stringHashDjb2Continue(match dim case RESIZABLE() then Expression.toString(canonicalExp(dim.exp)) + "(R)"; else toString(dim); end match, hash);
509 end for;
510 end hashList;
511
512 function toStringList
513 input list<Dimension> dims;
514 input Boolean brackets = true;
515 output String str;
516 algorithm
517
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 str := stringDelimitList(list(toString(d) for d in dims), ", ");
518
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if brackets then
520 6 str := "[" + str + "]";
521 end if;
522 end toStringList;
523
524 function toFlatString
525 input Dimension dim;
526 input BaseModelica.OutputFormat format;
527 output String str;
528 algorithm
529 str := match dim
530 229 case INTEGER() then String(dim.size);
531 case BOOLEAN() then "Boolean";
532 ✗ case ENUM() then Type.toFlatString(dim.enumType, format);
533 1 case EXP() then Expression.toFlatString(dim.exp, format);
534 ✗ case RESIZABLE() then Expression.toFlatString(dim.exp, format) + "(R)";
535 case UNKNOWN() then ":";
536 ✗ case UNTYPED() then Expression.toFlatString(dim.dimension, format);
537 end match;
538 end toFlatString;
539
540 function toFlatStringList
541 input list<Dimension> dims;
542 input BaseModelica.OutputFormat format;
543 input String name = "";
544 output String str;
545 algorithm
546 223 str := List.toStringCustom(dims, function toFlatString(format = format), name, "[", ", ", "]", false);
547 end toFlatStringList;
548
549 function endExp
550 "Returns an expression for the last index in a dimension."
551 input Dimension dim;
552 input Expression subscriptedExp;
553 input Integer index;
554 output Expression sizeExp;
555 algorithm
556 sizeExp := match dim
557 local
558 Type ty;
559
560 32 case INTEGER() then Expression.INTEGER(dim.size);
561 case BOOLEAN() then Expression.BOOLEAN(true);
562 case ENUM(enumType = ty as Type.ENUMERATION())
563 2 then Expression.makeEnumLiteral(ty, listLength(ty.literals));
564 ✗ case EXP() then dim.exp;
565 ✗ case RESIZABLE() then dim.exp;
566 case UNKNOWN()
567 then match subscriptedExp
568 case Expression.CREF()
569 6 then Expression.SIZE(Expression.fromCref(ComponentRef.stripSubscripts(subscriptedExp.cref)),
570 SOME(Expression.INTEGER(index)));
571 case Expression.SUBSCRIPTED_EXP()
572 ✗ then Expression.SIZE(subscriptedExp.exp, SOME(Expression.INTEGER(index)));
573 end match;
574 end match;
575 end endExp;
576
577 function sizeExp
578 "Returns the size of a dimension as an Expression."
579 input Dimension dim;
580 output Expression sizeExp;
581 algorithm
582 sizeExp := match dim
583 local
584 Type ty;
585
586 89213 case INTEGER() then Expression.INTEGER(dim.size);
587 case BOOLEAN() then Expression.INTEGER(2);
588 case ENUM(enumType = ty as Type.ENUMERATION())
589 ✗ then Expression.INTEGER(listLength(ty.literals));
590 251 case EXP() then dim.exp;
591 687 case RESIZABLE() then dim.exp;
592 end match;
593 end sizeExp;
594
595 function lowerBoundExp
596 input Dimension dim;
597 output Expression exp;
598 algorithm
599 exp := match dim
600 case BOOLEAN() then Expression.BOOLEAN(false);
601 1 case ENUM() then Expression.makeEnumLiteral(dim.enumType, 1);
602 else Expression.INTEGER(1);
603 end match;
604 end lowerBoundExp;
605
606 function expIsLowerBound
607 "Returns true if the expression represents the lower bound of a dimension."
608 input Expression exp;
609 output Boolean isStart;
610 algorithm
611 isStart := match exp
612 493 case Expression.INTEGER() then exp.value == 1;
613 ✗ case Expression.BOOLEAN() then exp.value == false;
614 ✗ case Expression.ENUM_LITERAL() then exp.index == 1;
615 else false;
616 end match;
617 end expIsLowerBound;
618
619 function upperBoundExp
620 input Dimension dim;
621 output Expression exp;
622 algorithm
623 exp := match dim
624 local
625 Type ty;
626
627 29 case INTEGER() then Expression.INTEGER(dim.size);
628 case BOOLEAN() then Expression.BOOLEAN(true);
629 case ENUM(enumType = ty as Type.ENUMERATION())
630 ✗ then Expression.makeEnumLiteral(ty, listLength(ty.literals));
631 ✗ case EXP() then dim.exp;
632 3 case RESIZABLE() then dim.exp;
633 end match;
634 end upperBoundExp;
635
636 function expIsUpperBound
637 "Returns true if the expression represents the upper bound of the given dimension."
638 input Expression exp;
639 input Dimension dim;
640 output Boolean isEnd;
641 algorithm
642 isEnd := match (exp, dim)
643 local
644 Type ty;
645
646 315 case (Expression.INTEGER(), INTEGER()) then exp.value == dim.size;
647 ✗ case (Expression.BOOLEAN(), _) then exp.value == true;
648 case (Expression.ENUM_LITERAL(), ENUM(enumType = ty as Type.ENUMERATION()))
649 ✗ then exp.index == listLength(ty.literals);
650 else false;
651 end match;
652 end expIsUpperBound;
653
654 function variability
655 input Dimension dim;
656 output Variability var;
657 algorithm
658 var := match dim
659 39702 case INTEGER() then dim.var;
660 case BOOLEAN() then Variability.CONSTANT;
661 case ENUM() then Variability.CONSTANT;
662 8 case EXP() then dim.var;
663 ✗ case RESIZABLE() then dim.var;
664 case UNKNOWN() then Variability.CONTINUOUS;
665 end match;
666 end variability;
667
668 function mapExp
669 input Dimension dim;
670 input MapFunc func;
671 output Dimension outDim;
672
673 partial function MapFunc
674 input output Expression e;
675 end MapFunc;
676 algorithm
677 outDim := match dim
678 local
679 Expression e1, e2;
680
681 case UNTYPED(dimension = e1)
682 algorithm
683 ✗ e2 := Expression.map(e1, func);
684 ✗ then
685 if referenceEq(e1, e2) then dim else UNTYPED(e2, dim.isProcessing);
686
687 case EXP(exp = e1)
688 algorithm
689 1539 e2 := Expression.map(e1, func);
690
1/2
✓ Branch 0 taken 1539 times.
✗ Branch 1 not taken.
1539 then
691 if referenceEq(e1, e2) then dim else fromExp(e2, dim.var);
692
693 case RESIZABLE(exp = e1)
694 algorithm
695 420 e2 := Expression.map(e1, func);
696
1/2
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
420 then
697 if referenceEq(e1, e2) then dim else fromExp(e2, dim.var);
698
699 else dim;
700 end match;
701 end mapExp;
702
703 function foldExp<ArgT>
704 input Dimension dim;
705 input FoldFunc func;
706 input ArgT arg;
707 output ArgT outArg;
708
709 partial function FoldFunc
710 input Expression dim;
711 input output ArgT arg;
712 end FoldFunc;
713 algorithm
714 outArg := match dim
715 ✗ case UNTYPED() then Expression.fold(dim.dimension, func, arg);
716 2651 case EXP() then Expression.fold(dim.exp, func, arg);
717 79 case RESIZABLE() then Expression.fold(dim.exp, func, arg);
718 else arg;
719 end match;
720 end foldExp;
721
722 function foldExpList<ArgT>
723 input list<Dimension> dims;
724 input FoldFunc func;
725 input output ArgT arg;
726
727 partial function FoldFunc
728 input Expression dim;
729 input output ArgT arg;
730 end FoldFunc;
731 algorithm
732
2/2
✓ Branch 0 taken 153508 times.
✓ Branch 1 taken 136376 times.
289884 for dim in dims loop
733 153508 arg := foldExp(dim, func, arg);
734 end for;
735 end foldExpList;
736
737 function eval
738 input Dimension dim;
739 input EvalTarget target = NFCeval.noTarget;
740 output Dimension outDim;
741 algorithm
742 outDim := match dim
743 ✗ case EXP() then fromExp(Ceval.evalExp(dim.exp, target), dim.var);
744 case RESIZABLE() algorithm
745 ✗ dim.exp := Ceval.evalExp(dim.exp, target);
746 then dim;
747 else dim;
748 end match;
749 end eval;
750
751 function simplify
752 input output Dimension dim;
753 algorithm
754 dim := match dim
755 local
756 Expression simple;
757 case EXP() algorithm
758 7818 simple := SimplifyExp.simplify(dim.exp);
759 7818 then fromExp(simple, Expression.variability(simple));
760 case RESIZABLE() algorithm
761 1011 dim.exp := SimplifyExp.simplify(dim.exp);
762 then dim;
763 else dim;
764 end match;
765 end simplify;
766
767 function typeOf
768 input Dimension dim;
769 output Type ty;
770 algorithm
771 ty := match dim
772 case INTEGER() then Type.INTEGER();
773 case BOOLEAN() then Type.BOOLEAN();
774 ✗ case ENUM() then dim.enumType;
775 ✗ case EXP() then Expression.typeOf(dim.exp);
776 3 case RESIZABLE() then Expression.typeOf(dim.exp);
777 else Type.UNKNOWN();
778 end match;
779 end typeOf;
780
781 annotation(__OpenModelica_Interface="nf_frontend");
782 end NFDimension;
783