Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 9.2% 7 / 0 / 76
Functions: -% 0 / 1 / 1
Branches: 9.5% 8 / 0 / 84

OMCompiler/Compiler/NBackEnd/Util/NBBackendUtil.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 package NBBackendUtil
37 " file: NBBackendUtil.mo
38 package: NBBackendUtil
39 description: This file contains util functions for the backend.
40 "
41
42 public
43 // NF imports
44 import NFBackendExtension.BackendInfo;
45 import ComponentRef = NFComponentRef;
46 import Expression = NFExpression;
47 import Operator = NFOperator;
48 import Type = NFType;
49 import Variable = NFVariable;
50
51 // backend imports
52 import BEquation = NBEquation;
53 import NBEquation.{Equation, Frame, FrameLocation};
54 import BVariable = NBVariable;
55
56 // Util imports
57 import Util;
58
59 // old imports
60 import MMath;
61 import Rational;
62
63 function convertRational
64 input Rational r;
65 output MMath.Rational oldR = MMath.RATIONAL(r.n, r.d);
66 end convertRational;
67
68 function findTrueIndices
69 "returns all indices of elements that are true"
70 input array<Boolean> arr;
71 output list<Integer> indices = list(i for i guard arr[i] in arrayLength(arr):-1:1);
72 end findTrueIndices;
73
74 function indexTplGt<T>
75 "use with List.sort() and a rating function to sort any list"
76 input tuple<Integer, T> tpl1;
77 input tuple<Integer, T> tpl2;
78 output Boolean gt;
79 protected
80 Integer i1, i2;
81 algorithm
82 ✗ (i1, _) := tpl1;
83 ✗ (i2, _) := tpl2;
84 ✗ gt := i1 > i2;
85 end indexTplGt;
86
87 public function noNameHashEq
88 input BEquation.Equation eq;
89 input Integer mod;
90 output Integer hash;
91 algorithm
92 ✗ hash := noNameHashExp(BEquation.Equation.getResidualExp(eq), mod);
93 end noNameHashEq;
94
95 function noNameHashExp
96 "ToDo: is this mod safe? (missing intMod!)"
97 input Expression exp;
98 input Integer mod;
99 output Integer hash = 0;
100 algorithm
101 hash := match exp
102 local
103 Variable var;
104 Integer hash1, hash2;
105 ✗ case Expression.INTEGER() then exp.value;
106 ✗ case Expression.REAL() then realInt(exp.value);
107 ✗ case Expression.STRING() then stringHashDjb2Mod(exp.value, mod);
108 ✗ case Expression.BOOLEAN() then Util.boolInt(exp.value);
109 ✗ case Expression.ENUM_LITERAL() then exp.index; // ty !!
110 case Expression.CLKCONST() then 0; // clk !!
111 case Expression.CREF() algorithm
112 ✗ var := BVariable.getVar(exp.cref, sourceInfo());
113 ✗ then stringHashDjb2Mod(BackendInfo.toString(var.backendinfo), mod);
114 case Expression.TYPENAME() then 1; // ty !!
115 case Expression.ARRAY() algorithm // ty !!
116 ✗ for elem in exp.elements loop
117 ✗ hash := hash + noNameHashExp(elem, mod);
118 end for;
119 ✗ hash := hash + Util.boolInt(exp.literal);
120 then hash;
121 case Expression.MATRIX() algorithm
122 ✗ for lst in exp.elements loop
123 ✗ for elem in lst loop
124 ✗ hash := hash + noNameHashExp(elem, mod);
125 end for;
126 end for;
127 then hash;
128 case Expression.RANGE() algorithm
129 ✗ if isSome(exp.step) then
130 ✗ hash := noNameHashExp(Util.getOption(exp.step), mod);
131 end if;
132 ✗ then hash + noNameHashExp(exp.start, mod) + noNameHashExp(exp.stop, mod);
133 case Expression.TUPLE() algorithm // ty !!
134 ✗ for elem in exp.elements loop
135 ✗ hash := hash + noNameHashExp(elem, mod);
136 end for;
137 then hash;
138 case Expression.RECORD() algorithm // path, ty !!
139 ✗ for elem in exp.elements loop
140 ✗ hash := hash + noNameHashExp(elem, mod);
141 end for;
142 then hash;
143 case Expression.CALL() then 2; // call!!
144 case Expression.SIZE() algorithm
145 ✗ if isSome(exp.dimIndex) then
146 ✗ hash := noNameHashExp(Util.getOption(exp.dimIndex), mod);
147 end if;
148 ✗ then hash + noNameHashExp(exp.exp, mod);
149 ✗ case Expression.END() then stringHashDjb2Mod("end", mod);
150 case Expression.BINARY() algorithm
151 ✗ hash1 := noNameHashExp(exp.exp1, mod);
152 ✗ hash2 := noNameHashExp(exp.exp2, mod);
153 hash := match Operator.classify(exp.operator)
154 ✗ case (NFOperator.MathClassification.ADDITION, _) then hash1 + hash2;
155 ✗ case (NFOperator.MathClassification.SUBTRACTION, _) then hash1 - hash2;
156 ✗ case (NFOperator.MathClassification.MULTIPLICATION, _) then hash1 * hash2;
157 ✗ case (NFOperator.MathClassification.DIVISION, _) then realInt(hash1 / hash2);
158 ✗ case (NFOperator.MathClassification.POWER, _) then realInt(hash1 ^ hash2);
159 ✗ case (NFOperator.MathClassification.LOGICAL, _) then -(hash1 + hash2);
160 ✗ case (NFOperator.MathClassification.RELATION, _) then hash2 - hash1;
161 ✗ else hash2 - hash1;
162 end match;
163 then hash;
164 ✗ case Expression.UNARY() then -noNameHashExp(exp.exp, mod);
165 case Expression.LBINARY() algorithm
166 ✗ hash1 := noNameHashExp(exp.exp1, mod);
167 ✗ hash2 := noNameHashExp(exp.exp2, mod);
168 hash := match exp.operator.op
169 ✗ case NFOperator.Op.AND then hash1 + hash2;
170 ✗ case NFOperator.Op.OR then hash1 - hash2;
171 ✗ else hash2 - hash1;
172 end match;
173 then hash;
174 ✗ case Expression.LUNARY() then -noNameHashExp(exp.exp, mod);
175 case Expression.RELATION() algorithm
176 ✗ hash1 := noNameHashExp(exp.exp1, mod);
177 ✗ hash2 := noNameHashExp(exp.exp2, mod);
178 hash := match exp.operator.op
179 ✗ case NFOperator.Op.LESS then hash1 + hash2;
180 ✗ case NFOperator.Op.LESSEQ then -(hash1 + hash2);
181 ✗ case NFOperator.Op.GREATER then hash1 - hash2;
182 ✗ case NFOperator.Op.GREATEREQ then hash2 - hash1;
183 ✗ case NFOperator.Op.EQUAL then hash1 * hash2;
184 ✗ case NFOperator.Op.NEQUAL then realInt(hash1 ^ hash2);
185 ✗ else hash2 - hash1;
186 end match;
187 then hash;
188 ✗ case Expression.IF() then noNameHashExp(exp.condition, mod) +
189 noNameHashExp(exp.trueBranch, mod) +
190 noNameHashExp(exp.falseBranch, mod);
191 ✗ case Expression.CAST() then noNameHashExp(exp.exp, mod);
192 ✗ case Expression.BOX() then noNameHashExp(exp.exp, mod);
193 ✗ case Expression.UNBOX() then noNameHashExp(exp.exp, mod);
194 ✗ case Expression.SUBSCRIPTED_EXP() then noNameHashExp(exp.exp, mod); // subscripts!
195 ✗ case Expression.TUPLE_ELEMENT() then noNameHashExp(exp.tupleExp, mod) + exp.index;
196 ✗ case Expression.RECORD_ELEMENT() then noNameHashExp(exp.recordExp, mod) + exp.index;
197 ✗ case Expression.MUTABLE() then noNameHashExp(Mutable.access(exp.exp), mod);
198 ✗ case Expression.EMPTY() then stringHashDjb2Mod("empty", mod);
199 case Expression.PARTIAL_FUNCTION_APPLICATION() algorithm
200 //should we hash function names here?
201 ✗ for arg in exp.args loop
202 ✗ hash := hash + noNameHashExp(arg, mod);
203 end for;
204 then hash;
205 else 0;
206 end match;
207 ✗ hash := intMod(intAbs(hash), mod);
208 end noNameHashExp;
209
210 function isOnlyTimeDependent
211 input Expression exp;
212 output Boolean b;
213 algorithm
214 186 b := Expression.fold(exp, isOnlyTimeDependentFold, true);
215 end isOnlyTimeDependent;
216
217 function isOnlyTimeDependentFold
218 input Expression exp;
219 input output Boolean b;
220 algorithm
221
2/2
✓ Branch 0 taken 349 times.
✓ Branch 1 taken 413 times.
762 if b then
222 b := match exp
223
4/4
✓ Branch 1 taken 184 times.
✓ Branch 2 taken 44 times.
✓ Branch 4 taken 55 times.
✓ Branch 5 taken 129 times.
228 case Expression.CREF() then ComponentRef.isTime(exp.cref) or BVariable.checkCref(exp.cref, BVariable.isParamOrConst, sourceInfo());
224 else true;
225 end match;
226 end if;
227 end isOnlyTimeDependentFold;
228
229 function isContinuous
230 input Expression exp;
231 input Boolean staticAsContinuous;
232 output Boolean b;
233 algorithm
234 ✗ b := Expression.fold(exp, function isContinuousFold(staticAsContinuous = staticAsContinuous), true);
235 end isContinuous;
236
237 function isContinuousFold
238 input Expression exp;
239 input Boolean staticAsContinuous;
240 input output Boolean b;
241 algorithm
242 ✗ if b then
243 b := match exp
244 ✗ case Expression.CREF() then BVariable.checkCref(exp.cref, function BVariable.isContinuous(staticAsContinuous = staticAsContinuous), sourceInfo());
245 else true;
246 end match;
247 end if;
248 end isContinuousFold;
249
250 function containsContinuousVar
251 "Returns true if the expression contains at least one continuous variable.
252 Unlike isContinuous (ALL-fold), this is an OR-fold: any single continuous
253 variable makes the whole expression 'continuous' for event purposes."
254 input Expression exp;
255 output Boolean b;
256 algorithm
257 374 b := Expression.fold(exp, containsContinuousVarFold, false);
258 end containsContinuousVar;
259
260 function containsContinuousVarFold
261 input Expression exp;
262 input output Boolean b;
263 algorithm
264
2/2
✓ Branch 0 taken 789 times.
✓ Branch 1 taken 376 times.
1165 if not b then
265 b := match exp
266 457 case Expression.CREF() then BVariable.checkCref(exp.cref, function BVariable.isContinuous(staticAsContinuous = false), sourceInfo());
267 else false;
268 end match;
269 end if;
270 end containsContinuousVarFold;
271
272 public function makeFDerString
273 input output String str;
274 input Option<Integer> i_opt = NONE();
275 protected
276 String i = if isSome(i_opt) then intString(Util.getOption(i_opt)) else "";
277 algorithm
278 291 str := NBVariable.FUNCTION_DERIVATIVE_STR + i + "_" + str;
279 end makeFDerString;
280 annotation(__OpenModelica_Interface="nbackend");
281 end NBBackendUtil;
282