Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 79.0% 113 / 0 / 143
Functions: -% 0 / 1 / 1
Branches: 61.6% 149 / 0 / 242

OMCompiler/Compiler/FrontEnd/ComponentReferenceBasics.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 ComponentReferenceBasics
37 " file: ComponentReferenceBasics.mo
38 package: ComponentReferenceBasics
39 description: Some stuff for ComponentRef datatypes
40
41
42 This file contains the module ComponentReferenceBasics,
43 which contains functions for ComponentRef."
44
45 // public imports
46 public import DAE;
47
48 // protected imports
49 protected import Config;
50 protected import ExpressionBasics;
51 protected import List;
52 protected import System;
53 protected import TypesDump;
54
55 public function crefDims "
56 function: crefDims
57 Return the all dimension (contained in the types) of a ComponentRef"
58 input DAE.ComponentRef inComponentRef;
59 output list<DAE.Dimension> outDimensionLst;
60 algorithm
61 outDimensionLst := match inComponentRef
62 local
63 list<DAE.Dimension> dims,res;
64 DAE.Type idType;
65 DAE.ComponentRef cr;
66
67 2583843 case DAE.CREF_IDENT(identType = idType) then TypesDump.getDimensions(idType);
68
69 case DAE.CREF_QUAL(componentRef = cr, identType = idType)
70 algorithm
71 5300809 dims := TypesDump.getDimensions(idType);
72 5300809 res := crefDims(cr);
73 5300809 res := listAppend(dims,res);
74 then
75 res;
76 end match;
77 end crefDims;
78
79 public function crefSubs "
80 function: crefSubs
81 Return all subscripts of a ComponentRef"
82 input DAE.ComponentRef inComponentRef;
83 output list<DAE.Subscript> outSubscriptLst;
84 algorithm
85 outSubscriptLst := match inComponentRef
86 local
87 list<DAE.Subscript> subs,res;
88 DAE.ComponentRef cr;
89
90 case DAE.CREF_IDENT(subscriptLst = subs) then subs;
91
92 case DAE.CREF_QUAL(componentRef = cr,subscriptLst=subs)
93 algorithm
94 12745413 res := crefSubs(cr);
95 12745413 res := listAppend(subs,res);
96 then
97 res;
98 end match;
99 end crefSubs;
100
101 /***************************************************/
102 /* Compare */
103 /***************************************************/
104
105 public function crefLastIdentEqual
106 "author: Frenkel TUD
107 Returns true if the ComponentRefs has the same name (the last identifier)."
108 input DAE.ComponentRef cr1;
109 input DAE.ComponentRef cr2;
110 output Boolean equal;
111 protected
112 DAE.Ident id1,id2;
113 algorithm
114 16215 id1 := crefLastIdent(cr1);
115 16215 id2 := crefLastIdent(cr2);
116
3/4
✓ Branch 0 taken 15359 times.
✓ Branch 1 taken 856 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15359 times.
16215 equal := stringEq(id1, id2);
117 end crefLastIdentEqual;
118
119 public function crefFirstCrefEqual
120 "author: Frenkel TUD
121 Returns true if the ComponentRefs have the same first Cref."
122 input DAE.ComponentRef cr1;
123 input DAE.ComponentRef cr2;
124 output Boolean equal;
125 protected
126 DAE.ComponentRef pcr1,pcr2;
127 algorithm
128 47523 pcr1 := crefFirstCref(cr1);
129 47523 pcr2 := crefFirstCref(cr2);
130 47523 equal := crefEqual(pcr1,pcr2);
131 end crefFirstCrefEqual;
132
133 public function crefFirstCrefLastCrefEqual
134 "author: Frenkel TUD
135 Returns true if the ComponentRefs have the same first Cref."
136 input DAE.ComponentRef cr1 "First Cref";
137 input DAE.ComponentRef cr2 "Last Cref";
138 output Boolean equal;
139 protected
140 DAE.ComponentRef pcr1,pcr2;
141 algorithm
142 10 pcr1 := crefFirstCref(cr1);
143 10 pcr2 := crefLastCref(cr2);
144 10 equal := crefEqual(pcr1,pcr2);
145 end crefFirstCrefLastCrefEqual;
146
147 public function crefFirstCref
148 "Returns the first part of a component reference, i.e the identifier"
149 input DAE.ComponentRef inCr;
150 output DAE.ComponentRef outCr;
151 algorithm
152 outCr := match inCr
153 local
154 DAE.Ident id;
155 list<DAE.Subscript> subs;
156 DAE.Type t2;
157
158 247300 case DAE.CREF_QUAL(id,t2,subs,_) then makeCrefIdent(id,t2,subs);
159 case DAE.CREF_IDENT(_,_,_) then inCr;
160 end match;
161 end crefFirstCref;
162
163 public function crefLastIdent
164 "author: PA
165 Returns the last identfifier of a ComponentRef."
166 input DAE.ComponentRef inComponentRef;
167 output DAE.Ident outIdent;
168 algorithm
169 outIdent := match inComponentRef
170 local
171 DAE.Ident id,res;
172 DAE.ComponentRef cr;
173
174 case DAE.CREF_IDENT(ident = id) then id;
175
176 case DAE.CREF_QUAL(componentRef = cr)
177 algorithm
178 9099435 res := crefLastIdent(cr);
179 then
180 res;
181 end match;
182 end crefLastIdent;
183
184 public function crefLastCref "
185 Return the last ComponentRef"
186 input DAE.ComponentRef inComponentRef;
187 output DAE.ComponentRef outComponentRef;
188 algorithm
189 outComponentRef := match inComponentRef
190 local
191 DAE.ComponentRef res,cr;
192
193 case DAE.CREF_IDENT() then inComponentRef;
194
195 case DAE.CREF_QUAL(componentRef = cr)
196 algorithm
197 1291025 res := crefLastCref(cr);
198 then
199 res;
200 end match;
201 end crefLastCref;
202
203 public function crefFirstIdentEqual
204 "Returns true if the first identifier in both crefs are the same, otherwise false."
205 input DAE.ComponentRef inCref1;
206 input DAE.ComponentRef inCref2;
207 output Boolean outEqual;
208 protected
209 DAE.Ident id1, id2;
210 algorithm
211 7478 id1 := crefFirstIdent(inCref1);
212 7478 id2 := crefFirstIdent(inCref2);
213
4/4
✓ Branch 0 taken 5865 times.
✓ Branch 1 taken 1613 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 5853 times.
7478 outEqual := stringEq(id1, id2);
214 end crefFirstIdentEqual;
215
216 public function crefFirstIdent
217 "Returns the first identifier of a component reference."
218 input DAE.ComponentRef inComponentRef;
219 output DAE.Ident outIdent;
220 algorithm
221 outIdent := match inComponentRef
222 local
223 DAE.Ident id;
224
225 case DAE.CREF_IDENT(ident = id) then id;
226 case DAE.CREF_QUAL(ident = id) then id;
227 end match;
228 end crefFirstIdent;
229
230 protected
231
232 type CompareWithSubsType = enumeration(WithoutSubscripts, WithGenericSubscript, WithGenericSubscriptNotAlphabetic, WithIntSubscript);
233
234 package CompareWithGenericSubscript "Package that can be modified to do different kinds of comparisons"
235 constant CompareWithSubsType compareSubscript=CompareWithSubsType.WithGenericSubscript;
236 function compare
237 input DAE.ComponentRef cr1, cr2;
238 output Integer res;
239 algorithm
240 res := match (cr1, cr2)
241 case (DAE.CREF_IDENT(),DAE.CREF_IDENT())
242 algorithm
243 12452128 res := stringCompare(cr1.ident, cr2.ident);
244
6/6
✓ Branch 0 taken 5898393 times.
✓ Branch 1 taken 5489722 times.
✓ Branch 2 taken 73449 times.
✓ Branch 3 taken 8532 times.
✓ Branch 4 taken 41003 times.
✓ Branch 5 taken 35918 times.
11547017 if compareSubscript==CompareWithSubsType.WithoutSubscripts or res <> 0 then
245 6917956 return;
246 end if;
247 5534172 then compareSubs(cr1.subscriptLst, cr2.subscriptLst);
248 case (DAE.CREF_QUAL(),DAE.CREF_QUAL())
249 algorithm
250 25284019 res := stringCompare(cr1.ident, cr2.ident);
251
8/8
✓ Branch 0 taken 2933412 times.
✓ Branch 1 taken 14120789 times.
✓ Branch 2 taken 294605 times.
✓ Branch 3 taken 400461 times.
✓ Branch 4 taken 1542170 times.
✓ Branch 5 taken 5653403 times.
✓ Branch 6 taken 89891 times.
✓ Branch 7 taken 249288 times.
25284019 if res <> 0 then
252 4860078 return;
253 end if;
254 if compareSubscript<>CompareWithSubsType.WithoutSubscripts then
255 14770538 res := compareSubs(cr1.subscriptLst, cr2.subscriptLst);
256
6/6
✓ Branch 0 taken 29044 times.
✓ Branch 1 taken 14091745 times.
✓ Branch 2 taken 27000 times.
✓ Branch 3 taken 373461 times.
✓ Branch 4 taken 1873 times.
✓ Branch 5 taken 247415 times.
14770538 if res <> 0 then
257 57917 return;
258 end if;
259 end if;
260 20366024 then compare(cr1.componentRef, cr2.componentRef);
261 case (DAE.CREF_QUAL(),DAE.CREF_IDENT())
262 algorithm
263 1095937 res := stringCompare(cr1.ident, cr2.ident);
264
6/8
✓ Branch 0 taken 869092 times.
✓ Branch 1 taken 26409 times.
✓ Branch 2 taken 18291 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 164281 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17840 times.
✗ Branch 7 not taken.
1095937 if res <> 0 then
265 1069504 return;
266 end if;
267 if compareSubscript<>CompareWithSubsType.WithoutSubscripts then
268 26433 res := compareSubs(cr1.subscriptLst, cr2.subscriptLst);
269 end if;
270
3/6
✓ Branch 0 taken 15000 times.
✓ Branch 1 taken 11409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
26433 if res <> 0 then
271 15000 return;
272 end if;
273 then 1;
274 case (DAE.CREF_IDENT(),DAE.CREF_QUAL())
275 algorithm
276 1735704 res := stringCompare(cr1.ident, cr2.ident);
277
5/8
✓ Branch 0 taken 1495770 times.
✓ Branch 1 taken 25591 times.
✓ Branch 2 taken 53614 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 137977 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22752 times.
✗ Branch 7 not taken.
1735704 if res <> 0 then
278 1710113 return;
279 end if;
280 if compareSubscript<>CompareWithSubsType.WithoutSubscripts then
281 25591 res := compareSubs(cr1.subscriptLst, cr2.subscriptLst);
282 end if;
283
2/6
✓ Branch 0 taken 10122 times.
✓ Branch 1 taken 15469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
25591 if res <> 0 then
284 10122 return;
285 end if;
286 then -1;
287 end match;
288 end compare;
289 function compareSubs
290 input list<DAE.Subscript> ss1, ss2;
291 output Integer res=0;
292 protected
293 list<DAE.Subscript> ss=ss2;
294 DAE.Subscript s2;
295 Integer i1, i2;
296 algorithm
297
6/8
✓ Branch 0 taken 6301552 times.
✓ Branch 1 taken 15141953 times.
✓ Branch 2 taken 48664 times.
✓ Branch 3 taken 381370 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 47750 times.
✓ Branch 7 taken 259401 times.
22180690 for s1 in ss1 loop
298
5/8
✓ Branch 0 taken 13499 times.
✓ Branch 1 taken 6288053 times.
✓ Branch 2 taken 647 times.
✓ Branch 3 taken 48017 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 47750 times.
6397966 if listEmpty(ss) then
299 res := -1;
300 14146 return;
301 end if;
302 6383820 s2::ss := ss;
303 if compareSubscript == CompareWithSubsType.WithGenericSubscript then
304 6288053 res := compareSubscriptStr(s1, s2);
305 elseif compareSubscript == CompareWithSubsType.WithGenericSubscriptNotAlphabetic then
306 48017 res := ExpressionBasics.compareSubscripts(s1, s2);
307 else
308 47750 i1 := ExpressionBasics.subscriptInt(s1);
309 47750 i2 := ExpressionBasics.subscriptInt(s2);
310
4/8
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 41541 times.
✓ Branch 5 taken 6209 times.
✓ Branch 6 taken 21945 times.
✓ Branch 7 taken 19596 times.
47750 res := if i1 < i2 then -1 elseif i1 > i2 then 1 else 0;
311 end if;
312
4/4
✓ Branch 0 taken 4507059 times.
✓ Branch 1 taken 1780994 times.
✓ Branch 2 taken 27000 times.
✓ Branch 3 taken 21017 times.
6336070 if res <> 0 then
313 4559864 return;
314 end if;
315 end for;
316
4/8
✓ Branch 0 taken 15125167 times.
✓ Branch 1 taken 16786 times.
✓ Branch 2 taken 381370 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 259401 times.
✗ Branch 7 not taken.
15782724 if not listEmpty(ss) then
317 res := 1;
318 end if;
319 end compareSubs;
320
321 function compareSubscriptStr
322 "stringCompare of the printed subscripts, without printing an integer index."
323 input DAE.Subscript s1, s2;
324 output Integer res;
325 algorithm
326 res := match (s1, s2)
327 local
328 Integer i1, i2;
329 case (DAE.INDEX(exp = DAE.ICONST(integer = i1)), DAE.INDEX(exp = DAE.ICONST(integer = i2)))
330
2/8
✓ Branch 0 taken 4505325 times.
✓ Branch 1 taken 1779202 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
6284527 then if i1 == i2 then 0 else stringCompare(intString(i1), intString(i2));
331
2/8
✓ Branch 0 taken 3419 times.
✓ Branch 1 taken 107 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
3526 else
332 if referenceEq(s1, s2) then 0
333 else stringCompare(ExpressionBasics.printSubscriptStr(s1), ExpressionBasics.printSubscriptStr(s2));
334 end match;
335 end compareSubscriptStr;
336 end CompareWithGenericSubscript;
337
338 package CompareWithGenericSubscriptNotAlphabetic
339 extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithGenericSubscriptNotAlphabetic);
340 end CompareWithGenericSubscriptNotAlphabetic;
341 package CompareWithoutSubscripts
342 extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithoutSubscripts);
343 end CompareWithoutSubscripts;
344 package CompareWithIntSubscript "More efficient than CompareWithGenericSubscript, assuming all subscripts are integers"
345 extends CompareWithGenericSubscript(compareSubscript=CompareWithSubsType.WithIntSubscript);
346 end CompareWithIntSubscript;
347
348 public function crefSortFunc "A sorting function (greatherThan) for crefs"
349 input DAE.ComponentRef cr1;
350 input DAE.ComponentRef cr2;
351 output Boolean greaterThan;
352 algorithm
353 24755 greaterThan := CompareWithGenericSubscript.compare(cr1,cr2) > 0;
354 end crefSortFunc;
355
356 public function crefCompareGeneric "A sorting function for crefs"
357 input DAE.ComponentRef cr1;
358 input DAE.ComponentRef cr2;
359 output Integer comp;
360 algorithm
361 16742678 comp := CompareWithGenericSubscript.compare(cr1,cr2);
362 end crefCompareGeneric;
363
364 public function crefCompareIntSubscript "A sorting function for crefs"
365 input DAE.ComponentRef cr1;
366 input DAE.ComponentRef cr2;
367 output Integer comp;
368 algorithm
369 209277 comp := CompareWithIntSubscript.compare(cr1,cr2);
370 end crefCompareIntSubscript;
371
372 public function crefCompareGenericNotAlphabetic "A sorting function for crefs"
373 input DAE.ComponentRef cr1;
374 input DAE.ComponentRef cr2;
375 output Integer comp;
376 algorithm
377 475515 comp := CompareWithGenericSubscriptNotAlphabetic.compare(cr1,cr2);
378 end crefCompareGenericNotAlphabetic;
379
380 public function crefLexicalGreaterSubsAtEnd
381 "mahge:
382 Compares two crefs lexically. Subscripts are treated as if they are
383 they are at the end of the whole component reference.
384 e.g. r[1].i is greater than r[2].a.
385 returns true if the first cref is greater than the second"
386 input DAE.ComponentRef cr1;
387 input DAE.ComponentRef cr2;
388 output Boolean isGreater;
389 algorithm
390 2749539 isGreater := crefLexicalCompareSubsAtEnd(cr1,cr2) > 0;
391 end crefLexicalGreaterSubsAtEnd;
392
393 public function crefLexicalCompareSubsAtEnd
394 "mahge:
395 Compares two crefs lexically. Subscripts are treated as if they are
396 they are at the end of the whole component reference.
397 e.g. r[1].i is greater than r[2].a.
398 returns value is same as C strcmp. 0 if equal, 1 if first is greater, -1 otherwise"
399 input DAE.ComponentRef cr1;
400 input DAE.ComponentRef cr2;
401 output Integer res;
402 protected
403 list<Integer> subs1;
404 list<Integer> subs2;
405 algorithm
406 2749539 res := CompareWithoutSubscripts.compare(cr1, cr2);
407
2/2
✓ Branch 0 taken 2440511 times.
✓ Branch 1 taken 309028 times.
2749539 if res <> 0 then
408 2440511 return;
409 end if;
410 309028 subs1 := ExpressionBasics.subscriptsInt(crefSubs(cr1));
411 309028 subs2 := ExpressionBasics.subscriptsInt(crefSubs(cr2));
412 309028 res := crefLexicalCompareSubsAtEnd2(subs1, subs2);
413 end crefLexicalCompareSubsAtEnd;
414
415 protected function crefLexicalCompareSubsAtEnd2
416 "mahge:
417 Helper function for crefLexicalCompareubsAtEnd
418 compares subs. However only if the crefs with out subs are equal.
419 (i.e. identsCompared is 0)
420 otherwise just returns"
421 input list<Integer> inSubs1;
422 input list<Integer> inSubs2;
423 output Integer res = 0;
424 protected
425 list<Integer> rest=inSubs2;
426 algorithm
427
1/2
✓ Branch 0 taken 373694 times.
✗ Branch 1 not taken.
373694 for i in inSubs1 loop
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 373694 times.
373694 res::rest := rest;
429
4/4
✓ Branch 0 taken 149099 times.
✓ Branch 1 taken 224595 times.
✓ Branch 2 taken 64666 times.
✓ Branch 3 taken 84433 times.
373694 res := if i>res then 1 elseif i < res then -1 else 0;
430 if res <> 0 then
431 309028 return;
432 end if;
433 end for;
434 end crefLexicalCompareSubsAtEnd2;
435
436 public function crefContainedIn
437 "author: PA
438 Returns true if second arg is a sub component ref of first arg.
439 For instance, b.c. is a sub_component of a.b.c."
440 input DAE.ComponentRef containerCref "the cref that might contain";
441 input DAE.ComponentRef containedCref "cref that might be contained";
442 output Boolean outBoolean;
443 algorithm
444 outBoolean := matchcontinue (containerCref, containedCref)
445 local
446 DAE.ComponentRef full,partOf,cr2;
447 Boolean res;
448
449 // a qualified cref cannot be contained in an ident cref.
450 case (DAE.CREF_IDENT(), DAE.CREF_QUAL()) then false;
451
452 // see if they are equal
453 case (full, partOf)
454 algorithm
455 ✗ true := crefEqualNoStringCompare(full, partOf);
456 then
457 true;
458
459 // dive into
460 case (full as DAE.CREF_QUAL(componentRef = cr2), partOf)
461 algorithm
462 ✗ false := crefEqualNoStringCompare(full, partOf);
463 ✗ res := crefContainedIn(cr2,partOf);
464 then
465 res;
466
467 // anything else is false
468 else false;
469 end matchcontinue;
470 end crefContainedIn;
471
472 public function crefPrefixOf
473 "author: PA
474 Returns true if prefixCref is a prefix of fullCref
475 For example, a.b is a prefix of a.b.c.
476 adrpo 2010-10-07,
477 added also that a.b.c is a prefix of a.b.c[1].*!"
478 input DAE.ComponentRef prefixCref;
479 input DAE.ComponentRef fullCref;
480 output Boolean outPrefixOf;
481 algorithm
482 outPrefixOf := match (prefixCref,fullCref)
483 // both are qualified, dive into
484 case (DAE.CREF_QUAL(), DAE.CREF_QUAL())
485
8/8
✓ Branch 0 taken 117982 times.
✓ Branch 1 taken 28592 times.
✓ Branch 3 taken 105921 times.
✓ Branch 4 taken 12061 times.
✓ Branch 6 taken 104441 times.
✓ Branch 7 taken 1480 times.
✓ Branch 9 taken 96071 times.
✓ Branch 10 taken 8370 times.
146574 then prefixCref.ident == fullCref.ident and
486 ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst) and
487 crefPrefixOf(prefixCref.componentRef, fullCref.componentRef);
488
489 // adrpo: 2010-10-07: first is an ID, second is qualified, see if one is prefix of the other
490 // even if the first one DOESN'T HAVE SUBSCRIPTS!
491 case (DAE.CREF_IDENT(subscriptLst = {}), DAE.CREF_QUAL())
492
4/4
✓ Branch 0 taken 12040 times.
✓ Branch 1 taken 927 times.
✓ Branch 3 taken 418 times.
✓ Branch 4 taken 11622 times.
12967 then prefixCref.ident == fullCref.ident;
493
494 // first is an ID, second is qualified, see if one is prefix of the other
495 case (DAE.CREF_IDENT(), DAE.CREF_QUAL())
496
5/6
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 5768 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 672 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48 times.
6488 then prefixCref.ident == fullCref.ident and
497 ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst);
498
499 // adrpo: 2010-10-07: first is an ID, second is an ID, see if one is prefix of the other
500 // even if the first one DOESN'T HAVE SUBSCRIPTS!
501 case (DAE.CREF_IDENT(subscriptLst = {}), DAE.CREF_IDENT())
502
4/4
✓ Branch 0 taken 5792 times.
✓ Branch 1 taken 9137 times.
✓ Branch 3 taken 5362 times.
✓ Branch 4 taken 430 times.
14929 then stringEq(prefixCref.ident, fullCref.ident);
503
504 case (DAE.CREF_IDENT(), DAE.CREF_IDENT())
505
6/6
✓ Branch 0 taken 3987 times.
✓ Branch 1 taken 8264 times.
✓ Branch 3 taken 123 times.
✓ Branch 4 taken 3864 times.
✓ Branch 6 taken 104 times.
✓ Branch 7 taken 19 times.
12251 then prefixCref.ident == fullCref.ident and
506 ExpressionBasics.subscriptEqual(prefixCref.subscriptLst, fullCref.subscriptLst);
507
508 // they are not a prefix of one-another
509 else false;
510 end match;
511 end crefPrefixOf;
512
513 public function crefPrefixOfIgnoreSubscripts
514 "author: PA
515 Returns true if prefixCref is a prefix of fullCref
516 For example, a.b is a prefix of a.b.c.
517 This function ignores the subscripts"
518 input DAE.ComponentRef prefixCref;
519 input DAE.ComponentRef fullCref;
520 output Boolean outPrefixOf;
521 algorithm
522 outPrefixOf := match (prefixCref,fullCref)
523 // both are qualified, dive into
524 case (DAE.CREF_QUAL(), DAE.CREF_QUAL())
525
6/6
✓ Branch 0 taken 3475626 times.
✓ Branch 1 taken 1705696 times.
✓ Branch 3 taken 798789 times.
✓ Branch 4 taken 2676837 times.
✓ Branch 6 taken 795727 times.
✓ Branch 7 taken 3062 times.
5181322 then prefixCref.ident == fullCref.ident and
526 crefPrefixOfIgnoreSubscripts(prefixCref.componentRef, fullCref.componentRef);
527
528 // first is an ID, second is qualified, see if one is prefix of the other
529 case (DAE.CREF_IDENT(), DAE.CREF_QUAL())
530
4/4
✓ Branch 0 taken 13524 times.
✓ Branch 1 taken 79576 times.
✓ Branch 3 taken 11758 times.
✓ Branch 4 taken 1766 times.
93100 then prefixCref.ident == fullCref.ident;
531
532 case (DAE.CREF_IDENT(), DAE.CREF_IDENT())
533
4/4
✓ Branch 0 taken 15606 times.
✓ Branch 1 taken 82033 times.
✓ Branch 3 taken 15581 times.
✓ Branch 4 taken 25 times.
97639 then prefixCref.ident == fullCref.ident;
534
535 // they are not a prefix of one-another
536 else false;
537 end match;
538 end crefPrefixOfIgnoreSubscripts;
539
540 public function crefNotPrefixOf "negation of crefPrefixOf"
541 input DAE.ComponentRef cr1;
542 input DAE.ComponentRef cr2;
543 output Boolean outBoolean;
544 algorithm
545 outBoolean := match(cr1, cr2)
546 // first is qualified, second is an unqualified ident, return false!
547 case (DAE.CREF_QUAL(), DAE.CREF_IDENT()) then true;
548 ✗ else not crefPrefixOf(cr1, cr2);
549 end match;
550 end crefNotPrefixOf;
551
552 public function crefEqual
553 "Returns true if two component references are equal.
554 No string comparison of unparsed crefs is performed!"
555 input DAE.ComponentRef inComponentRef1;
556 input DAE.ComponentRef inComponentRef2;
557 output Boolean outBoolean;
558 algorithm
559 34663005 outBoolean := crefEqualNoStringCompare(inComponentRef1,inComponentRef2);
560 end crefEqual;
561
562 public function crefInLst "returns true if the cref is in the list of crefs"
563 input DAE.ComponentRef cref;
564 input list<DAE.ComponentRef> lst;
565 output Boolean b;
566 algorithm
567 88322 b := List.isMemberOnTrue(cref,lst,crefEqual);
568 end crefInLst;
569
570 public function crefNotInLst "returns true if the cref is not in the list of crefs"
571 input DAE.ComponentRef cref;
572 input list<DAE.ComponentRef> lst;
573 output Boolean b;
574 algorithm
575 ✗ b := not List.isMemberOnTrue(cref,lst,crefEqual);
576 end crefNotInLst;
577
578 public function crefEqualVerySlowStringCompareDoNotUse
579 "Returns true if two component references are equal,
580 comparing strings if no other solution is found"
581 input DAE.ComponentRef inComponentRef1;
582 input DAE.ComponentRef inComponentRef2;
583 output Boolean outBoolean;
584 algorithm
585 outBoolean := matchcontinue (inComponentRef1,inComponentRef2)
586 local
587 DAE.Ident n1,n2,s1,s2;
588 list<DAE.Subscript> idx1,idx2;
589 DAE.ComponentRef cr1,cr2;
590
591 // check for pointer equality first, if they point to the same thing, they are equal
592 case (_,_)
593 algorithm
594 ✗ true := referenceEq(inComponentRef1,inComponentRef2);
595 then
596 true;
597
598 // simple identifiers
599 case (DAE.CREF_IDENT(ident = n1,subscriptLst = {}),DAE.CREF_IDENT(ident = n2,subscriptLst = {}))
600 algorithm
601 ✗ true := stringEq(n1, n2);
602 then
603 true;
604 case (DAE.CREF_IDENT(ident = n1,subscriptLst = (idx1 as _::_)),DAE.CREF_IDENT(ident = n2,subscriptLst = (idx2 as _::_)))
605 algorithm
606 ✗ true := stringEq(n1, n2);
607 ✗ true := ExpressionBasics.subscriptEqual(idx1, idx2);
608 then
609 true;
610 // BZ 2009-12
611 // For some reason in some examples we get crefs on different forms.
612 // the compare can be crefEqual(CREF_IDENT("mycref",_,{1,2,3}),CREF_IDENT("mycref[1,2,3]",_,{}))
613 // I do belive this has something to do with variable replacement and BackendDAE.
614 // TODO: investigate reason, until then keep as is.
615 // I do believe that this is the same bug as adrians qual-ident bug below.
616 case (DAE.CREF_IDENT(ident = n1,subscriptLst = {}),DAE.CREF_IDENT(ident = n2,subscriptLst = (idx2 as _::_)))
617 algorithm
618 ✗ 0 := System.stringFind(n1, n2); // n2 should be first in n1!
619 ✗ s1 := n2 + "[" + ExpressionBasics.printListStr(idx2, ExpressionBasics.printSubscriptStr, ",") + "]";
620 ✗ true := stringEq(s1,n1);
621 then
622 true;
623 case (DAE.CREF_IDENT(ident = n1,subscriptLst = (idx2 as _::_)),DAE.CREF_IDENT(ident = n2,subscriptLst = {}))
624 algorithm
625 ✗ 0 := System.stringFind(n2, n1); // n1 should be first in n2!
626 ✗ s1 := n1 + "[" + ExpressionBasics.printListStr(idx2, ExpressionBasics.printSubscriptStr, ",") + "]";
627 ✗ true := stringEq(s1,n2);
628 then
629 true;
630 // qualified crefs
631 case (DAE.CREF_QUAL(ident = n1,subscriptLst = idx1,componentRef = cr1),DAE.CREF_QUAL(ident = n2,subscriptLst = idx2,componentRef = cr2))
632 algorithm
633 ✗ true := stringEq(n1, n2);
634 ✗ true := crefEqualVerySlowStringCompareDoNotUse(cr1, cr2);
635 ✗ true := ExpressionBasics.subscriptEqual(idx1, idx2);
636 then
637 true;
638 // this is a VERY expensive case! Do we NEED IT??!!
639 // There is a bug here somewhere or in MetaModelica Compiler (MMC).
640 // Therefore as a last resort, print the strings and compare.
641 // adrpo: this is really not needed BUT unfortunately IT IS as
642 // QUAL(x, IDENT(y)) == IDENT(x.y)
643 // somewhere in the compiler the lhs is replaced by the rhs
644 // and makes this case needed! THIS SHOULD BE FIXED!! TODO! FIXME!
645 // NOTE: THIS IS NOT A BUG IN MMC!
646 /* adrpo: comment this and try to make it work faster with the two cases below!
647 case (cr1 as DAE.CREF_QUAL(ident = n1),cr2 as DAE.CREF_IDENT)
648 algorithm
649 s1 = printComponentRefStr(cr1);
650 s2 = printComponentRefStr(cr2);
651 true = stringEq(s1, s2);
652 // debug_print("cr1", cr1);
653 // debug_print("cr2", cr2);
654 // enableTrace();
655 then
656 true;
657 */
658 // the following two cases replaces the one below
659 // right cref is stringified!
660 case (cr1 as DAE.CREF_QUAL(ident = n1),cr2 as DAE.CREF_IDENT(ident = n2))
661 algorithm
662 ✗ 0 := System.stringFind(n2, n1); // n1 should be first in n2!
663 ✗ s1 := printComponentRefStr(cr1);
664 ✗ s2 := printComponentRefStr(cr2);
665 ✗ true := stringEq(s1, s2);
666 then
667 true;
668 // left cref is stringified!
669 case (cr1 as DAE.CREF_IDENT(ident = n1),cr2 as DAE.CREF_QUAL(ident = n2))
670 algorithm
671 ✗ 0 := System.stringFind(n1, n2); // n2 should be first in n1!
672 ✗ s1 := printComponentRefStr(cr1);
673 ✗ s2 := printComponentRefStr(cr2);
674 ✗ true := stringEq(s1, s2);
675 then
676 true;
677 // the crefs are not equal!
678 else false;
679 end matchcontinue;
680 end crefEqualVerySlowStringCompareDoNotUse;
681
682 public function crefEqualNoStringCompare
683 "Returns true if two component references are equal!
684 IMPORTANT! do not use this function if you have
685 stringified components, meaning this function will
686 return false for: cref1: QUAL(x, IDENT(y)) != cref2: IDENT(x.y)"
687 input DAE.ComponentRef inCref1;
688 input DAE.ComponentRef inCref2;
689 output Boolean outEqual;
690 algorithm
691
2/2
✓ Branch 0 taken 16662124 times.
✓ Branch 1 taken 122075312 times.
138737436 if referenceEq(inCref1, inCref2) then
692 outEqual := true;
693 16662124 return;
694 end if;
695
696 outEqual := match(inCref1, inCref2)
697 case (DAE.CREF_IDENT(), DAE.CREF_IDENT())
698
6/6
✓ Branch 0 taken 25119331 times.
✓ Branch 1 taken 3072090 times.
✓ Branch 3 taken 24152324 times.
✓ Branch 4 taken 967007 times.
✓ Branch 6 taken 3154214 times.
✓ Branch 7 taken 20998110 times.
28191421 then inCref1.ident == inCref2.ident and
699 ExpressionBasics.subscriptEqual(inCref1.subscriptLst, inCref2.subscriptLst);
700
701 case (DAE.CREF_QUAL(), DAE.CREF_QUAL())
702
8/8
✓ Branch 0 taken 71376348 times.
✓ Branch 1 taken 16282380 times.
✓ Branch 3 taken 65050893 times.
✓ Branch 4 taken 6325455 times.
✓ Branch 6 taken 43055866 times.
✓ Branch 7 taken 21995027 times.
✓ Branch 9 taken 19944 times.
✓ Branch 10 taken 43035922 times.
87658728 then inCref1.ident == inCref2.ident and
703 crefEqualNoStringCompare(inCref1.componentRef, inCref2.componentRef) and
704 ExpressionBasics.subscriptEqual(inCref1.subscriptLst, inCref2.subscriptLst);
705
706 else false;
707 end match;
708 end crefEqualNoStringCompare;
709
710 public function crefEqualReturn
711 "author: PA
712 Checks if two crefs are equal and if
713 so returns the cref, otherwise fail."
714 input DAE.ComponentRef cr;
715 input DAE.ComponentRef cr2;
716 output DAE.ComponentRef ocr;
717 algorithm
718 ✗ true := crefEqualNoStringCompare(cr, cr2);
719 ocr := cr;
720 end crefEqualReturn;
721
722 public function crefEqualWithoutLastSubs
723 "Checks if two crefs are equal, without considering their last subscripts."
724 input DAE.ComponentRef cr1;
725 input DAE.ComponentRef cr2;
726 output Boolean res;
727 algorithm
728 ✗ res := crefEqualNoStringCompare(crefStripLastSubs(cr1),crefStripLastSubs(cr2));
729 end crefEqualWithoutLastSubs;
730
731 public function crefEqualWithoutSubs
732 "Checks if two crefs are equal, without considering their subscripts."
733 input DAE.ComponentRef cr1;
734 input DAE.ComponentRef cr2;
735 output Boolean res;
736 algorithm
737 863673 res := crefEqualWithoutSubs2(referenceEq(cr1, cr2), cr1, cr2);
738 end crefEqualWithoutSubs;
739
740 protected function crefEqualWithoutSubs2
741 input Boolean refEq;
742 input DAE.ComponentRef icr1;
743 input DAE.ComponentRef icr2;
744 output Boolean res;
745 algorithm
746 res := match(refEq, icr1, icr2)
747 local
748 DAE.Ident n1, n2;
749 Boolean r;
750 DAE.ComponentRef cr1,cr2;
751
752 case (true, _, _) then true;
753
754 case (_, DAE.CREF_IDENT(ident = n1), DAE.CREF_IDENT(ident = n2))
755
4/4
✓ Branch 0 taken 59829 times.
✓ Branch 1 taken 68237 times.
✓ Branch 3 taken 33642 times.
✓ Branch 4 taken 26187 times.
128066 then stringEq(n1, n2);
756
757 case (_, DAE.CREF_QUAL(ident = n1, componentRef = cr1),
758 DAE.CREF_QUAL(ident = n2, componentRef = cr2))
759 algorithm
760
4/4
✓ Branch 0 taken 661846 times.
✓ Branch 1 taken 572402 times.
✓ Branch 3 taken 537094 times.
✓ Branch 4 taken 124752 times.
1234248 r := stringEq(n1, n2);
761 537094 r := if r then crefEqualWithoutSubs2(referenceEq(cr1, cr2), cr1, cr2) else false;
762 then
763 r;
764
765 else false;
766 end match;
767 end crefEqualWithoutSubs2;
768
769 public function crefStripLastSubs
770 "Strips the last subscripts of a ComponentRef"
771 input DAE.ComponentRef inComponentRef;
772 output DAE.ComponentRef outComponentRef;
773 algorithm
774 outComponentRef := match inComponentRef
775 local
776 DAE.Ident id;
777 list<DAE.Subscript> s;
778 DAE.ComponentRef cr_1,cr;
779 DAE.Type t2;
780
781 case DAE.CREF_IDENT(subscriptLst = {}) then inComponentRef;
782
783 case DAE.CREF_IDENT(ident = id,identType = t2)
784 3255743 then
785 makeCrefIdent(id,t2,{});
786
787 case DAE.CREF_QUAL(ident = id,identType = t2,subscriptLst = s,componentRef = cr)
788 algorithm
789 10384703 cr_1 := crefStripLastSubs(cr);
790
2/2
✓ Branch 0 taken 5085290 times.
✓ Branch 1 taken 5299413 times.
10384703 then
791 if referenceEq(cr, cr_1) then inComponentRef else makeCrefQual(id,t2,s,cr_1);
792 end match;
793 end crefStripLastSubs;
794
795 public function makeCrefIdent
796 "@author: adrpo
797 This function creates a DAE.CREF_IDENT(ident, identType, subscriptLst)"
798 input DAE.Ident ident;
799 input DAE.Type identType "type of the identifier, without considering the subscripts";
800 input list<DAE.Subscript> subscriptLst;
801 output DAE.ComponentRef outCrefIdent;
802 annotation(__OpenModelica_EarlyInline = true);
803 algorithm
804 20182808 outCrefIdent := DAE.CREF_IDENT(ident, identType, subscriptLst);
805 end makeCrefIdent;
806
807 public function makeCrefQual
808 "@author: adrpo
809 This function creates a DAE.CREF_QUAL(ident, identType, subscriptLst, componentRef)"
810 input DAE.Ident ident;
811 input DAE.Type identType "type of the identifier, without considering the subscripts";
812 input list<DAE.Subscript> subscriptLst;
813 input DAE.ComponentRef componentRef;
814 output DAE.ComponentRef outCrefQual;
815 annotation(__OpenModelica_EarlyInline = true);
816 algorithm
817 // subCref := shareCref(componentRef);
818 // outCrefQual := shareCref(DAE.CREF_QUAL(ident, identType, subscriptLst, subCref));
819 20921659 outCrefQual := DAE.CREF_QUAL(ident, identType, subscriptLst, componentRef);
820 end makeCrefQual;
821
822 public function printComponentRefStr
823 "Print a ComponentRef.
824 LS: print functions that return a string instead of printing
825 Had to duplicate the huge printExp2 and modify.
826 An alternative would be to implement sprint somehow
827 which would need internal state, with reset and
828 getString methods.
829 Once these are tested and ok, the printExp above can
830 be replaced by a call to these _str functions and
831 printing the result."
832 input DAE.ComponentRef inComponentRef;
833 output String outString;
834 algorithm
835 outString := match inComponentRef
836 local
837 DAE.Ident s,str,strrest,strseb;
838 list<DAE.Subscript> subs;
839 DAE.ComponentRef cr;
840 Boolean b;
841
842 // Optimize -- a function call less
843 case DAE.CREF_IDENT(ident = s,subscriptLst = {})
844 then s;
845
846 // idents with subscripts
847 case DAE.CREF_IDENT(ident = s,subscriptLst = subs)
848 algorithm
849 427786 str := printComponentRef2Str(s, subs);
850 then
851 str;
852
853 // Qualified - Modelica output - does not handle names with underscores
854 // Qualified - non Modelica output
855 case DAE.CREF_QUAL(ident = s,subscriptLst = subs,componentRef = cr)
856 algorithm
857 798597 b := Config.modelicaOutput();
858 798597 str := printComponentRef2Str(s, subs);
859 798597 strrest := printComponentRefStr(cr);
860
1/2
✓ Branch 0 taken 798597 times.
✗ Branch 1 not taken.
798597 strseb := if b then "__" else ".";
861 798597 str := stringAppendList({str, strseb, strrest});
862 then
863 str;
864
865 // Wild
866 case DAE.WILD() then "_";
867 end match;
868 end printComponentRefStr;
869
870 public function printComponentRef2Str
871 "Helper function to printComponentRefStr."
872 input DAE.Ident inIdent;
873 input list<DAE.Subscript> inSubscriptLst;
874 output String outString;
875 algorithm
876 outString := match (inIdent,inSubscriptLst)
877 local
878 DAE.Ident s,str,strseba,strsebb;
879 list<DAE.Subscript> l;
880 Boolean b;
881
882 // no subscripts
883 case (s,{}) then s;
884
885 // some subscripts, Modelica output
886 // some subscripts, non Modelica output
887 case (s,l)
888 algorithm
889 482450 b := Config.modelicaOutput();
890 482450 str := ExpressionBasics.printListStr(l, ExpressionBasics.printSubscriptStr, ",");
891
1/2
✓ Branch 0 taken 482450 times.
✗ Branch 1 not taken.
964900 (strseba,strsebb) := if b then ("_L","_R") else ("[","]");
892 482450 str := stringAppendList({s, strseba, str, strsebb});
893 then
894 str;
895
896 end match;
897 end printComponentRef2Str;
898
899 public function printComponentRefListStr
900 input list<DAE.ComponentRef> crs;
901 output String res;
902 algorithm
903 ✗ res := "{" + stringDelimitList(List.map(crs, printComponentRefStr), ",") + "}";
904 end printComponentRefListStr;
905
906 public constant Integer crefHashSeed = 5381;
907
908 public function crefHasNoSubscripts
909 "A chain of qualifiers and an identifier none of which has subscripts, so a
910 traversal of the expressions in it has nothing to visit."
911 input DAE.ComponentRef cr;
912 output Boolean b;
913 algorithm
914 b := match cr
915 166382281 case DAE.CREF_QUAL(subscriptLst = {}) then crefHasNoSubscripts(cr.componentRef);
916 case DAE.CREF_IDENT(subscriptLst = {}) then true;
917 else false;
918 end match;
919 end crefHasNoSubscripts;
920
921 public function hashComponentRef
922 "djb2 continued over the qualifiers and subscripts in order."
923 input DAE.ComponentRef cr;
924 output Integer hash = hashComponentRefFrom(cr, crefHashSeed);
925 end hashComponentRef;
926
927 protected function hashComponentRefFrom
928 input DAE.ComponentRef cr;
929 input Integer hash;
930 output Integer outHash;
931 algorithm
932 outHash := match cr
933 61391839 case DAE.CREF_IDENT() then crefHashSubscripts(cr.subscriptLst, crefHashIdent(cr.ident, hash));
934 123830435 case DAE.CREF_QUAL() then hashComponentRefFrom(cr.componentRef, crefHashSubscripts(cr.subscriptLst, crefHashIdent(cr.ident, hash)));
935 else hash;
936 end match;
937 end hashComponentRefFrom;
938
939 public function crefHashIdent
940 input String ident;
941 input Integer hash;
942 output Integer outHash = stringHashDjb2Continue(ident, stringHashDjb2Continue(".", hash));
943 end crefHashIdent;
944
945 protected function crefHashSubscripts
946 input list<DAE.Subscript> subs;
947 input output Integer hash;
948 algorithm
949
2/2
✓ Branch 0 taken 38662580 times.
✓ Branch 1 taken 185222274 times.
223884854 for sub in subs loop
950 38662580 hash := crefHashSubscript(sub, hash);
951 end for;
952 end crefHashSubscripts;
953
954 public function crefHashSubscript
955 input DAE.Subscript sub;
956 input Integer hash;
957 output Integer outHash = intHashDjb2Continue(hashSubscript(sub), stringHashDjb2Continue("[", hash));
958 end crefHashSubscript;
959
960 public function hashSubscript "help function"
961 input DAE.Subscript sub;
962 output Integer hash;
963 algorithm
964 hash := match sub
965 local
966 DAE.Exp exp;
967 Integer i;
968
969 case DAE.WHOLEDIM() then 0;
970 case DAE.INDEX(DAE.ICONST(i)) then i;
971 538 case DAE.SLICE(exp) then ExpressionBasics.hashExp(exp);
972 114950 case DAE.INDEX(exp) then ExpressionBasics.hashExp(exp);
973 ✗ case DAE.WHOLE_NONEXP(exp) then ExpressionBasics.hashExp(exp);
974 end match;
975 end hashSubscript;
976
977 annotation(__OpenModelica_Interface="frontend_dump");
978 end ComponentReferenceBasics;
979