Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 47.4% 537 / 0 / 1133
Functions: -% 0 / 1 / 1
Branches: 53.4% 443 / 0 / 829

OMCompiler/Compiler/FrontEnd/DAEUtil.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 DAEUtil
37 " file: DAEUtil.mo
38 package: DAE
39 description: DAE management and output
40
41
42 This module exports some helper functions to the DAE AST."
43
44 import Absyn;
45 import AbsynUtil;
46 import ClassInf;
47 import DAE;
48 import DAEDumpTypes;
49 import FCore;
50 import SCode;
51 import Values;
52 import ValuesUtil;
53 import HashTable;
54 import AvlSetCR;
55
56 protected
57 import Algorithm;
58 import BaseHashTable;
59 import AvlTreePathFunction;
60 import ClassInfUtil;
61 import ComponentReference;
62 import ComponentReferenceBasics;
63 import Config;
64 import DAEDump;
65 import Debug;
66 import DoubleEnded;
67 import ElementSource;
68 import Error;
69 import Expression;
70 protected import ExpressionBasics;
71 import ExpressionSimplify;
72 import Flags;
73 import List;
74 import SCodeUtil;
75 import System;
76 import Types;
77 import Util;
78 import VarTransform;
79 import ValuesDump;
80 import MetaModelica.Dangerous.listReverseInPlace;
81
82 public function constStr "return the DAE.Const as a string. (VAR|PARAM|CONST)
83 Used for debugging."
84 input DAE.Const const;
85 output String str;
86 algorithm
87 str := match const
88 case DAE.C_VAR() then "VAR";
89 case DAE.C_PARAM() then "PARAM";
90 case DAE.C_CONST() then "CONST";
91
92 end match;
93 end constStr;
94
95 public function const2VarKind
96 input DAE.Const const;
97 output DAE.VarKind kind;
98 algorithm
99 kind := match const
100 case DAE.C_VAR() then DAE.VARIABLE();
101 case DAE.C_PARAM() then DAE.PARAM();
102 case DAE.C_CONST() then DAE.CONST();
103 end match;
104 end const2VarKind;
105
106 public function expTypeSimple "returns true if type is simple type"
107 input DAE.Type tp;
108 output Boolean isSimple;
109 algorithm
110 isSimple := match tp
111 case DAE.T_REAL() then true;
112 case DAE.T_INTEGER() then true;
113 case DAE.T_STRING() then true;
114 case DAE.T_BOOL() then true;
115 // BTH
116 case DAE.T_CLOCK() then true;
117 case DAE.T_ENUMERATION() then true;
118 else false;
119 end match;
120 end expTypeSimple;
121
122 public function expTypeElementType "returns the element type of an array"
123 input DAE.Type tp;
124 output DAE.Type eltTp;
125 algorithm
126 eltTp := match tp
127 local
128 DAE.Type ty;
129 14608 case DAE.T_ARRAY(ty=ty) then expTypeElementType(ty);
130 else tp;
131 end match;
132 end expTypeElementType;
133
134 public function expTypeComplex "returns true if type is complex type"
135 input DAE.Type tp;
136 output Boolean isComplex;
137 algorithm
138 isComplex := match tp
139 case DAE.T_COMPLEX() then true;
140 else false;
141 end match;
142 end expTypeComplex;
143
144 public function expTypeArray "returns true if type is array type
145 Alternative names: isArrayType, isExpTypeArray"
146 input DAE.Type tp;
147 output Boolean isArray;
148 algorithm
149 isArray := match tp
150 case DAE.T_ARRAY() then true;
151 else false;
152 end match;
153 end expTypeArray;
154
155 public function expTypeTuple
156 "returns true if type is tuple type."
157 input DAE.Type tp;
158 output Boolean isTuple;
159 algorithm
160 isTuple := match tp
161 case DAE.T_TUPLE() then true;
162 else false;
163 end match;
164 end expTypeTuple;
165
166 public function expTypeArrayDimensions "returns the array dimensions of an ExpType"
167 input DAE.Type tp;
168 output list<Integer> dims;
169 algorithm
170 dims := match tp
171 local DAE.Dimensions array_dims;
172 case DAE.T_ARRAY(dims=array_dims) algorithm
173 ✗ dims := List.map(array_dims, Expression.dimensionSize);
174 then dims;
175 end match;
176 end expTypeArrayDimensions;
177
178 public function typeExp
179 "Converts a type to an expression, covering constants and parameters."
180 input DAE.Type tp;
181 output DAE.Exp exp;
182 algorithm
183 exp := match tp
184 local
185 DAE.Dimension dim;
186 list<DAE.Dimension> rest;
187 case DAE.T_ARRAY(dims = dim :: rest) algorithm
188 ✗ exp := dimExp(dim);
189 ✗ for d in rest loop
190 ✗ exp := DAE.BINARY(exp, DAE.MUL(DAE.T_INTEGER_DEFAULT), dimExp(d));
191 end for;
192 then exp;
193 else DAE.ICONST(1);
194 end match;
195 end typeExp;
196
197 public function dimExp
198 "Converts a dimension to an expression, covering constants and parameters."
199 input DAE.Dimension dim;
200 output DAE.Exp exp;
201 algorithm
202 exp := match dim
203 local
204 Integer iconst;
205 1 case DAE.DIM_INTEGER(iconst) then
206 DAE.ICONST(iconst);
207 case DAE.DIM_EXP(exp) then
208 exp;
209 else algorithm
210 ✗ Error.addMessage(Error.DIMENSION_NOT_KNOWN, {anyString(dim)});
211 ✗ then fail();
212 end match;
213 end dimExp;
214
215 public function derivativeOrder "
216 Function to sort derivatives.
217 Used for Util.sort"
218 input tuple<Integer,DAE.derivativeCond> e1,e2; //greaterThanFunc
219 output Boolean b;
220 protected
221 Integer i1,i2;
222 algorithm
223 b := match(e1,e2)
224 case((i1,_),(i2,_))
225 10 then Util.isIntGreater(i1,i2);
226 end match;
227 end derivativeOrder;
228
229 public function getDerivativePaths " collects all paths representing derivative functions for a list of FunctionDefinition's"
230 input list<DAE.FunctionDefinition> inFuncDefs;
231 output list<Absyn.Path> paths;
232 algorithm
233 paths := match inFuncDefs
234 local
235 list<Absyn.Path> pLst1,pLst2;
236 Absyn.Path p1,p2;
237 list<DAE.FunctionDefinition> funcDefs;
238
239 case {} then {};
240
241 case DAE.FUNCTION_DER_MAPPER(derivativeFunction=p1,defaultDerivative=SOME(p2),lowerOrderDerivatives=pLst1)::funcDefs
242 algorithm
243 ✗ pLst2 := getDerivativePaths(funcDefs);
244 ✗ paths := List.union(p1::p2::pLst1,pLst2);
245 then
246 paths;
247
248 case DAE.FUNCTION_DER_MAPPER(derivativeFunction=p1,defaultDerivative=NONE(),lowerOrderDerivatives=pLst1)::funcDefs
249 algorithm
250 960 pLst2 := getDerivativePaths(funcDefs);
251 960 paths := List.union(p1::pLst1,pLst2);
252 then
253 paths;
254
255 ✗ case _::funcDefs then getDerivativePaths(funcDefs);
256 end match;
257 end getDerivativePaths;
258
259 public function addEquationBoundString "
260 Set the optional equationBound value"
261 input DAE.Exp bindExp;
262 input Option<DAE.VariableAttributes> attr;
263 output Option<DAE.VariableAttributes> oattr;
264 algorithm
265 oattr := match attr
266 local
267 Option<DAE.Exp> e1,e2,e3,e4,e5,e6,min,max;
268 Option<DAE.StartOrigin> so;
269 Option<DAE.StateSelect> sSelectOption;
270 Option<DAE.Uncertainty> unc;
271 Option<DAE.Distribution> distOption;
272 Option<Boolean> ip,fn;
273
274 case SOME(DAE.VAR_ATTR_REAL(e1,e2,e3,min,max,e4,e5,e6,sSelectOption,unc,distOption,_,ip,fn,so))
275 ✗ then (SOME(DAE.VAR_ATTR_REAL(e1,e2,e3,min,max,e4,e5,e6,sSelectOption,unc,distOption,SOME(bindExp),ip,fn,so)));
276
277 case SOME(DAE.VAR_ATTR_INT(e1,min,max,e2,e3,unc,distOption,_,ip,fn,so))
278 ✗ then SOME(DAE.VAR_ATTR_INT(e1,min,max,e2,e3,unc,distOption,SOME(bindExp),ip,fn,so));
279
280 case SOME(DAE.VAR_ATTR_BOOL(e1,e2,e3,_,ip,fn,so))
281 ✗ then SOME(DAE.VAR_ATTR_BOOL(e1,e2,e3,SOME(bindExp),ip,fn,so));
282
283 case SOME(DAE.VAR_ATTR_STRING(e1,e2,e3,_,ip,fn,so))
284 ✗ then SOME(DAE.VAR_ATTR_STRING(e1,e2,e3,SOME(bindExp),ip,fn,so));
285
286 case SOME(DAE.VAR_ATTR_ENUMERATION(e1,min,max,e2,e3,_,ip,fn,so))
287 ✗ then SOME(DAE.VAR_ATTR_ENUMERATION(e1,min,max,e2,e3,SOME(bindExp),ip,fn,so));
288
289 ✗ else algorithm print("-failure in DAEUtil.addEquationBoundString\n"); then fail();
290 end match;
291 end addEquationBoundString;
292
293 public function getClassList "get list of classes from Var"
294 input DAE.Element v;
295 output list<Absyn.Path> lst;
296 algorithm
297 lst := match v
298 case DAE.VAR(source = DAE.SOURCE(typeLst=lst)) then lst;
299 else {};
300 end match;
301 end getClassList;
302
303 public function getEmptyVarAttr
304 input DAE.Type ty;
305 output Option<DAE.VariableAttributes> attr;
306 algorithm
307 attr := match Types.getBasicType(ty)
308 case DAE.Type.T_REAL() then SOME(DAE.emptyVarAttrReal);
309 case DAE.Type.T_INTEGER() then SOME(DAE.emptyVarAttrInt);
310 case DAE.Type.T_BOOL() then SOME(DAE.emptyVarAttrBool);
311 case DAE.Type.T_STRING() then SOME(DAE.emptyVarAttrString);
312 case DAE.Type.T_ENUMERATION() then SOME(DAE.emptyVarAttrEnum);
313 case DAE.Type.T_CLOCK() then SOME(DAE.emptyVarAttrClock);
314 else NONE();
315 end match;
316 end getEmptyVarAttr;
317
318 public function getBoundStartEquation "
319 Returned bound equation"
320 input DAE.VariableAttributes attr;
321 output DAE.Exp oe;
322 algorithm
323 oe := match attr
324 local DAE.Exp beq;
325 case DAE.VAR_ATTR_REAL(equationBound = SOME(beq)) then beq;
326 case DAE.VAR_ATTR_INT(equationBound = SOME(beq)) then beq;
327 case DAE.VAR_ATTR_BOOL(equationBound = SOME(beq)) then beq;
328 case DAE.VAR_ATTR_ENUMERATION(equationBound = SOME(beq)) then beq;
329 end match;
330 end getBoundStartEquation;
331
332 public function splitDAEIntoVarsAndEquations
333 "Splits the DAE into one with vars and no equations and algorithms
334 and another one which has all the equations and algorithms but no variables.
335 Note: the functions are copied to both dae's.
336 "
337 input DAE.DAElist inDae;
338 output DAE.DAElist allVars;
339 output DAE.DAElist allEqs;
340 protected
341 list<DAE.Element> rest;
342 DoubleEnded.MutableList<DAE.Element> vars, eqs;
343 algorithm
344 721 DAE.DAE(rest) := inDae;
345 721 vars := DoubleEnded.fromList({});
346 721 eqs := DoubleEnded.fromList({});
347
5/29
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 83 times.
✓ Branch 28 taken 721 times.
804 for elt in rest loop
348 () := match elt
349 local
350 list<DAE.Element> elts1,elts11,elts3;
351 String id;
352 DAE.ElementSource source "the origin of the element";
353 Option<SCode.Comment> cmt;
354
355 case DAE.VAR()
356 algorithm
357 43 DoubleEnded.push_back(vars, elt);
358 then ();
359
360 // adrpo: TODO! FIXME! a DAE.COMP SHOULD NOT EVER BE HERE!
361 case DAE.COMP(id,elts1,source,cmt)
362 algorithm
363 10 (DAE.DAE(elts11),DAE.DAE(elts3)) := splitDAEIntoVarsAndEquations(DAE.DAE(elts1));
364 10 DoubleEnded.push_back(vars, DAE.COMP(id,elts11,source,cmt));
365 10 DoubleEnded.push_list_back(eqs, elts3);
366 then ();
367
368 case DAE.EQUATION()
369 algorithm
370 30 DoubleEnded.push_back(eqs, elt);
371 then ();
372
373 case DAE.EQUEQUATION()
374 algorithm
375 ✗ DoubleEnded.push_back(eqs, elt);
376 then ();
377
378 case DAE.INITIALEQUATION()
379 algorithm
380 ✗ DoubleEnded.push_back(eqs, elt);
381 then ();
382
383 case DAE.ARRAY_EQUATION()
384 algorithm
385 ✗ DoubleEnded.push_back(eqs, elt);
386 then ();
387
388 case DAE.INITIAL_ARRAY_EQUATION()
389 algorithm
390 ✗ DoubleEnded.push_back(eqs, elt);
391 then ();
392
393 case DAE.COMPLEX_EQUATION()
394 algorithm
395 ✗ DoubleEnded.push_back(eqs, elt);
396 then ();
397
398 case DAE.INITIAL_COMPLEX_EQUATION()
399 algorithm
400 ✗ DoubleEnded.push_back(eqs, elt);
401 then ();
402
403 case DAE.INITIALDEFINE()
404 algorithm
405 ✗ DoubleEnded.push_back(eqs, elt);
406 then ();
407
408 case DAE.DEFINE()
409 algorithm
410 ✗ DoubleEnded.push_back(eqs, elt);
411 then ();
412
413 case DAE.WHEN_EQUATION()
414 algorithm
415 ✗ DoubleEnded.push_back(eqs, elt);
416 then ();
417
418 case DAE.FOR_EQUATION()
419 algorithm
420 ✗ DoubleEnded.push_back(eqs, elt);
421 then ();
422
423 case DAE.INITIAL_FOR_EQUATION()
424 algorithm
425 ✗ DoubleEnded.push_back(eqs, elt);
426 then ();
427
428 case DAE.IF_EQUATION()
429 algorithm
430 ✗ DoubleEnded.push_back(eqs, elt);
431 then ();
432
433 case DAE.INITIAL_IF_EQUATION()
434 algorithm
435 ✗ DoubleEnded.push_back(eqs, elt);
436 then ();
437
438 case DAE.ALGORITHM()
439 algorithm
440 ✗ DoubleEnded.push_back(eqs, elt);
441 then ();
442
443 case DAE.INITIALALGORITHM()
444 algorithm
445 ✗ DoubleEnded.push_back(eqs, elt);
446 then ();
447
448 // adrpo: TODO! FIXME! why are external object constructor calls added to the non-equations DAE??
449 // PA: are these external object constructor CALLS? Do not think so. But they should anyway be in funcs..
450 case DAE.EXTOBJECTCLASS()
451 algorithm
452 ✗ DoubleEnded.push_back(vars, elt);
453 then ();
454
455 case DAE.ASSERT()
456 algorithm
457 ✗ DoubleEnded.push_back(eqs, elt);
458 then ();
459
460 case DAE.INITIAL_ASSERT()
461 algorithm
462 ✗ DoubleEnded.push_back(eqs, elt);
463 then ();
464
465 case DAE.TERMINATE()
466 algorithm
467 ✗ DoubleEnded.push_back(eqs, elt);
468 then ();
469
470 case DAE.INITIAL_TERMINATE()
471 algorithm
472 ✗ DoubleEnded.push_back(eqs, elt);
473 then ();
474
475 case DAE.REINIT()
476 algorithm
477 ✗ DoubleEnded.push_back(eqs, elt);
478 then ();
479
480 // handle also NORETCALL! Connections.root(...)
481 case DAE.NORETCALL()
482 algorithm
483 ✗ DoubleEnded.push_back(eqs, elt);
484 then ();
485
486 case DAE.INITIAL_NORETCALL()
487 algorithm
488 ✗ DoubleEnded.push_back(eqs, elt);
489 then ();
490
491 else
492 algorithm
493 ✗ Error.addInternalError(getInstanceName() + " failed for " + DAEDump.dumpDAEElementsStr(DAE.DAE({elt})), sourceInfo());
494 ✗ then fail();
495 end match;
496 end for;
497 721 allVars := DAE.DAE(DoubleEnded.toListAndClear(vars));
498 721 allEqs := DAE.DAE(DoubleEnded.toListAndClear(eqs));
499 end splitDAEIntoVarsAndEquations;
500
501 public function removeVariables "Remove the variables in the list from the DAE"
502 input DAE.DAElist dae;
503 input list<DAE.ComponentRef> vars;
504 output DAE.DAElist outDae;
505 algorithm
506 // adrpo: TODO! FIXME! rather expensive function!
507 // implement this by walking dae once and check element with each var in the list
508 // instead of walking the dae once for each var.
509 // outDae := List.fold(vars,removeVariable,dae);
510 outDae := match(dae, vars)
511 local
512 list<DAE.Element> elements;
513
514 case (_, {}) then dae;
515
516 case (DAE.DAE(elements), _)
517 algorithm
518 7 elements := removeVariablesFromElements(elements, vars);
519 7 then
520 DAE.DAE(elements);
521
522 end match;
523 end removeVariables;
524
525 protected function removeVariablesFromElements
526 "@author: adrpo
527 remove the variables that match for the element list"
528 input list<DAE.Element> inElements;
529 input list<DAE.ComponentRef> variableNames;
530 output list<DAE.Element> outElements = {};
531 algorithm
532
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if listEmpty(variableNames) then
533 outElements := inElements;
534 ✗ return;
535 end if;
536
2/2
✓ Branch 0 taken 13320 times.
✓ Branch 1 taken 7 times.
13327 for el in inElements loop
537 () := match el
538 local
539 DAE.ComponentRef cr;
540 list<DAE.Element> elist;
541 DAE.Element v;
542 String id;
543 DAE.ElementSource source "the origin of the element";
544 Option<SCode.Comment> cmt;
545
546 case v as DAE.VAR(componentRef = cr)
547 algorithm
548 // variable is in the list! jump over it
549
2/2
✓ Branch 1 taken 8720 times.
✓ Branch 2 taken 2084 times.
10804 if listEmpty(List.select1(variableNames, ComponentReferenceBasics.crefEqual, cr)) then
550 outElements := v::outElements;
551 end if;
552 then ();
553
554 // handle components
555 case DAE.COMP(id,elist,source,cmt)
556 algorithm
557 ✗ elist := removeVariablesFromElements(elist, variableNames);
558 ✗ outElements := DAE.COMP(id,elist,source,cmt)::outElements;
559 then ();
560
561 // anything else, just keep it
562 else
563 algorithm
564 outElements := el::outElements;
565 then ();
566 end match;
567 end for;
568 7 outElements := MetaModelica.Dangerous.listReverseInPlace(outElements);
569 end removeVariablesFromElements;
570
571 protected function removeVariable "Remove the variable from the DAE, UNUSED"
572 input DAE.ComponentRef var;
573 input DAE.DAElist dae;
574 output DAE.DAElist outDae;
575 algorithm
576 outDae := matchcontinue dae
577 local
578 DAE.ComponentRef cr;
579 list<DAE.Element> elist,elist2;
580 DAE.Element e; String id;
581 DAE.ElementSource source "the origin of the element";
582 Option<SCode.Comment> cmt;
583
584 case DAE.DAE({}) then DAE.DAE({});
585
586 case DAE.DAE((DAE.VAR(componentRef = cr))::elist)
587 algorithm
588 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(var,cr);
589 ✗ then DAE.DAE(elist);
590
591 case DAE.DAE(DAE.COMP(id,elist,source,cmt)::elist2)
592 algorithm
593 ✗ DAE.DAE(elist) := removeVariable(var,DAE.DAE(elist));
594 ✗ DAE.DAE(elist2) := removeVariable(var,DAE.DAE(elist2));
595 ✗ then DAE.DAE(DAE.COMP(id,elist,source,cmt)::elist2);
596
597 case DAE.DAE(e::elist)
598 algorithm
599 ✗ DAE.DAE(elist) := removeVariable(var,DAE.DAE(elist));
600 ✗ then DAE.DAE(e::elist);
601 end matchcontinue;
602 end removeVariable;
603
604 public function removeInnerAttrs "Remove the inner attribute of all vars in list"
605 input DAE.DAElist dae;
606 input list<DAE.ComponentRef> vars;
607 output DAE.DAElist outDae;
608 algorithm
609 ✗ outDae := List.fold(vars,removeInnerAttr,dae);
610 end removeInnerAttrs;
611
612 public function removeInnerAttr "Remove the inner attribute from variable in the DAE"
613 input DAE.ComponentRef var;
614 input DAE.DAElist dae;
615 output DAE.DAElist outDae;
616 algorithm
617 outDae := match dae
618 local
619 DAE.ComponentRef cr,oldVar,newVar;
620 list<DAE.Element> elist,elist2;
621 DAE.Element e,u,o; String id;
622 DAE.VarKind kind; DAE.VarParallelism prl;
623 DAE.VarDirection dir; DAE.Type tp;
624 Option<DAE.Exp> bind; DAE.InstDims dim;
625 DAE.ConnectorType ct; Option<DAE.VariableAttributes> attr;
626 Option<SCode.Comment> cmt; Absyn.InnerOuter io,io2;
627 Boolean ie;
628 DAE.VarVisibility prot;
629 DAE.ElementSource source "the origin of the element";
630
631 case DAE.DAE({}) then DAE.DAE({});
632 /* When having an inner outer, we declare two variables on the same line.
633 Since we can not handle this with current instantiation procedure, we create temporary variables in the dae.
634 These are named uniqly and renamed later in "instClass"
635 */
636 case DAE.DAE(DAE.VAR(oldVar,kind,dir,prl,prot,tp,bind,dim,ct,source,attr,cmt,(Absyn.INNER_OUTER()),ie)::elist)
637 guard
638 compareUniquedVarWithNonUnique(var,oldVar)
639 algorithm
640 ✗ newVar := nameInnerouterUniqueCref(oldVar);
641 ✗ o := DAE.VAR(oldVar,kind,dir,prl,prot,tp,NONE(),dim,ct,source,attr,cmt,Absyn.OUTER(),ie) "intact";
642 ✗ u := DAE.VAR(newVar,kind,dir,prl,prot,tp,bind,dim,ct,source,attr,cmt,Absyn.NOT_INNER_OUTER(),ie) " unique'ified";
643 elist:= u::o::elist;
644 ✗ then
645 DAE.DAE(elist);
646
647 case DAE.DAE(DAE.VAR(cr,kind,dir,prl,prot,tp,bind,dim,ct,source,attr,cmt,io,ie)::elist)
648 guard
649 ComponentReferenceBasics.crefEqualNoStringCompare(var,cr)
650 algorithm
651 ✗ io2 := removeInnerAttribute(io);
652 ✗ then
653 DAE.DAE(DAE.VAR(cr,kind,dir,prl,prot,tp,bind,dim,ct,source,attr,cmt,io2,ie)::elist);
654
655 case DAE.DAE(DAE.COMP(id,elist,source,cmt)::elist2)
656 algorithm
657 ✗ DAE.DAE(elist) := removeInnerAttr(var,DAE.DAE(elist));
658 ✗ DAE.DAE(elist2) := removeInnerAttr(var,DAE.DAE(elist2));
659 ✗ then DAE.DAE(DAE.COMP(id,elist,source,cmt)::elist2);
660
661 case DAE.DAE(e::elist)
662 algorithm
663 ✗ DAE.DAE(elist):= removeInnerAttr(var,DAE.DAE(elist));
664 ✗ then DAE.DAE(e::elist);
665 end match;
666 end removeInnerAttr;
667
668 protected function compareUniquedVarWithNonUnique "
669 Author: BZ, workaround to get innerouter elements to work.
670 This function strips the 'unique identifer' from the cref and compares.
671 "
672 input DAE.ComponentRef cr1;
673 input DAE.ComponentRef cr2;
674 output Boolean equal;
675 protected
676 String s1,s2;
677 algorithm
678 ✗ s1 := ComponentReferenceBasics.printComponentRefStr(cr1);
679 ✗ s2 := ComponentReferenceBasics.printComponentRefStr(cr2);
680 ✗ s1 := System.stringReplace(s1, DAE.UNIQUEIO, "");
681 ✗ s2 := System.stringReplace(s2, DAE.UNIQUEIO, "");
682 ✗ equal := stringEq(s1,s2);
683 end compareUniquedVarWithNonUnique;
684
685 public function nameInnerouterUniqueCref "
686 Author: BZ, 2008-11
687 Renames a var to unique name"
688 input DAE.ComponentRef inCr;
689 output DAE.ComponentRef outCr;
690 algorithm outCr := match inCr
691 local
692 DAE.ComponentRef newChild,child;
693 String id;
694 DAE.Type idt;
695 list<DAE.Subscript> subs;
696 case DAE.CREF_IDENT(id,idt,subs)
697 algorithm
698 ✗ id := DAE.UNIQUEIO + id;
699 ✗ then
700 ComponentReferenceBasics.makeCrefIdent(id,idt,subs);
701 case DAE.CREF_QUAL(id,idt,subs,child)
702 algorithm
703 ✗ newChild := nameInnerouterUniqueCref(child);
704 ✗ then
705 ComponentReferenceBasics.makeCrefQual(id,idt,subs,newChild);
706 end match;
707 end nameInnerouterUniqueCref;
708
709 public function unNameInnerouterUniqueCref "
710 Function for stripping a cref of its uniqified part.
711 Remove 'removalString' from the cref if found
712 "
713 input DAE.ComponentRef cr;
714 input String removalString;
715 output DAE.ComponentRef ocr;
716 algorithm ocr := matchcontinue cr
717 local
718 String str,str2;
719 DAE.Type ty;
720 DAE.ComponentRef child,child_2;
721 list<DAE.Subscript> subs;
722 case DAE.CREF_IDENT(str,ty,subs)
723 algorithm
724 ✗ str2 := System.stringReplace(str, removalString, "");
725 ✗ then
726 ComponentReferenceBasics.makeCrefIdent(str2,ty,subs);
727 case DAE.CREF_QUAL(str,ty,subs,child)
728 algorithm
729 ✗ child_2 := unNameInnerouterUniqueCref(child,removalString);
730 ✗ str2 := System.stringReplace(str, removalString, "");
731 ✗ then
732 ComponentReferenceBasics.makeCrefQual(str2,ty,subs,child_2);
733 case DAE.WILD() then DAE.WILD();
734 case child
735 algorithm
736 ✗ print(" failure unNameInnerouterUniqueCref: ");
737 ✗ print(ComponentReferenceBasics.printComponentRefStr(child) + "\n");
738 ✗ then fail();
739 end matchcontinue;
740 end unNameInnerouterUniqueCref;
741
742 protected function removeInnerAttribute "Help function to removeInnerAttr"
743 input Absyn.InnerOuter io;
744 output Absyn.InnerOuter ioOut;
745 algorithm
746 ioOut := match io
747 case Absyn.INNER() then Absyn.NOT_INNER_OUTER();
748 case Absyn.INNER_OUTER() then Absyn.OUTER();
749 else io;
750 end match;
751 end removeInnerAttribute;
752
753 public function varCref " returns the component reference of a variable"
754 input DAE.Element elt;
755 output DAE.ComponentRef cr;
756 algorithm
757
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93332 times.
93332 DAE.VAR(componentRef = cr) := elt;
758 end varCref;
759
760 public function getVariableAttributes " gets the attributes of a DAE.Element that is VAR"
761 input DAE.Element elt;
762 output Option<DAE.VariableAttributes> variableAttributesOption;
763 algorithm
764 ✗ DAE.VAR(variableAttributesOption=variableAttributesOption) := elt;
765 end getVariableAttributes;
766
767 public function getUnitAttr "
768 Return the unit attribute"
769 input Option<DAE.VariableAttributes> inVariableAttributesOption;
770 output DAE.Exp start;
771 algorithm
772 start := match inVariableAttributesOption
773 local
774 DAE.Exp u;
775 case SOME(DAE.VAR_ATTR_REAL(unit=SOME(u))) then u;
776 else DAE.SCONST("");
777 end match;
778 end getUnitAttr;
779
780 public function getStartAttrEmpty "
781 Return the start attribute."
782 input Option<DAE.VariableAttributes> inVariableAttributesOption;
783 input DAE.Exp optExp;
784 output DAE.Exp start;
785 algorithm
786 start := match inVariableAttributesOption
787 local
788 DAE.Exp r;
789 case SOME(DAE.VAR_ATTR_REAL(start = SOME(r))) then r;
790 case SOME(DAE.VAR_ATTR_INT(start = SOME(r))) then r;
791 case SOME(DAE.VAR_ATTR_BOOL(start = SOME(r))) then r;
792 case SOME(DAE.VAR_ATTR_STRING(start = SOME(r))) then r;
793 case SOME(DAE.VAR_ATTR_ENUMERATION(start = SOME(r))) then r;
794 else optExp;
795 end match;
796 end getStartAttrEmpty;
797
798 public function getMinMax "
799 Author: BZ, returns a list of optional exp, {opt<Min> opt<Max} "
800 input Option<DAE.VariableAttributes> inVariableAttributesOption;
801 output list<Option<DAE.Exp>> oExps;
802 algorithm
803 oExps := match inVariableAttributesOption
804 local
805 Option<DAE.Exp> e1,e2;
806
807 case SOME(DAE.VAR_ATTR_ENUMERATION(min = e1, max = e2)) then {e1, e2};
808 case SOME(DAE.VAR_ATTR_INT(min = e1, max = e2)) then {e1, e2};
809 case SOME(DAE.VAR_ATTR_REAL(min = e1, max = e2)) then {e1, e2};
810 else {};
811
812 end match;
813 end getMinMax;
814
815 public function getMinMaxValues
816 input Option<DAE.VariableAttributes> inVariableAttributesOption;
817 output Option<DAE.Exp> outMinValue;
818 output Option<DAE.Exp> outMaxValue;
819 algorithm
820 (outMinValue, outMaxValue) := match inVariableAttributesOption
821 local
822 Option<DAE.Exp> minValue, maxValue;
823
824 case SOME(DAE.VAR_ATTR_ENUMERATION(min = minValue, max = maxValue))
825 then (minValue, maxValue);
826
827 case SOME(DAE.VAR_ATTR_INT(min = minValue, max = maxValue))
828 then (minValue, maxValue);
829
830 case SOME(DAE.VAR_ATTR_REAL(min = minValue, max = maxValue))
831 then (minValue, maxValue);
832
833 else (NONE(), NONE());
834 end match;
835 end getMinMaxValues;
836
837 public function setMinMax
838 "Sets the min and max attributes. If inAttr is NONE(), assumes Real attributes."
839 input Option<DAE.VariableAttributes> inAttr;
840 input Option<DAE.Exp> inMin;
841 input Option<DAE.Exp> inMax;
842 output Option<DAE.VariableAttributes> outAttr;
843 algorithm
844 outAttr := match inAttr
845 local
846 Option<DAE.Exp> q,u,du,f,n,i;
847 Option<DAE.StateSelect> ss;
848 Option<DAE.Uncertainty> unc;
849 Option<DAE.Distribution> distOpt;
850 Option<DAE.Exp> eb;
851 Option<Boolean> ip,fn;
852 Option<DAE.StartOrigin> so;
853 Option<DAE.Exp> min,max;
854
855 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,ip,fn,so))
856
1/2
✓ Branch 0 taken 4705 times.
✗ Branch 1 not taken.
4705 then if referenceEq(min,inMin) and referenceEq(max,inMax) then inAttr else SOME(DAE.VAR_ATTR_REAL(q,u,du,inMin,inMax,i,f,n,ss,unc,distOpt,eb,ip,fn,so));
857
858 case SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,ip,fn,so))
859
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 then if referenceEq(min,inMin) and referenceEq(max,inMax) then inAttr else SOME(DAE.VAR_ATTR_INT(q,inMin,inMax,i,f,unc,distOpt,eb,ip,fn,so));
860
861 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,ip,fn,so))
862
1/2
✓ Branch 0 taken 2367 times.
✗ Branch 1 not taken.
2367 then if referenceEq(min,inMin) and referenceEq(max,inMax) then inAttr else SOME(DAE.VAR_ATTR_ENUMERATION(q,inMin,inMax,u,du,eb,ip,fn,so));
863
864 case NONE()
865 ✗ then SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),inMin,inMax,NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE()));
866 end match;
867 end setMinMax;
868
869 public function getStartAttr "
870 Return the start attribute."
871 input Option<DAE.VariableAttributes> inAttributes;
872 input DAE.Type inType;
873 output DAE.Exp start;
874 protected
875 DAE.Exp e;
876 algorithm
877 start := match inAttributes
878 case SOME(DAE.VAR_ATTR_REAL(start = SOME(e))) then e;
879 case SOME(DAE.VAR_ATTR_INT(start = SOME(e))) then e;
880 case SOME(DAE.VAR_ATTR_BOOL(start = SOME(e))) then e;
881 case SOME(DAE.VAR_ATTR_STRING(start = SOME(e))) then e;
882 case SOME(DAE.VAR_ATTR_ENUMERATION(start = SOME(e))) then e;
883 else
884 match Types.getBasicType(inType)
885 case DAE.Type.T_INTEGER() then DAE.ICONST(0);
886 case DAE.Type.T_STRING() then DAE.SCONST("");
887 case DAE.Type.T_BOOL() then DAE.BCONST(false);
888 545 case DAE.Type.T_ENUMERATION() then Types.getNthEnumLiteral(inType, 1);
889 else DAE.RCONST(0.0);
890 end match;
891 end match;
892 end getStartAttr;
893
894 public function getStartOrigin "
895 Return the startOrigin attribute"
896 input Option<DAE.VariableAttributes> inVariableAttributesOption;
897 output Option<DAE.StartOrigin> startOrigin;
898 algorithm startOrigin:= match inVariableAttributesOption
899 local
900 Option<DAE.StartOrigin> so;
901 case SOME(DAE.VAR_ATTR_REAL(startOrigin = so)) then so;
902 case SOME(DAE.VAR_ATTR_INT(startOrigin = so)) then so;
903 case SOME(DAE.VAR_ATTR_BOOL(startOrigin = so)) then so;
904 case SOME(DAE.VAR_ATTR_STRING(startOrigin = so)) then so;
905 case SOME(DAE.VAR_ATTR_ENUMERATION(startOrigin = so)) then so;
906 case NONE() then NONE();
907 end match;
908 end getStartOrigin;
909
910 public function getStartAttrFail "
911 Return the start attribute. or fails"
912 input Option<DAE.VariableAttributes> inVariableAttributesOption;
913 output DAE.Exp start;
914 algorithm start:= match inVariableAttributesOption
915 local
916 DAE.Exp r;
917 case SOME(DAE.VAR_ATTR_REAL(start = SOME(r))) then r;
918 case SOME(DAE.VAR_ATTR_INT(start = SOME(r))) then r;
919 case SOME(DAE.VAR_ATTR_BOOL(start = SOME(r))) then r;
920 case SOME(DAE.VAR_ATTR_STRING(start = SOME(r))) then r;
921 case SOME(DAE.VAR_ATTR_ENUMERATION(start = SOME(r))) then r;
922 end match;
923 end getStartAttrFail;
924
925 public function getNominalAttrFail "
926 Return the nominal attribute. or fails"
927 input Option<DAE.VariableAttributes> inVariableAttributesOption;
928 output DAE.Exp nominal;
929 algorithm nominal := match inVariableAttributesOption
930 local
931 DAE.Exp r;
932 case SOME(DAE.VAR_ATTR_REAL(nominal = SOME(r))) then r;
933 end match;
934 end getNominalAttrFail;
935
936 public function getMinAttrFail "
937 Return the min attribute. or fails"
938 input Option<DAE.VariableAttributes> inVariableAttributesOption;
939 output DAE.Exp outMin;
940 algorithm
941
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 253037 times.
✓ Branch 2 taken 4317 times.
✓ Branch 3 taken 248720 times.
✓ Branch 5 taken 26246 times.
✓ Branch 6 taken 222474 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 222474 times.
✓ Branch 10 taken 194137 times.
✓ Branch 11 taken 28337 times.
253037 SOME(DAE.VAR_ATTR_REAL(min = SOME(outMin))) := inVariableAttributesOption;
942 end getMinAttrFail;
943
944 public function getMaxAttrFail "
945 Return the max attribute. or fails"
946 input Option<DAE.VariableAttributes> inVariableAttributesOption;
947 output DAE.Exp outMax;
948 algorithm
949
8/10
✗ Branch 0 not taken.
✓ Branch 1 taken 253037 times.
✓ Branch 2 taken 4317 times.
✓ Branch 3 taken 248720 times.
✓ Branch 5 taken 26246 times.
✓ Branch 6 taken 222474 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 222474 times.
✓ Branch 10 taken 212849 times.
✓ Branch 11 taken 9625 times.
253037 SOME(DAE.VAR_ATTR_REAL(max = SOME(outMax))) := inVariableAttributesOption;
950 end getMaxAttrFail;
951
952 public function setVariableAttributes "sets the attributes of a DAE.Element that is VAR"
953 input DAE.Element var;
954 input Option<DAE.VariableAttributes> varOpt;
955 output DAE.Element v = var;
956 algorithm
957 v := match v
958 case DAE.VAR()
959 algorithm
960 1699 v.variableAttributesOption := varOpt;
961 then v;
962 end match;
963 end setVariableAttributes;
964
965 public function setStateSelect "
966 sets the stateselect attribute. If NONE(), assumes Real attributes."
967 input Option<DAE.VariableAttributes> attr;
968 input DAE.StateSelect s;
969 output Option<DAE.VariableAttributes> outAttr;
970 algorithm
971 outAttr := match attr
972 local
973 DAE.VariableAttributes va;
974 case SOME(va as DAE.VAR_ATTR_REAL())
975 algorithm
976 4231 va.stateSelectOption := SOME(s);
977 then SOME(va);
978 case NONE()
979 ✗ then SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),SOME(s),NONE(),NONE(),NONE(),NONE(),NONE(),NONE()));
980 end match;
981 end setStateSelect;
982
983 public function setStartAttr "
984 sets the start attribute. If NONE(), assumes Real attributes."
985 input Option<DAE.VariableAttributes> attr;
986 input DAE.Exp start;
987 output Option<DAE.VariableAttributes> outAttr;
988 algorithm
989 16457 outAttr := setStartAttrOption(attr,SOME(start));
990 end setStartAttr;
991
992 public function setStartAttrOption "
993 sets the start attribute. If NONE(), assumes Real attributes."
994 input Option<DAE.VariableAttributes> attr;
995 input Option<DAE.Exp> start;
996 output Option<DAE.VariableAttributes> outAttr;
997 algorithm
998 outAttr := match attr
999 local
1000 DAE.VariableAttributes va;
1001 Option<DAE.VariableAttributes> at;
1002 case SOME(va as DAE.VAR_ATTR_REAL())
1003 algorithm
1004
2/2
✓ Branch 1 taken 233506 times.
✓ Branch 2 taken 87937 times.
321443 if valueEq(va.start, start) then
1005 at := attr;
1006 else
1007 233506 va.start := start;
1008 at := SOME(va);
1009 end if;
1010 then at;
1011 case SOME(va as DAE.VAR_ATTR_INT())
1012 algorithm
1013
2/2
✓ Branch 1 taken 2625 times.
✓ Branch 2 taken 3435 times.
6060 if valueEq(va.start, start) then
1014 at := attr;
1015 else
1016 2625 va.start := start;
1017 at := SOME(va);
1018 end if;
1019 then at;
1020 case SOME(va as DAE.VAR_ATTR_BOOL())
1021 algorithm
1022
2/2
✓ Branch 1 taken 2019 times.
✓ Branch 2 taken 1206 times.
3225 if valueEq(va.start, start) then
1023 at := attr;
1024 else
1025 2019 va.start := start;
1026 at := SOME(va);
1027 end if;
1028 then at;
1029 case SOME(va as DAE.VAR_ATTR_STRING())
1030 algorithm
1031
2/2
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 13 times.
36 if valueEq(va.start, start) then
1032 at := attr;
1033 else
1034 23 va.start := start;
1035 at := SOME(va);
1036 end if;
1037 then at;
1038 case SOME(va as DAE.VAR_ATTR_ENUMERATION())
1039 algorithm
1040
2/2
✓ Branch 1 taken 690 times.
✓ Branch 2 taken 365 times.
1055 if valueEq(va.start, start) then
1041 at := attr;
1042 else
1043 690 va.start := start;
1044 at := SOME(va);
1045 end if;
1046 then at;
1047 case NONE()
1048
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
116 then if isNone(start) then NONE() else SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),NONE(),NONE(),start,NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE()));
1049 end match;
1050 end setStartAttrOption;
1051
1052 public function setStartOrigin "
1053 sets the startOrigin attribute. If NONE(), assumes Real attributes."
1054 input Option<DAE.VariableAttributes> attr;
1055 input Option<DAE.StartOrigin> startOrigin;
1056 output Option<DAE.VariableAttributes> outAttr;
1057 algorithm
1058 outAttr := match attr
1059 local
1060 DAE.VariableAttributes va;
1061 case SOME(va as DAE.VAR_ATTR_REAL())
1062 algorithm
1063 9316 va.startOrigin := startOrigin;
1064 then SOME(va);
1065 case SOME(va as DAE.VAR_ATTR_INT())
1066 algorithm
1067 ✗ va.startOrigin := startOrigin;
1068 then SOME(va);
1069 case SOME(va as DAE.VAR_ATTR_BOOL())
1070 algorithm
1071 ✗ va.startOrigin := startOrigin;
1072 then SOME(va);
1073 case SOME(va as DAE.VAR_ATTR_STRING())
1074 algorithm
1075 ✗ va.startOrigin := startOrigin;
1076 then SOME(va);
1077 case SOME(va as DAE.VAR_ATTR_ENUMERATION())
1078 algorithm
1079 ✗ va.startOrigin := startOrigin;
1080 then SOME(va);
1081 case NONE()
1082 ✗ then if isNone(startOrigin) then NONE() else SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),startOrigin));
1083 end match;
1084 end setStartOrigin;
1085
1086 public function getNominalAttr "
1087 returns the nominal attribute. If NONE(), assumes Real attributes."
1088 input Option<DAE.VariableAttributes> attr;
1089 output DAE.Exp nominal;
1090 algorithm
1091 nominal:= match attr
1092 local
1093 DAE.Exp n;
1094 case SOME(DAE.VAR_ATTR_REAL(nominal=SOME(n))) then n;
1095 else DAE.RCONST(1.0);
1096 end match;
1097 end getNominalAttr;
1098
1099 public function setNominalAttr "
1100 sets the nominal attribute. If NONE(), assumes Real attributes."
1101 input Option<DAE.VariableAttributes> attr;
1102 input DAE.Exp nominal;
1103 output Option<DAE.VariableAttributes> outAttr;
1104 algorithm
1105 outAttr := match attr
1106 local
1107 DAE.VariableAttributes va;
1108 case SOME(va as DAE.VAR_ATTR_REAL())
1109 algorithm
1110 3101 va.nominal := SOME(nominal);
1111 then SOME(va);
1112 case NONE()
1113 ✗ then SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),SOME(nominal),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE()));
1114 end match;
1115 end setNominalAttr;
1116
1117 public function setUnitAttr "
1118 sets the unit attribute."
1119 input Option<DAE.VariableAttributes> attr;
1120 input DAE.Exp unit;
1121 output Option<DAE.VariableAttributes> outAttr;
1122 algorithm
1123 outAttr:=
1124 match attr
1125 local
1126 Option<DAE.Exp> q,du,f,n,s,min,max;
1127 Option<DAE.StartOrigin> so;
1128 Option<DAE.StateSelect> ss;
1129 Option<DAE.Uncertainty> unc;
1130 Option<DAE.Distribution> distOpt;
1131 Option<DAE.Exp> eb;
1132 Option<Boolean> ip,fn;
1133
1134 case SOME(DAE.VAR_ATTR_REAL(q,_,du,min,max,s,f,n,ss,unc,distOpt,eb,ip,fn,so))
1135 8 then SOME(DAE.VAR_ATTR_REAL(q,SOME(unit),du,min,max,s,f,n,ss,unc,distOpt,eb,ip,fn,so));
1136 case NONE()
1137 ✗ then SOME(DAE.VAR_ATTR_REAL(NONE(),SOME(unit),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE()));
1138 end match;
1139 end setUnitAttr;
1140
1141 public function setElementVarVisibility "
1142 This function takes a VAR elemets and sets var visibility."
1143 input DAE.Element elt;
1144 input DAE.VarVisibility visibility;
1145 output DAE.Element e = elt;
1146 algorithm
1147 e := match e
1148 case DAE.VAR()
1149 algorithm
1150 6331 e.protection := visibility;
1151 then e;
1152 else e;
1153 end match;
1154 end setElementVarVisibility;
1155
1156 public function setElementVarDirection "
1157 This function takes a VAR elemets and sets var direction."
1158 input DAE.Element elt;
1159 input DAE.VarDirection direction;
1160 output DAE.Element e = elt;
1161 algorithm
1162 e := match e
1163 case DAE.VAR()
1164 algorithm
1165 6331 e.direction := direction;
1166 then e;
1167 else e;
1168 end match;
1169 end setElementVarDirection;
1170
1171 public function setElementVarBinding
1172 "Sets the binding of a VAR DAE.Element."
1173 input DAE.Element elt;
1174 input Option<DAE.Exp> binding;
1175 output DAE.Element e = elt;
1176 algorithm
1177 e := match e
1178 case DAE.VAR()
1179 algorithm
1180 185 e.binding := binding;
1181 then e;
1182 else e;
1183 end match;
1184 end setElementVarBinding;
1185
1186 public function setProtectedAttr "
1187 sets the start attribute. If NONE(), assumes Real attributes."
1188 input Option<DAE.VariableAttributes> attr;
1189 input Boolean isProtected;
1190 output Option<DAE.VariableAttributes> outAttr;
1191 algorithm
1192 outAttr:=
1193 match attr
1194 local
1195 Option<DAE.Exp> q,u,du,i,f,n,min,max;
1196 Option<DAE.StartOrigin> so;
1197 Option<DAE.StateSelect> ss;
1198 Option<DAE.Uncertainty> unc;
1199 Option<DAE.Distribution> distOpt;
1200 Option<DAE.Exp> eb;
1201 Option<Boolean> fn;
1202
1203 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,_,fn,so))
1204
2/2
✓ Branch 0 taken 255219 times.
✓ Branch 1 taken 87972 times.
686382 then SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,SOME(isProtected),fn,so));
1205 case SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,_,fn,so))
1206
2/2
✓ Branch 0 taken 10768 times.
✓ Branch 1 taken 2586 times.
26708 then SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,SOME(isProtected),fn,so));
1207 case SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,_,fn,so))
1208
2/2
✓ Branch 0 taken 11476 times.
✓ Branch 1 taken 1699 times.
26350 then SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,SOME(isProtected),fn,so));
1209 case SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,_,fn,so))
1210
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 1021 times.
2810 then SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,SOME(isProtected),fn,so));
1211 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,_,fn,so))
1212
2/2
✓ Branch 0 taken 1643 times.
✓ Branch 1 taken 555 times.
4396 then SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,SOME(isProtected),fn,so));
1213 case SOME(DAE.VAR_ATTR_CLOCK(fn,_))
1214
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 143 times.
324 then SOME(DAE.VAR_ATTR_CLOCK(fn,SOME(isProtected)));
1215 case NONE()
1216 // lochel: maybe we should let this case just fail
1217 65282 then setProtectedAttr(SOME(DAE.emptyVarAttrReal), isProtected);
1218 end match;
1219 end setProtectedAttr;
1220
1221 public function getProtectedAttr "
1222 retrieves the protected attribute form VariableAttributes."
1223 input Option<DAE.VariableAttributes> attr;
1224 output Boolean isProtected;
1225 algorithm
1226 isProtected := match attr
1227 case SOME(DAE.VAR_ATTR_REAL(isProtected=SOME(isProtected))) then isProtected;
1228 case SOME(DAE.VAR_ATTR_INT(isProtected=SOME(isProtected))) then isProtected;
1229 case SOME(DAE.VAR_ATTR_BOOL(isProtected=SOME(isProtected))) then isProtected;
1230 case SOME(DAE.VAR_ATTR_STRING(isProtected=SOME(isProtected))) then isProtected;
1231 case SOME(DAE.VAR_ATTR_ENUMERATION(isProtected=SOME(isProtected))) then isProtected;
1232 case SOME(DAE.VAR_ATTR_CLOCK(isProtected=SOME(isProtected))) then isProtected;
1233 else false;
1234 end match;
1235 end getProtectedAttr;
1236
1237 public function setFixedAttr "Function: setFixedAttr
1238 Sets the start attribute:fixed to inputarg"
1239 input Option<DAE.VariableAttributes> attr;
1240 input Option<DAE.Exp> fixed;
1241 output Option<DAE.VariableAttributes> outAttr;
1242 algorithm
1243 outAttr:=
1244 match attr
1245 local
1246 Option<DAE.Exp> q,u,du,n,ini,min,max;
1247 Option<DAE.StartOrigin> so;
1248 Option<DAE.StateSelect> ss;
1249 Option<DAE.Uncertainty> unc;
1250 Option<DAE.Distribution> distOpt;
1251 Option<DAE.Exp> eb;
1252 Option<Boolean> ip,fn;
1253
1254 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,ini,_,n,ss,unc,distOpt,eb,ip,fn,so))
1255 359545 then SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,ini,fixed,n,ss,unc,distOpt,eb,ip,fn,so));
1256 case SOME(DAE.VAR_ATTR_INT(q,min,max,ini,_,unc,distOpt,eb,ip,fn,so))
1257 12613 then SOME(DAE.VAR_ATTR_INT(q,min,max,ini,fixed,unc,distOpt,eb,ip,fn,so));
1258 case SOME(DAE.VAR_ATTR_BOOL(q,ini,_,eb,ip,fn,so))
1259 5118 then SOME(DAE.VAR_ATTR_BOOL(q,ini,fixed,eb,ip,fn,so));
1260 case SOME(DAE.VAR_ATTR_STRING(q,ini,_,eb,ip,fn,so))
1261 41 then SOME(DAE.VAR_ATTR_STRING(q,ini,fixed,eb,ip,fn,so));
1262 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,_,eb,ip,fn,so))
1263 1428 then SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,fixed,eb,ip,fn,so));
1264 end match;
1265 end setFixedAttr;
1266
1267 public function getFixedAttr "
1268 retrieves the protected attribute form VariableAttributes."
1269 input Option<DAE.VariableAttributes> attr;
1270 output Option<DAE.Exp> isFixed;
1271 algorithm
1272 isFixed := match attr
1273 case SOME(DAE.VAR_ATTR_REAL(fixed=isFixed)) then isFixed;
1274 case SOME(DAE.VAR_ATTR_INT(fixed=isFixed)) then isFixed;
1275 case SOME(DAE.VAR_ATTR_BOOL(fixed=isFixed)) then isFixed;
1276 case SOME(DAE.VAR_ATTR_STRING(fixed=isFixed)) then isFixed;
1277 case SOME(DAE.VAR_ATTR_ENUMERATION(fixed=isFixed)) then isFixed;
1278 else NONE();
1279 end match;
1280 end getFixedAttr;
1281
1282 public function setFinalAttr "
1283 sets the start attribute. If NONE(), assumes Real attributes."
1284 input Option<DAE.VariableAttributes> attr;
1285 input Boolean finalPrefix;
1286 output Option<DAE.VariableAttributes> outAttr;
1287 algorithm
1288 outAttr := match attr
1289 local
1290 Option<DAE.Exp> q,u,du,i,f,n,min,max;
1291 Option<DAE.StartOrigin> so;
1292 Option<DAE.StateSelect> ss;
1293 Option<DAE.Uncertainty> unc;
1294 Option<DAE.Distribution> distOpt;
1295 Option<DAE.Exp> eb;
1296 Option<Boolean> ip;
1297
1298 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,ip,_,so))
1299
2/2
✓ Branch 0 taken 422110 times.
✓ Branch 1 taken 64430 times.
973080 then SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,ip,SOME(finalPrefix),so));
1300 case SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,ip,_,so))
1301
2/2
✓ Branch 0 taken 43762 times.
✓ Branch 1 taken 8638 times.
104800 then SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,ip,SOME(finalPrefix),so));
1302 case SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,ip,_,so))
1303
2/2
✓ Branch 0 taken 67054 times.
✓ Branch 1 taken 7297 times.
148702 then SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,ip,SOME(finalPrefix),so));
1304 // BTH
1305 case SOME(DAE.VAR_ATTR_CLOCK(ip,_))
1306
1/2
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
332 then SOME(DAE.VAR_ATTR_CLOCK(ip,SOME(finalPrefix)));
1307 case SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,ip,_,so))
1308
2/2
✓ Branch 0 taken 75261 times.
✓ Branch 1 taken 20 times.
150562 then SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,ip,SOME(finalPrefix),so));
1309 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,ip,_,so))
1310
2/2
✓ Branch 0 taken 27133 times.
✓ Branch 1 taken 925 times.
56116 then SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,ip,SOME(finalPrefix),so));
1311 case NONE()
1312
2/2
✓ Branch 0 taken 145870 times.
✓ Branch 1 taken 347 times.
292434 then SOME(DAE.VAR_ATTR_REAL(NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),NONE(),SOME(finalPrefix),NONE()));
1313 end match;
1314 end setFinalAttr;
1315
1316 public function getFinalAttr "
1317 returns true if have final attr."
1318 input Option<DAE.VariableAttributes> attr;
1319 output Boolean finalPrefix;
1320 algorithm
1321 finalPrefix := match attr
1322 local Boolean b;
1323 case SOME(DAE.VAR_ATTR_REAL(finalPrefix=SOME(b))) then b;
1324 case SOME(DAE.VAR_ATTR_INT(finalPrefix=SOME(b))) then b;
1325 case SOME(DAE.VAR_ATTR_BOOL(finalPrefix=SOME(b))) then b;
1326 case SOME(DAE.VAR_ATTR_STRING(finalPrefix=SOME(b))) then b;
1327 case SOME(DAE.VAR_ATTR_ENUMERATION(finalPrefix=SOME(b))) then b;
1328 case SOME(DAE.VAR_ATTR_CLOCK(finalPrefix=SOME(b))) then b;
1329 else false;
1330 end match;
1331 end getFinalAttr;
1332
1333 public function boolVarVisibility "Function: boolVarVisibility
1334 Takes a DAE.varprotection and returns true/false (is_protected / not)"
1335 input DAE.VarVisibility vp;
1336 output Boolean prot;
1337 algorithm
1338 prot := match vp
1339 case DAE.PUBLIC() then false;
1340 case DAE.PROTECTED() then true;
1341 ✗ else algorithm print("- DAEUtil.boolVarVisibility failed\n"); then fail();
1342 end match;
1343 end boolVarVisibility;
1344
1345 public function hasStartAttr "
1346 Returns true if variable attributes defines a start value."
1347 input Option<DAE.VariableAttributes> inVariableAttributesOption;
1348 output Boolean hasStart;
1349 algorithm
1350 hasStart:= match inVariableAttributesOption
1351 local
1352 case SOME(DAE.VAR_ATTR_REAL(start = SOME(_))) then true;
1353 case SOME(DAE.VAR_ATTR_INT(start = SOME(_))) then true;
1354 case SOME(DAE.VAR_ATTR_BOOL(start = SOME(_))) then true;
1355 case SOME(DAE.VAR_ATTR_STRING(start = SOME(_))) then true;
1356 else false;
1357 end match;
1358 end hasStartAttr;
1359
1360 public function getStartAttrString "
1361 Return the start attribute as a string.
1362 "
1363 input Option<DAE.VariableAttributes> inVariableAttributesOption;
1364 output String outString;
1365 algorithm
1366 outString:=
1367 matchcontinue inVariableAttributesOption
1368 local
1369 String s;
1370 DAE.Exp r;
1371 case NONE() then "";
1372 case SOME(DAE.VAR_ATTR_REAL(start = SOME(r)))
1373 algorithm
1374 ✗ s := ExpressionBasics.printExpStr(r);
1375 then
1376 s;
1377 case SOME(DAE.VAR_ATTR_INT(start = SOME(r)))
1378 algorithm
1379 ✗ s := ExpressionBasics.printExpStr(r);
1380 then
1381 s;
1382 else "";
1383 end matchcontinue;
1384 end getStartAttrString;
1385
1386 public function getMatchingElements "author: LS
1387
1388 Retrive the elements for which the function given as second argument
1389 succeeds.
1390 "
1391 input list<DAE.Element> elist;
1392 input FuncTypeElementTo cond;
1393 output list<DAE.Element> oelist;
1394 partial function FuncTypeElementTo
1395 input DAE.Element inElement;
1396 output Boolean outMatch;
1397 end FuncTypeElementTo;
1398 algorithm
1399 9781 oelist := List.filterOnTrue(elist, cond);
1400 end getMatchingElements;
1401
1402 public function getAllMatchingElements "author: PA
1403
1404 Similar to getMatchingElements but traverses down in COMP elements also.
1405 "
1406 input list<DAE.Element> elist;
1407 input FuncTypeElementTo cond;
1408 output list<DAE.Element> outElist;
1409 partial function FuncTypeElementTo
1410 input DAE.Element inElement;
1411 end FuncTypeElementTo;
1412 algorithm
1413 outElist := matchcontinue elist
1414 local
1415 list<DAE.Element> elist1,elist2;
1416 DAE.Element e;
1417 case {} then {};
1418 case DAE.COMP(dAElist=elist1)::elist2
1419 algorithm
1420 ✗ elist1 := getAllMatchingElements(elist1,cond);
1421 ✗ elist2 := getAllMatchingElements(elist2,cond);
1422 ✗ then listAppend(elist1,elist2);
1423 case e::elist2
1424 algorithm
1425 ✗ cond(e);
1426 ✗ elist2 := getAllMatchingElements(elist2,cond);
1427 then e::elist2;
1428 case _::elist2
1429 ✗ then getAllMatchingElements(elist2,cond);
1430 end matchcontinue;
1431 end getAllMatchingElements;
1432
1433 public function findAllMatchingElements "author: adrpo
1434 Similar to getMatchingElements but gets two conditions and returns two lists. The functions are copied to both."
1435 input DAE.DAElist dae;
1436 input CondFunc cond1;
1437 input CondFunc cond2;
1438 output DAE.DAElist firstList;
1439 output DAE.DAElist secondList;
1440
1441 partial function CondFunc
1442 input DAE.Element element;
1443 output Boolean result;
1444 end CondFunc;
1445 protected
1446 list<DAE.Element> elements, el1, el2;
1447 algorithm
1448 ✗ DAE.DAE(elementLst = elements) := dae;
1449 ✗ (el1, el2) := findAllMatchingElements2(elements, cond1, cond2);
1450 ✗ firstList := DAE.DAE(MetaModelica.Dangerous.listReverseInPlace(el1));
1451 ✗ secondList := DAE.DAE(MetaModelica.Dangerous.listReverseInPlace(el2));
1452 end findAllMatchingElements;
1453
1454 protected function findAllMatchingElements2
1455 input list<DAE.Element> elements;
1456 input CondFunc cond1;
1457 input CondFunc cond2;
1458 input list<DAE.Element> accumFirst = {};
1459 input list<DAE.Element> accumSecond = {};
1460 output list<DAE.Element> firstList = accumFirst;
1461 output list<DAE.Element> secondList = accumSecond;
1462
1463 partial function CondFunc
1464 input DAE.Element element;
1465 output Boolean result;
1466 end CondFunc;
1467 algorithm
1468 ✗ for e in elements loop
1469 () := match e
1470 case DAE.COMP()
1471 algorithm
1472 ✗ (firstList, secondList) :=
1473 findAllMatchingElements2(e.dAElist, cond1, cond2, firstList, secondList);
1474 then
1475 ();
1476
1477 else
1478 algorithm
1479 ✗ if cond1(e) then
1480 firstList := e :: firstList;
1481 end if;
1482
1483 ✗ if cond2(e) then
1484 ✗ secondList := e :: secondList;
1485 end if;
1486 then
1487 ();
1488
1489 end match;
1490 end for;
1491 end findAllMatchingElements2;
1492
1493 public function isAfterIndexInlineFunc "
1494 Author BZ
1495 "
1496 input DAE.Function inElem;
1497 output Boolean b;
1498 algorithm
1499 b := match inElem
1500 case DAE.FUNCTION(inlineType=DAE.AFTER_INDEX_RED_INLINE()) then true;
1501 else false;
1502 end match;
1503 end isAfterIndexInlineFunc;
1504
1505 public function isParameter "author: LS
1506 True if element is parameter.
1507 "
1508 input DAE.Element inElement;
1509 output Boolean outB;
1510 algorithm
1511 outB :=
1512 match inElement
1513 case DAE.VAR(kind = DAE.PARAM()) then true;
1514 else false;
1515 end match;
1516 end isParameter;
1517
1518 public function isParameterOrConstant "
1519 author: BZ 2008-06
1520 Succeeds if element is constant/parameter.
1521 "
1522 input DAE.Element inElement;
1523 output Boolean b;
1524 algorithm
1525 b := match inElement
1526 case DAE.VAR(kind = DAE.CONST()) then true;
1527 case DAE.VAR(kind = DAE.PARAM()) then true;
1528 else false;
1529 end match;
1530 end isParameterOrConstant;
1531
1532 public function isParamOrConstVar
1533 input DAE.Var inVar;
1534 output Boolean outIsParamOrConst;
1535 protected
1536 SCode.Variability var;
1537 algorithm
1538 ✗ DAE.TYPES_VAR(attributes = DAE.ATTR(variability = var)) := inVar;
1539 ✗ outIsParamOrConst := SCodeUtil.isParameterOrConst(var);
1540 end isParamOrConstVar;
1541
1542 public function isConstVar
1543 "Return true if variable has variability CONST."
1544 input DAE.Var var;
1545 output Boolean isConstVar = false;
1546 algorithm
1547 isConstVar := match var.attributes.variability
1548 case SCode.CONST() then true;
1549 else false;
1550 end match;
1551 end isConstVar;
1552
1553 public function isNotParamOrConstVar
1554 input DAE.Var inVar;
1555 output Boolean outIsNotParamOrConst;
1556 algorithm
1557 ✗ outIsNotParamOrConst := not isParamOrConstVar(inVar);
1558 end isNotParamOrConstVar;
1559
1560 public function isParamConstOrComplexVar
1561 input DAE.Var inVar;
1562 output Boolean outIsParamConstComplex;
1563 algorithm
1564 ✗ outIsParamConstComplex := isParamOrConstVar(inVar) or
1565 isComplexVar(inVar);
1566 end isParamConstOrComplexVar;
1567
1568 public function isParamOrConstVarKind
1569 input DAE.VarKind inVarKind;
1570 output Boolean outIsParamOrConst;
1571 algorithm
1572 outIsParamOrConst := match inVarKind
1573 case DAE.PARAM() then true;
1574 case DAE.CONST() then true;
1575 else false;
1576 end match;
1577 end isParamOrConstVarKind;
1578
1579 public function isInnerVar
1580 "Returns true if the element is an inner variable."
1581 input DAE.Element element;
1582 output Boolean isInner;
1583 algorithm
1584 isInner := match element
1585 ✗ case DAE.VAR() then AbsynUtil.isInner(element.innerOuter);
1586 else false;
1587 end match;
1588 end isInnerVar;
1589
1590 public function isOuterVar
1591 "Returns true if the element is an outer variable."
1592 input DAE.Element element;
1593 output Boolean isOuter;
1594 algorithm
1595 isOuter := match element
1596 case DAE.VAR(innerOuter = Absyn.OUTER()) then true;
1597 // FIXME? adrpo: do we need this?
1598 // case DAE.VAR(innerOuter = Absyn.INNER_OUTER()) then true;
1599 else false;
1600 end match;
1601 end isOuterVar;
1602
1603 public function isComp "author: LS
1604
1605 Succeeds if element is component, COMP.
1606 "
1607 input DAE.Element inElement;
1608 algorithm
1609 ():=
1610 match inElement
1611 case DAE.COMP() then ();
1612 end match;
1613 end isComp;
1614
1615 public function getOutputVars "author: LS
1616
1617 Retrieve all output variables from an Element list.
1618 "
1619 input list<DAE.Element> vl;
1620 output list<DAE.Element> vl_1;
1621 algorithm
1622 ✗ vl_1 := getMatchingElements(vl, isOutputVar);
1623 end getOutputVars;
1624
1625 public function getOutputElements
1626 input list<DAE.Element> vl;
1627 output list<DAE.Element> vl_1;
1628 algorithm
1629 8549 vl_1 := getMatchingElements(vl, isOutputElement);
1630 end getOutputElements;
1631
1632 public function getProtectedVars "
1633 author: PA
1634
1635 Retrieve all protected variables from an Element list.
1636 "
1637 input list<DAE.Element> vl;
1638 output list<DAE.Element> vl_1;
1639 algorithm
1640 ✗ vl_1 := getMatchingElements(vl, isProtectedVar);
1641 end getProtectedVars;
1642
1643 public function getBidirVars "author: LS
1644
1645 Retrieve all bidirectional variables from an Element list.
1646 "
1647 input list<DAE.Element> vl;
1648 output list<DAE.Element> vl_1;
1649 algorithm
1650 ✗ vl_1 := getMatchingElements(vl, isBidirVar);
1651 end getBidirVars;
1652
1653 public function getBidirElements
1654 input list<DAE.Element> vl;
1655 output list<DAE.Element> vl_1;
1656 algorithm
1657 616 vl_1 := getMatchingElements(vl, isBidirElement);
1658 end getBidirElements;
1659
1660 public function getInputVars "
1661 Retrieve all input variables from an Element list.
1662 "
1663 input list<DAE.Element> vl;
1664 output list<DAE.Element> vl_1;
1665 algorithm
1666 616 vl_1 := getMatchingElements(vl, isInput);
1667 end getInputVars;
1668
1669 public function isFlowVar
1670 "Succeeds if the given variable has a flow prefix."
1671 input DAE.Element inElement;
1672 algorithm
1673 ✗ DAE.VAR(kind = DAE.VARIABLE(), connectorType = DAE.FLOW()) := inElement;
1674 end isFlowVar;
1675
1676 public function isStreamVar
1677 "Succeeds if the given variable has a stream prefix."
1678 input DAE.Element inElement;
1679 algorithm
1680 ✗ DAE.VAR(kind = DAE.VARIABLE(), connectorType = DAE.STREAM()) := inElement;
1681 end isStreamVar;
1682
1683 public function isFlow
1684 input DAE.ConnectorType inFlow;
1685 output Boolean outIsFlow;
1686 algorithm
1687 outIsFlow := match inFlow
1688 case DAE.FLOW() then true;
1689 else false;
1690 end match;
1691 end isFlow;
1692
1693 public function isStream
1694 input DAE.ConnectorType inStream;
1695 output Boolean outIsStream;
1696 algorithm
1697 outIsStream := match inStream
1698 case DAE.STREAM() then true;
1699 else false;
1700 end match;
1701 end isStream;
1702
1703 public function isOutputVar
1704 "Succeeds if Element is an output variable."
1705 input DAE.Element inElement;
1706 output Boolean outMatch;
1707 algorithm
1708 outMatch := match inElement
1709 case DAE.VAR(kind = DAE.VARIABLE(),direction = DAE.OUTPUT()) then true;
1710 else false;
1711 end match;
1712 end isOutputVar;
1713
1714 public function isOutputElement
1715 input DAE.Element inElement;
1716 output Boolean outMatch;
1717 algorithm
1718 outMatch := match inElement
1719 case DAE.VAR(direction = DAE.OUTPUT()) then true;
1720 else false;
1721 end match;
1722 end isOutputElement;
1723
1724 public function assertProtectedVar
1725 "Succeeds if Element is a protected variable."
1726 input DAE.Element inElement;
1727 algorithm
1728 () := match inElement
1729 case DAE.VAR(protection=DAE.PROTECTED()) then ();
1730 end match;
1731 end assertProtectedVar;
1732
1733 public function isProtectedVar
1734 "Succeeds if Element is a protected variable."
1735 input DAE.Element inElement;
1736 output Boolean b;
1737 algorithm
1738 b := match inElement
1739 case DAE.VAR(protection=DAE.PROTECTED()) then true;
1740 else false;
1741 end match;
1742 end isProtectedVar;
1743
1744 public function isPublicVar "
1745 Succeeds if Element is a public variable.
1746 "
1747 input DAE.Element inElement;
1748 output Boolean outMatch;
1749 algorithm
1750 outMatch := match inElement
1751 case DAE.VAR(protection=DAE.PUBLIC()) then true;
1752 else false;
1753 end match;
1754 end isPublicVar;
1755
1756 public function isBidirVar "
1757 Succeeds if Element is a bidirectional variable.
1758 "
1759 input DAE.Element inElement;
1760 output Boolean outMatch;
1761 algorithm
1762 outMatch := match inElement
1763 case DAE.VAR(kind = DAE.VARIABLE(),direction = DAE.BIDIR()) then true;
1764 else false;
1765 end match;
1766 end isBidirVar;
1767
1768 public function isBidirElement
1769 input DAE.Element inElement;
1770 output Boolean outMatch;
1771 algorithm
1772 outMatch := match inElement
1773 case DAE.VAR(direction = DAE.BIDIR()) then true;
1774 else false;
1775 end match;
1776 end isBidirElement;
1777
1778 public function isInputVar "
1779 Succeeds if Element is an input variable.
1780 "
1781 input DAE.Element inElement;
1782 output Boolean outMatch;
1783 algorithm
1784 outMatch := match inElement
1785 case DAE.VAR(kind = DAE.VARIABLE(),direction = DAE.INPUT()) then true;
1786 else false;
1787 end match;
1788 end isInputVar;
1789
1790 public function isInput "
1791 Succeeds if Element is an input .
1792 "
1793 input DAE.Element inElement;
1794 output Boolean outMatch;
1795 algorithm
1796 outMatch := match inElement
1797 case DAE.VAR(direction = DAE.INPUT()) then true;
1798 else false;
1799 end match;
1800 end isInput;
1801
1802 public function isNotVar
1803 "Returns true if the element is not a variable, otherwise false."
1804 input DAE.Element e;
1805 output Boolean outMatch;
1806 algorithm
1807 outMatch := match e
1808 case DAE.VAR(__) then false;
1809 else true;
1810 end match;
1811 end isNotVar;
1812
1813 public function isVar
1814 "Returns true if the element is a variable, otherwise false."
1815 input DAE.Element inElement;
1816 output Boolean outMatch;
1817 algorithm
1818 outMatch := match inElement
1819 case DAE.VAR(__) then true;
1820 else false;
1821 end match;
1822 end isVar;
1823
1824 public function isFunctionRefVar "
1825 return true if the element is a function reference variable"
1826 input DAE.Element inElem;
1827 output Boolean outBoolean;
1828 algorithm
1829 outBoolean := match inElem
1830 case DAE.VAR(ty = DAE.T_FUNCTION()) then true;
1831 else false;
1832 end match;
1833 end isFunctionRefVar;
1834
1835 function isComment
1836 input DAE.Element elt;
1837 output Boolean b;
1838 algorithm
1839 b := match elt
1840 case DAE.COMMENT(__) then true;
1841 else false;
1842 end match;
1843 end isComment;
1844
1845 public function isAlgorithm "author: LS
1846 Succeeds if Element is an algorithm."
1847 input DAE.Element inElement;
1848 output Boolean outMatch;
1849 algorithm
1850 outMatch := match inElement
1851 case DAE.ALGORITHM(__) then true;
1852 else false;
1853 end match;
1854 end isAlgorithm;
1855
1856 public function isStmtAssert" outputs true if the stmt is an assert.
1857 author:Waurich TUD 2014-04"
1858 input DAE.Statement stmt;
1859 output Boolean b;
1860 algorithm
1861 b := match stmt
1862 case DAE.STMT_ASSERT(__) then true;
1863 else false;
1864 end match;
1865 end isStmtAssert;
1866
1867 public function isStmtReturn" outputs true if the stmt is a return.
1868 author:Waurich TUD 2014-04"
1869 input DAE.Statement stmt;
1870 output Boolean b;
1871 algorithm
1872 b := match stmt
1873 case DAE.STMT_RETURN(__) then true;
1874 else false;
1875 end match;
1876 end isStmtReturn;
1877
1878 public function isStmtReinit" outputs true if the stmt is a reinit.
1879 author:Waurich TUD 2014-04"
1880 input DAE.Statement stmt;
1881 output Boolean b;
1882 algorithm
1883 b := match stmt
1884 case DAE.STMT_REINIT(__) then true;
1885 else false;
1886 end match;
1887 end isStmtReinit;
1888
1889 public function isStmtTerminate" outputs true if the stmt is a terminate.
1890 author:Waurich TUD 2014-04"
1891 input DAE.Statement stmt;
1892 output Boolean b;
1893 algorithm
1894 b := match stmt
1895 case DAE.STMT_TERMINATE(__) then true;
1896 else false;
1897 end match;
1898 end isStmtTerminate;
1899
1900 public function isComplexEquation "author: LS
1901 Succeeds if Element is an complex equation."
1902 input DAE.Element inElement;
1903 output Boolean outMatch;
1904 algorithm
1905 outMatch := match inElement
1906 case DAE.COMPLEX_EQUATION(__) then true;
1907 else false;
1908 end match;
1909 end isComplexEquation;
1910
1911 public function isFunctionInlineFalse "author: PA
1912
1913 Succeeds if is a function with Inline=false"
1914 input DAE.Function inElement;
1915 output Boolean res;
1916 algorithm
1917 res := match inElement
1918 case DAE.FUNCTION(inlineType = DAE.NO_INLINE()) then true;
1919 else false;
1920 end match;
1921 end isFunctionInlineFalse;
1922
1923 public function findElement "
1924 Search for an element for which the function passed as second
1925 argument succeds. If no element is found return NONE.
1926 "
1927 input list<DAE.Element> inElementLst;
1928 input FuncTypeElementTo inFuncTypeElementTo;
1929 output Option<DAE.Element> outElementOption;
1930 partial function FuncTypeElementTo
1931 input DAE.Element inElement;
1932 end FuncTypeElementTo;
1933 algorithm
1934 outElementOption:= match (inElementLst,inFuncTypeElementTo)
1935 local
1936 DAE.Element e;
1937 list<DAE.Element> rest;
1938 FuncTypeElementTo f;
1939 Option<DAE.Element> e_1;
1940
1941 case ({},_) then NONE();
1942
1943 case (e::rest, f)
1944 algorithm
1945 e_1 := matchcontinue ()
1946 case ()
1947 algorithm
1948 ✗ f(e);
1949 then SOME(e);
1950 else
1951 algorithm
1952 ✗ failure(f(e));
1953 ✗ e_1 := findElement(rest, f);
1954 then e_1;
1955 end matchcontinue;
1956 then
1957 e_1;
1958
1959 end match;
1960 end findElement;
1961
1962 public function getVariableBindingsStr "
1963 This function takes a `DAE.Element\' list and returns a comma separated
1964 string of variable bindings.
1965 E.g. model A Real x=1; Real y=2; end A; => \"1,2\"
1966 "
1967 input list<DAE.Element> elts;
1968 output String str;
1969 protected
1970 list<DAE.Element> varlst, els;
1971 algorithm
1972 str := match elts
1973 139 case {DAE.COMP(dAElist = els)} then getVariableBindingsStr(els);
1974 else
1975 algorithm
1976 139 varlst := getVariableList(elts);
1977 139 str := getBindingsStr(varlst);
1978 then str;
1979 end match;
1980 end getVariableBindingsStr;
1981
1982 protected function getVariableList "
1983 Return all variables from an Element list.
1984 "
1985 input list<DAE.Element> inElementLst;
1986 output list<DAE.Element> outElementLst;
1987 algorithm
1988 /* adrpo: filter out records! */
1989
2/2
✓ Branch 0 taken 1489 times.
✓ Branch 1 taken 139 times.
1628 outElementLst := list(e for e guard match e
1990 case DAE.VAR(ty = DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_))) then false;
1991 case DAE.VAR() then true;
1992 else false;
1993 end match in inElementLst);
1994 end getVariableList;
1995
1996 public function getVariableType
1997 "function: getVariableType
1998 Return the type of a variable, otherwise fails.
1999 "
2000 input DAE.Element inElement;
2001 output DAE.Type outType;
2002 algorithm
2003 outType := match inElement
2004 local
2005 DAE.Type tp;
2006
2007 case DAE.VAR(ty = tp) then tp;
2008
2009 else fail();
2010 end match;
2011 end getVariableType;
2012
2013 protected function getBindingsStr "
2014 Retrive the bindings from a list of Elements and output to a string.
2015 "
2016 input list<DAE.Element> inElementLst;
2017 output String outString;
2018 algorithm
2019 outString:=
2020 match inElementLst
2021 local
2022 String expstr,s3,s4,str,s1,s2;
2023 DAE.Exp e;
2024 list<DAE.Element> lst;
2025 case (DAE.VAR(binding = SOME(e)))::(lst as (_::_))
2026 algorithm
2027 743 expstr := ExpressionBasics.printExpStr(e);
2028 743 s3 := stringAppend(expstr, ",");
2029 743 s4 := getBindingsStr(lst);
2030 743 str := stringAppend(s3, s4);
2031 then
2032 str;
2033 case (DAE.VAR(binding = NONE()))::(lst as (_::_))
2034 algorithm
2035 s1 := "-,";
2036 607 s2 := getBindingsStr(lst);
2037 607 str := stringAppend(s1, s2);
2038 then
2039 str;
2040 case {(DAE.VAR(binding = SOME(e)))}
2041 algorithm
2042 108 str := ExpressionBasics.printExpStr(e);
2043 then
2044 str;
2045 case {(DAE.VAR(binding = NONE()))} then "";
2046 end match;
2047 end getBindingsStr;
2048
2049 public function getBindings "Author: BZ, 2008-11
2050 Get variable-bindings from element list.
2051 "
2052 input list<DAE.Element> inElementLst;
2053 output list<DAE.ComponentRef> outc;
2054 output list<DAE.Exp> oute;
2055 algorithm
2056 (outc,oute) := matchcontinue inElementLst
2057 local
2058 DAE.ComponentRef cr;
2059 DAE.Exp e;
2060 list<DAE.Element> rest;
2061 ✗ case {} then ({},{});
2062 case DAE.VAR(componentRef = cr,binding = SOME(e))::rest
2063 algorithm
2064 ✗ (outc,oute) := getBindings(rest);
2065 ✗ then
2066 (cr::outc,e::oute);
2067 case DAE.VAR(binding = NONE())::rest
2068 algorithm
2069 ✗ (outc,oute) := getBindings(rest);
2070 then (outc,oute);
2071 ✗ else algorithm print(" error in getBindings \n"); then fail();
2072 end matchcontinue;
2073 end getBindings;
2074
2075 public function toConnectorType
2076 "Converts a SCode.ConnectorType to a DAE.ConnectorType, given a class type."
2077 input SCode.ConnectorType inConnectorType;
2078 input ClassInf.State inState;
2079 output DAE.ConnectorType outConnectorType;
2080 algorithm
2081 outConnectorType := match(inConnectorType, inState)
2082 case (SCode.FLOW(), _) then DAE.FLOW();
2083 case (SCode.STREAM(), _) then DAE.STREAM(NONE());
2084 case (_, ClassInf.CONNECTOR()) then DAE.POTENTIAL();
2085 else DAE.NON_CONNECTOR();
2086 end match;
2087 end toConnectorType;
2088
2089 public function toConnectorTypeNoState
2090 input SCode.ConnectorType scodeConnectorType;
2091 input Option<DAE.ComponentRef> flowName = NONE();
2092 output DAE.ConnectorType daeConnectorType;
2093 algorithm
2094 daeConnectorType := match scodeConnectorType
2095 case SCode.FLOW() then DAE.FLOW();
2096 979 case SCode.STREAM() then DAE.STREAM(flowName);
2097 else DAE.POTENTIAL();
2098 end match;
2099 end toConnectorTypeNoState;
2100
2101 public function toDaeParallelism "Converts scode parallelsim to dae parallelism.
2102 Prints a warning if parallel variables are used
2103 in a non-function class."
2104 input DAE.ComponentRef inCref;
2105 input SCode.Parallelism inParallelism;
2106 input ClassInf.State inState;
2107 input SourceInfo inInfo;
2108 output DAE.VarParallelism outParallelism;
2109 algorithm
2110 outParallelism := matchcontinue (inParallelism, inState)
2111 local
2112 String str1;
2113 Absyn.Path path;
2114
2115 case (SCode.NON_PARALLEL(), _) then DAE.NON_PARALLEL();
2116
2117 //In functions. No worries.
2118 case (SCode.PARGLOBAL(), ClassInf.FUNCTION(_,_)) then DAE.PARGLOBAL();
2119 case (SCode.PARLOCAL(), ClassInf.FUNCTION(_,_)) then DAE.PARLOCAL();
2120
2121 // In other classes print warning
2122 case (SCode.PARGLOBAL(), _)
2123 algorithm
2124 ✗ path := ClassInfUtil.getStateName(inState);
2125 ✗ str1 := "\n" +
2126 "- DAEUtil.toDaeParallelism: parglobal component '" + ComponentReferenceBasics.printComponentRefStr(inCref)
2127 + "' in non-function class: " + ClassInfUtil.printStateStr(inState) + " " + AbsynUtil.pathString(path);
2128
2129 ✗ Error.addSourceMessage(Error.PARMODELICA_WARNING,
2130 {str1}, inInfo);
2131 then DAE.PARGLOBAL();
2132
2133 case (SCode.PARLOCAL(), _)
2134 algorithm
2135 ✗ path := ClassInfUtil.getStateName(inState);
2136 ✗ str1 := "\n" +
2137 "- DAEUtil.toDaeParallelism: parlocal component '" + ComponentReferenceBasics.printComponentRefStr(inCref)
2138 + "' in non-function class: " + ClassInfUtil.printStateStr(inState) + " " + AbsynUtil.pathString(path);
2139
2140 ✗ Error.addSourceMessage(Error.PARMODELICA_WARNING,
2141 {str1}, inInfo);
2142 then DAE.PARLOCAL();
2143 end matchcontinue;
2144 end toDaeParallelism;
2145
2146 public function scodePrlToDaePrl
2147 "Translates SCode.Parallelism to DAE.VarParallelism
2148 without considering if it is a function or not."
2149 input SCode.Parallelism inParallelism;
2150 output DAE.VarParallelism outVarParallelism;
2151 algorithm
2152 outVarParallelism := match inParallelism
2153 case SCode.NON_PARALLEL() then DAE.NON_PARALLEL();
2154 case SCode.PARGLOBAL() then DAE.PARGLOBAL();
2155 case SCode.PARLOCAL() then DAE.PARLOCAL();
2156 end match;
2157 end scodePrlToDaePrl;
2158
2159 public function daeParallelismEqual
2160 input DAE.VarParallelism inParallelism1;
2161 input DAE.VarParallelism inParallelism2;
2162 output Boolean equal;
2163 algorithm
2164 equal := match(inParallelism1,inParallelism2)
2165 case(DAE.NON_PARALLEL(),DAE.NON_PARALLEL()) then true;
2166 case(DAE.PARGLOBAL(),DAE.PARGLOBAL()) then true;
2167 case(DAE.PARLOCAL(),DAE.PARLOCAL()) then true;
2168 else false;
2169 end match;
2170 end daeParallelismEqual;
2171
2172 public function getFlowVariables "Retrive the flow variables of an Element list."
2173 input list<DAE.Element> inElementLst;
2174 output list<DAE.ComponentRef> outExpComponentRefLst;
2175 algorithm
2176 outExpComponentRefLst := matchcontinue inElementLst
2177 local
2178 list<DAE.ComponentRef> res,res1,res1_1,res2;
2179 DAE.ComponentRef cr;
2180 list<DAE.Element> xs,lst;
2181 String id;
2182 case {} then {};
2183 case DAE.VAR(componentRef = cr,connectorType = DAE.FLOW())::xs
2184 algorithm
2185 ✗ res := getFlowVariables(xs);
2186 then
2187 (cr::res);
2188 case DAE.COMP(ident = id,dAElist = lst)::xs
2189 algorithm
2190 ✗ res1 := getFlowVariables(lst);
2191 ✗ res1_1 := getFlowVariables2(res1, id);
2192 ✗ res2 := getFlowVariables(xs);
2193 ✗ res := listAppend(res1_1, res2);
2194 then
2195 res;
2196 case _::xs
2197 algorithm
2198 ✗ res := getFlowVariables(xs);
2199 then
2200 res;
2201 end matchcontinue;
2202 end getFlowVariables;
2203
2204 protected function getFlowVariables2 "
2205 Helper function to get_flow_variables.
2206 "
2207 input list<DAE.ComponentRef> inExpComponentRefLst;
2208 input String inIdent;
2209 output list<DAE.ComponentRef> outExpComponentRefLst;
2210 algorithm
2211 outExpComponentRefLst:=
2212 match (inExpComponentRefLst,inIdent)
2213 local
2214 String id;
2215 list<DAE.ComponentRef> res,xs;
2216 DAE.ComponentRef cr_1,cr;
2217 case ({},_) then {};
2218 case ((cr::xs),id)
2219 algorithm
2220 ✗ res := getFlowVariables2(xs, id);
2221 ✗ cr_1 := ComponentReferenceBasics.makeCrefQual(id,DAE.T_UNKNOWN_DEFAULT,{}, cr);
2222 then
2223 (cr_1::res);
2224 end match;
2225 end getFlowVariables2;
2226
2227 public function getStreamVariables "Retrive the stream variables of an Element list."
2228 input list<DAE.Element> inElementLst;
2229 output list<DAE.ComponentRef> outExpComponentRefLst;
2230 algorithm
2231 outExpComponentRefLst:=
2232 matchcontinue inElementLst
2233 local
2234 list<DAE.ComponentRef> res,res1,res1_1,res2;
2235 DAE.ComponentRef cr;
2236 list<DAE.Element> xs,lst;
2237 String id;
2238 case {} then {};
2239 case DAE.VAR(componentRef = cr,connectorType = DAE.STREAM())::xs
2240 algorithm
2241 ✗ res := getStreamVariables(xs);
2242 then
2243 (cr::res);
2244 case DAE.COMP(ident = id,dAElist = lst)::xs
2245 algorithm
2246 ✗ res1 := getStreamVariables(lst);
2247 ✗ res1_1 := getStreamVariables2(res1, id);
2248 ✗ res2 := getStreamVariables(xs);
2249 ✗ res := listAppend(res1_1, res2);
2250 then
2251 res;
2252 case _::xs
2253 algorithm
2254 ✗ res := getStreamVariables(xs);
2255 then
2256 res;
2257 end matchcontinue;
2258 end getStreamVariables;
2259
2260 protected function getStreamVariables2 "
2261 Helper function to get_flow_variables.
2262 "
2263 input list<DAE.ComponentRef> inExpComponentRefLst;
2264 input String inIdent;
2265 output list<DAE.ComponentRef> outExpComponentRefLst;
2266 algorithm
2267 outExpComponentRefLst:=
2268 match (inExpComponentRefLst,inIdent)
2269 local
2270 String id;
2271 list<DAE.ComponentRef> res,xs;
2272 DAE.ComponentRef cr_1,cr;
2273 case ({},_) then {};
2274 case ((cr::xs),id)
2275 algorithm
2276 ✗ res := getStreamVariables2(xs, id);
2277 ✗ cr_1 := ComponentReferenceBasics.makeCrefQual(id,DAE.T_UNKNOWN_DEFAULT,{}, cr);
2278 then
2279 (cr_1::res);
2280 end match;
2281 end getStreamVariables2;
2282
2283 public function toModelicaForm "function toModelicaForm.
2284
2285 Transforms all variables from a.b.c to a_b_c, etc
2286 "
2287 input DAE.DAElist inDAElist;
2288 output DAE.DAElist outDAElist;
2289 algorithm
2290 outDAElist:=
2291 match inDAElist
2292 local list<DAE.Element> elts_1,elts;
2293 case DAE.DAE(elts)
2294 algorithm
2295 ✗ elts_1 := toModelicaFormElts(elts);
2296 ✗ then
2297 DAE.DAE(elts_1);
2298 end match;
2299 end toModelicaForm;
2300
2301 protected function toModelicaFormElts "Helper function to toModelicaForm."
2302 input list<DAE.Element> inElementLst;
2303 output list<DAE.Element> outElementLst;
2304 algorithm
2305 outElementLst := match inElementLst
2306 local
2307 String str,str_1,id;
2308 list<DAE.Element> elts_1,elts,welts_1,welts,eelts_1,eelts,elts2;
2309 Option<DAE.Exp> d_1,d;
2310 DAE.ComponentRef cr,cr_1,cref_,cr1,cr2;
2311 DAE.Type ty;
2312 DAE.VarKind a;
2313 DAE.VarDirection b;
2314 DAE.VarParallelism prl;
2315 DAE.Type t;
2316 DAE.InstDims instDim;
2317 DAE.ConnectorType ct;
2318 DAE.Element elt_1,elt;
2319 DAE.VarVisibility prot;
2320 Option<DAE.VariableAttributes> dae_var_attr;
2321 Option<SCode.Comment> comment;
2322 DAE.Exp e_1,e1_1,e2_1,e1,e2,e_2,e,e3,e_3;
2323 Absyn.InnerOuter io;
2324 Boolean encrypted;
2325 list<DAE.Exp> conds, conds_1;
2326 list<list<DAE.Element>> trueBranches, trueBranches_1;
2327 DAE.ElementSource source "the element origin";
2328 DAE.Algorithm alg;
2329
2330 case {} then {};
2331 case DAE.VAR(componentRef = cr,
2332 kind = a,
2333 direction = b,
2334 parallelism = prl,
2335 protection = prot,
2336 ty = t,
2337 binding = d,
2338 dims = instDim,
2339 connectorType = ct,
2340 source=source,
2341 variableAttributesOption = dae_var_attr,
2342 comment = comment,
2343 innerOuter=io,
2344 encrypted=encrypted)::elts
2345 algorithm
2346 ✗ str := ComponentReferenceBasics.printComponentRefStr(cr);
2347 ✗ str_1 := Util.stringReplaceChar(str, ".", "_");
2348 ✗ elts_1 := toModelicaFormElts(elts);
2349 ✗ d_1 := toModelicaFormExpOpt(d);
2350 ✗ ty := ComponentReference.crefLastType(cr);
2351 ✗ cref_ := ComponentReferenceBasics.makeCrefIdent(str_1,ty,{});
2352 ✗ then
2353 (DAE.VAR(cref_,a,b,prl,prot,t,d_1,instDim,ct,source,dae_var_attr,comment,io,encrypted)::elts_1);
2354
2355 case DAE.DEFINE(componentRef = cr,exp = e,source = source)::elts
2356 algorithm
2357 ✗ e_1 := toModelicaFormExp(e);
2358 ✗ cr_1 := toModelicaFormCref(cr);
2359 ✗ elts_1 := toModelicaFormElts(elts);
2360 ✗ then
2361 (DAE.DEFINE(cr_1,e_1,source)::elts_1);
2362
2363 case DAE.INITIALDEFINE(componentRef = cr,exp = e,source = source)::elts
2364 algorithm
2365 ✗ e_1 := toModelicaFormExp(e);
2366 ✗ cr_1 := toModelicaFormCref(cr);
2367 ✗ elts_1 := toModelicaFormElts(elts);
2368 ✗ then
2369 (DAE.INITIALDEFINE(cr_1,e_1,source)::elts_1);
2370
2371 case DAE.EQUATION(exp = e1,scalar = e2,source = source)::elts
2372 algorithm
2373 ✗ e1_1 := toModelicaFormExp(e1);
2374 ✗ e2_1 := toModelicaFormExp(e2);
2375 ✗ elts_1 := toModelicaFormElts(elts);
2376 ✗ then
2377 (DAE.EQUATION(e1_1,e2_1,source)::elts_1);
2378
2379 case DAE.COMPLEX_EQUATION(lhs = e1,rhs = e2,source = source)::elts
2380 algorithm
2381 ✗ e1_1 := toModelicaFormExp(e1);
2382 ✗ e2_1 := toModelicaFormExp(e2);
2383 ✗ elts_1 := toModelicaFormElts(elts);
2384 ✗ then
2385 (DAE.COMPLEX_EQUATION(e1_1,e2_1,source)::elts_1);
2386
2387 case DAE.INITIAL_COMPLEX_EQUATION(lhs = e1,rhs = e2,source = source)::elts
2388 algorithm
2389 ✗ e1_1 := toModelicaFormExp(e1);
2390 ✗ e2_1 := toModelicaFormExp(e2);
2391 ✗ elts_1 := toModelicaFormElts(elts);
2392 ✗ then
2393 (DAE.INITIAL_COMPLEX_EQUATION(e1_1,e2_1,source)::elts_1);
2394
2395 case DAE.EQUEQUATION(cr1 = cr1,cr2 = cr2,source = source)::elts
2396 algorithm
2397 ✗ DAE.CREF(cr1,_) := toModelicaFormExp(Expression.crefExp(cr1));
2398 ✗ DAE.CREF(cr2,_) := toModelicaFormExp(Expression.crefExp(cr2));
2399 ✗ elts_1 := toModelicaFormElts(elts);
2400 ✗ then
2401 (DAE.EQUEQUATION(cr1,cr2,source)::elts_1);
2402
2403 case DAE.WHEN_EQUATION(condition = e1,equations = welts,elsewhen_ = SOME(elt),source = source)::elts
2404 algorithm
2405 ✗ e1_1 := toModelicaFormExp(e1);
2406 ✗ welts_1 := toModelicaFormElts(welts);
2407 ✗ {elt_1} := toModelicaFormElts({elt});
2408 ✗ elts_1 := toModelicaFormElts(elts);
2409 ✗ then
2410 (DAE.WHEN_EQUATION(e1_1,welts_1,SOME(elt_1),source)::elts_1);
2411
2412 case DAE.WHEN_EQUATION(condition = e1,equations = welts,elsewhen_ = NONE(),source = source)::elts
2413 algorithm
2414 ✗ e1_1 := toModelicaFormExp(e1);
2415 ✗ welts_1 := toModelicaFormElts(welts);
2416 ✗ elts_1 := toModelicaFormElts(elts);
2417 ✗ then
2418 (DAE.WHEN_EQUATION(e1_1,welts_1,NONE(),source)::elts_1);
2419
2420 case DAE.IF_EQUATION(condition1 = conds,equations2 = trueBranches,equations3 = eelts,source = source)::elts
2421 algorithm
2422 ✗ conds_1 := List.map(conds,toModelicaFormExp);
2423 ✗ trueBranches_1 := List.map(trueBranches,toModelicaFormElts);
2424 ✗ eelts_1 := toModelicaFormElts(eelts);
2425 ✗ elts_1 := toModelicaFormElts(elts);
2426 ✗ then
2427 (DAE.IF_EQUATION(conds_1,trueBranches_1,eelts_1,source)::elts_1);
2428
2429 case DAE.INITIAL_IF_EQUATION(condition1 = conds,equations2 = trueBranches,equations3 = eelts,source = source)::elts
2430 algorithm
2431 ✗ conds_1 := List.map(conds,toModelicaFormExp);
2432 ✗ trueBranches_1 := List.map(trueBranches,toModelicaFormElts);
2433 ✗ eelts_1 := toModelicaFormElts(eelts);
2434 ✗ elts_1 := toModelicaFormElts(elts);
2435 ✗ then
2436 (DAE.INITIAL_IF_EQUATION(conds_1,trueBranches_1,eelts_1,source)::elts_1);
2437
2438 case DAE.INITIALEQUATION(exp1 = e1,exp2 = e2,source = source)::elts
2439 algorithm
2440 ✗ e1_1 := toModelicaFormExp(e1);
2441 ✗ e2_1 := toModelicaFormExp(e2);
2442 ✗ elts_1 := toModelicaFormElts(elts);
2443 ✗ then
2444 (DAE.INITIALEQUATION(e1_1,e2_1,source)::elts_1);
2445
2446 case DAE.ALGORITHM(algorithm_ = alg,source = source)::elts
2447 algorithm
2448 ✗ print("to_modelica_form_elts(ALGORITHM) not impl. yet\n");
2449 ✗ elts_1 := toModelicaFormElts(elts);
2450 ✗ then
2451 (DAE.ALGORITHM(alg,source)::elts_1);
2452
2453 case DAE.INITIALALGORITHM(algorithm_ = alg,source = source)::elts
2454 algorithm
2455 ✗ print("to_modelica_form_elts(INITIALALGORITHM) not impl. yet\n");
2456 ✗ elts_1 := toModelicaFormElts(elts);
2457 ✗ then
2458 (DAE.INITIALALGORITHM(alg,source)::elts_1);
2459
2460 case DAE.COMP(ident = id,dAElist = elts2,source = source, comment = comment)::elts
2461 algorithm
2462 ✗ elts2 := toModelicaFormElts(elts2);
2463 ✗ elts_1 := toModelicaFormElts(elts);
2464 ✗ then
2465 (DAE.COMP(id,elts2,source,comment)::elts_1);
2466
2467 case DAE.ASSERT(condition = e1,message=e2,level=e3,source = source)::elts
2468 algorithm
2469 ✗ elts_1 := toModelicaFormElts(elts);
2470 ✗ e_1 := toModelicaFormExp(e1);
2471 ✗ e_2 := toModelicaFormExp(e2);
2472 ✗ e_3 := toModelicaFormExp(e3);
2473 ✗ then
2474 (DAE.ASSERT(e_1,e_2,e_3,source)::elts_1);
2475
2476 case DAE.INITIAL_ASSERT(condition = e1,message=e2,level=e3,source = source)::elts
2477 algorithm
2478 ✗ elts_1 := toModelicaFormElts(elts);
2479 ✗ e_1 := toModelicaFormExp(e1);
2480 ✗ e_2 := toModelicaFormExp(e2);
2481 ✗ e_3 := toModelicaFormExp(e3);
2482 ✗ then
2483 (DAE.INITIAL_ASSERT(e_1,e_2,e_3,source)::elts_1);
2484
2485 case DAE.TERMINATE(message = e1,source = source)::elts
2486 algorithm
2487 ✗ elts_1 := toModelicaFormElts(elts);
2488 ✗ e_1 := toModelicaFormExp(e1);
2489 ✗ then
2490 (DAE.TERMINATE(e_1,source)::elts_1);
2491
2492 case DAE.INITIAL_TERMINATE(message = e1,source = source)::elts
2493 algorithm
2494 ✗ elts_1 := toModelicaFormElts(elts);
2495 ✗ e_1 := toModelicaFormExp(e1);
2496 ✗ then
2497 (DAE.INITIAL_TERMINATE(e_1,source)::elts_1);
2498 end match;
2499 end toModelicaFormElts;
2500
2501 public function replaceCrefInVar "
2502 Author BZ
2503 Function for updating the Component Ref of the Var"
2504 input DAE.ComponentRef newCr;
2505 input DAE.Element inelem;
2506 output DAE.Element outelem;
2507 algorithm
2508 outelem := match inelem
2509 local
2510 DAE.VarKind a2;
2511 DAE.VarDirection a3; DAE.VarParallelism prl;
2512 DAE.VarVisibility a4;
2513 DAE.Type a5; DAE.InstDims a7; DAE.ConnectorType ct;
2514 Option<DAE.Exp> a6;
2515 DAE.ElementSource source;
2516 Option<DAE.VariableAttributes> a11;
2517 Option<SCode.Comment> a12; Absyn.InnerOuter a13;
2518 Boolean e;
2519
2520 case DAE.VAR(_,a2,a3,prl,a4,a5,a6,a7,ct,source,a11,a12,a13,e)
2521
1/2
✓ Branch 0 taken 492 times.
✗ Branch 1 not taken.
984 then DAE.VAR(newCr,a2,a3,prl,a4,a5,a6,a7,ct,source,a11,a12,a13,e);
2522 end match;
2523 end replaceCrefInVar;
2524
2525 public function replaceTypeInVar "
2526 Author BZ
2527 Function for updating the Type of the Var"
2528 input DAE.Type newType;
2529 input DAE.Element inelem;
2530 output DAE.Element outelem;
2531 algorithm
2532 outelem := match inelem
2533 local
2534 DAE.ComponentRef a1; DAE.VarKind a2;
2535 DAE.VarDirection a3; DAE.VarParallelism prl;
2536 DAE.VarVisibility a4;
2537 DAE.InstDims a7; DAE.ConnectorType ct;
2538 Option<DAE.Exp> a6;
2539 DAE.ElementSource source;
2540 Option<DAE.VariableAttributes> a11;
2541 Option<SCode.Comment> a12; Absyn.InnerOuter a13;
2542 Boolean e;
2543
2544 case DAE.VAR(a1,a2,a3,prl,a4,_,a6,a7,ct,source,a11,a12,a13,e)
2545 ✗ then DAE.VAR(a1,a2,a3,prl,a4,newType,a6,a7,ct,source,a11,a12,a13,e);
2546 end match;
2547 end replaceTypeInVar;
2548
2549 public function replaceCrefandTypeInVar "
2550 Author BZ
2551 Function for updating the Component Ref and the Type of the Var"
2552 input DAE.ComponentRef newCr;
2553 input DAE.Type newType;
2554 input DAE.Element inelem;
2555 output DAE.Element outelem;
2556 algorithm
2557 outelem := match inelem
2558 local
2559 DAE.VarKind a2;
2560 DAE.VarDirection a3; DAE.VarParallelism prl;
2561 DAE.VarVisibility a4;
2562 DAE.InstDims a7; DAE.ConnectorType ct;
2563 Option<DAE.Exp> a6;
2564 DAE.ElementSource source;
2565 Option<DAE.VariableAttributes> a11;
2566 Option<SCode.Comment> a12; Absyn.InnerOuter a13;
2567 Boolean e;
2568
2569 case DAE.VAR(_,a2,a3,prl,a4,_,a6,a7,ct,source,a11,a12,a13,e)
2570 algorithm
2571
1/2
✓ Branch 0 taken 3002 times.
✗ Branch 1 not taken.
6004 outelem := DAE.VAR(newCr,a2,a3,prl,a4,newType,a6,a7,ct,source,a11,a12,a13,e);
2572 then outelem;
2573 end match;
2574 end replaceCrefandTypeInVar;
2575
2576
2577 public function replaceBindungInVar "
2578 Author BZ
2579 Function for updating the Component Ref of the Var"
2580 input DAE.Exp newBindung;
2581 input DAE.Element inelem;
2582 output DAE.Element outelem;
2583 algorithm
2584 outelem := match inelem
2585 local
2586 DAE.ComponentRef a1; DAE.VarKind a2;
2587 DAE.VarDirection a3; DAE.VarParallelism prl;
2588 DAE.VarVisibility a4;
2589 DAE.Type a5; DAE.InstDims a7; DAE.ConnectorType ct;
2590 DAE.ElementSource source;
2591 Option<DAE.VariableAttributes> a11;
2592 Option<SCode.Comment> a12; Absyn.InnerOuter a13;
2593 Boolean e;
2594
2595 case DAE.VAR(a1,a2,a3,prl,a4,a5,_,a7,ct,source,a11,a12,a13,e)
2596
1/2
✓ Branch 0 taken 726 times.
✗ Branch 1 not taken.
1452 then DAE.VAR(a1,a2,a3,prl,a4,a5,SOME(newBindung),a7,ct,source,a11,a12,a13,e);
2597 end match;
2598 end replaceBindungInVar;
2599
2600 protected function toModelicaFormExpOpt "Helper function to toMdelicaFormElts."
2601 input Option<DAE.Exp> inExpExpOption;
2602 output Option<DAE.Exp> outExpExpOption;
2603 algorithm
2604 outExpExpOption := match inExpExpOption
2605 local DAE.Exp e_1,e;
2606 ✗ case SOME(e) algorithm e_1 := toModelicaFormExp(e); then SOME(e_1);
2607 case NONE() then NONE();
2608 end match;
2609 end toModelicaFormExpOpt;
2610
2611 protected function toModelicaFormCref "Helper function to toModelicaFormElts."
2612 input DAE.ComponentRef cr;
2613 output DAE.ComponentRef outComponentRef;
2614 protected
2615 String str,str_1;
2616 DAE.Type ty;
2617 algorithm
2618 ✗ str := ComponentReferenceBasics.printComponentRefStr(cr);
2619 ✗ ty := ComponentReference.crefLastType(cr);
2620 ✗ str_1 := Util.stringReplaceChar(str, ".", "_");
2621 ✗ outComponentRef := ComponentReferenceBasics.makeCrefIdent(str_1,ty,{});
2622 end toModelicaFormCref;
2623
2624 protected function toModelicaFormExp "Helper function to toModelicaFormElts."
2625 input DAE.Exp inExp;
2626 output DAE.Exp outExp;
2627 algorithm
2628 outExp := matchcontinue inExp
2629 local
2630 DAE.ComponentRef cr_1,cr;
2631 DAE.Type t;
2632 DAE.Exp e1_1,e2_1,e1,e2,e_1,e,e3_1,e3;
2633 DAE.Operator op;
2634 list<DAE.Exp> expl_1,expl;
2635 Absyn.Path f;
2636 Boolean b;
2637 Integer i;
2638 Option<DAE.Exp> eopt_1,eopt;
2639 DAE.CallAttributes attr;
2640 Option<tuple<DAE.Exp,Integer,Integer>> optionExpisASUB;
2641 list<DAE.Subscript> subs;
2642
2643 case DAE.CREF(componentRef = cr,ty = t)
2644 algorithm
2645 ✗ cr_1 := toModelicaFormCref(cr);
2646 ✗ then
2647 Expression.makeCrefExp(cr_1,t);
2648
2649 case DAE.BINARY(exp1 = e1,operator = op,exp2 = e2)
2650 algorithm
2651 ✗ e1_1 := toModelicaFormExp(e1);
2652 ✗ e2_1 := toModelicaFormExp(e2);
2653 ✗ then
2654 DAE.BINARY(e1_1,op,e2_1);
2655 case DAE.LBINARY(exp1 = e1,operator = op,exp2 = e2)
2656 algorithm
2657 ✗ e1_1 := toModelicaFormExp(e1);
2658 ✗ e2_1 := toModelicaFormExp(e2);
2659 ✗ then
2660 DAE.LBINARY(e1_1,op,e2_1);
2661 case DAE.UNARY(operator = op,exp = e)
2662 algorithm
2663 ✗ e_1 := toModelicaFormExp(e);
2664 ✗ then
2665 DAE.UNARY(op,e_1);
2666 case DAE.LUNARY(operator = op,exp = e)
2667 algorithm
2668 ✗ e_1 := toModelicaFormExp(e);
2669 ✗ then
2670 DAE.LUNARY(op,e_1);
2671 case DAE.RELATION(exp1 = e1,operator = op,exp2 = e2,index=i,optionExpisASUB=optionExpisASUB)
2672 algorithm
2673 ✗ e1_1 := toModelicaFormExp(e1);
2674 ✗ e2_1 := toModelicaFormExp(e2);
2675 ✗ then
2676 DAE.RELATION(e1_1,op,e2_1,i,optionExpisASUB);
2677 case DAE.IFEXP(expCond = e1,expThen = e2,expElse = e3)
2678 algorithm
2679 ✗ e1_1 := toModelicaFormExp(e1);
2680 ✗ e2_1 := toModelicaFormExp(e2);
2681 ✗ e3_1 := toModelicaFormExp(e3);
2682 ✗ then
2683 DAE.IFEXP(e1_1,e2_1,e3_1);
2684 case DAE.CALL(path = f,expLst = expl,attr = attr)
2685 algorithm
2686 ✗ expl_1 := List.map(expl, toModelicaFormExp);
2687 ✗ then
2688 DAE.CALL(f,expl_1,attr);
2689 case DAE.ARRAY(ty = t,scalar = b,array = expl)
2690 algorithm
2691 ✗ expl_1 := List.map(expl, toModelicaFormExp);
2692 ✗ then
2693 DAE.ARRAY(t,b,expl_1);
2694 case DAE.TUPLE(PR = expl)
2695 algorithm
2696 ✗ expl_1 := List.map(expl, toModelicaFormExp);
2697 ✗ then
2698 DAE.TUPLE(expl_1);
2699 case DAE.CAST(ty = t,exp = e)
2700 algorithm
2701 ✗ e_1 := toModelicaFormExp(e);
2702 ✗ then
2703 DAE.CAST(t,e_1);
2704 case DAE.ASUB(exp = e,sub = subs)
2705 algorithm
2706 ✗ e_1 := toModelicaFormExp(e);
2707 ✗ expl := list(Expression.getSubscriptExp(sub) for sub in subs);
2708 ✗ then
2709 Expression.makeASUB(e_1,expl);
2710 case DAE.SIZE(exp = e,sz = eopt)
2711 algorithm
2712 ✗ e_1 := toModelicaFormExp(e);
2713 ✗ eopt_1 := toModelicaFormExpOpt(eopt);
2714 ✗ then
2715 DAE.SIZE(e_1,eopt_1);
2716 case e then e;
2717 end matchcontinue;
2718 end toModelicaFormExp;
2719
2720 public function getNamedFunction "Return the FUNCTION with the given name. Fails if not found."
2721 input Absyn.Path path;
2722 input AvlTreePathFunction.Tree functions;
2723 output DAE.Function outElement;
2724 algorithm
2725 outElement := matchcontinue functions
2726 local
2727 String msg;
2728
2729 5955 case _ then Util.getOption(AvlTreePathFunction.get(functions, path));
2730 else
2731 algorithm
2732
1/2
✓ Branch 1 taken 915 times.
✗ Branch 2 not taken.
915 true := Flags.isSet(Flags.FAILTRACE);
2733 ✗ msg := stringDelimitList(List.mapMap(getFunctionList(functions), functionName, AbsynUtil.pathStringDefault), "\n ");
2734 ✗ msg := "DAEUtil.getNamedFunction failed: " + AbsynUtil.pathString(path) + "\nThe following functions were part of the cache:\n " + msg;
2735 // Error.addMessage(Error.INTERNAL_ERROR,{msg});
2736 ✗ Debug.traceln(msg);
2737 ✗ then
2738 fail();
2739 end matchcontinue;
2740 end getNamedFunction;
2741
2742 public function getNamedFunctionWithError "Return the FUNCTION with the given name. Fails if not found."
2743 input Absyn.Path path;
2744 input AvlTreePathFunction.Tree functions;
2745 input SourceInfo info;
2746 output DAE.Function outElement;
2747 algorithm
2748 outElement := matchcontinue info
2749 local
2750 String msg;
2751
2752 ✗ case _ then Util.getOption(AvlTreePathFunction.get(functions, path));
2753 else
2754 algorithm
2755 ✗ msg := stringDelimitList(List.mapMap(getFunctionList(functions), functionName, AbsynUtil.pathStringDefault), "\n ");
2756 ✗ msg := "DAEUtil.getNamedFunction failed: " + AbsynUtil.pathString(path) + "\nThe following functions were part of the cache:\n " + msg;
2757 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR,{msg},info);
2758 ✗ then fail();
2759 end matchcontinue;
2760 end getNamedFunctionWithError;
2761
2762 public function getNamedFunctionFromList "Is slow; PartFn.mo should be rewritten using the FunctionTree"
2763 input Absyn.Path ipath;
2764 input list<DAE.Function> ifns;
2765 output DAE.Function fn;
2766 algorithm
2767 fn := matchcontinue (ipath,ifns)
2768 local Absyn.Path path; list<DAE.Function> fns;
2769 case (path,fn::_)
2770 algorithm
2771 ✗ true := AbsynUtil.pathEqual(functionName(fn),path);
2772 then fn;
2773 ✗ case (path,_::fns) then getNamedFunctionFromList(path, fns);
2774 case (path,{})
2775 algorithm
2776 ✗ true := Flags.isSet(Flags.FAILTRACE);
2777 ✗ Debug.traceln("- DAEUtil.getNamedFunctionFromList failed " + AbsynUtil.pathString(path));
2778 ✗ then
2779 fail();
2780 end matchcontinue;
2781 end getNamedFunctionFromList;
2782
2783 public function getFunctionVisibility
2784 input DAE.Function fn;
2785 output SCode.Visibility visibility;
2786 algorithm
2787 visibility := match fn
2788 case DAE.FUNCTION(visibility = visibility) then visibility;
2789 else SCode.PUBLIC();
2790 end match;
2791 end getFunctionVisibility;
2792
2793 protected function getFunctionsElements
2794 input list<DAE.Function> elements;
2795 output list<DAE.Element> els;
2796 protected
2797 list<list<DAE.Element>> elsList;
2798 algorithm
2799 112 elsList := List.map(elements, getFunctionElements);
2800 112 els := List.flatten(elsList);
2801 end getFunctionsElements;
2802
2803 public function getFunctionElements
2804 input DAE.Function fn;
2805 output list<DAE.Element> els;
2806 algorithm
2807 els := match fn
2808 local
2809 list<DAE.Element> elements;
2810 case DAE.FUNCTION(functions = (DAE.FUNCTION_DEF(body = elements)::_)) then elements;
2811 case DAE.FUNCTION(functions = (DAE.FUNCTION_EXT(body = elements)::_)) then elements;
2812 case DAE.RECORD_CONSTRUCTOR() then {};
2813 end match;
2814 end getFunctionElements;
2815
2816 public function getFunctionType
2817 input DAE.Function fn;
2818 output DAE.Type outType;
2819 algorithm
2820 outType := match fn
2821 local
2822 case DAE.FUNCTION(type_ = outType) then outType;
2823 case DAE.FUNCTION(type_ = outType) then outType;
2824 case DAE.RECORD_CONSTRUCTOR(type_ = outType) then outType;
2825 end match;
2826 end getFunctionType;
2827
2828 public function getFunctionImpureAttribute
2829 input DAE.Function fn;
2830 output Boolean outImpure;
2831 algorithm
2832 outImpure := match fn
2833 local
2834 case DAE.FUNCTION(isImpure = outImpure) then outImpure;
2835 end match;
2836 end getFunctionImpureAttribute;
2837
2838 public function getFunctionInlineType
2839 input DAE.Function fn;
2840 output DAE.InlineType outInlineType;
2841 algorithm
2842 outInlineType := match fn
2843 local
2844 case DAE.FUNCTION(inlineType = outInlineType) then outInlineType;
2845 end match;
2846 end getFunctionInlineType;
2847
2848 public function getFunctionInputVars
2849 input DAE.Function fn;
2850 output list<DAE.Element> outEls;
2851 protected
2852 list<DAE.Element> elements;
2853 algorithm
2854 11452 elements := getFunctionElements(fn);
2855 11452 outEls := List.filterOnTrue(elements, isInputVar);
2856 end getFunctionInputVars;
2857
2858 public function getFunctionOutputVars
2859 input DAE.Function fn;
2860 output list<DAE.Element> outEls;
2861 protected
2862 list<DAE.Element> elements;
2863 algorithm
2864 4406 elements := getFunctionElements(fn);
2865 4406 outEls := List.filterOnTrue(elements, isOutputElement);
2866 end getFunctionOutputVars;
2867
2868 public function getFunctionProtectedVars
2869 input DAE.Function fn;
2870 output list<DAE.Element> outEls;
2871 protected
2872 list<DAE.Element> elements;
2873 algorithm
2874 75 elements := getFunctionElements(fn);
2875 75 outEls := List.filterOnTrue(elements, isProtectedVar);
2876 end getFunctionProtectedVars;
2877
2878 public function getFunctionAlgorithms
2879 input DAE.Function fn;
2880 output list<DAE.Element> outEls;
2881 protected
2882 list<DAE.Element> elements;
2883 algorithm
2884 ✗ elements := getFunctionElements(fn);
2885 ✗ outEls := List.filterOnTrue(elements, isAlgorithm);
2886 end getFunctionAlgorithms;
2887
2888 public function getFunctionAlgorithmStmts
2889 input DAE.Function fn;
2890 output list<DAE.Statement> bodyStmts;
2891 protected
2892 list<DAE.Element> elements;
2893 algorithm
2894 75 elements := getFunctionElements(fn);
2895 75 bodyStmts := List.mapFlat(List.filterOnTrue(elements, isAlgorithm), getStatement);
2896 end getFunctionAlgorithmStmts;
2897
2898 public function getStatement
2899 input DAE.Element inElement;
2900 output list<DAE.Statement> outStatements;
2901 algorithm
2902 outStatements:=
2903 match inElement
2904 local
2905 list<DAE.Statement> stmts;
2906 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(statementLst = stmts))
2907 then
2908 stmts;
2909 else
2910 algorithm
2911 ✗ true := Flags.isSet(Flags.FAILTRACE);
2912 ✗ Debug.trace("- Differentiatte.getStatement failed\n");
2913 ✗ then
2914 fail();
2915 end match;
2916 end getStatement;
2917
2918 public function getTupleSize "gets the size of a DAE.TUPLE"
2919 input DAE.Exp inExp;
2920 output Integer size;
2921 algorithm
2922 size := match inExp
2923 local
2924 list<DAE.Exp> exps;
2925 case DAE.TUPLE(exps)
2926 algorithm
2927 2041 size := listLength(exps);
2928 then
2929 size;
2930 else
2931 then
2932 0;
2933 end match;
2934 end getTupleSize;
2935
2936 public function getTupleExps "gets the list<DAE.Exp> of a DAE.TUPLE or the list of the exp if its not a tuple"
2937 input DAE.Exp inExp;
2938 output list<DAE.Exp> exps;
2939 algorithm
2940 exps := match inExp
2941 local
2942 case DAE.TUPLE(exps)
2943 then
2944 exps;
2945 else
2946 then
2947 {inExp};
2948 end match;
2949 end getTupleExps;
2950
2951 protected function crefToExp "
2952 Makes an expression from a ComponentRef.
2953 "
2954 input DAE.ComponentRef inComponentRef;
2955 output DAE.Exp outExp;
2956 algorithm
2957 ✗ outExp:= Expression.makeCrefExp(inComponentRef,DAE.T_UNKNOWN_DEFAULT);
2958 end crefToExp;
2959
2960 public function verifyEquationsDAE "
2961 Perform some checks for DAE equations:
2962 1. Assert equations should be used only inside when equations;
2963 2. Bolean when equation should:
2964 2.1 not contain nested clocked or boolean when equations;
2965 2.2 not have clocked else-when parts;
2966 2.3 have component references on left side of its equations, and
2967 for each branch the set of left hand references should be same;
2968 3. Clocked when equation should not:
2969 3.1 contain nested clocked when equations;
2970 3.2 contain else-when parts;
2971 3.3 contain reinit equation(?);
2972 4. Initial when equation should not contain assert equation.
2973 "
2974 input DAE.DAElist dae;
2975 protected
2976 DAE.Exp cond;
2977 list<DAE.Element> dae_elts, eqs;
2978 Option<DAE.Element> ew;
2979 DAE.ElementSource source;
2980 DAE.Element el;
2981 SourceInfo info;
2982 algorithm
2983 159943 DAE.DAE(dae_elts) := dae;
2984
4/5
✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25331 times.
✓ Branch 3 taken 25469 times.
✓ Branch 4 taken 159943 times.
185412 for el in dae_elts loop
2985 () := match el
2986 case DAE.WHEN_EQUATION(cond, eqs, ew, source)
2987 138 algorithm verifyWhenEquation(cond, eqs, ew, source);
2988 then ();
2989 case DAE.REINIT()
2990 algorithm
2991 ✗ info := ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(el));
2992 ✗ Error.addSourceMessageAndFail(Error.REINIT_NOT_IN_WHEN, {}, info);
2993 then ();
2994 else ();
2995 end match;
2996 end for;
2997 end verifyEquationsDAE;
2998
2999 protected function verifyWhenEquation
3000 input DAE.Exp cond;
3001 input list<DAE.Element> eqs;
3002 input Option<DAE.Element> ew;
3003 input DAE.ElementSource source;
3004 algorithm
3005
2/2
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 115 times.
138 if Types.isClockOrSubTypeClock(Expression.typeof(cond))
3006 23 then verifyClockWhenEquation(cond, eqs, ew, source);
3007 115 else verifyBoolWhenEquation(cond, eqs, ew, source);
3008 end if;
3009 end verifyWhenEquation;
3010
3011 protected function verifyClockWhenEquation
3012 input DAE.Exp cond;
3013 input list<DAE.Element> eqs;
3014 input Option<DAE.Element> ew;
3015 input DAE.ElementSource source;
3016 protected
3017 SourceInfo info;
3018 algorithm
3019
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
23 if isSome(ew) then
3020 ✗ info := ElementSource.getElementSourceFileInfo(source);
3021 ✗ Error.addSourceMessageAndFail(Error.ELSE_WHEN_CLOCK, {}, info);
3022 end if;
3023 23 verifyClockWhenEquation1(eqs);
3024 end verifyClockWhenEquation;
3025
3026 protected function verifyClockWhenEquation1
3027 input list<DAE.Element> inEqs;
3028 protected
3029 DAE.Element el;
3030 algorithm
3031
3/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 23 times.
52 for el in inEqs loop
3032 () := match el
3033 local
3034 DAE.Exp cond;
3035 list<DAE.Element> eqs;
3036 Option<DAE.Element> ew;
3037 DAE.ElementSource source;
3038 SourceInfo info;
3039 case DAE.REINIT()
3040 algorithm
3041 ✗ info := ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(el));
3042 ✗ Error.addSourceMessageAndFail(Error.REINIT_NOT_IN_WHEN, {}, info);
3043 then ();
3044 case DAE.WHEN_EQUATION(cond, eqs, ew, source)
3045 algorithm
3046 ✗ if Types.isClockOrSubTypeClock(Expression.typeof(cond)) then
3047 ✗ info := ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(el));
3048 ✗ Error.addSourceMessageAndFail(Error.NESTED_CLOCKED_WHEN, {}, info);
3049 end if;
3050 ✗ verifyBoolWhenEquation(cond, eqs, ew, source);
3051 then ();
3052 else ();
3053 end match;
3054 end for;
3055 end verifyClockWhenEquation1;
3056
3057 protected function verifyBoolWhenEquation
3058 input DAE.Exp inCond;
3059 input list<DAE.Element> inEqs;
3060 input Option<DAE.Element> inElseWhen;
3061 input DAE.ElementSource source;
3062 protected
3063 list<DAE.ComponentRef> crefs1, crefs2;
3064 list<tuple<DAE.Exp, list<DAE.Element>>> whenBranches;
3065 tuple<DAE.Exp, list<DAE.Element>> whenBranch;
3066 DAE.Exp cond;
3067 list<DAE.Element> eqs;
3068 SourceInfo info;
3069 algorithm
3070 115 crefs1 := verifyBoolWhenEquationBranch(inCond, inEqs);
3071 115 whenBranches := collectWhenEquationBranches(inElseWhen);
3072
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 115 times.
116 for whenBranch in whenBranches loop
3073 1 (cond, eqs) := whenBranch;
3074
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if Types.isClockOrSubTypeClock(Expression.typeof(cond)) then
3075 ✗ info := ElementSource.getElementSourceFileInfo(source);
3076 ✗ Error.addSourceMessageAndFail(Error.CLOCKED_WHEN_BRANCH, {}, info);
3077 end if;
3078 1 crefs2 := verifyBoolWhenEquationBranch(cond, eqs);
3079 1 crefs2 := List.unionOnTrue(crefs1, crefs2, ComponentReferenceBasics.crefEqual);
3080
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 if listLength(crefs2) <> listLength(crefs1) then
3081 ✗ info := ElementSource.getElementSourceFileInfo(source);
3082 ✗ Error.addSourceMessageAndFail(Error.DIFFERENT_VARIABLES_SOLVED_IN_ELSEWHEN, {}, info);
3083 end if;
3084 end for;
3085 end verifyBoolWhenEquation;
3086
3087 protected function collectWhenEquationBranches
3088 input Option<DAE.Element> inElseWhen;
3089 input list<tuple<DAE.Exp, list<DAE.Element>>> inWhenBranches = {};
3090 output list<tuple<DAE.Exp, list<DAE.Element>>> outWhenBranches;
3091 algorithm
3092 outWhenBranches := match inElseWhen
3093 local
3094 DAE.Exp cond;
3095 list<DAE.Element> eqs;
3096 Option<DAE.Element> ew;
3097 SourceInfo info;
3098 String msg;
3099 DAE.Element el;
3100 case NONE()
3101 then inWhenBranches;
3102 case SOME(DAE.WHEN_EQUATION(cond, eqs, ew, _))
3103 2 then collectWhenEquationBranches(ew, (cond, eqs)::inWhenBranches);
3104 case SOME(el)
3105 algorithm
3106 ✗ msg := "- DAEUtil.collectWhenEquationBranches failed on: " + DAEDump.dumpElementsStr({el});
3107 ✗ info := ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(el));
3108 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {msg}, info);
3109 ✗ then fail();
3110 end match;
3111 end collectWhenEquationBranches;
3112
3113 protected function verifyBoolWhenEquationBranch
3114 input DAE.Exp inCond;
3115 input list<DAE.Element> inEqs;
3116 output list<DAE.ComponentRef> crefs;
3117 protected
3118 Boolean initCond = Expression.containsInitialCall(inCond);
3119 algorithm
3120 116 crefs := verifyBoolWhenEquation1(inEqs, initCond);
3121 end verifyBoolWhenEquationBranch;
3122
3123 protected function verifyBoolWhenEquation1
3124 input list<DAE.Element> inElems;
3125 input Boolean initCond;
3126 input list<DAE.ComponentRef> inCrefs = {};
3127 output list<DAE.ComponentRef> outCrefs;
3128 algorithm
3129 outCrefs := match inElems
3130 local
3131 list<DAE.Element> rest;
3132 DAE.ComponentRef cr;
3133 DAE.Exp e;
3134 list<DAE.ComponentRef> crefs;
3135 list<list<DAE.ComponentRef>> crefsLists;
3136 DAE.ElementSource source;
3137 SourceInfo info;
3138 DAE.Element el;
3139 list<DAE.Element> falseEqs;
3140 list<list<DAE.Element>> trueEqs;
3141 Boolean b;
3142 String msg;
3143 case {} then inCrefs;
3144
3145 case DAE.VAR()::rest
3146 ✗ then verifyBoolWhenEquation1(rest, initCond, inCrefs);
3147
3148 case DAE.DEFINE(componentRef = cr)::rest
3149 ✗ then verifyBoolWhenEquation1(rest, initCond, cr::inCrefs);
3150
3151 case DAE.EQUATION(exp = e, source = source)::rest
3152 133 algorithm crefs := collectWhenCrefs1(e, source, inCrefs);
3153 133 then verifyBoolWhenEquation1(rest, initCond, crefs);
3154
3155 case DAE.ARRAY_EQUATION(exp = e, source = source)::rest
3156 ✗ algorithm crefs := collectWhenCrefs1(e, source, inCrefs);
3157 ✗ then verifyBoolWhenEquation1(rest, initCond, crefs);
3158
3159 case DAE.COMPLEX_EQUATION(lhs = e, source = source)::rest
3160 ✗ algorithm crefs := collectWhenCrefs1(e, source, inCrefs);
3161 ✗ then verifyBoolWhenEquation1(rest, initCond, crefs);
3162
3163 case DAE.EQUEQUATION(cr1 = cr)::rest
3164 ✗ then verifyBoolWhenEquation1(rest, initCond, cr::inCrefs);
3165
3166 case DAE.IF_EQUATION(equations2 = trueEqs, equations3 = falseEqs, source = source)::rest
3167 algorithm
3168 ✗ crefsLists := List.map2(trueEqs, verifyBoolWhenEquation1, initCond, {});
3169 ✗ crefs := verifyBoolWhenEquation1(falseEqs, initCond);
3170 crefsLists := crefs::crefsLists;
3171 ✗ (crefs, b) := compareCrefList(crefsLists);
3172 ✗ if not b then
3173 ✗ info := ElementSource.getElementSourceFileInfo(source);
3174 msg := "All branches must write to the same variable";
3175 ✗ Error.addSourceMessage(Error.WHEN_EQ_LHS, {msg}, info);
3176 ✗ fail();
3177 end if;
3178 ✗ then verifyBoolWhenEquation1(rest, initCond, listAppend(crefs, inCrefs));
3179
3180 case DAE.ASSERT()::rest
3181 2 then verifyBoolWhenEquation1(rest, initCond, inCrefs);
3182
3183 case DAE.TERMINATE()::rest
3184 5 then verifyBoolWhenEquation1(rest, initCond, inCrefs);
3185
3186 case DAE.REINIT(source = source)::rest
3187 algorithm
3188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if initCond then
3189 ✗ info := ElementSource.getElementSourceFileInfo(source);
3190 ✗ Error.addSourceMessage(Error.REINIT_IN_WHEN_INITIAL, {}, info);
3191 ✗ fail();
3192 end if;
3193 16 then verifyBoolWhenEquation1(rest, initCond, inCrefs);
3194
3195 // adrpo: TODO! FIXME! WHY??!! we might push values to a file writeFile(time);
3196 case DAE.NORETCALL()::rest
3197 3 then verifyBoolWhenEquation1(rest, initCond, inCrefs);
3198
3199 case DAE.WHEN_EQUATION(condition = e, source=source)::_
3200 algorithm
3201 ✗ info := ElementSource.getElementSourceFileInfo(source);
3202 ✗ if Types.isClockOrSubTypeClock(Expression.typeof(e)) then
3203 ✗ Error.addSourceMessage(Error.CLOCKED_WHEN_IN_WHEN_EQ , {}, info);
3204 else
3205 ✗ Error.addSourceMessage(Error.NESTED_WHEN, {}, info);
3206 end if;
3207 ✗ then fail();
3208
3209 case el::_
3210 algorithm
3211 ✗ msg := "- DAEUtil.verifyWhenEquationStatements failed on: " + DAEDump.dumpElementsStr({el});
3212 ✗ info := ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(el));
3213 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {msg}, info);
3214 ✗ then fail();
3215 end match;
3216 end verifyBoolWhenEquation1;
3217
3218 protected function collectWhenCrefs
3219 input list<DAE.Exp> inExps;
3220 input DAE.ElementSource source;
3221 input list<DAE.ComponentRef> inCrefs = {};
3222 output list<DAE.ComponentRef> outCrefs;
3223 algorithm
3224 ✗ outCrefs := List.fold1(inExps, collectWhenCrefs1, source, inCrefs);
3225 end collectWhenCrefs;
3226
3227 protected function collectWhenCrefs1
3228 input DAE.Exp inExp;
3229 input DAE.ElementSource source;
3230 input list<DAE.ComponentRef> inCrefs = {};
3231 output list<DAE.ComponentRef> outCrefs;
3232 protected
3233 list<DAE.Exp> exps;
3234 DAE.ComponentRef cr;
3235 algorithm
3236 outCrefs := match inExp
3237 local
3238 String msg;
3239 SourceInfo info;
3240 case DAE.CREF(cr, _) then cr::inCrefs;
3241 ✗ case DAE.TUPLE(exps) then collectWhenCrefs(exps, source, inCrefs);
3242 else
3243 algorithm
3244 ✗ msg := ExpressionBasics.printExpStr(inExp);
3245 ✗ info := ElementSource.getElementSourceFileInfo(source);
3246 ✗ Error.addSourceMessage(Error.WHEN_EQ_LHS, {msg}, info);
3247 ✗ then fail();
3248 end match;
3249 end collectWhenCrefs1;
3250
3251 protected function compareCrefList ""
3252 input list<list<DAE.ComponentRef>> inCrefs;
3253 output list<DAE.ComponentRef> outrefs;
3254 output Boolean matching;
3255 algorithm (outrefs,matching) := match inCrefs
3256 local
3257 list<DAE.ComponentRef> crefs,recRefs;
3258 Integer i;
3259 Boolean b1,b2,b3;
3260 list<list<DAE.ComponentRef>> llrefs;
3261
3262
3263 case {} then ({},true);
3264
3265 case crefs::{} then (crefs,true);
3266
3267 case crefs::llrefs
3268 algorithm
3269 ✗ (recRefs,b3) := compareCrefList(llrefs);
3270 ✗ i := listLength(recRefs);
3271 // make sure is more than 0!
3272 ✗ if (intGt(i, 0))
3273 then
3274 // this case will allways have revRefs >=1 unless we are supposed to have 0
3275 ✗ b1 := (0 == intMod(listLength(crefs),i));
3276 ✗ crefs := List.unionOnTrueList({recRefs,crefs},ComponentReferenceBasics.crefEqual);
3277 ✗ b2 := intEq(listLength(crefs),i);
3278 ✗ b1 := boolAnd(b1,boolAnd(b2,b3));
3279 else
3280 // this deals with 0 as the number of set crefs in one of the branches, for example:
3281 // if then reinint;reinit; else reinit;reinit; end if;
3282 // make sure both of them are 0!
3283 ✗ true := intEq(i, 0);
3284 ✗ true := listEmpty(crefs);
3285 b1 := true;
3286 end if;
3287 then
3288 (crefs,b1);
3289
3290 end match;
3291 end compareCrefList;
3292
3293 public function renameUniqueOuterVars "author: BZ, 2008-12
3294 Rename innerouter(the inner part of innerouter) variables that have been renamed to a.b.$unique$var
3295 Just remove the $unique$ from the var name.
3296 This function traverses the entire dae."
3297 input DAE.DAElist dae;
3298 output DAE.DAElist odae;
3299 algorithm
3300 ✗ (odae,_,_) := traverseDAE(dae, AvlTreePathFunction.Tree.EMPTY(), Expression.traverseSubexpressionsHelper, (removeUniqieIdentifierFromCref, 0));
3301 end renameUniqueOuterVars;
3302
3303 protected function removeUniqieIdentifierFromCref "Function for Expression.traverseExpBottomUp, removes the constant 'UNIQUEIO' from any cref it might visit."
3304 input DAE.Exp inExp;
3305 input Type_a oarg;
3306 output DAE.Exp outExp;
3307 output Type_a outDummy;
3308 replaceable type Type_a subtypeof Any;
3309 algorithm
3310 (outExp,outDummy) := matchcontinue inExp
3311 local
3312 DAE.ComponentRef cr,cr2;
3313 DAE.Type ty;
3314 DAE.Exp exp;
3315
3316 case DAE.CREF(cr,ty)
3317 algorithm
3318 ✗ cr2 := unNameInnerouterUniqueCref(cr,DAE.UNIQUEIO);
3319 ✗ exp := Expression.makeCrefExp(cr2,ty);
3320 then (exp,oarg);
3321
3322 else (inExp,oarg);
3323
3324 end matchcontinue;
3325 end removeUniqieIdentifierFromCref;
3326
3327 public function nameUniqueOuterVars "author: BZ, 2008-12
3328 Rename all variables to the form a.b.$unique$var, call
3329 This function traverses the entire dae."
3330 input DAE.DAElist dae;
3331 output DAE.DAElist odae;
3332 algorithm
3333 4 (odae,_,_) := traverseDAE(dae, AvlTreePathFunction.Tree.EMPTY(), Expression.traverseSubexpressionsHelper, (addUniqueIdentifierToCref, 0));
3334 end nameUniqueOuterVars;
3335
3336 protected function addUniqueIdentifierToCref "author: BZ, 2008-12
3337 Function for Expression.traverseExpBottomUp, adds the constant 'UNIQUEIO' to the CREF_IDENT() part of the cref."
3338 input DAE.Exp inExp;
3339 input Type_a oarg;
3340 output DAE.Exp outExp;
3341 output Type_a outDummy;
3342 replaceable type Type_a subtypeof Any;
3343 algorithm
3344 (outExp,outDummy) := matchcontinue inExp
3345 local
3346 DAE.ComponentRef cr,cr2;
3347 DAE.Type ty;
3348 DAE.Exp exp;
3349
3350 case DAE.CREF(cr,ty)
3351 algorithm
3352 ✗ cr2 := nameInnerouterUniqueCref(cr);
3353 ✗ exp := Expression.makeCrefExp(cr2,ty);
3354 then (exp,oarg);
3355
3356 else (inExp,oarg);
3357
3358 end matchcontinue;
3359 end addUniqueIdentifierToCref;
3360
3361 // helper functions for traverseDAE
3362 protected function traverseDAEOptExp "author: BZ, 2008-12
3363 Traverse an optional expression, helper function for traverseDAE"
3364 input Option<DAE.Exp> oexp;
3365 input FuncExpType func;
3366 input Type_a iextraArg;
3367 output Option<DAE.Exp> ooexp;
3368 output Type_a oextraArg;
3369 partial function FuncExpType
3370 input DAE.Exp inExp;
3371 input Type_a inTypeA;
3372 output DAE.Exp outExp;
3373 output Type_a outA;
3374 end FuncExpType;
3375 replaceable type Type_a subtypeof Any;
3376 algorithm
3377 (ooexp,oextraArg) := match(oexp, iextraArg)
3378 local
3379 DAE.Exp e;
3380 Type_a extraArg;
3381
3382 case(NONE(), extraArg) then (NONE(),extraArg);
3383
3384 case(SOME(e), extraArg)
3385 algorithm
3386
2/2
✓ Branch 0 taken 279048 times.
✓ Branch 1 taken 1134955 times.
1414003 (e,extraArg) := func(e,extraArg);
3387 1414003 then
3388 (SOME(e),extraArg);
3389 end match;
3390 end traverseDAEOptExp;
3391
3392 protected function traverseDAEExpList "author: BZ, 2008-12
3393 Traverse an list of expressions, helper function for traverseDAE"
3394 input list<DAE.Exp> iexps;
3395 input FuncExpType func;
3396 input Type_a iextraArg;
3397 output list<DAE.Exp> oexps;
3398 output Type_a oextraArg;
3399 partial function FuncExpType
3400 input DAE.Exp inExp;
3401 input Type_a inTypeA;
3402 output DAE.Exp outExp;
3403 output Type_a outA;
3404 end FuncExpType;
3405 replaceable type Type_a subtypeof Any;
3406 algorithm
3407 (oexps,oextraArg) := match(iexps, iextraArg)
3408 local
3409 DAE.Exp e;
3410 Type_a extraArg;
3411 list<DAE.Exp> exps;
3412
3413 case({}, extraArg) then ({},extraArg);
3414
3415 case(e::exps, extraArg)
3416 algorithm
3417
2/2
✓ Branch 0 taken 546 times.
✓ Branch 1 taken 1531 times.
2077 (e,extraArg) := func(e,extraArg);
3418 2077 (oexps,extraArg) := traverseDAEExpList(exps,func,extraArg);
3419 2077 then
3420 (e::oexps,extraArg);
3421 end match;
3422 end traverseDAEExpList;
3423
3424 protected function traverseDAEList "author: BZ, 2008-12
3425 Helper function for traverseDAE, traverses a list of dae element list."
3426 input list<list<DAE.Element>> idaeList;
3427 input FuncExpType func;
3428 input Type_a iextraArg;
3429 output list<list<DAE.Element>> traversedDaeList;
3430 output Type_a oextraArg;
3431 partial function FuncExpType
3432 input DAE.Exp inExp;
3433 input Type_a inTypeA;
3434 output DAE.Exp outExp;
3435 output Type_a outA;
3436 end FuncExpType;
3437 replaceable type Type_a subtypeof Any;
3438 algorithm
3439 (traversedDaeList,oextraArg) := match(idaeList, iextraArg)
3440 local
3441 list<DAE.Element> branch,branch2;
3442 list<list<DAE.Element>> recRes,daeList;
3443 Type_a extraArg;
3444
3445 case({}, extraArg) then ({},extraArg);
3446
3447 case(branch::daeList, extraArg)
3448 algorithm
3449 2069 (branch2,extraArg) := traverseDAEElementList(branch,func,extraArg);
3450 2069 (recRes,extraArg) := traverseDAEList(daeList,func,extraArg);
3451 2069 then
3452 (branch2::recRes,extraArg);
3453 end match;
3454 end traverseDAEList;
3455
3456 public function getFunctionList
3457 input AvlTreePathFunction.Tree ft;
3458 input Boolean failOnError=false;
3459 output list<DAE.Function> fns;
3460 protected
3461 list<tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value>> lst, lstInvalid;
3462 String str;
3463 algorithm
3464 try
3465 4526 fns := List.map(AvlTreePathFunction.listValues(ft), Util.getOption);
3466 else
3467 ✗ lst := AvlTreePathFunction.toList(ft);
3468 ✗ lstInvalid := List.select(lst, isInvalidFunctionEntry);
3469 ✗ str := stringDelimitList(list(AbsynUtil.pathString(p) for p in List.map(lstInvalid, Util.tuple21)), "\n ");
3470 ✗ str := "\n " + str + "\n";
3471 ✗ Error.addMessage(Error.NON_INSTANTIATED_FUNCTION, {str});
3472 ✗ if failOnError then
3473 ✗ fail();
3474 end if;
3475 ✗ fns := List.mapMap(List.select(lst, isValidFunctionEntry), Util.tuple22, Util.getOption);
3476 end try;
3477 end getFunctionList;
3478
3479 public function getFunctionNames
3480 input AvlTreePathFunction.Tree ft;
3481 output list<String> strs;
3482 algorithm
3483 ✗ strs := List.mapMap(getFunctionList(ft), functionName, AbsynUtil.pathStringDefault);
3484 end getFunctionNames;
3485
3486 protected function isInvalidFunctionEntry
3487 input tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value> tpl;
3488 output Boolean b;
3489 algorithm
3490 b := match tpl
3491 case (_,NONE()) then true;
3492 else false;
3493 end match;
3494 end isInvalidFunctionEntry;
3495
3496 protected function isValidFunctionEntry
3497 input tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value> tpl;
3498 output Boolean b;
3499 algorithm
3500 ✗ b := not isInvalidFunctionEntry(tpl);
3501 end isValidFunctionEntry;
3502
3503 public function traverseDAE<ArgT>
3504 "This function traverses all dae exps.
3505 NOTE, it also traverses DAE.VAR(componenname) as an expression."
3506 input output DAE.DAElist dae;
3507 input output AvlTreePathFunction.Tree functionTree;
3508 input FuncExpType func;
3509 input output ArgT arg;
3510
3511 partial function FuncExpType
3512 input output DAE.Exp exp;
3513 input output ArgT arg;
3514 end FuncExpType;
3515 protected
3516 list<DAE.Element> el;
3517 algorithm
3518 28212 (el, arg) := traverseDAEElementList(dae.elementLst, func, arg);
3519 28212 dae.elementLst := el;
3520 28212 (functionTree, arg) := AvlTreePathFunction.mapFold(functionTree,
3521 function traverseDAEFuncHelper(func = func), arg);
3522 end traverseDAE;
3523
3524 protected function traverseDAEFuncHelper<ArgT>
3525 "Helper function to traverseDae. Traverses the functions."
3526 input AvlTreePathFunction.Key key;
3527 input output AvlTreePathFunction.Value value;
3528 input FuncExpType func;
3529 input output ArgT arg;
3530
3531 partial function FuncExpType
3532 input output DAE.Exp exp;
3533 input output ArgT arg;
3534 end FuncExpType;
3535 algorithm
3536 (value,arg) := match value
3537 local
3538 DAE.Function daeFunc1,daeFunc2;
3539 case SOME(daeFunc1)
3540 algorithm
3541 17564 (daeFunc2,arg) := traverseDAEFunc(daeFunc1,func,arg);
3542
3/4
✓ Branch 0 taken 13085 times.
✓ Branch 1 taken 4479 times.
✓ Branch 2 taken 17564 times.
✗ Branch 3 not taken.
30649 then (if referenceEq(daeFunc1,daeFunc2) then value else SOME(daeFunc2),arg);
3543 case NONE()
3544 algorithm
3545 ✗ true := Flags.isSet(Flags.FAILTRACE);
3546 ✗ Debug.traceln("- DAEUtil.traverseDAEFuncLst failed: " + AbsynUtil.pathString(key));
3547 ✗ then fail();
3548 end match;
3549 end traverseDAEFuncHelper;
3550
3551 public function traverseDAEFunctions<ArgT>
3552 "Traverses the functions.
3553 Note: Only calls the top-most expressions. If you need to also traverse the
3554 expression, use an extra helper function."
3555 input output list<DAE.Function> functions;
3556 input FuncExpType func;
3557 input output ArgT arg;
3558
3559 partial function FuncExpType
3560 input output DAE.Exp exp;
3561 input output ArgT arg;
3562 end FuncExpType;
3563 algorithm
3564 1605 (functions, arg) := List.mapFold(functions,
3565 function traverseDAEFunc(func = func), arg);
3566 end traverseDAEFunctions;
3567
3568 protected function traverseDAEFunc<ArgT>
3569 input output DAE.Function daeFunction;
3570 input FuncExpType func;
3571 input output ArgT arg;
3572
3573 partial function FuncExpType
3574 input output DAE.Exp exp;
3575 input output ArgT arg;
3576 end FuncExpType;
3577 algorithm
3578 () := match daeFunction
3579 local
3580 DAE.FunctionDefinition fdef;
3581 list<DAE.FunctionDefinition> rest_defs;
3582 list<DAE.Element> el;
3583
3584 case DAE.FUNCTION(functions = (fdef as DAE.FUNCTION_DEF()) :: rest_defs)
3585 algorithm
3586 21196 (el, arg) := traverseDAEElementList(fdef.body, func, arg);
3587
3588
1/2
✓ Branch 0 taken 21196 times.
✗ Branch 1 not taken.
21196 if not referenceEq(fdef.body, el) then
3589 21196 fdef.body := el;
3590 21196 daeFunction.functions := fdef :: rest_defs;
3591 end if;
3592 then
3593 ();
3594
3595 case DAE.FUNCTION(functions = (fdef as DAE.FUNCTION_EXT()) :: rest_defs)
3596 algorithm
3597 3024 (el, arg) := traverseDAEElementList(fdef.body, func, arg);
3598
3599
1/2
✓ Branch 0 taken 3024 times.
✗ Branch 1 not taken.
3024 if not referenceEq(fdef.body, el) then
3600 3024 fdef.body := el;
3601 3024 daeFunction.functions := fdef :: rest_defs;
3602 end if;
3603 then
3604 ();
3605
3606 case DAE.RECORD_CONSTRUCTOR() then ();
3607 end match;
3608 end traverseDAEFunc;
3609
3610 public function traverseDAEElementList<ArgT>
3611 "author: BZ, 2008-12, adrpo, 2010-12
3612 This function traverses all dae exps.
3613 NOTE, it also traverses DAE.VAR(componenname) as an expression."
3614 input output list<DAE.Element> elements;
3615 input FuncExpType func;
3616 input output ArgT arg;
3617
3618 partial function FuncExpType
3619 input output DAE.Exp exp;
3620 input output ArgT arg;
3621 end FuncExpType;
3622 algorithm
3623 70203 (elements, arg) := List.mapFold(elements,
3624 function traverseDAEElement(func = func), arg);
3625 end traverseDAEElementList;
3626
3627 protected function traverseDAEElement<ArgT>
3628 "author: adrpo, 2010-12
3629 This function is a tail recursive function that traverses all dae exps.
3630 NOTE, it also traverses DAE.VAR(componenname) as an expression."
3631 input output DAE.Element element;
3632 input FuncExpType func;
3633 input output ArgT arg;
3634
3635 partial function FuncExpType
3636 input output DAE.Exp exp;
3637 input output ArgT arg;
3638 end FuncExpType;
3639 algorithm
3640 () := match element
3641 local
3642 DAE.Exp e1, e2, e3, new_e1, new_e2, new_e3;
3643 DAE.ComponentRef cr1, cr2, new_cr1, new_cr2;
3644 list<DAE.Element> el, new_el;
3645 list<list<DAE.Element>> eqll, new_eqll;
3646 DAE.Element e, new_e;
3647 list<DAE.Statement> stmts, new_stmts;
3648 list<DAE.Exp> expl, new_expl;
3649 Option<DAE.Exp> binding, new_binding;
3650 Option<DAE.VariableAttributes> attr, new_attr;
3651 list<DAE.Var> varLst;
3652 DAE.Binding daebinding, new_daebinding;
3653 Boolean changed;
3654 DAE.Type new_ty;
3655
3656 case DAE.VAR(componentRef = cr1, binding = binding,
3657 variableAttributesOption = attr)
3658 algorithm
3659
2/2
✓ Branch 0 taken 157556 times.
✓ Branch 1 taken 598224 times.
755780 (e1, arg) := func(Expression.crefExp(cr1), arg);
3660
3661
1/2
✓ Branch 1 taken 755780 times.
✗ Branch 2 not taken.
755780 if Expression.isCref(e1) then
3662 755780 new_cr1 := Expression.expCref(e1);
3663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 755780 times.
755780 if not referenceEq(cr1, new_cr1) then
3664 ✗ element.componentRef := new_cr1;
3665 end if;
3666 end if;
3667
3668
4/4
✓ Branch 0 taken 500780 times.
✓ Branch 1 taken 755780 times.
✓ Branch 2 taken 500780 times.
✓ Branch 3 taken 755780 times.
1256560 element.dims := list(match d
3669 case DAE.DIM_EXP(e1)
3670 algorithm
3671
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 1002 times.
1462 (new_e1, arg) := func(e1, arg);
3672
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1425 times.
1462 then
3673 if referenceEq(e1, new_e1) then d else DAE.DIM_EXP(new_e1);
3674 else d;
3675 end match for d in element.dims);
3676
3677 new_ty := match ty as element.ty
3678 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD())
3679 algorithm
3680 changed := false;
3681
4/4
✓ Branch 0 taken 208769 times.
✓ Branch 1 taken 18804 times.
✓ Branch 2 taken 208769 times.
✓ Branch 3 taken 18804 times.
227573 varLst := list(
3682 match v
3683 case DAE.TYPES_VAR(binding=daebinding as DAE.EQBOUND())
3684 algorithm
3685
2/2
✓ Branch 0 taken 12215 times.
✓ Branch 1 taken 33404 times.
45619 (e2,arg) := func(daebinding.exp, arg);
3686
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 45572 times.
45619 if not referenceEq(daebinding.exp, e2) then
3687 47 daebinding := DAE.EQBOUND(e2,NONE(),daebinding.constant_,daebinding.source);
3688 47 v.binding := daebinding;
3689 changed := true;
3690 end if;
3691 then v;
3692 case DAE.TYPES_VAR(binding=daebinding as DAE.VALBOUND())
3693 algorithm
3694 ✗ e1 := ValuesUtil.valueExp(daebinding.valBound);
3695 ✗ (e2,arg) := func(e1, arg);
3696 ✗ if not referenceEq(e1, e2) then
3697 ✗ new_daebinding := DAE.EQBOUND(e2,NONE(),DAE.C_CONST(),daebinding.source);
3698 ✗ v.binding := new_daebinding;
3699 changed := true;
3700 end if;
3701 then v;
3702 else v;
3703 end match
3704 for v in ty.varLst
3705 );
3706
1/2
✓ Branch 0 taken 18804 times.
✗ Branch 1 not taken.
18804 if not referenceEq(varLst, ty.varLst) then
3707 18804 ty.varLst := varLst;
3708 end if;
3709 then ty;
3710 else ty;
3711 end match;
3712
3713
2/2
✓ Branch 0 taken 18804 times.
✓ Branch 1 taken 736976 times.
774584 if not referenceEq(element.ty, new_ty) then element.ty := new_ty; end if;
3714
3715 755780 (new_binding, arg) := traverseDAEOptExp(binding, func, arg);
3716
2/2
✓ Branch 0 taken 562243 times.
✓ Branch 1 taken 193537 times.
1318023 if not referenceEq(binding, new_binding) then element.binding := new_binding; end if;
3717 755780 (new_attr, arg) := traverseDAEVarAttr(attr, func, arg);
3718
2/2
✓ Branch 0 taken 706284 times.
✓ Branch 1 taken 49496 times.
755780 if not referenceEq(attr, new_attr) then
3719 706284 element.variableAttributesOption := new_attr;
3720 end if;
3721 then
3722 ();
3723
3724 case DAE.DEFINE(componentRef = cr1, exp = e1)
3725 algorithm
3726
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 (new_e1, arg) := func(e1, arg);
3727
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if not referenceEq(e1, new_e1) then element.exp := new_e1; end if;
3728
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 17 times.
17 (DAE.CREF(new_cr1), arg) := func(Expression.crefExp(cr1), arg);
3729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if not referenceEq(cr1, new_cr1) then element.componentRef := new_cr1; end if;
3730 then
3731 ();
3732
3733 case DAE.INITIALDEFINE(componentRef = cr1, exp = e1)
3734 algorithm
3735 ✗ (new_e1, arg) := func(e1, arg);
3736 ✗ if not referenceEq(e1, new_e1) then element.exp := new_e1; end if;
3737 ✗ (DAE.CREF(new_cr1), arg) := func(Expression.crefExp(cr1), arg);
3738 ✗ if not referenceEq(cr1, new_cr1) then element.componentRef := new_cr1; end if;
3739 then
3740 ();
3741
3742 case DAE.EQUEQUATION(cr1 = cr1, cr2 = cr2)
3743 algorithm
3744
3/4
✓ Branch 0 taken 15309 times.
✓ Branch 1 taken 50330 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 65639 times.
65639 (DAE.CREF(new_cr1), arg) := func(Expression.crefExp(cr1), arg);
3745
3/4
✓ Branch 0 taken 15309 times.
✓ Branch 1 taken 50330 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 65639 times.
65639 (DAE.CREF(new_cr2), arg) := func(Expression.crefExp(cr2), arg);
3746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65639 times.
65639 if not referenceEq(cr1, new_cr1) or not referenceEq(cr2, new_cr2) then
3747 ✗ element := DAE.EQUEQUATION(new_cr1, new_cr2, element.source);
3748 end if;
3749 then
3750 ();
3751
3752 case DAE.EQUATION(exp = e1, scalar = e2)
3753 algorithm
3754
2/2
✓ Branch 0 taken 26084 times.
✓ Branch 1 taken 123926 times.
150010 (new_e1, arg) := func(e1, arg);
3755
2/2
✓ Branch 0 taken 26084 times.
✓ Branch 1 taken 123926 times.
150010 (new_e2, arg) := func(e2, arg);
3756
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 149850 times.
150010 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3757 160 element := DAE.EQUATION(new_e1, new_e2, element.source);
3758 end if;
3759 then
3760 ();
3761
3762 case DAE.INITIALEQUATION(exp1 = e1, exp2 = e2)
3763 algorithm
3764
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 2553 times.
2798 (new_e1, arg) := func(e1, arg);
3765
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 2553 times.
2798 (new_e2, arg) := func(e2, arg);
3766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2798 times.
2798 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3767 ✗ element := DAE.INITIALEQUATION(new_e1, new_e2, element.source);
3768 end if;
3769 then
3770 ();
3771
3772 case DAE.COMPLEX_EQUATION(lhs = e1, rhs = e2)
3773 algorithm
3774
2/2
✓ Branch 0 taken 884 times.
✓ Branch 1 taken 5538 times.
6422 (new_e1, arg) := func(e1, arg);
3775
2/2
✓ Branch 0 taken 884 times.
✓ Branch 1 taken 5538 times.
6422 (new_e2, arg) := func(e2, arg);
3776
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 6393 times.
6422 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3777 29 element := DAE.COMPLEX_EQUATION(new_e1, new_e2, element.source);
3778 end if;
3779 then
3780 ();
3781
3782 case DAE.INITIAL_COMPLEX_EQUATION(lhs = e1, rhs = e2)
3783 algorithm
3784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 (new_e1, arg) := func(e1, arg);
3785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 (new_e2, arg) := func(e2, arg);
3786
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3787 ✗ element := DAE.INITIAL_COMPLEX_EQUATION(new_e1, new_e2, element.source);
3788 end if;
3789 then
3790 ();
3791
3792 case DAE.ARRAY_EQUATION(exp = e1, array = e2)
3793 algorithm
3794
2/2
✓ Branch 0 taken 5551 times.
✓ Branch 1 taken 20681 times.
26232 (new_e1, arg) := func(e1, arg);
3795
2/2
✓ Branch 0 taken 5551 times.
✓ Branch 1 taken 20681 times.
26232 (new_e2, arg) := func(e2, arg);
3796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26232 times.
26232 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3797 ✗ element := DAE.ARRAY_EQUATION(element.dimension, new_e1, new_e2, element.source);
3798 end if;
3799 then
3800 ();
3801
3802 case DAE.INITIAL_ARRAY_EQUATION(exp = e1, array = e2)
3803 algorithm
3804
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 60 times.
69 (new_e1, arg) := func(e1, arg);
3805
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 60 times.
69 (new_e2, arg) := func(e2, arg);
3806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if not referenceEq(e1, new_e1) or not referenceEq(e2, new_e2) then
3807 ✗ element := DAE.INITIAL_ARRAY_EQUATION(element.dimension, new_e1, new_e2, element.source);
3808 end if;
3809 then
3810 ();
3811
3812 case DAE.WHEN_EQUATION(condition = e1, equations = el)
3813 algorithm
3814
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 522 times.
568 (new_e1, arg) := func(e1, arg);
3815
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 449 times.
687 if not referenceEq(e1, new_e1) then element.condition := new_e1; end if;
3816 568 (new_el, arg) := traverseDAEElementList(el, func, arg);
3817
1/2
✓ Branch 0 taken 568 times.
✗ Branch 1 not taken.
1136 if not referenceEq(el, new_el) then element.equations := new_el; end if;
3818
3819
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 568 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 560 times.
568 if isSome(element.elsewhen_) then
3820 8 SOME(e) := element.elsewhen_;
3821 8 (new_e, arg) := traverseDAEElement(e, func, arg);
3822
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
16 if not referenceEq(e, new_e) then element.elsewhen_ := SOME(new_e); end if;
3823 end if;
3824 then
3825 ();
3826
3827 case DAE.FOR_EQUATION(range = e1, equations = el)
3828 algorithm
3829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 (new_e1, arg) := func(e1, arg);
3830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if not referenceEq(e1, new_e1) then element.range := new_e1; end if;
3831 10 (new_el, arg) := traverseDAEElementList(el, func, arg);
3832
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
20 if not referenceEq(el, new_el) then element.equations := new_el; end if;
3833 then
3834 ();
3835
3836 case DAE.INITIAL_FOR_EQUATION(range = e1, equations = el)
3837 algorithm
3838 ✗ (new_e1, arg) := func(e1, arg);
3839 ✗ if not referenceEq(e1, new_e1) then element.range := new_e1; end if;
3840 ✗ (new_el, arg) := traverseDAEElementList(el, func, arg);
3841 ✗ if not referenceEq(el, new_el) then element.equations := new_el; end if;
3842 then
3843 ();
3844
3845 case DAE.COMP(dAElist = el)
3846 algorithm
3847 1100 (new_el, arg) := traverseDAEElementList(el, func, arg);
3848
1/2
✓ Branch 0 taken 1100 times.
✗ Branch 1 not taken.
2200 if not referenceEq(el, new_el) then element.dAElist := new_el; end if;
3849 then
3850 ();
3851
3852 case DAE.EXTOBJECTCLASS() then ();
3853
3854 case DAE.ASSERT(condition = e1, message = e2, level = e3)
3855 algorithm
3856
2/2
✓ Branch 0 taken 1169 times.
✓ Branch 1 taken 4401 times.
5570 (new_e1, arg) := func(e1, arg);
3857
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 5096 times.
6044 if not referenceEq(e1, new_e1) then element.condition := new_e1; end if;
3858
2/2
✓ Branch 0 taken 1169 times.
✓ Branch 1 taken 4401 times.
5570 (new_e2, arg) := func(e2, arg);
3859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5570 times.
5570 if not referenceEq(e2, new_e2) then element.message := new_e2; end if;
3860
2/2
✓ Branch 0 taken 1169 times.
✓ Branch 1 taken 4401 times.
5570 (new_e3, arg) := func(e3, arg);
3861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5570 times.
5570 if not referenceEq(e3, new_e3) then element.level := new_e3; end if;
3862 then
3863 ();
3864
3865 case DAE.INITIAL_ASSERT(condition = e1, message = e2, level = e3)
3866 algorithm
3867
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 46 times.
54 (new_e1, arg) := func(e1, arg);
3868
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if not referenceEq(e1, new_e1) then element.condition := new_e1; end if;
3869
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 46 times.
54 (new_e2, arg) := func(e2, arg);
3870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if not referenceEq(e2, new_e2) then element.message := new_e2; end if;
3871
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 46 times.
54 (new_e3, arg) := func(e3, arg);
3872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if not referenceEq(e3, new_e3) then element.level := new_e3; end if;
3873 then
3874 ();
3875
3876 case DAE.TERMINATE(message = e1)
3877 algorithm
3878
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 21 times.
23 (new_e1, arg) := func(e1, arg);
3879
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if not referenceEq(e1, new_e1) then element.message := new_e1; end if;
3880 then
3881 ();
3882
3883 case DAE.INITIAL_TERMINATE(message = e1)
3884 algorithm
3885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 (new_e1, arg) := func(e1, arg);
3886
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if not referenceEq(e1, new_e1) then element.message := new_e1; end if;
3887 then
3888 ();
3889
3890 case DAE.NORETCALL(exp = e1)
3891 algorithm
3892
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 142 times.
157 (new_e1, arg) := func(e1, arg);
3893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 157 times.
157 if not referenceEq(e1, new_e1) then element.exp := new_e1; end if;
3894 then
3895 ();
3896
3897 case DAE.INITIAL_NORETCALL(exp = e1)
3898 algorithm
3899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 (new_e1, arg) := func(e1, arg);
3900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if not referenceEq(e1, new_e1) then element.exp := new_e1; end if;
3901 then
3902 ();
3903
3904 case DAE.REINIT(componentRef = cr1, exp = e1)
3905 algorithm
3906
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 69 times.
70 (new_e1, arg) := func(e1, arg);
3907
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if not referenceEq(e1, new_e1) then element.exp := new_e1; end if;
3908
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 69 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 70 times.
70 (DAE.CREF(new_cr1), arg) := func(Expression.crefExp(cr1), arg);
3909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if not referenceEq(cr1, new_cr1) then element.componentRef := new_cr1; end if;
3910 then
3911 ();
3912
3913 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(stmts))
3914 algorithm
3915 30960 (new_stmts, arg) := traverseDAEEquationsStmts(stmts, func, arg);
3916
2/2
✓ Branch 0 taken 7047 times.
✓ Branch 1 taken 23913 times.
30960 if not referenceEq(stmts, new_stmts) then
3917 14094 element.algorithm_ := DAE.ALGORITHM_STMTS(new_stmts);
3918 end if;
3919 then
3920 ();
3921
3922 case DAE.INITIALALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(stmts))
3923 algorithm
3924 71 (new_stmts, arg) := traverseDAEEquationsStmts(stmts, func, arg);
3925
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 69 times.
71 if not referenceEq(stmts, new_stmts) then
3926 4 element.algorithm_ := DAE.ALGORITHM_STMTS(new_stmts);
3927 end if;
3928 then
3929 ();
3930
3931 case DAE.CONSTRAINT(constraints = DAE.CONSTRAINT_EXPS(expl))
3932 algorithm
3933 3 (new_expl, arg) := traverseDAEExpList(expl, func, arg);
3934
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if not referenceEq(expl, new_expl) then
3935 6 element.constraints := DAE.CONSTRAINT_EXPS(new_expl);
3936 end if;
3937 then
3938 ();
3939
3940 case DAE.CLASS_ATTRIBUTES() then ();
3941
3942 case DAE.IF_EQUATION(condition1 = expl, equations2 = eqll, equations3 = el)
3943 algorithm
3944 1263 (new_expl, arg) := traverseDAEExpList(expl, func, arg);
3945
1/2
✓ Branch 0 taken 1263 times.
✗ Branch 1 not taken.
2526 if not referenceEq(expl, new_expl) then element.condition1 := new_expl; end if;
3946 1263 (new_eqll, arg) := traverseDAEList(eqll, func, arg);
3947
1/2
✓ Branch 0 taken 1263 times.
✗ Branch 1 not taken.
2526 if not referenceEq(eqll, new_eqll) then element.equations2 := new_eqll; end if;
3948 1263 (new_el, arg) := traverseDAEElementList(el, func, arg);
3949
2/2
✓ Branch 0 taken 1185 times.
✓ Branch 1 taken 78 times.
2448 if not referenceEq(el, new_el) then element.equations3 := new_el; end if;
3950 then
3951 ();
3952
3953 case DAE.INITIAL_IF_EQUATION(condition1 = expl, equations2 = eqll, equations3 = el)
3954 algorithm
3955 16 (new_expl, arg) := traverseDAEExpList(expl, func, arg);
3956
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
32 if not referenceEq(expl, new_expl) then element.condition1 := new_expl; end if;
3957 16 (new_eqll, arg) := traverseDAEList(eqll, func, arg);
3958
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
32 if not referenceEq(eqll, new_eqll) then element.equations2 := new_eqll; end if;
3959 16 (new_el, arg) := traverseDAEElementList(el, func, arg);
3960
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5 times.
27 if not referenceEq(el, new_el) then element.equations3 := new_el; end if;
3961 then
3962 ();
3963
3964 case DAE.FLAT_SM(dAElist = el)
3965 algorithm
3966 5 (new_el, arg) := traverseDAEElementList(el, func, arg);
3967
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
10 if not referenceEq(el, new_el) then element.dAElist := new_el; end if;
3968 then
3969 ();
3970
3971 case DAE.SM_COMP(dAElist = el)
3972 algorithm
3973 32 (new_el, arg) := traverseDAEElementList(el, func, arg);
3974
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 7 times.
57 if not referenceEq(el, new_el) then element.dAElist := new_el; end if;
3975 then
3976 ();
3977
3978 case DAE.COMMENT()
3979 then ();
3980 else
3981 algorithm
3982 ✗ Error.addMessage(Error.INTERNAL_ERROR,
3983 {"DAEUtil.traverseDAEElement not implemented correctly for element: " +
3984 DAEDump.dumpElementsStr({element})});
3985 ✗ then
3986 fail();
3987
3988 end match;
3989 end traverseDAEElement;
3990
3991 protected uniontype TraverseStatementsOptions
3992 record TRAVERSE_ALL
3993 end TRAVERSE_ALL;
3994 record TRAVERSE_RHS_ONLY
3995 end TRAVERSE_RHS_ONLY;
3996 end TraverseStatementsOptions;
3997
3998 public function traverseAlgorithmExps "
3999 This function goes through the Algorithm structure and finds all the
4000 expressions and performs the function on them
4001 "
4002 replaceable type Type_a subtypeof Any;
4003 input DAE.Algorithm inAlgorithm;
4004 input FuncExpType func;
4005 input Type_a inTypeA;
4006 output Type_a outTypeA;
4007 partial function FuncExpType
4008 input DAE.Exp inExp;
4009 input Type_a inTypeA;
4010 output DAE.Exp outExp;
4011 output Type_a outA;
4012 end FuncExpType;
4013 algorithm
4014 outTypeA := match inAlgorithm
4015 local
4016 list<DAE.Statement> stmts;
4017 Type_a ext_arg_1;
4018 case DAE.ALGORITHM_STMTS(statementLst = stmts)
4019 algorithm
4020 1687 (_,ext_arg_1) := DAEUtil.traverseDAEEquationsStmts(stmts,func,inTypeA);
4021 1687 then
4022 ext_arg_1;
4023 end match;
4024 end traverseAlgorithmExps;
4025
4026 public function traverseDAEEquationsStmts "Traversing of DAE.Statement."
4027 input list<DAE.Statement> inStmts;
4028 input FuncExpType func;
4029 input Type_a iextraArg;
4030 output list<DAE.Statement> outStmts;
4031 output Type_a oextraArg;
4032 partial function FuncExpType
4033 input DAE.Exp inExp;
4034 input Type_a inTypeA;
4035 output DAE.Exp outExp;
4036 output Type_a outA;
4037 end FuncExpType;
4038 replaceable type Type_a subtypeof Any;
4039 algorithm
4040 188314 (outStmts,oextraArg) := traverseDAEEquationsStmtsList(inStmts,func,TRAVERSE_ALL(),iextraArg);
4041 end traverseDAEEquationsStmts;
4042
4043 public function traverseDAEEquationsStmtsRhsOnly "Traversing of DAE.Statement. Only rhs expressions are replaced, keeping lhs intact."
4044 input list<DAE.Statement> inStmts;
4045 input FuncExpType func;
4046 input Type_a iextraArg;
4047 output list<DAE.Statement> outStmts;
4048 output Type_a oextraArg;
4049 partial function FuncExpType
4050 input DAE.Exp inExp;
4051 input Type_a inTypeA;
4052 output DAE.Exp outExp;
4053 output Type_a outA;
4054 end FuncExpType;
4055 replaceable type Type_a subtypeof Any;
4056 algorithm
4057 ✗ (outStmts,oextraArg) := traverseDAEEquationsStmtsList(inStmts,func,TRAVERSE_RHS_ONLY(),iextraArg);
4058 end traverseDAEEquationsStmtsRhsOnly;
4059
4060 protected function traverseDAEEquationsStmtsList "Traversing of DAE.Statement."
4061 input list<DAE.Statement> inStmts;
4062 input FuncExpType func;
4063 input TraverseStatementsOptions opt;
4064 input Type_a iextraArg;
4065 output list<DAE.Statement> outStmts;
4066 output Type_a oextraArg;
4067 partial function FuncExpType
4068 input DAE.Exp inExp;
4069 input Type_a inTypeA;
4070 output DAE.Exp outExp;
4071 output Type_a outA;
4072 end FuncExpType;
4073 replaceable type Type_a subtypeof Any;
4074 protected
4075 list<list<DAE.Statement>> outStmtsLst;
4076 Boolean b;
4077 algorithm
4078 281619 (outStmtsLst,oextraArg) := List.map2Fold(inStmts,traverseDAEEquationsStmtsWork,func,opt,iextraArg);
4079 281619 outStmts := List.flatten(outStmtsLst);
4080 281619 b := List.allReferenceEq(inStmts,outStmts);
4081
2/2
✓ Branch 0 taken 55136 times.
✓ Branch 1 taken 226483 times.
281619 outStmts := if b then inStmts else outStmts;
4082 end traverseDAEEquationsStmtsList;
4083
4084 protected function traverseStatementsOptionsEvalLhs
4085 input DAE.Exp inExp;
4086 input Type_a inA;
4087 input FuncExpType func;
4088 input TraverseStatementsOptions opt;
4089 output DAE.Exp outExp;
4090 output Type_a outA;
4091 partial function FuncExpType
4092 input DAE.Exp inExp;
4093 input Type_a inTypeA;
4094 output DAE.Exp outExp;
4095 output Type_a outA;
4096 end FuncExpType;
4097 replaceable type Type_a subtypeof Any;
4098 algorithm
4099 (outExp,outA) := match opt
4100 case TRAVERSE_ALL()
4101 algorithm
4102
2/2
✓ Branch 0 taken 92343 times.
✓ Branch 1 taken 839333 times.
931676 (outExp,outA) := func(inExp,inA);
4103 then (outExp,outA);
4104 ✗ else (inExp,inA);
4105 end match;
4106 end traverseStatementsOptionsEvalLhs;
4107
4108 protected function traverseDAEEquationsStmtsWork "Handles the traversing of DAE.Statement."
4109 input DAE.Statement inStmt;
4110 input FuncExpType func;
4111 input TraverseStatementsOptions opt;
4112 input Type_a iextraArg;
4113 output list<DAE.Statement> outStmts;
4114 output Type_a oextraArg;
4115 partial function FuncExpType
4116 input DAE.Exp inExp;
4117 input Type_a inTypeA;
4118 output DAE.Exp outExp;
4119 output Type_a outA;
4120 end FuncExpType;
4121 replaceable type Type_a subtypeof Any;
4122 algorithm
4123 (outStmts,oextraArg) := matchcontinue (inStmt, iextraArg)
4124 local
4125 DAE.Exp e_1,e_2,e,e2,e3,e_3;
4126 list<DAE.Exp> expl1,expl2;
4127 list<DAE.Statement> stmts,stmts1,stmts2;
4128 DAE.Type tp;
4129 DAE.Statement x,ew,ew_1;
4130 Boolean b1;
4131 String id1,str;
4132 DAE.ElementSource source;
4133 DAE.Else algElse,algElse1;
4134 Type_a extraArg;
4135 list<tuple<DAE.ComponentRef,SourceInfo>> loopPrlVars "list of parallel variables used/referenced in the parfor loop";
4136 list<DAE.ComponentRef> conditions;
4137 Boolean initialCall,b;
4138 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
4139
4140 case (DAE.STMT_ASSIGN(type_ = tp,exp1 = e,exp = e2, source = source), extraArg)
4141 algorithm
4142 904454 (e_1,extraArg) := traverseStatementsOptionsEvalLhs(e, extraArg, func, opt);
4143
2/2
✓ Branch 0 taken 89558 times.
✓ Branch 1 taken 814896 times.
904454 (e_2,extraArg) := func(e2, extraArg);
4144
2/2
✓ Branch 0 taken 457094 times.
✓ Branch 1 taken 447360 times.
904454 x := if referenceEq(e,e_1) and referenceEq(e2,e_2) then inStmt else DAE.STMT_ASSIGN(tp,e_1,e_2,source);
4145 904454 then (x::{},extraArg);
4146
4147 case (DAE.STMT_TUPLE_ASSIGN(type_ = tp,expExpLst = expl1, exp = e, source = source), extraArg)
4148 algorithm
4149
2/2
✓ Branch 0 taken 1575 times.
✓ Branch 1 taken 9552 times.
11127 (e_1, extraArg) := func(e, extraArg);
4150
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 11127 times.
11127 (DAE.TUPLE(expl2), extraArg) := traverseStatementsOptionsEvalLhs(DAE.TUPLE(expl1), extraArg, func, opt);
4151
2/2
✓ Branch 0 taken 3799 times.
✓ Branch 1 taken 7328 times.
11127 x := if referenceEq(e,e_1) and referenceEq(expl1,expl2) then inStmt else DAE.STMT_TUPLE_ASSIGN(tp,expl2,e_1,source);
4152 11127 then (x::{},extraArg);
4153
4154 case (DAE.STMT_ASSIGN_ARR(type_ = tp, lhs=e, exp = e2, source = source), extraArg)
4155 algorithm
4156
2/2
✓ Branch 0 taken 1210 times.
✓ Branch 1 taken 14885 times.
16095 (e_2, extraArg) := func(e2, extraArg);
4157 16095 (e_1, extraArg) := traverseStatementsOptionsEvalLhs(e, extraArg, func, opt);
4158 x := match e_1
4159
2/2
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 15044 times.
16092 case DAE.CREF() then if referenceEq(e2,e_2) and referenceEq(e,e_1) then inStmt else DAE.STMT_ASSIGN_ARR(tp,e_1,e_2,source);
4160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 else if referenceEq(e2,e_2) then inStmt else DAE.STMT_ASSIGN_ARR(tp,e,e_2,source);
4161 end match;
4162 16095 then (x::{},extraArg);
4163
4164 case (DAE.STMT_IF(exp=e,statementLst=stmts,else_ = algElse, source = source), extraArg)
4165 algorithm
4166 41916 (algElse1,extraArg) := traverseDAEEquationsStmtsElse(algElse,func,opt,extraArg);
4167 41916 (stmts2,extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4168
2/2
✓ Branch 0 taken 7915 times.
✓ Branch 1 taken 34001 times.
41916 (e_1,extraArg) := func(e, extraArg);
4169 41916 (stmts1,b) := Algorithm.optimizeIf(e_1,stmts2,algElse1,source);
4170
6/6
✓ Branch 0 taken 41846 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 29155 times.
✓ Branch 3 taken 12691 times.
✓ Branch 4 taken 26307 times.
✓ Branch 5 taken 2848 times.
41916 stmts1 := if not b and referenceEq(e,e_1) and referenceEq(stmts,stmts2) and referenceEq(algElse,algElse1) then (inStmt::{}) else stmts1;
4171 41916 then (stmts1,extraArg);
4172
4173 case (DAE.STMT_FOR(type_=tp,iterIsArray=b1,iter=id1,range=e,statementLst=stmts, source = source, sub_iters=sub_iters), extraArg)
4174 algorithm
4175 9183 (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4176
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 7249 times.
9183 (e_1, extraArg) := func(e, extraArg);
4177
3/4
✓ Branch 0 taken 1869 times.
✓ Branch 1 taken 7314 times.
✓ Branch 2 taken 1869 times.
✗ Branch 3 not taken.
11052 x := if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then inStmt else DAE.STMT_FOR(tp,b1,id1,e_1,stmts2,source,sub_iters);
4178 9183 then (x::{},extraArg);
4179
4180 case (DAE.STMT_PARFOR(type_=tp,iterIsArray=b1,iter=id1,range=e,statementLst=stmts, loopPrlVars=loopPrlVars, source = source), extraArg)
4181 algorithm
4182 ✗ (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4183 ✗ (e_1, extraArg) := func(e, extraArg);
4184 ✗ x := if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then inStmt else DAE.STMT_PARFOR(tp,b1,id1,e_1,stmts2,loopPrlVars,source);
4185 ✗ then (x::{},extraArg);
4186
4187 case (DAE.STMT_WHILE(exp = e,statementLst=stmts, source = source), extraArg)
4188 algorithm
4189 1193 (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4190
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 952 times.
1193 (e_1, extraArg) := func(e, extraArg);
4191
2/2
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 704 times.
1193 x := if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then inStmt else DAE.STMT_WHILE(e_1,stmts2,source);
4192 1193 then (x::{},extraArg);
4193
4194 case (DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=NONE(),source=source), extraArg)
4195 algorithm
4196 3519 (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4197
2/2
✓ Branch 0 taken 1062 times.
✓ Branch 1 taken 2457 times.
3519 (e_1, extraArg) := func(e, extraArg);
4198
4/4
✓ Branch 0 taken 687 times.
✓ Branch 1 taken 2832 times.
✓ Branch 2 taken 637 times.
✓ Branch 3 taken 50 times.
4156 x := if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then inStmt else DAE.STMT_WHEN(e_1,conditions,initialCall,stmts2,NONE(),source);
4199 3519 then (x::{},extraArg);
4200
4201 case (DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=SOME(ew),source=source), extraArg)
4202 algorithm
4203
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1364 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1364 times.
1364 ({ew_1}, extraArg) := traverseDAEEquationsStmtsList({ew},func,opt,extraArg);
4204 1364 (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4205
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 950 times.
1364 (e_1, extraArg) := func(e, extraArg);
4206
6/6
✓ Branch 0 taken 1013 times.
✓ Branch 1 taken 351 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 953 times.
✓ Branch 4 taken 269 times.
✓ Branch 5 taken 142 times.
2044 x := if referenceEq(ew,ew_1) and referenceEq(e,e_1) and referenceEq(stmts,stmts2) then inStmt else DAE.STMT_WHEN(e_1,conditions,initialCall,stmts2,SOME(ew_1),source);
4207 1364 then (x::{},extraArg);
4208
4209 case (DAE.STMT_ASSERT(cond = e, msg=e2, level=e3, source = source), extraArg)
4210 algorithm
4211
2/2
✓ Branch 0 taken 12549 times.
✓ Branch 1 taken 38184 times.
50733 (e_1, extraArg) := func(e, extraArg);
4212
2/2
✓ Branch 0 taken 12549 times.
✓ Branch 1 taken 38184 times.
50733 (e_2, extraArg) := func(e2, extraArg);
4213
2/2
✓ Branch 0 taken 12549 times.
✓ Branch 1 taken 38184 times.
50733 (e_3, extraArg) := func(e3, extraArg);
4214
3/4
✓ Branch 0 taken 35207 times.
✓ Branch 1 taken 15526 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35207 times.
50733 x := if referenceEq(e,e_1) and referenceEq(e2,e_2) and referenceEq(e3,e_3) then inStmt else DAE.STMT_ASSERT(e_1,e_2,e_3,source);
4215 50733 then (x::{},extraArg);
4216
4217 case (DAE.STMT_TERMINATE(msg = e, source = source), extraArg)
4218 algorithm
4219
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 26 times.
41 (e_1, extraArg) := func(e, extraArg);
4220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 x := if referenceEq(e,e_1) then inStmt else DAE.STMT_TERMINATE(e_1,source);
4221 41 then (x::{},extraArg);
4222
4223 case (DAE.STMT_REINIT(var = e,value=e2, source = source), extraArg)
4224 algorithm
4225
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 448 times.
648 (e_1, extraArg) := func(e, extraArg);
4226
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 448 times.
648 (e_2, extraArg) := func(e2, extraArg);
4227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 648 times.
648 x := if referenceEq(e,e_1) and referenceEq(e2,e_2) then inStmt else DAE.STMT_REINIT(e_1,e_2,source);
4228 648 then (x::{},extraArg);
4229
4230 case (DAE.STMT_NORETCALL(exp = e, source = source), extraArg)
4231 algorithm
4232
2/2
✓ Branch 0 taken 717 times.
✓ Branch 1 taken 9241 times.
9958 (e_1, extraArg) := func(e, extraArg);
4233
2/2
✓ Branch 0 taken 1635 times.
✓ Branch 1 taken 8323 times.
9958 x := if referenceEq(e,e_1) then inStmt else DAE.STMT_NORETCALL(e_1,source);
4234 9958 then (x::{},extraArg);
4235
4236 case (x as DAE.STMT_RETURN(), extraArg)
4237 600 then (x::{},extraArg);
4238
4239 case (x as DAE.STMT_BREAK(), extraArg)
4240 1296 then (x::{},extraArg);
4241
4242 case (x as DAE.STMT_CONTINUE(), extraArg)
4243 7 then (x::{},extraArg);
4244
4245 // MetaModelica extension. KS
4246 case (DAE.STMT_FAILURE(body=stmts, source = source), extraArg)
4247 algorithm
4248 45 (stmts2, extraArg) := traverseDAEEquationsStmtsList(stmts,func,opt,extraArg);
4249
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 44 times.
45 x := if referenceEq(stmts,stmts2) then inStmt else DAE.STMT_FAILURE(stmts2,source);
4250 45 then (x::{},extraArg);
4251
4252 case (x, _)
4253 algorithm
4254 ✗ str := DAEDump.ppStatementStr(x);
4255 ✗ str := "DAEUtil.traverseDAEEquationsStmts not implemented correctly: " + str;
4256 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
4257 ✗ then fail();
4258 end matchcontinue;
4259 end traverseDAEEquationsStmtsWork;
4260
4261 protected function traverseDAEEquationsStmtsElse "Helper function for traverseDAEEquationsStmts"
4262 input DAE.Else inElse;
4263 input FuncExpType func;
4264 input TraverseStatementsOptions opt;
4265 input Type_a iextraArg;
4266 output DAE.Else outElse;
4267 output Type_a oextraArg;
4268 partial function FuncExpType
4269 input DAE.Exp inExp;
4270 input Type_a inTypeA;
4271 output DAE.Exp outExp;
4272 output Type_a outA;
4273 end FuncExpType;
4274 replaceable type Type_a subtypeof Any;
4275 algorithm
4276 (outElse,oextraArg) := match(inElse, iextraArg)
4277 local
4278 DAE.Exp e,e_1;
4279 list<DAE.Statement> st,st_1;
4280 DAE.Else el,el_1;
4281 Type_a extraArg;
4282 Boolean b;
4283 case (DAE.NOELSE(), extraArg) then (DAE.NOELSE(),extraArg);
4284 case (DAE.ELSEIF(e,st,el), extraArg)
4285 algorithm
4286 12776 (el_1,extraArg) := traverseDAEEquationsStmtsElse(el,func,opt,extraArg);
4287 12776 (st_1,extraArg) := traverseDAEEquationsStmtsList(st,func,opt,extraArg);
4288
2/2
✓ Branch 0 taken 2350 times.
✓ Branch 1 taken 10426 times.
12776 (e_1,extraArg) := func(e, extraArg);
4289 12776 outElse := Algorithm.optimizeElseIf(e_1,st_1,el_1);
4290
4/4
✓ Branch 0 taken 8083 times.
✓ Branch 1 taken 4693 times.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 7939 times.
12776 b := referenceEq(el,el_1) and referenceEq(st,st_1) and referenceEq(e,e_1);
4291 outElse := if b then inElse else outElse;
4292 12776 then (outElse,extraArg);
4293 case(DAE.ELSE(st), extraArg)
4294 algorithm
4295 21945 (st_1,extraArg) := traverseDAEEquationsStmtsList(st,func,opt,extraArg);
4296
2/2
✓ Branch 0 taken 4949 times.
✓ Branch 1 taken 16996 times.
21945 outElse := if referenceEq(st,st_1) then inElse else DAE.ELSE(st_1);
4297 21945 then (outElse,extraArg);
4298 end match;
4299 end traverseDAEEquationsStmtsElse;
4300
4301 public function traverseDAEStmts
4302 "Author: BZ, 2008-12, wbraun 2012-09
4303 Traversing statemeant and provide current statement
4304 to FuncExptype
4305 Handles the traversing of DAE.Statement."
4306 input list<DAE.Statement> inStmts;
4307 input FuncExpType func;
4308 input Type_a iextraArg;
4309 output list<DAE.Statement> outStmts = {};
4310 output Type_a extraArg = iextraArg;
4311 partial function FuncExpType
4312 input DAE.Exp inExp;
4313 input DAE.Statement inStmt;
4314 input Type_a arg;
4315 output DAE.Exp outExp;
4316 output Type_a oarg;
4317 end FuncExpType;
4318 replaceable type Type_a subtypeof Any;
4319 protected
4320 DAE.Exp e_1,e_2,e,e2,e3,e_3;
4321 list<DAE.Exp> expl1,expl2;
4322 list<DAE.Statement> stmts,stmts1,stmts2;
4323 DAE.Type tp;
4324 DAE.Statement ew;
4325 Boolean b1;
4326 String id1,str;
4327 DAE.ElementSource source;
4328 DAE.Else algElse;
4329 list<tuple<DAE.ComponentRef,SourceInfo>> loopPrlVars "list of parallel variables used/referenced in the parfor loop";
4330 list<DAE.ComponentRef> conditions;
4331 Boolean initialCall;
4332 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
4333 algorithm
4334
2/2
✓ Branch 0 taken 210651 times.
✓ Branch 1 taken 140153 times.
350804 for stmt in inStmts loop
4335 outStmts := matchcontinue stmt
4336 case DAE.STMT_ASSIGN(type_ = tp,exp1 = e2,exp = e, source = source)
4337 algorithm
4338
2/2
✓ Branch 0 taken 13137 times.
✓ Branch 1 taken 73058 times.
86195 (e_1, extraArg) := func(e, stmt, extraArg);
4339
2/2
✓ Branch 0 taken 13137 times.
✓ Branch 1 taken 73058 times.
86195 (e_2, extraArg) := func(e2, stmt, extraArg);
4340
2/2
✓ Branch 0 taken 82459 times.
✓ Branch 1 taken 3736 times.
86195 then
4341 if referenceEq(e,e_1) and referenceEq(e2,e_2) then stmt :: outStmts else DAE.STMT_ASSIGN(tp,e_2,e_1,source)::outStmts;
4342
4343 case DAE.STMT_TUPLE_ASSIGN(type_ = tp,expExpLst = expl1, exp = e, source = source)
4344 algorithm
4345
2/2
✓ Branch 0 taken 1025 times.
✓ Branch 1 taken 1774 times.
2799 (e_1, extraArg) := func(e, stmt, extraArg);
4346 2799 (expl2, extraArg) := traverseDAEExpListStmt(expl1,func, stmt, extraArg);
4347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2799 times.
2799 then
4348 if referenceEq(e,e_1) and referenceEq(expl2,expl1) then stmt :: outStmts else DAE.STMT_TUPLE_ASSIGN(tp,expl2,e_1,source)::outStmts;
4349
4350 case DAE.STMT_ASSIGN_ARR(type_ = tp, lhs=e, exp = e2, source = source)
4351 algorithm
4352
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 595 times.
929 (e_2, extraArg) := func(e2, stmt, extraArg);
4353 try
4354
3/4
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 595 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 929 times.
929 (e_1 as DAE.CREF(_,_), extraArg) := func(e, stmt, extraArg);
4355 else
4356 // We need to pass this through because simplify/etc may scalarize the cref...
4357 ✗ e_1 := e;
4358 end try;
4359
2/2
✓ Branch 0 taken 794 times.
✓ Branch 1 taken 135 times.
929 then
4360 if referenceEq(e,e_1) and referenceEq(e2,e_2) then stmt :: outStmts else DAE.STMT_ASSIGN_ARR(tp,e_1,e_2,source)::outStmts;
4361
4362 case DAE.STMT_IF(exp=e,statementLst=stmts,else_ = algElse, source = source)
4363 algorithm
4364 5739 (algElse,extraArg) := traverseDAEStmtsElse(algElse,func, stmt, extraArg);
4365 5739 (stmts2,extraArg) := traverseDAEStmts(stmts,func,extraArg);
4366
2/2
✓ Branch 0 taken 1194 times.
✓ Branch 1 taken 4545 times.
5739 (e_1,extraArg) := func(e, stmt, extraArg);
4367 5739 (stmts1,_) := Algorithm.optimizeIf(e_1,stmts2,algElse,source);
4368 5739 then
4369 List.append_reverse(stmts1, outStmts);
4370
4371 case DAE.STMT_FOR(type_=tp,iterIsArray=b1,iter=id1,range=e,statementLst=stmts, source = source, sub_iters=sub_iters)
4372 algorithm
4373 1564 (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4374
2/2
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 980 times.
1564 (e_1, extraArg) := func(e, stmt, extraArg);
4375
3/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 1498 times.
✓ Branch 2 taken 1498 times.
✗ Branch 3 not taken.
3062 then
4376 if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then stmt :: outStmts else DAE.STMT_FOR(tp,b1,id1,e_1,stmts2,source,sub_iters)::outStmts;
4377
4378 case DAE.STMT_PARFOR(type_=tp,iterIsArray=b1,iter=id1,range=e,statementLst=stmts, loopPrlVars=loopPrlVars, source = source)
4379 algorithm
4380 ✗ (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4381 ✗ (e_1, extraArg) := func(e, stmt, extraArg);
4382 ✗ then
4383 DAE.STMT_PARFOR(tp,b1,id1,e_1,stmts2,loopPrlVars,source)::outStmts;
4384
4385 case DAE.STMT_WHILE(exp = e,statementLst=stmts, source = source)
4386 algorithm
4387 262 (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 262 times.
262 (e_1, extraArg) := func(e, stmt, extraArg);
4389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 262 times.
262 then
4390 if referenceEq(e,e_1) and referenceEq(stmts,stmts2) then stmt :: outStmts else DAE.STMT_WHILE(e_1,stmts2,source)::outStmts;
4391
4392 case DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=NONE(),source=source)
4393 algorithm
4394 590 (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4395
2/2
✓ Branch 0 taken 453 times.
✓ Branch 1 taken 137 times.
590 (e_1, extraArg) := func(e, stmt, extraArg);
4396
2/2
✓ Branch 0 taken 555 times.
✓ Branch 1 taken 35 times.
1145 then
4397 DAE.STMT_WHEN(e_1,conditions,initialCall,stmts2,NONE(),source)::outStmts;
4398
4399 case DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=SOME(ew),source=source)
4400 algorithm
4401
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 193 times.
193 ({_}, extraArg) := traverseDAEStmts({ew},func,extraArg);
4402 193 (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4403
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 53 times.
193 (e_1, extraArg) := func(e, stmt, extraArg);
4404
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 110 times.
276 then
4405 DAE.STMT_WHEN(e_1,conditions,initialCall,stmts2,SOME(ew),source)::outStmts;
4406
4407 case DAE.STMT_ASSERT(cond = e, msg=e2, level=e3, source = source)
4408 algorithm
4409
2/2
✓ Branch 0 taken 74984 times.
✓ Branch 1 taken 35438 times.
110422 (e_1, extraArg) := func(e, stmt, extraArg);
4410
2/2
✓ Branch 0 taken 74984 times.
✓ Branch 1 taken 35438 times.
110422 (e_2, extraArg) := func(e2, stmt, extraArg);
4411
2/2
✓ Branch 0 taken 74984 times.
✓ Branch 1 taken 35438 times.
110422 (e_3, extraArg) := func(e3, stmt, extraArg);
4412
3/4
✓ Branch 0 taken 73487 times.
✓ Branch 1 taken 36935 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 73487 times.
110422 then
4413 if referenceEq(e,e_1) and referenceEq(e2,e_2) and referenceEq(e3,e_3) then stmt :: outStmts else DAE.STMT_ASSERT(e_1,e_2,e_3,source)::outStmts;
4414
4415 case DAE.STMT_TERMINATE(msg = e, source = source)
4416 algorithm
4417
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 (e_1, extraArg) := func(e, stmt, extraArg);
4418
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
17 then
4419 if referenceEq(e,e_1) then stmt :: outStmts else DAE.STMT_TERMINATE(e_1,source)::outStmts;
4420
4421 case DAE.STMT_REINIT(var = e,value=e2, source = source)
4422 algorithm
4423
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 24 times.
122 (e_1, extraArg) := func(e, stmt, extraArg);
4424
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 24 times.
122 (e_2, extraArg) := func(e2, stmt, extraArg);
4425
1/2
✓ Branch 0 taken 122 times.
✗ Branch 1 not taken.
122 then
4426 if referenceEq(e,e_1) and referenceEq(e2,e_2) then stmt :: outStmts else DAE.STMT_REINIT(e_1,e_2,source)::outStmts;
4427
4428 case DAE.STMT_NORETCALL(exp = e, source = source)
4429 algorithm
4430
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 1015 times.
1543 (e_1, extraArg) := func(e, stmt, extraArg);
4431
2/2
✓ Branch 0 taken 1218 times.
✓ Branch 1 taken 325 times.
1543 then
4432 if referenceEq(e,e_1) then stmt :: outStmts else DAE.STMT_NORETCALL(e_1,source)::outStmts;
4433
4434 case DAE.STMT_RETURN()
4435 algorithm
4436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 (, extraArg) := func(DAE.ICONST(-1), stmt, extraArg); // Dummy argument, so we can traverse over statements without expressions
4437 then
4438 stmt::outStmts;
4439
4440 case DAE.STMT_BREAK()
4441 algorithm
4442
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 45 times.
129 (, extraArg) := func(DAE.ICONST(-1), stmt, extraArg); // Dummy argument, so we can traverse over statements without expressions
4443 then
4444 stmt::outStmts;
4445
4446 case DAE.STMT_CONTINUE()
4447 algorithm
4448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 (, extraArg) := func(DAE.ICONST(-1), stmt, extraArg); // Dummy argument, so we can traverse over statements without expressions
4449 then
4450 stmt::outStmts;
4451
4452 // MetaModelica extension. KS
4453 case DAE.STMT_FAILURE(body=stmts, source = source)
4454 algorithm
4455 5 (stmts2, extraArg) := traverseDAEStmts(stmts,func,extraArg);
4456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 then
4457 if referenceEq(stmts,stmts2) then stmt :: outStmts else DAE.STMT_FAILURE(stmts2,source)::outStmts;
4458
4459 else
4460 algorithm
4461 ✗ str := DAEDump.ppStatementStr(stmt);
4462 ✗ str := "DAEUtil.traverseDAEStmts not implemented correctly: " + str;
4463 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
4464 ✗ then fail();
4465 end matchcontinue;
4466 end for;
4467
4468 140153 outStmts := listReverseInPlace(outStmts);
4469 end traverseDAEStmts;
4470
4471 protected function traverseDAEStmtsElse "Helper function for traverseDAEEquationsStmts"
4472 input DAE.Else inElse;
4473 input FuncExpType func;
4474 input DAE.Statement istmt;
4475 input Type_a iextraArg;
4476 output DAE.Else outElse;
4477 output Type_a oextraArg;
4478 partial function FuncExpType
4479 input DAE.Exp inExp;
4480 input DAE.Statement inStmt;
4481 input Type_a arg;
4482 output DAE.Exp outExp;
4483 output Type_a oarg;
4484 end FuncExpType;
4485 replaceable type Type_a subtypeof Any;
4486 algorithm
4487 (outElse,oextraArg) := match(inElse, iextraArg)
4488 local
4489 DAE.Exp e,e_1;
4490 list<DAE.Statement> st,st_1;
4491 DAE.Else el,el_1;
4492 Type_a extraArg;
4493 case (DAE.NOELSE(), extraArg) then (DAE.NOELSE(),extraArg);
4494 case (DAE.ELSEIF(e,st,el), extraArg)
4495 algorithm
4496 1661 (el_1,extraArg) := traverseDAEStmtsElse(el,func,istmt,extraArg);
4497 1661 (st_1,extraArg) := traverseDAEStmts(st,func,extraArg);
4498
2/2
✓ Branch 0 taken 438 times.
✓ Branch 1 taken 1223 times.
1661 (e_1,extraArg) := func(e, istmt, extraArg);
4499 1661 then (Algorithm.optimizeElseIf(e_1,st_1,el_1),extraArg);
4500 case(DAE.ELSE(st), extraArg)
4501 algorithm
4502 3305 (st_1,extraArg) := traverseDAEStmts(st,func,extraArg);
4503 3305 then (DAE.ELSE(st_1),extraArg);
4504 end match;
4505 end traverseDAEStmtsElse;
4506
4507 protected function traverseDAEExpListStmt "
4508 Author: BZ, 2008-12
4509 Traverse an list of expressions, helper function for traverseDAE"
4510 input list<DAE.Exp> iexps;
4511 input FuncExpType func;
4512 input DAE.Statement istmt;
4513 input Type_a iextraArg;
4514 output list<DAE.Exp> oexps;
4515 output Type_a oextraArg;
4516 partial function FuncExpType
4517 input DAE.Exp inExp;
4518 input DAE.Statement inStmt;
4519 input Type_a arg;
4520 output DAE.Exp outExp;
4521 output Type_a oarg;
4522 end FuncExpType;
4523 replaceable type Type_a subtypeof Any;
4524 algorithm
4525 (oexps,oextraArg) := match(iexps, iextraArg)
4526 local
4527 DAE.Exp e;
4528 Type_a extraArg;
4529 list<DAE.Exp> exps;
4530
4531 case({}, extraArg) then ({},extraArg);
4532
4533 case(e::exps, extraArg)
4534 algorithm
4535
2/2
✓ Branch 0 taken 5608 times.
✓ Branch 1 taken 4534 times.
10142 (e,extraArg) := func(e, istmt, extraArg);
4536 10142 (oexps,extraArg) := traverseDAEExpListStmt(exps, func, istmt, extraArg);
4537 10142 then
4538 (e::oexps,extraArg);
4539 end match;
4540 end traverseDAEExpListStmt;
4541
4542 protected function traverseDAEVarAttr "
4543 Author: BZ, 2008-12
4544 Help function to traverseDAE
4545 "
4546 input Option<DAE.VariableAttributes> attr;
4547 input FuncExpType func;
4548 input Type_a iextraArg;
4549 output Option<DAE.VariableAttributes> traversedDaeList;
4550 output Type_a oextraArg;
4551 partial function FuncExpType
4552 input DAE.Exp inExp;
4553 input Type_a inTypeA;
4554 output DAE.Exp outExp;
4555 output Type_a outA;
4556 end FuncExpType;
4557 replaceable type Type_a subtypeof Any;
4558 algorithm
4559 (traversedDaeList,oextraArg) := match(attr, iextraArg)
4560 local
4561 Option<DAE.Exp> quantity,unit,displayUnit,min,max,start,fixed,nominal,eb;
4562 Option<DAE.StartOrigin> so;
4563 Option<DAE.StateSelect> stateSelect;
4564 Option<DAE.Uncertainty> uncertainty;
4565 Option<DAE.Distribution> distribution;
4566 Option<Boolean> ip,fn;
4567 Type_a extraArg;
4568
4569 case(SOME(DAE.VAR_ATTR_REAL(quantity,unit,displayUnit,min,max,start,fixed,nominal,stateSelect,uncertainty,distribution,eb,ip,fn,so)), extraArg)
4570 algorithm
4571 561191 (quantity,extraArg) := traverseDAEOptExp(quantity,func,extraArg);
4572 561191 (unit,extraArg) := traverseDAEOptExp(unit,func,extraArg);
4573 561191 (displayUnit,extraArg) := traverseDAEOptExp(displayUnit,func,extraArg);
4574 561191 (min,extraArg) := traverseDAEOptExp(min,func,extraArg);
4575 561191 (max,extraArg) := traverseDAEOptExp(max,func,extraArg);
4576 561191 (start,extraArg) := traverseDAEOptExp(start,func,extraArg);
4577 561191 (fixed,extraArg) := traverseDAEOptExp(fixed,func,extraArg);
4578 561191 (nominal,extraArg) := traverseDAEOptExp(nominal,func,extraArg);
4579 1122382 then (SOME(DAE.VAR_ATTR_REAL(quantity,unit,displayUnit,min,max,start,fixed,nominal,stateSelect,uncertainty,distribution,eb,ip,fn,so)),extraArg);
4580
4581 case(SOME(DAE.VAR_ATTR_INT(quantity,min,max,start,fixed,uncertainty,distribution,eb,ip,fn,so)), extraArg)
4582 algorithm
4583 31284 (quantity,extraArg) := traverseDAEOptExp(quantity,func,extraArg);
4584 31284 (min,extraArg) := traverseDAEOptExp(min,func,extraArg);
4585 31284 (max,extraArg) := traverseDAEOptExp(max,func,extraArg);
4586 31284 (start,extraArg) := traverseDAEOptExp(start,func,extraArg);
4587 31284 (fixed,extraArg) := traverseDAEOptExp(fixed,func,extraArg);
4588 62568 then (SOME(DAE.VAR_ATTR_INT(quantity,min,max,start,fixed,uncertainty,distribution,eb,ip,fn,so)),extraArg);
4589
4590 case(SOME(DAE.VAR_ATTR_BOOL(quantity,start,fixed,eb,ip,fn,so)), extraArg)
4591 algorithm
4592 22619 (quantity,extraArg) := traverseDAEOptExp(quantity,func,extraArg);
4593 22619 (start,extraArg) := traverseDAEOptExp(start,func,extraArg);
4594 22619 (fixed,extraArg) := traverseDAEOptExp(fixed,func,extraArg);
4595 45238 then (SOME(DAE.VAR_ATTR_BOOL(quantity,start,fixed,eb,ip,fn,so)),extraArg);
4596 // BTH
4597 case(SOME(DAE.VAR_ATTR_CLOCK(_,_)), extraArg)
4598 then (attr,extraArg);
4599
4600 case(SOME(DAE.VAR_ATTR_STRING(quantity,start,fixed,eb,ip,fn,so)), extraArg)
4601 algorithm
4602 4979 (quantity,extraArg) := traverseDAEOptExp(quantity,func,extraArg);
4603 4979 (start,extraArg) := traverseDAEOptExp(start,func,extraArg);
4604 4979 (fixed,extraArg) := traverseDAEOptExp(fixed,func,extraArg);
4605 9958 then (SOME(DAE.VAR_ATTR_STRING(quantity,start,fixed,eb,ip,fn,so)),extraArg);
4606
4607 case(SOME(DAE.VAR_ATTR_ENUMERATION(quantity,min,max,start,fixed,eb,ip,fn,so)), extraArg)
4608 algorithm
4609 3246 (quantity,extraArg) := traverseDAEOptExp(quantity,func,extraArg);
4610 3246 (start,extraArg) := traverseDAEOptExp(start,func,extraArg);
4611 6492 then (SOME(DAE.VAR_ATTR_ENUMERATION(quantity,min,max,start,fixed,eb,ip,fn,so)),extraArg);
4612
4613 case (NONE(), extraArg) then (NONE(),extraArg);
4614
4615 end match;
4616 end traverseDAEVarAttr;
4617
4618 public function addComponentTypeOpt "
4619 See setComponentType"
4620 input DAE.DAElist inDae;
4621 input Option<Absyn.Path> inPath;
4622 output DAE.DAElist outDae;
4623 algorithm
4624 outDae := match (inDae,inPath)
4625 local Absyn.Path p; DAE.DAElist dae;
4626 case (dae,SOME(p)) algorithm
4627 ✗ dae := addComponentType(dae,p);
4628 then dae;
4629 case(dae,NONE()) then dae;
4630 end match;
4631 end addComponentTypeOpt;
4632
4633 public function addComponentType "
4634 This function takes a dae element list and a type name and
4635 inserts the type name into each Var (variable) of the dae.
4636 This type name is the origin of the variable."
4637 input output DAE.DAElist dae;
4638 input Absyn.Path newtype;
4639 algorithm
4640
4/4
✓ Branch 1 taken 902897 times.
✓ Branch 2 taken 205 times.
✓ Branch 4 taken 902693 times.
✓ Branch 5 taken 204 times.
903102 if not (Flags.isSet(Flags.INFO_XML_OPERATIONS) or Flags.isSet(Flags.VISUAL_XML)) then
4641 902693 return;
4642 end if;
4643 dae := match dae
4644 local
4645 list<DAE.Element> elts;
4646 case DAE.DAE(elts)
4647 algorithm
4648 409 elts := List.map1(elts,addComponentType2,newtype);
4649 409 then DAE.DAE(elts);
4650 end match;
4651 end addComponentType;
4652
4653 protected function addComponentType2 "
4654 This function takes a dae element list and a type name and
4655 inserts the type name into each Var (variable) of the dae.
4656 This type name is the origin of the variable."
4657 input output DAE.Element elt;
4658 input Absyn.Path inPath;
4659 algorithm
4660 elt := match elt
4661 local
4662 DAE.ElementSource source;
4663 case DAE.VAR()
4664 algorithm
4665 115 elt.source := ElementSource.addElementSourceType(elt.source, inPath);
4666 then elt;
4667 else elt;
4668 end match;
4669 end addComponentType2;
4670
4671 public function isExtFunction "returns true if element matches an external function"
4672 input DAE.Function elt;
4673 output Boolean res;
4674 algorithm
4675 res := match elt
4676 case DAE.FUNCTION(functions=DAE.FUNCTION_EXT()::_) then true;
4677 else false;
4678 end match;
4679 end isExtFunction;
4680
4681
4682 public function functionName "returns the name of a FUNCTION or RECORD_CONSTRUCTOR"
4683 input DAE.Function elt;
4684 output Absyn.Path name;
4685 algorithm
4686 name:= match elt
4687 case DAE.FUNCTION(path=name) then name;
4688 case DAE.RECORD_CONSTRUCTOR(path=name) then name;
4689 end match;
4690 end functionName;
4691
4692 public function convertInlineTypeToBool "
4693 Author: BZ, 2009-12
4694 Function for converting a InlineType to a bool.
4695 Whether the inline takes place before or after index reduction does not mather.
4696 Any kind of inline will result in true.
4697 "
4698 input DAE.InlineType it;
4699 output Boolean b;
4700 algorithm
4701 b := match it
4702 case DAE.NO_INLINE() then false;
4703 else true;
4704 end match;
4705 end convertInlineTypeToBool;
4706
4707 public function inlineTypeEqual
4708 input DAE.InlineType it1;
4709 input DAE.InlineType it2;
4710 output Boolean b;
4711 algorithm
4712 b := match (it1, it2)
4713 case (DAE.NORM_INLINE(), DAE.NORM_INLINE()) then true;
4714 case (DAE.BUILTIN_EARLY_INLINE(), DAE.BUILTIN_EARLY_INLINE()) then true;
4715 case (DAE.EARLY_INLINE(), DAE.EARLY_INLINE()) then true;
4716 case (DAE.DEFAULT_INLINE(), DAE.DEFAULT_INLINE()) then true;
4717 case (DAE.NO_INLINE(), DAE.NO_INLINE()) then true;
4718 case (DAE.AFTER_INDEX_RED_INLINE(), DAE.AFTER_INDEX_RED_INLINE()) then true;
4719 else false;
4720 end match;
4721 end inlineTypeEqual;
4722
4723 public function daeElements "Retrieve the elements from a DAEList"
4724 input DAE.DAElist dae;
4725 output list<DAE.Element> elts;
4726 algorithm
4727 elts := match dae
4728 case DAE.DAE(elts) then elts;
4729 end match;
4730 end daeElements;
4731
4732 public function joinDaes "joins two daes by appending the element lists and joining the function trees"
4733 input DAE.DAElist dae1;
4734 input DAE.DAElist dae2;
4735 output DAE.DAElist outDae;
4736 algorithm
4737 outDae := match(dae1,dae2)
4738 local
4739 list<DAE.Element> elts1,elts2,elts;
4740
4741 // just append lists
4742 case(DAE.DAE(elts1),
4743 DAE.DAE(elts2))
4744 algorithm
4745 // t1 = clock();
4746 2441649 elts := listAppend(elts1,elts2);
4747 // t2 = clock();
4748 // ti = t2 -. t1;
4749 // fprintln(Flags.INNER_OUTER, " joinDAEs: (" + realString(ti) + ") -> " + intString(listLength(elts1)) + " + " + intString(listLength(elts2)));
4750 2441649 then DAE.DAE(elts);
4751
4752 end match;
4753 end joinDaes;
4754
4755 public function joinDaeLst "joins a list of daes by using joinDaes"
4756 input list<DAE.DAElist> idaeLst;
4757 output DAE.DAElist outDae;
4758 algorithm
4759 outDae := match idaeLst
4760 local
4761 DAE.DAElist dae,dae1;
4762 list<DAE.DAElist> daeLst;
4763 case {dae} then dae;
4764 case dae::daeLst
4765 algorithm
4766 1120884 dae1 := joinDaeLst(daeLst);
4767 1120884 dae := joinDaes(dae,dae1);
4768 then dae;
4769 end match;
4770 end joinDaeLst;
4771
4772 public function splitElements
4773 "This functions splits DAE elements into multiple groups."
4774 input list<DAE.Element> elements;
4775 output list<DAE.Element> variables = {};
4776 output list<DAE.Element> initialEquations = {};
4777 output list<DAE.Element> initialAlgorithms = {};
4778 output list<DAE.Element> equations = {};
4779 output list<DAE.Element> algorithms = {};
4780 output list<DAE.Element> classAttributes = {};
4781 output list<DAE.Element> constraints = {};
4782 output list<DAE.Element> externalObjects = {};
4783 output list<DAEDumpTypes.compWithSplitElements> stateMachineComps = {};
4784 output list<SCode.Comment> comments = {};
4785 protected
4786 DAEDumpTypes.compWithSplitElements split_comp;
4787 algorithm
4788
24/34
✓ Branch 0 taken 19970 times.
✓ Branch 1 taken 176 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✓ Branch 11 taken 3818 times.
✓ Branch 12 taken 2357 times.
✓ Branch 13 taken 521 times.
✓ Branch 14 taken 70 times.
✓ Branch 15 taken 7 times.
✓ Branch 16 taken 180 times.
✓ Branch 17 taken 1 time.
✓ Branch 18 taken 15 times.
✓ Branch 19 taken 17 times.
✓ Branch 20 taken 37 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 13 times.
✓ Branch 23 taken 63 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
✓ Branch 28 taken 1 time.
✓ Branch 29 taken 2 times.
✓ Branch 30 taken 455 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 27719 times.
✓ Branch 33 taken 2764 times.
30483 for e in elements loop
4789 () := match e
4790 case DAE.VAR()
4791 algorithm variables := e :: variables; then ();
4792
4793 case DAE.INITIALEQUATION()
4794 algorithm initialEquations := e :: initialEquations; then ();
4795 case DAE.INITIAL_ARRAY_EQUATION()
4796 algorithm initialEquations := e :: initialEquations; then ();
4797 case DAE.INITIAL_COMPLEX_EQUATION()
4798 algorithm initialEquations := e :: initialEquations; then ();
4799 case DAE.INITIALDEFINE()
4800 algorithm initialEquations := e :: initialEquations; then ();
4801 case DAE.INITIAL_IF_EQUATION()
4802 algorithm initialEquations := e :: initialEquations; then ();
4803 case DAE.INITIAL_FOR_EQUATION()
4804 algorithm initialEquations := e :: initialEquations; then ();
4805 case DAE.INITIAL_ASSERT()
4806 algorithm initialEquations := e :: initialEquations; then ();
4807 case DAE.INITIAL_TERMINATE()
4808 algorithm initialEquations := e :: initialEquations; then ();
4809 case DAE.INITIAL_NORETCALL()
4810 algorithm initialEquations := e :: initialEquations; then ();
4811 case DAE.INITIALALGORITHM()
4812 algorithm initialAlgorithms := e :: initialAlgorithms; then ();
4813
4814 case DAE.EQUATION()
4815 algorithm equations := e :: equations; then ();
4816 case DAE.EQUEQUATION()
4817 algorithm equations := e :: equations; then ();
4818 case DAE.ARRAY_EQUATION()
4819 algorithm equations := e :: equations; then ();
4820 case DAE.COMPLEX_EQUATION()
4821 algorithm equations := e :: equations; then ();
4822 case DAE.DEFINE()
4823 algorithm equations := e :: equations; then ();
4824 case DAE.ASSERT()
4825 algorithm equations := e :: equations; then ();
4826 case DAE.TERMINATE()
4827 algorithm equations := e :: equations; then ();
4828 case DAE.IF_EQUATION()
4829 algorithm equations := e :: equations; then ();
4830 case DAE.FOR_EQUATION()
4831 algorithm equations := e :: equations; then ();
4832 case DAE.WHEN_EQUATION()
4833 algorithm equations := e :: equations; then ();
4834 case DAE.REINIT()
4835 algorithm equations := e :: equations; then ();
4836 case DAE.NORETCALL()
4837 algorithm equations := e :: equations; then ();
4838
4839 case DAE.ALGORITHM()
4840 algorithm algorithms := e :: algorithms; then ();
4841 case DAE.CONSTRAINT()
4842 algorithm constraints := e :: constraints; then ();
4843 case DAE.CLASS_ATTRIBUTES()
4844 algorithm classAttributes := e :: classAttributes; then ();
4845 case DAE.EXTOBJECTCLASS()
4846 algorithm externalObjects := e :: externalObjects; then ();
4847 case DAE.COMP()
4848 ✗ algorithm variables := listAppend(e.dAElist, variables); then ();
4849 case DAE.FLAT_SM()
4850 algorithm
4851 1 split_comp := splitComponent(DAE.COMP(e.ident, e.dAElist,
4852 DAE.emptyElementSource, SOME(SCode.COMMENT(NONE(), SOME("stateMachine")))));
4853 stateMachineComps := split_comp :: stateMachineComps;
4854 then
4855 ();
4856 case DAE.SM_COMP()
4857 algorithm
4858 2 split_comp := splitComponent(DAE.COMP(ComponentReference.crefStr(e.componentRef),
4859 e.dAElist, DAE.emptyElementSource, SOME(SCode.COMMENT(NONE(), SOME("state")))));
4860 stateMachineComps := split_comp :: stateMachineComps;
4861 then
4862 ();
4863
4864 case DAE.COMMENT()
4865 455 algorithm comments := e.cmt :: comments; then ();
4866
4867 else
4868 algorithm
4869 ✗ Error.addInternalError("DAEUtil.splitElements got unknown element.", Absyn.dummyInfo);
4870 ✗ then
4871 fail();
4872 end match;
4873 end for;
4874
4875 2764 variables := listReverse(variables);
4876 2764 initialEquations := listReverse(initialEquations);
4877 2764 initialAlgorithms := listReverse(initialAlgorithms);
4878 2764 equations := listReverse(equations);
4879 2764 algorithms := listReverse(algorithms);
4880 2764 classAttributes := listReverse(classAttributes);
4881 2764 constraints := listReverse(constraints);
4882 2764 externalObjects := listReverse(externalObjects);
4883 2764 stateMachineComps := listReverse(stateMachineComps);
4884 end splitElements;
4885
4886 public function splitComponent
4887 "Transforms a DAE.COMP to a DAEDump.COMP_WITH_SPLIT."
4888 input DAE.Element component;
4889 output DAEDumpTypes.compWithSplitElements splitComponent;
4890 protected
4891 list<DAE.Element> v, ie, ia, e, a, co, o, ca;
4892 list<DAEDumpTypes.compWithSplitElements> sm;
4893 protected
4894 DAEDumpTypes.splitElements split_el;
4895 algorithm
4896 splitComponent := match component
4897 case DAE.COMP()
4898 algorithm
4899 1029 (v, ie, ia, e, a, co, o, ca, sm) := splitElements(component.dAElist);
4900 1029 split_el := DAEDumpTypes.SPLIT_ELEMENTS(v, ie, ia, e, a, co, o, ca, sm);
4901 1029 then
4902 DAEDumpTypes.COMP_WITH_SPLIT(component.ident, split_el, component.comment);
4903 end match;
4904 end splitComponent;
4905
4906 protected function isIfEquation "Succeeds if Element is an if-equation.
4907 "
4908 input DAE.Element inElement;
4909 algorithm
4910 ():=
4911 match inElement
4912 case DAE.IF_EQUATION() then ();
4913 case DAE.INITIAL_IF_EQUATION() then ();
4914 end match;
4915 end isIfEquation;
4916
4917 public function collectLocalDecls
4918 "Used to traverse expressions and collect all local declarations"
4919 input DAE.Exp e;
4920 input list<DAE.Element> inElements;
4921 output DAE.Exp outExp;
4922 output list<DAE.Element> outElements;
4923 algorithm
4924 (outExp,outElements) := match (e,inElements)
4925 local
4926 list<DAE.Element> ld1,ld2,ld;
4927 case (DAE.MATCHEXPRESSION(localDecls = ld1),ld2)
4928 algorithm
4929 1114 ld := listAppend(ld1,ld2);
4930 then (e,ld);
4931 else (e,inElements);
4932 end match;
4933 end collectLocalDecls;
4934
4935 public function getUniontypePaths
4936 "Traverses DAE elements to find all Uniontypes, and return the paths
4937 of all of their records. This list contains duplicates; handle that in
4938 the other function."
4939 input list<DAE.Function> funcs;
4940 input list<DAE.Element> els;
4941 output list<Absyn.Path> outPaths;
4942 protected
4943 list<Absyn.Path> paths1,paths2;
4944 algorithm
4945 outPaths := matchcontinue els
4946 case _
4947 algorithm
4948
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 36 times.
148 false := Config.acceptMetaModelicaGrammar();
4949 then {};
4950 else
4951 algorithm
4952 112 paths1 := getUniontypePathsFunctions(funcs);
4953 112 paths2 := getUniontypePathsElements(els,{});
4954 // Use accumulators? Small gain as T_METAUNIONTYPE has lists of paths anyway?
4955 112 outPaths := listAppend(paths1, paths2);
4956 then outPaths;
4957 end matchcontinue;
4958 end getUniontypePaths;
4959
4960 protected function getUniontypePathsFunctions
4961 "May contain duplicates."
4962 input list<DAE.Function> elements;
4963 output list<Absyn.Path> outPaths;
4964 algorithm
4965 outPaths := match elements
4966 local
4967 list<DAE.Element> els,els1,els2;
4968 case _
4969 algorithm
4970 112 (_,(_,els1)) := traverseDAEFunctions(elements, Expression.traverseSubexpressionsHelper, (collectLocalDecls,{}));
4971 112 els2 := getFunctionsElements(elements);
4972 112 els := listAppend(els1, els2);
4973 112 outPaths := getUniontypePathsElements(els,{});
4974 then outPaths;
4975 end match;
4976 end getUniontypePathsFunctions;
4977
4978 protected function getUniontypePathsElements
4979 "May contain duplicates."
4980 input list<DAE.Element> elements;
4981 input list<DAE.Type> acc;
4982 output list<Absyn.Path> outPaths;
4983 algorithm
4984 outPaths := match elements
4985 local
4986 list<DAE.Element> rest;
4987 list<DAE.Type> tys;
4988 DAE.Type ft;
4989 224 case {} then List.applyAndFold(acc, listAppend, Types.getUniontypePaths, {});
4990 case DAE.VAR(ty = ft)::rest
4991 algorithm
4992 10686 tys := Types.getAllInnerTypesOfType(ft, Types.uniontypeFilter);
4993 10686 then getUniontypePathsElements(rest,listAppend(tys,acc));
4994 1635 case _::rest then getUniontypePathsElements(rest,acc);
4995 end match;
4996 end getUniontypePathsElements;
4997
4998 protected function getDAEDeclsFromValueblocks
4999 input list<DAE.Exp> exps;
5000 output list<DAE.Element> outEls = {};
5001 algorithm
5002 ✗ for ex in exps loop
5003 () := match ex
5004 local
5005 list<DAE.Element> els1;
5006 case DAE.MATCHEXPRESSION(localDecls = els1)
5007 algorithm
5008 ✗ outEls := List.append_reverse(els1, outEls);
5009 then ();
5010 else ();
5011 end match;
5012 end for;
5013 ✗ outEls := MetaModelica.Dangerous.listReverseInPlace(outEls);
5014 end getDAEDeclsFromValueblocks;
5015
5016 // protected function transformDerInline "This is not used.
5017 // Simple euler inline of the equation system; only does explicit euler, and only der(cref)"
5018 // input DAE.DAElist dae;
5019 // output DAE.DAElist d;
5020 // algorithm
5021 // d := matchcontinue (dae)
5022 // local
5023 // HashTable.HashTable ht;
5024 // case _
5025 // equation
5026 // false = Flags.isSet(Flags.FRONTEND_INLINE_EULER);
5027 // then dae;
5028 // case _
5029 // equation
5030 // ht = HashTable.emptyHashTable();
5031 // (d,_,ht) = traverseDAE(dae,AvlTreePathFunction.Tree.EMPTY(),simpleInlineDerEuler,ht);
5032 // then d;
5033 // end matchcontinue;
5034 // end transformDerInline;
5035 //
5036 // protected function simpleInlineDerEuler "This is not used.
5037 // Helper function of transformDerInline."
5038 // input tuple<DAE.Exp,HashTable.HashTable> itpl;
5039 // output tuple<DAE.Exp,HashTable.HashTable> otpl;
5040 // algorithm
5041 // otpl := matchcontinue (itpl)
5042 // local
5043 // DAE.ComponentRef cr,cref_1,cref_2;
5044 // HashTable.HashTable crs0,crs1;
5045 // DAE.Exp exp,e1,e2;
5046 //
5047 // case ((DAE.CALL(path=Absyn.IDENT("der"),expLst={exp as DAE.CREF(componentRef = cr, ty = DAE.T_REAL(varLst = _))}),crs0))
5048 // equation
5049 // cref_1 = ComponentReferenceBasics.makeCrefQual("$old",DAE.T_REAL_DEFAULT,{},cr);
5050 // cref_2 = ComponentReferenceBasics.makeCrefIdent("$current_step_size",DAE.T_REAL_DEFAULT,{});
5051 // e1 = Expression.makeCrefExp(cref_1,DAE.T_REAL_DEFAULT);
5052 // e2 = Expression.makeCrefExp(cref_2,DAE.T_REAL_DEFAULT);
5053 // exp = DAE.BINARY(
5054 // DAE.BINARY(exp, DAE.SUB(DAE.T_REAL_DEFAULT), e1),
5055 // DAE.DIV(DAE.T_REAL_DEFAULT),
5056 // e2);
5057 // crs1 = BaseHashTable.add((cr,0),crs0);
5058 // then
5059 // ((exp,crs1));
5060 //
5061 // case ((exp,crs0)) then ((exp,crs0));
5062 //
5063 // end matchcontinue;
5064 // end simpleInlineDerEuler;
5065
5066 public function transformationsBeforeBackend
5067 input FCore.Cache cache;
5068 input FCore.Graph env;
5069 input DAE.DAElist inDAElist;
5070 input StateMachineToDataFlowFunc stateMachineToDataFlow;
5071 output DAE.DAElist outDAElist;
5072 partial function StateMachineToDataFlowFunc
5073 input FCore.Cache cache;
5074 input FCore.Graph env;
5075 input DAE.DAElist inDAElist;
5076 output DAE.DAElist outDAElist;
5077 end StateMachineToDataFlowFunc;
5078 protected
5079 DAE.DAElist dAElist;
5080 list<DAE.Element> elts;
5081 AvlSetCR.Tree ht;
5082 algorithm
5083 // Transform Modelica state machines to flat data-flow equations
5084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1097 times.
1097 dAElist := stateMachineToDataFlow(cache, env, inDAElist);
5085
5086
2/2
✓ Branch 1 taken 611 times.
✓ Branch 2 taken 486 times.
1097 if Flags.isSet(Flags.SCODE_INST) then
5087 // This is stupid, but `outDAElist := dAElist` causes crashes for some reason. GC bug?
5088 611 DAE.DAE(elts) := dAElist;
5089 611 outDAElist := DAE.DAE(elts);
5090 else
5091 486 DAE.DAE(elts) := dAElist;
5092
5093 486 ht := FCore.getEvaluatedParams(cache);
5094 486 elts := List.map1(elts, makeEvaluatedParamFinal, ht);
5095
5096
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 486 times.
486 if Flags.isSet(Flags.PRINT_STRUCTURAL) then
5097 ✗ transformationsBeforeBackendNotification(ht);
5098 end if;
5099
5100 486 outDAElist := DAE.DAE(elts);
5101 end if;
5102
5103 // Don't even run the function to try and do this; it doesn't work very well
5104 // outDAElist := transformDerInline(outDAElist);
5105 end transformationsBeforeBackend;
5106
5107 protected function transformationsBeforeBackendNotification
5108 input AvlSetCR.Tree ht;
5109 protected
5110 list<DAE.ComponentRef> crs;
5111 list<String> strs;
5112 String str;
5113 algorithm
5114 ✗ crs := AvlSetCR.listKeys(ht);
5115 ✗ if not listEmpty(crs) then
5116 ✗ strs := List.map(crs, ComponentReferenceBasics.printComponentRefStr);
5117 ✗ str := stringDelimitList(strs, ", ");
5118 ✗ Error.addMessage(Error.NOTIFY_FRONTEND_STRUCTURAL_PARAMETERS, {str});
5119 end if;
5120 end transformationsBeforeBackendNotification;
5121
5122 protected function makeEvaluatedParamFinal "
5123 This function makes all evaluated parameters final."
5124 input DAE.Element inElement;
5125 input AvlSetCR.Tree ht "evaluated parameters";
5126 output DAE.Element outElement;
5127 algorithm
5128 outElement := match inElement
5129 local
5130 DAE.ComponentRef cr;
5131 Option<DAE.VariableAttributes> varOpt;
5132 String id;
5133 list<DAE.Element> elts;
5134 DAE.ElementSource source;
5135 Option<SCode.Comment> cmt;
5136 DAE.Element elt;
5137
5138 case DAE.VAR(componentRef=cr, kind=DAE.PARAM(), variableAttributesOption=varOpt) algorithm
5139
2/2
✓ Branch 1 taken 1583 times.
✓ Branch 2 taken 32589 times.
34172 elt := if AvlSetCR.hasKey(ht, cr) then setVariableAttributes(inElement, setFinalAttr(varOpt, true)) else inElement;
5140 then elt;
5141
5142 case DAE.COMP(id, elts, source, cmt) algorithm
5143 486 elts := List.map1(elts, makeEvaluatedParamFinal, ht);
5144 486 then DAE.COMP(id, elts, source, cmt);
5145
5146 else inElement;
5147 end match;
5148 end makeEvaluatedParamFinal;
5149
5150 public function setBindingSource "author: adrpo
5151 This function will set the source of the binding"
5152 input DAE.Binding inBinding;
5153 input DAE.BindingSource bindingSource;
5154 output DAE.Binding outBinding;
5155 algorithm
5156 outBinding := match inBinding
5157 local
5158 DAE.Exp exp "exp";
5159 Option<Values.Value> evaluatedExp "evaluatedExp; evaluated exp";
5160 DAE.Const cnst "constant";
5161 Values.Value valBound;
5162
5163 case DAE.UNBOUND() then inBinding;
5164 155 case DAE.EQBOUND(exp, evaluatedExp, cnst, _) then DAE.EQBOUND(exp, evaluatedExp, cnst, bindingSource);
5165 ✗ case DAE.VALBOUND(valBound, _) then DAE.VALBOUND(valBound, bindingSource);
5166 end match;
5167 end setBindingSource;
5168
5169 public function printBindingExpStr "prints a binding"
5170 input DAE.Binding binding;
5171 output String str;
5172 algorithm
5173 str := match binding
5174 local
5175 DAE.Exp e; Values.Value v;
5176 case DAE.UNBOUND() then "";
5177 case DAE.EQBOUND(exp=e)
5178 algorithm
5179 ✗ str := ExpressionBasics.printExpStr(e);
5180 then
5181 str;
5182 case DAE.VALBOUND(valBound=v)
5183 algorithm
5184 ✗ str := " = " + ValuesDump.valString(v);
5185 then
5186 str;
5187 end match;
5188 end printBindingExpStr;
5189
5190 public function collectValueblockFunctionRefVars
5191 "Collect the function names of variables in valueblock local sections"
5192 input DAE.Exp exp;
5193 input list<Absyn.Path> acc;
5194 output DAE.Exp outExp;
5195 output list<Absyn.Path> outAcc;
5196 algorithm
5197 (outExp,outAcc) := match exp
5198 local
5199 list<DAE.Element> decls;
5200 case DAE.MATCHEXPRESSION(localDecls = decls)
5201 algorithm
5202 1171 outAcc := List.fold(decls, collectFunctionRefVarPaths, acc);
5203 then (exp,outAcc);
5204 else (exp,acc);
5205 end match;
5206 end collectValueblockFunctionRefVars;
5207
5208 public function collectFunctionRefVarPaths
5209 "Collect the function names of declared variables"
5210 input DAE.Element inElem;
5211 input list<Absyn.Path> acc;
5212 output list<Absyn.Path> outAcc;
5213 algorithm
5214 outAcc := match inElem
5215 local
5216 Absyn.Path path;
5217 case DAE.VAR(ty = DAE.T_FUNCTION(path = path))
5218 then path::acc;
5219 else acc;
5220 end match;
5221 end collectFunctionRefVarPaths;
5222
5223 public function addFunctionDefinition
5224 "adds a functionDefinition to a function. can be used to add function_der_mapper to a function"
5225 input DAE.Function ifunc;
5226 input DAE.FunctionDefinition iFuncDef;
5227 output DAE.Function func = ifunc;
5228 algorithm
5229 () := match func
5230 case DAE.FUNCTION()
5231 algorithm
5232 75 func.functions := List.appendElt(iFuncDef, func.functions);
5233 then
5234 ();
5235
5236 else ();
5237 end match;
5238 end addFunctionDefinition;
5239
5240 public function getFunctionsInfo
5241 input AvlTreePathFunction.Tree ft;
5242 output list<String> strs;
5243 algorithm
5244 strs := match ft
5245 local
5246 list<tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value>> lst;
5247
5248 case _
5249 algorithm
5250 ✗ lst := AvlTreePathFunction.toList(ft);
5251 ✗ strs := List.map(lst, getInfo);
5252 ✗ strs := List.sort(strs, Util.strcmpBool);
5253 then
5254 strs;
5255 end match;
5256 end getFunctionsInfo;
5257
5258
5259 public function getInfo
5260 input tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value> tpl;
5261 output String str;
5262 algorithm
5263 str := match tpl
5264 local
5265 Absyn.Path p;
5266 case (p, NONE())
5267 algorithm
5268 ✗ str := AbsynUtil.pathString(p) + " [invalid]";
5269 then
5270 str;
5271 case (p, SOME(_))
5272 algorithm
5273 ✗ str := AbsynUtil.pathString(p) + " [valid] ";
5274 then
5275 str;
5276 end match;
5277 end getInfo;
5278
5279 protected function showCacheFuncs
5280 input AvlTreePathFunction.Tree tree;
5281 algorithm
5282 () := match tree
5283 local
5284 String msg;
5285 case _
5286 algorithm
5287 ✗ msg := stringDelimitList(getFunctionsInfo(tree), "\n ");
5288 ✗ print("Cache has: \n " + msg + "\n");
5289 then ();
5290 end match;
5291 end showCacheFuncs;
5292
5293 public function setAttrVariability "
5294 Sets the variability attribute in an Attributes record."
5295 input output DAE.Attributes attr;
5296 input SCode.Variability var;
5297 annotation(__OpenModelica_EarlyInline = true);
5298 algorithm
5299 41107 attr.variability := var;
5300 end setAttrVariability;
5301
5302 public function getAttrVariability "
5303 Get the variability attribute in an Attributes record."
5304 input DAE.Attributes attr;
5305 output SCode.Variability var = attr.variability;
5306 annotation(__OpenModelica_EarlyInline = true);
5307 end getAttrVariability;
5308
5309 public function setAttrDirection
5310 "Sets the direction attribute in an Attributes record."
5311 input output DAE.Attributes attr;
5312 input Absyn.Direction dir;
5313 annotation(__OpenModelica_EarlyInline = true);
5314 algorithm
5315 ✗ attr.direction := dir;
5316 end setAttrDirection;
5317
5318 public function getAttrDirection
5319 input DAE.Attributes attr;
5320 output Absyn.Direction dir = attr.direction;
5321 annotation(__OpenModelica_EarlyInline = true);
5322 end getAttrDirection;
5323
5324 public function setAttrInnerOuter
5325 "Sets the innerOuter attribute in an Attributes record."
5326 input output DAE.Attributes attr;
5327 input Absyn.InnerOuter io;
5328 annotation(__OpenModelica_EarlyInline = true);
5329 algorithm
5330 31240 attr.innerOuter := io;
5331 end setAttrInnerOuter;
5332
5333 public function getAttrInnerOuter
5334 input DAE.Attributes attr;
5335 output Absyn.InnerOuter io = attr.innerOuter;
5336 annotation(__OpenModelica_EarlyInline = true);
5337 end getAttrInnerOuter;
5338
5339 public function translateSCodeAttrToDAEAttr
5340 input SCode.Attributes inAttributes;
5341 input SCode.Prefixes inPrefixes;
5342 output DAE.Attributes outAttributes;
5343 protected
5344 SCode.ConnectorType ct;
5345 SCode.Parallelism prl;
5346 SCode.Variability var;
5347 Absyn.Direction dir;
5348 Absyn.InnerOuter io;
5349 SCode.Visibility vis;
5350 algorithm
5351 1221411 SCode.ATTR(connectorType = ct, parallelism = prl, variability = var, direction = dir) := inAttributes;
5352 1221411 SCode.PREFIXES(innerOuter = io, visibility = vis) := inPrefixes;
5353 1221411 outAttributes := DAE.ATTR(toConnectorTypeNoState(ct), prl, var, dir, io, vis);
5354 end translateSCodeAttrToDAEAttr;
5355
5356 public function varName
5357 input DAE.Element var;
5358 output String name;
5359 algorithm
5360
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 82410 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 82410 times.
82410 DAE.VAR(componentRef=DAE.CREF_IDENT(ident=name)) := var;
5361 end varName;
5362
5363 public function typeVarIdent
5364 input DAE.Var var;
5365 output DAE.Ident name;
5366 algorithm
5367 200338 DAE.TYPES_VAR(name=name) := var;
5368 end typeVarIdent;
5369
5370 public function typeVarIdentEqual
5371 input DAE.Var var;
5372 input String name;
5373 output Boolean b;
5374 protected
5375 String name2;
5376 algorithm
5377 48 DAE.TYPES_VAR(name=name2) := var;
5378
4/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 18 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 29 times.
48 b := stringEq(name,name2);
5379 end typeVarIdentEqual;
5380
5381 public function varType
5382 input DAE.Var var;
5383 output DAE.Type type_;
5384 algorithm
5385 199393 DAE.TYPES_VAR(ty=type_) := var;
5386 end varType;
5387
5388 public function bindingExp "
5389 help function to instBinding, returns the expression of a binding"
5390 input DAE.Binding bind;
5391 output Option<DAE.Exp> exp;
5392 algorithm
5393 exp := match bind
5394 local DAE.Exp e; Values.Value v;
5395 case DAE.UNBOUND() then NONE();
5396 case DAE.EQBOUND(evaluatedExp = SOME(v))
5397 algorithm
5398 468794 e := ValuesUtil.valueExp(v);
5399 then
5400 SOME(e);
5401 case DAE.EQBOUND(exp = e) then SOME(e);
5402 case DAE.VALBOUND(valBound=v)
5403 algorithm
5404 ✗ e := ValuesUtil.valueExp(v);
5405 then
5406 SOME(e);
5407 end match;
5408 end bindingExp;
5409
5410 public function isBound
5411 input DAE.Binding inBinding;
5412 output Boolean outIsBound;
5413 algorithm
5414 outIsBound := match inBinding
5415 case DAE.UNBOUND() then false;
5416 else true;
5417 end match;
5418 end isBound;
5419
5420 public function isCompleteFunction "author: adrpo
5421 this function returns true if the given function is complete:
5422 - has inputs
5423 - has outputs
5424 - has an algorithm section
5425 note that record constructors are always considered complete"
5426 input DAE.Function f;
5427 output Boolean isComplete;
5428 algorithm
5429 isComplete := match f
5430 local
5431 list<DAE.FunctionDefinition> functions;
5432
5433 // record constructors are always complete!
5434 case DAE.RECORD_CONSTRUCTOR() then true;
5435
5436 // functions are complete if they have inputs, outputs and algorithm section
5437 case DAE.FUNCTION(functions = functions)
5438 ✗ then isCompleteFunctionBody(functions);
5439
5440 else false;
5441 end match;
5442 end isCompleteFunction;
5443
5444 public function isCompleteFunctionBody "author: adrpo
5445 this function returns true if the given function body is complete"
5446 input list<DAE.FunctionDefinition> functions;
5447 output Boolean isComplete;
5448 algorithm
5449 isComplete := matchcontinue functions
5450 local
5451 list<DAE.FunctionDefinition> rest;
5452 list<DAE.Element> els;
5453 list<DAE.Element> a;
5454
5455 case {} then false;
5456
5457 // external are complete!
5458 case DAE.FUNCTION_EXT()::_ then true;
5459
5460 // functions are complete if they have inputs, outputs and algorithm section
5461 case DAE.FUNCTION_DEF(els)::_
5462 algorithm
5463 // algs are not empty
5464 ✗ (_,_,_,_,a,_,_,_) := splitElements(els);
5465 ✗ false := listEmpty(a);
5466 then
5467 true;
5468
5469 case DAE.FUNCTION_DER_MAPPER()::rest
5470 ✗ then isCompleteFunctionBody(rest);
5471
5472 else false;
5473 end matchcontinue;
5474 end isCompleteFunctionBody;
5475
5476 public function isNotCompleteFunction
5477 input DAE.Function f;
5478 output Boolean isNotComplete;
5479 algorithm
5480 ✗ isNotComplete := not isCompleteFunction(f);
5481 end isNotCompleteFunction;
5482
5483 public function setAttributeDirection
5484 input Absyn.Direction inDirection;
5485 input DAE.Attributes inAttributes;
5486 output DAE.Attributes outAttributes;
5487 protected
5488 DAE.ConnectorType ct;
5489 SCode.Parallelism p;
5490 SCode.Variability var;
5491 Absyn.InnerOuter io;
5492 SCode.Visibility vis;
5493 algorithm
5494 ✗ DAE.ATTR(ct, p, var, _, io, vis) := inAttributes;
5495 ✗ outAttributes := DAE.ATTR(ct, p, var, inDirection, io, vis);
5496 end setAttributeDirection;
5497
5498 public function varKindEqual
5499 input DAE.VarKind inVariability1;
5500 input DAE.VarKind inVariability2;
5501 output Boolean outIsEqual;
5502 algorithm
5503 outIsEqual := match(inVariability1, inVariability2)
5504 case (DAE.VARIABLE(), DAE.VARIABLE()) then true;
5505 case (DAE.DISCRETE(), DAE.DISCRETE()) then true;
5506 case (DAE.CONST(), DAE.CONST()) then true;
5507 case (DAE.PARAM(), DAE.PARAM()) then true;
5508 end match;
5509 end varKindEqual;
5510
5511 public function varDirectionEqual
5512 input DAE.VarDirection inDirection1;
5513 input DAE.VarDirection inDirection2;
5514 output Boolean outIsEqual;
5515 algorithm
5516 outIsEqual := match(inDirection1, inDirection2)
5517 case (DAE.BIDIR(), DAE.BIDIR()) then true;
5518 case (DAE.INPUT(), DAE.INPUT()) then true;
5519 case (DAE.OUTPUT(), DAE.OUTPUT()) then true;
5520 else false;
5521 end match;
5522 end varDirectionEqual;
5523
5524 public function isComplexVar
5525 input DAE.Var inVar;
5526 output Boolean outIsComplex;
5527 protected
5528 DAE.Type ty;
5529 algorithm
5530 ✗ DAE.TYPES_VAR(ty = ty) := inVar;
5531 ✗ outIsComplex := Types.isComplexType(ty);
5532 end isComplexVar;
5533
5534 public function getElements
5535 input DAE.DAElist inDAE;
5536 output list<DAE.Element> outElements;
5537 algorithm
5538 ✗ DAE.DAE(outElements) := inDAE;
5539 end getElements;
5540
5541 public function mkEmptyVar
5542 input String name;
5543 output DAE.Var outVar;
5544 algorithm
5545 ✗ outVar := DAE.TYPES_VAR(
5546 name,
5547 DAE.dummyAttrVar,
5548 DAE.T_UNKNOWN_DEFAULT,
5549 DAE.UNBOUND(),
5550 false,
5551 NONE());
5552 end mkEmptyVar;
5553
5554 public function sortDAEInModelicaCodeOrder
5555 "@author: adrpo
5556 sort the DAE back in the order they are in the file"
5557 input Boolean inShouldSort;
5558 input list<tuple<SCode.Element, DAE.Mod>> inElements;
5559 input DAE.DAElist inDae;
5560 output DAE.DAElist outDae;
5561 algorithm
5562 outDae := match(inShouldSort, inElements, inDae)
5563 local
5564 list<DAE.Element> els;
5565
5566 case (false, _, _) then inDae;
5567
5568 case (true, {}, _) then inDae;
5569
5570 case (true, _, DAE.DAE(els))
5571 algorithm
5572 ✗ els := sortDAEElementsInModelicaCodeOrder(inElements, els);
5573 ✗ then DAE.DAE(els);
5574
5575 end match;
5576 end sortDAEInModelicaCodeOrder;
5577
5578 protected function sortDAEElementsInModelicaCodeOrder
5579 "@author: adrpo
5580 sort the DAE elements back in the order they are in the file"
5581 input list<tuple<SCode.Element, DAE.Mod>> inElements;
5582 input list<DAE.Element> inDaeEls;
5583 output list<DAE.Element> outDaeEls = {};
5584 protected
5585 list<DAE.Element> rest = inDaeEls;
5586 algorithm
5587 ✗ for e in inElements loop
5588 () := match e
5589 local
5590 list<DAE.Element> named;
5591 Absyn.Ident name;
5592 case (SCode.COMPONENT(name = name),_)
5593 algorithm
5594 ✗ (named, rest) := splitVariableNamed(rest, name, {}, {});
5595 ✗ outDaeEls := List.append_reverse(named, outDaeEls);
5596 then ();
5597 else ();
5598 end match;
5599 end for;
5600 ✗ outDaeEls := List.append_reverse(inDaeEls, outDaeEls);
5601 ✗ outDaeEls := MetaModelica.Dangerous.listReverseInPlace(outDaeEls);
5602 end sortDAEElementsInModelicaCodeOrder;
5603
5604 protected function splitVariableNamed
5605 "@author: adrpo
5606 Splits into a list with all variables with the given name and the rest"
5607 input list<DAE.Element> inElementLst;
5608 input Absyn.Ident inName;
5609 input list<DAE.Element> inAccNamed;
5610 input list<DAE.Element> inAccRest;
5611 output list<DAE.Element> outNamed;
5612 output list<DAE.Element> outRest;
5613 algorithm
5614 (outNamed, outRest) := match(inElementLst, inAccNamed, inAccRest)
5615 local
5616 list<DAE.Element> lst, accNamed, accRest;
5617 DAE.Element x;
5618 Boolean equal;
5619 DAE.ComponentRef cr;
5620
5621 ✗ case ({}, _, _) then (listReverse(inAccNamed), listReverse(inAccRest));
5622
5623 case ((x as DAE.VAR(componentRef = cr))::lst, accNamed, accRest)
5624 algorithm
5625 ✗ equal := stringEq(ComponentReferenceBasics.crefFirstIdent(cr), inName);
5626 ✗ accNamed := List.consOnTrue(equal, x, accNamed);
5627 ✗ accRest := List.consOnTrue(boolNot(equal), x, accRest);
5628 ✗ (accNamed, accRest) := splitVariableNamed(lst, inName, accNamed, accRest);
5629 then
5630 (accNamed, accRest);
5631
5632 case (x::lst, accNamed, accRest)
5633 algorithm
5634 ✗ (accNamed, accRest) := splitVariableNamed(lst, inName, accNamed, x::accRest);
5635 then
5636 (accNamed, accRest);
5637
5638 end match;
5639 end splitVariableNamed;
5640
5641 public function daeDescription
5642 input DAE.DAElist inDAE;
5643 output String comment;
5644 algorithm
5645 comment := match inDAE
5646 case DAE.DAE(elementLst=DAE.COMP(comment=SOME(SCode.COMMENT(comment=SOME(comment))))::_) then comment;
5647 else "";
5648 end match;
5649 end daeDescription;
5650
5651 public function replaceCallAttrType "replaces the type in the geiven DAE.CALL_ATTR"
5652 input DAE.CallAttributes caIn;
5653 input DAE.Type typeIn;
5654 output DAE.CallAttributes caOut;
5655 algorithm
5656 caOut := caIn;
5657 10952 caOut.ty := typeIn;
5658
2/2
✓ Branch 1 taken 5058 times.
✓ Branch 2 taken 5894 times.
10952 if Types.isTuple(typeIn) then
5659 5894 caOut.tuple_ := true;
5660 end if;
5661 end replaceCallAttrType;
5662
5663 public function funcIsRecord
5664 input DAE.Function func;
5665 output Boolean isRec;
5666 algorithm
5667 isRec := match func
5668 case DAE.RECORD_CONSTRUCTOR()
5669 then true;
5670 else
5671 then false;
5672 end match;
5673 end funcIsRecord;
5674
5675 public function funcArgDim"gets the number of flattened scalars for a FuncArg"
5676 input DAE.FuncArg argIn;
5677 output Integer dim;
5678 algorithm
5679 dim := match argIn
5680 local
5681 DAE.Type ty;
5682 DAE.Dimensions arrayDims;
5683 list<String> names;
5684 case DAE.FUNCARG(ty = DAE.T_ARRAY(dims=arrayDims))
5685 algorithm
5686 ✗ then List.applyAndFold(arrayDims, intAdd, Expression.dimensionSize,0);
5687 case DAE.FUNCARG(ty = DAE.T_ENUMERATION(names=names))
5688 algorithm
5689 ✗ then listLength(names);
5690 else
5691 then 1;
5692 end match;
5693 end funcArgDim;
5694
5695 public function toDAEInnerOuter
5696 input Absyn.InnerOuter ioIn;
5697 output DAE.VarInnerOuter ioOut;
5698 algorithm
5699 ioOut := match ioIn
5700 case Absyn.INNER() then DAE.INNER();
5701 case Absyn.OUTER() then DAE.OUTER();
5702 case Absyn.INNER_OUTER() then DAE.INNER_OUTER();
5703 case Absyn.NOT_INNER_OUTER() then DAE.NOT_INNER_OUTER();
5704 end match;
5705 end toDAEInnerOuter;
5706
5707 public function getAssertConditionCrefs"gets the crefs of the assert condition.
5708 author:Waurich 2015-04"
5709 input DAE.Statement stmt;
5710 input list<DAE.ComponentRef> crefsIn;
5711 output list<DAE.ComponentRef> crefsOut;
5712 algorithm
5713 crefsOut := match stmt
5714 local
5715 DAE.Exp cond;
5716 list<DAE.ComponentRef> crefs;
5717 case DAE.STMT_ASSERT(cond=cond)
5718 algorithm
5719 ✗ crefs := Expression.extractCrefsFromExp(cond);
5720 ✗ then (listAppend(crefsIn,crefs));
5721 else
5722 then crefsIn;
5723 end match;
5724 end getAssertConditionCrefs;
5725
5726 public function getSubscriptIndex "author: marcusw
5727 Get the index of the given subscript as Integer. If the subscript is not a constant integer, the function returns -1."
5728 input DAE.Subscript iSubscript;
5729 output Integer oIndex;
5730 protected
5731 Integer index;
5732 algorithm
5733 oIndex := match iSubscript
5734 case DAE.INDEX(DAE.ICONST(integer=index))
5735 then index;
5736 case DAE.INDEX(DAE.ENUM_LITERAL(index=index))
5737 then index;
5738 else
5739 then -1;
5740 end match;
5741 end getSubscriptIndex;
5742
5743 public function bindingValue
5744 input DAE.Binding inBinding;
5745 output Option<Values.Value> outValue;
5746 algorithm
5747 outValue := match inBinding
5748 32 case DAE.EQBOUND() then inBinding.evaluatedExp;
5749 ✗ case DAE.VALBOUND() then SOME(inBinding.valBound);
5750 else NONE();
5751 end match;
5752 end bindingValue;
5753
5754 public
5755
5756 function statementsContainReturn
5757 input list<DAE.Statement> stmts;
5758 output Boolean b;
5759 algorithm
5760 12669 (,b) := traverseDAEStmts(stmts, statementsContainReturn2, false);
5761 end statementsContainReturn;
5762
5763 function statementsContainTryBlock
5764 input list<DAE.Statement> stmts;
5765 output Boolean b;
5766 algorithm
5767 54 (,b) := traverseDAEStmts(stmts, statementsContainTryBlock2, false);
5768 end statementsContainTryBlock;
5769
5770 protected
5771
5772 function statementsContainReturn2
5773 input DAE.Exp inExp;
5774 input DAE.Statement inStmt;
5775 input Boolean b;
5776 output DAE.Exp outExp = inExp;
5777 output Boolean ob = b;
5778 algorithm
5779
2/2
✓ Branch 0 taken 155224 times.
✓ Branch 1 taken 565 times.
155789 if not b then
5780 ob := match inStmt
5781 case DAE.STMT_RETURN() then true;
5782 else (match inExp
5783 local
5784 list<DAE.MatchCase> cases;
5785 list<DAE.Statement> body;
5786 case DAE.MATCHEXPRESSION(cases=cases)
5787 algorithm
5788
2/2
✓ Branch 0 taken 5027 times.
✓ Branch 1 taken 1145 times.
6172 for c in cases loop
5789
2/2
✓ Branch 0 taken 5016 times.
✓ Branch 1 taken 11 times.
5027 if not ob then
5790 5016 DAE.CASE(body=body) := c;
5791 5016 ob := statementsContainReturn(body);
5792 end if;
5793 end for;
5794 then ob;
5795 else false;
5796 end match);
5797 end match;
5798 end if;
5799 end statementsContainReturn2;
5800
5801 function statementsContainTryBlock2
5802 input DAE.Exp inExp;
5803 input DAE.Statement inStmt;
5804 input Boolean b;
5805 output DAE.Exp outExp = inExp;
5806 output Boolean ob = b;
5807 algorithm
5808
2/2
✓ Branch 0 taken 903 times.
✓ Branch 1 taken 20 times.
923 if not b then
5809 ob := match inExp
5810 case DAE.MATCHEXPRESSION(matchType=DAE.MATCHCONTINUE()) then true;
5811 else false;
5812 end match;
5813 end if;
5814 end statementsContainTryBlock2;
5815
5816 public function getVarBinding "
5817 Retrive the binding from a list of Elements
5818 that matches the given cref
5819 "
5820 input list<DAE.Element> iels;
5821 input DAE.ComponentRef icr;
5822 output Option<DAE.Exp> obnd;
5823 protected
5824 DAE.ComponentRef cr;
5825 DAE.Exp e;
5826 algorithm
5827 obnd := NONE();
5828 ✗ for i in iels loop
5829 obnd := match i
5830 case DAE.VAR(componentRef = cr, binding = obnd)
5831 algorithm
5832 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5833 ✗ return;
5834 end if;
5835 then
5836 obnd;
5837
5838 case DAE.DEFINE(componentRef = cr, exp = e)
5839 algorithm
5840 obnd := SOME(e);
5841 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5842 ✗ return;
5843 end if;
5844 then
5845 obnd;
5846
5847 case DAE.INITIALDEFINE(componentRef = cr, exp = e)
5848 algorithm
5849 obnd := SOME(e);
5850 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5851 ✗ return;
5852 end if;
5853 then
5854 obnd;
5855
5856 case DAE.EQUATION(exp = DAE.CREF(componentRef = cr), scalar = e)
5857 algorithm
5858 obnd := SOME(e);
5859 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5860 ✗ return;
5861 end if;
5862 then
5863 obnd;
5864
5865 case DAE.EQUATION(exp = e, scalar = DAE.CREF(componentRef = cr))
5866 algorithm
5867 obnd := SOME(e);
5868 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5869 ✗ return;
5870 end if;
5871 then
5872 obnd;
5873
5874 case DAE.INITIALEQUATION(exp1 = DAE.CREF(componentRef = cr), exp2 = e)
5875 algorithm
5876 obnd := SOME(e);
5877 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5878 ✗ return;
5879 end if;
5880 then
5881 obnd;
5882
5883 case DAE.INITIALEQUATION(exp1 = e, exp2 = DAE.CREF(componentRef = cr))
5884 algorithm
5885 obnd := SOME(e);
5886 ✗ if ComponentReferenceBasics.crefEqualNoStringCompare(icr, cr) then
5887 ✗ return;
5888 end if;
5889 then
5890 obnd;
5891
5892 else obnd;
5893
5894 end match;
5895 end for;
5896 end getVarBinding;
5897
5898 public function evaluateCref
5899 "pour man's constant evaluation"
5900 input DAE.ComponentRef icr;
5901 input list<DAE.Element> iels;
5902 output Option<DAE.Exp> oexp;
5903 protected
5904 DAE.Exp e, ee;
5905 list<DAE.ComponentRef> crefs;
5906 list<Option<DAE.Exp>> oexps;
5907 algorithm
5908 ✗ oexp := getVarBinding(iels, icr);
5909 ✗ if isSome(oexp) then
5910 ✗ SOME(e) := oexp;
5911 ✗ (e, _) := ExpressionSimplify.simplify(e);
5912 // is constant
5913 ✗ if Expression.isConst(e) then
5914 oexp := SOME(e);
5915 ✗ return;
5916 end if;
5917 // not constant
5918 ✗ crefs := Expression.getAllCrefs(e);
5919 ✗ oexps := List.map1(crefs, evaluateCref, iels);
5920 ✗ for c in crefs loop
5921 ✗ SOME(ee)::oexps := oexps;
5922 ✗ e := Expression.replaceCref(e, (c, ee));
5923 ✗ (e, _) := ExpressionSimplify.simplify(e);
5924 end for;
5925 oexp := SOME(e);
5926 end if;
5927 end evaluateCref;
5928
5929 public function evaluateExp
5930 "pour man's constant evaluation"
5931 input DAE.Exp iexp;
5932 input list<DAE.Element> iels;
5933 output Option<DAE.Exp> oexp = NONE();
5934 protected
5935 DAE.Exp e, ee;
5936 list<DAE.ComponentRef> crefs;
5937 list<Option<DAE.Exp>> oexps;
5938 algorithm
5939 // is constant
5940 ✗ if Expression.isConst(iexp) then
5941 oexp := SOME(iexp);
5942 ✗ return;
5943 end if;
5944
5945 // not constant
5946 try
5947 e := iexp;
5948 ✗ crefs := Expression.getAllCrefs(e);
5949 ✗ oexps := List.map1(crefs, evaluateCref, iels);
5950 ✗ for c in crefs loop
5951 ✗ SOME(ee)::oexps := oexps;
5952 ✗ e := Expression.replaceCrefBottomUp(e, c, ee);
5953 ✗ (e, _) := ExpressionSimplify.simplify(e);
5954 end for;
5955 oexp := SOME(e);
5956 else
5957 oexp := NONE();
5958 end try;
5959 end evaluateExp;
5960
5961 public function replaceCrefInDAEElements
5962 input list<DAE.Element> inElements;
5963 input DAE.ComponentRef inCref;
5964 input DAE.Exp inExp;
5965 output list<DAE.Element> outElements;
5966 protected
5967 VarTransform.VariableReplacements repl;
5968 algorithm
5969 ✗ repl := VarTransform.emptyReplacements();
5970 ✗ repl := VarTransform.addReplacement(repl,inCref,inExp);
5971 ✗ (outElements, _) := traverseDAEElementList(inElements,replaceCrefBottomUp,repl);
5972 end replaceCrefInDAEElements;
5973
5974 public function replaceCrefBottomUp
5975 input DAE.Exp inExp;
5976 input VarTransform.VariableReplacements replIn;
5977 output DAE.Exp outExp;
5978 output VarTransform.VariableReplacements replOut;
5979 algorithm
5980 replOut := replIn;
5981 ✗ (outExp,_) := Expression.traverseExpBottomUp(inExp,replaceCompRef,replIn);
5982 end replaceCrefBottomUp;
5983
5984 protected function replaceCompRef
5985 input DAE.Exp inExp;
5986 input VarTransform.VariableReplacements replIn;
5987 output DAE.Exp outExp;
5988 output VarTransform.VariableReplacements replOut;
5989 algorithm
5990 replOut := replIn;
5991 ✗ (outExp,_) := VarTransform.replaceExp(inExp,replIn,NONE());
5992 end replaceCompRef;
5993
5994 public function connectorTypeStr
5995 input DAE.ConnectorType connectorType;
5996 output String string;
5997 algorithm
5998 string := match connectorType
5999 local
6000 DAE.ComponentRef cref;
6001 String cref_str;
6002
6003 case DAE.POTENTIAL() then "";
6004 case DAE.FLOW() then "flow";
6005 case DAE.STREAM(NONE()) then "stream()";
6006 case DAE.STREAM(SOME(cref))
6007 algorithm
6008 ✗ cref_str := ComponentReferenceBasics.printComponentRefStr(cref);
6009 ✗ then
6010 "stream(" + cref_str + ")";
6011 else "non connector";
6012 end match;
6013 end connectorTypeStr;
6014
6015 public function streamBool
6016 input DAE.ConnectorType inStream;
6017 output Boolean bStream;
6018 algorithm
6019 bStream := match inStream
6020 case DAE.STREAM() then true;
6021 else false;
6022 end match;
6023 end streamBool;
6024
6025 public function potentialBool
6026 input DAE.ConnectorType inConnectorType;
6027 output Boolean outPotential;
6028 algorithm
6029 outPotential := match inConnectorType
6030 case DAE.POTENTIAL() then true;
6031 else false;
6032 end match;
6033 end potentialBool;
6034
6035 public function connectorTypeEqual
6036 input DAE.ConnectorType inConnectorType1;
6037 input DAE.ConnectorType inConnectorType2;
6038 output Boolean outEqual;
6039 algorithm
6040 outEqual := match(inConnectorType1, inConnectorType2)
6041 case (DAE.POTENTIAL(), DAE.POTENTIAL()) then true;
6042 case (DAE.FLOW(), DAE.FLOW()) then true;
6043 case (DAE.STREAM(_), DAE.STREAM(_)) then true;
6044 case (DAE.NON_CONNECTOR(), DAE.NON_CONNECTOR()) then true;
6045 end match;
6046 end connectorTypeEqual;
6047
6048 public function toSCodeConnectorType
6049 input DAE.ConnectorType daeConnectorType;
6050 output SCode.ConnectorType scodeConnectorType;
6051 algorithm
6052 scodeConnectorType := match daeConnectorType
6053 case DAE.FLOW() then SCode.FLOW();
6054 case DAE.STREAM(_) then SCode.STREAM();
6055 case DAE.POTENTIAL() then SCode.POTENTIAL();
6056 case DAE.NON_CONNECTOR() then SCode.POTENTIAL();
6057 end match;
6058 end toSCodeConnectorType;
6059
6060 public function mergeAlgorithmSections
6061 "@author: adrpo
6062 experimental merging of all algorithm sections into:
6063 - one for initial algorithms
6064 - one for normal algorithms
6065 - only happens on a flag (-d=mergeAlgSections)"
6066 input DAE.DAElist inDae;
6067 output DAE.DAElist outDae;
6068 protected
6069 list<DAE.Element> els, newEls = {}, dAElist;
6070 list<DAE.Statement> istmts = {}, stmts = {}, s;
6071 DAE.ElementSource source = DAE.emptyElementSource, src;
6072 DAE.Ident ident;
6073 Option<SCode.Comment> comment;
6074 algorithm
6075 // do nothing if the flag is not activated
6076
1/2
✓ Branch 1 taken 986 times.
✗ Branch 2 not taken.
986 if not Flags.isSet(Flags.MERGE_ALGORITHM_SECTIONS) then
6077 outDae := inDae;
6078 986 return;
6079 end if;
6080
6081 ✗ DAE.DAE(els) := inDae;
6082 ✗ for e in els loop
6083 () :=
6084 match e
6085 case DAE.COMP(ident, dAElist, src, comment)
6086 algorithm
6087 ✗ DAE.DAE(dAElist) := mergeAlgorithmSections(DAE.DAE(dAElist));
6088 ✗ newEls := DAE.COMP(ident, dAElist, src, comment)::newEls;
6089 then
6090 ();
6091
6092 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(s), source = source)
6093 algorithm
6094 ✗ stmts := List.append_reverse(s, stmts);
6095 then ();
6096 case DAE.INITIALALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(s), source = source)
6097 algorithm
6098 ✗ istmts := List.append_reverse(s, istmts);
6099 then ();
6100 else
6101 algorithm
6102 newEls := e::newEls;
6103 then ();
6104 end match;
6105 end for;
6106 ✗ if not listEmpty(istmts) then
6107 ✗ newEls := DAE.INITIALALGORITHM(DAE.ALGORITHM_STMTS(listReverse(istmts)), source) :: newEls;
6108 end if;
6109 ✗ if not listEmpty(stmts) then
6110 ✗ newEls := DAE.ALGORITHM(DAE.ALGORITHM_STMTS(listReverse(stmts)), source) :: newEls;
6111 end if;
6112
6113 ✗ newEls := listReverse(newEls);
6114 ✗ outDae := DAE.DAE(newEls);
6115
6116 end mergeAlgorithmSections;
6117
6118 public function moveElementToInitialSection "Converts DAE.Element from the equation section to the initial equation section"
6119 input output DAE.Element elt;
6120 algorithm
6121 elt := match elt
6122 41 case DAE.EQUATION() then DAE.INITIALEQUATION(elt.exp, elt.scalar, elt.source);
6123 ✗ case DAE.DEFINE() then DAE.INITIALDEFINE(elt.componentRef, elt.exp, elt.source);
6124 ✗ case DAE.ARRAY_EQUATION() then DAE.INITIAL_ARRAY_EQUATION(elt.dimension, elt.exp, elt.array, elt.source);
6125 332 case DAE.COMPLEX_EQUATION() then DAE.INITIAL_COMPLEX_EQUATION(elt.lhs, elt.rhs, elt.source);
6126 ✗ case DAE.IF_EQUATION() then DAE.INITIAL_IF_EQUATION(elt.condition1, elt.equations2, elt.equations3, elt.source);
6127 ✗ case DAE.ALGORITHM() then DAE.INITIALALGORITHM(elt.algorithm_, elt.source);
6128 ✗ case DAE.ASSERT() then DAE.INITIAL_ASSERT(elt.condition, elt.message, elt.level, elt.source);
6129 ✗ case DAE.TERMINATE() then DAE.INITIAL_TERMINATE(elt.message, elt.source);
6130 ✗ case DAE.NORETCALL() then DAE.INITIAL_NORETCALL(elt.exp, elt.source);
6131 else elt;
6132 end match;
6133 end moveElementToInitialSection;
6134
6135 public function getParameters
6136 input list<DAE.Element> elts;
6137 input list<DAE.Element> acc;
6138 output list<DAE.Element> params;
6139 algorithm
6140 params := match elts
6141 local
6142 DAE.Element e;
6143 list<DAE.Element> rest, celts, a;
6144
6145 case {} then acc;
6146
6147 case (DAE.COMP(dAElist = celts))::rest
6148 algorithm
6149 ✗ a := getParameters(celts, acc);
6150 ✗ a := getParameters(rest, a);
6151 then
6152 a;
6153
6154 case (e as DAE.VAR())::rest
6155 ✗ then if isParameterOrConstant(e)
6156 then e::getParameters(rest, acc)
6157 else getParameters(rest, acc);
6158
6159 case _::rest
6160 ✗ then getParameters(rest, acc);
6161
6162 end match;
6163 end getParameters;
6164
6165 public function getInteger
6166 input DAE.Exp exp;
6167 output Integer i;
6168 algorithm
6169 i := match exp
6170 case DAE.ICONST(integer = i) then i;
6171 else algorithm
6172 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because expression is not an ICONST: " + ExpressionBasics.printExpStr(exp) + ".\n"});
6173 ✗ then fail();
6174 end match;
6175 end getInteger;
6176
6177 public function optimizeMetaRecordFieldAssigns
6178 "Merges consecutive field-update statements on the same MetaModelica
6179 uniontype/metarecord variable into a single metarecord construction.
6180 For N consecutive updates the emitted C code drops from N pairs of
6181 mmc_alloc_words+memcpy to a single mmc_mk_box call. See issue #11909.
6182
6183 When a group is merged each rhs is first assigned to a fresh local temp
6184 and the merged METARECORDCALL takes refs to those temps as arguments.
6185 This pins evaluation order at the DAE level so the C codegen does not
6186 leave it up to the C compiler's unspecified argument-evaluation order
6187 (the inlined function-call args of mmc_mk_box would otherwise be
6188 evaluated right-to-left under gcc and left-to-right under clang).
6189 `tempVars` accumulates the DAE.VAR declarations the caller must lift
6190 into the surrounding function's element list."
6191 input list<DAE.Statement> inStmts;
6192 output list<DAE.Statement> outStmts;
6193 input output list<DAE.Element> tempVars;
6194 protected
6195 DAE.Statement s2;
6196 algorithm
6197 // First recurse into compound statements, then merge contiguous runs.
6198 outStmts := {};
6199
2/2
✓ Branch 0 taken 76167 times.
✓ Branch 1 taken 17302 times.
93469 for s in inStmts loop
6200 76167 (s2, tempVars) := optMRFAInStmt(s, tempVars);
6201 outStmts := s2 :: outStmts;
6202 end for;
6203 17302 outStmts := listReverse(outStmts);
6204 17302 (outStmts, tempVars) := optMRFAMergeList(outStmts, tempVars);
6205 end optimizeMetaRecordFieldAssigns;
6206
6207 protected function optMRFAInStmt
6208 "Recurses into compound statements so inner bodies are optimized too."
6209 input output DAE.Statement stmt;
6210 input output list<DAE.Element> tempVars;
6211 algorithm
6212 (stmt, tempVars) := match stmt
6213 local
6214 DAE.Statement ew;
6215 list<DAE.Statement> stmts;
6216 DAE.Else els;
6217
6218 case DAE.STMT_IF()
6219 algorithm
6220 4176 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.statementLst, tempVars);
6221 4176 stmt.statementLst := stmts;
6222 4176 (els, tempVars) := optMRFAInElse(stmt.else_, tempVars);
6223 4176 stmt.else_ := els;
6224 4176 then (stmt, tempVars);
6225
6226 case DAE.STMT_FOR()
6227 algorithm
6228 737 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.statementLst, tempVars);
6229 737 stmt.statementLst := stmts;
6230 737 then (stmt, tempVars);
6231
6232 case DAE.STMT_PARFOR()
6233 algorithm
6234 ✗ (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.statementLst, tempVars);
6235 ✗ stmt.statementLst := stmts;
6236 ✗ then (stmt, tempVars);
6237
6238 case DAE.STMT_WHILE()
6239 algorithm
6240 265 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.statementLst, tempVars);
6241 265 stmt.statementLst := stmts;
6242 265 then (stmt, tempVars);
6243
6244 case DAE.STMT_WHEN()
6245 algorithm
6246 ✗ (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.statementLst, tempVars);
6247 ✗ stmt.statementLst := stmts;
6248 stmt.elseWhen := match stmt.elseWhen
6249 case SOME(ew)
6250 algorithm
6251 ✗ (ew, tempVars) := optMRFAInStmt(ew, tempVars);
6252 then SOME(ew);
6253 else NONE();
6254 end match;
6255 ✗ then (stmt, tempVars);
6256
6257 case DAE.STMT_FAILURE()
6258 algorithm
6259 1 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(stmt.body, tempVars);
6260 1 stmt.body := stmts;
6261 1 then (stmt, tempVars);
6262
6263 else (stmt, tempVars);
6264 end match;
6265 end optMRFAInStmt;
6266
6267 protected function optMRFAInElse
6268 input output DAE.Else els;
6269 input output list<DAE.Element> tempVars;
6270 algorithm
6271 (els, tempVars) := match els
6272 local
6273 list<DAE.Statement> stmts;
6274 DAE.Else nestedEls;
6275 case DAE.ELSEIF()
6276 algorithm
6277 1133 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(els.statementLst, tempVars);
6278 1133 els.statementLst := stmts;
6279 1133 (nestedEls, tempVars) := optMRFAInElse(els.else_, tempVars);
6280 1133 els.else_ := nestedEls;
6281 1133 then (els, tempVars);
6282
6283 case DAE.ELSE()
6284 algorithm
6285 3109 (stmts, tempVars) := optimizeMetaRecordFieldAssigns(els.statementLst, tempVars);
6286 3109 els.statementLst := stmts;
6287 3109 then (els, tempVars);
6288
6289 else (els, tempVars);
6290 end match;
6291 end optMRFAInElse;
6292
6293 // (field name, rhs expression, originating statement -- kept so we can reuse
6294 // its ElementSource when the group is merged into a single statement).
6295 protected type MRFAUpdate = tuple<String, DAE.Exp, DAE.Statement>;
6296
6297 protected function optMRFAMergeList
6298 "Greedy pass: walks a flat statement list, gathers runs of consecutive
6299 field-update statements that write the same base cref and that do not
6300 observe each other's writes, and emits a single merged statement per run."
6301 input list<DAE.Statement> inStmts;
6302 output list<DAE.Statement> outStmts = {};
6303 input output list<DAE.Element> tempVars;
6304 protected
6305 list<DAE.Statement> rest = inStmts;
6306 DAE.Statement stmt;
6307 Option<tuple<DAE.Exp, DAE.Type, String, DAE.Exp>> m;
6308 DAE.Exp base, rhs;
6309 DAE.Type mrecTy;
6310 String field;
6311 list<MRFAUpdate> group;
6312 list<String> writtenFields;
6313 Boolean extended;
6314 algorithm
6315
2/2
✓ Branch 0 taken 76167 times.
✓ Branch 1 taken 17302 times.
93469 while not listEmpty(rest) loop
6316 76167 stmt :: rest := rest;
6317 76167 m := optMRFAMatch(stmt);
6318 (outStmts, rest, tempVars) := match m
6319 case SOME((base, mrecTy, field, rhs))
6320 algorithm
6321 4 group := {(field, rhs, stmt)};
6322 writtenFields := {field};
6323 2 extended := true;
6324
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 while extended loop
6325 2 (writtenFields, group, extended) :=
6326 optMRFATryExtend(rest, base, mrecTy, writtenFields, group);
6327
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if extended then
6328 ✗ rest := listRest(rest);
6329 end if;
6330 end while;
6331 2 (outStmts, tempVars) := optMRFACommitGroup(listReverse(group), base, mrecTy, outStmts, tempVars);
6332 2 then (outStmts, rest, tempVars);
6333 76165 else
6334 (stmt :: outStmts, rest, tempVars);
6335 end match;
6336 end while;
6337 17302 outStmts := listReverse(outStmts);
6338 end optMRFAMergeList;
6339
6340 protected function optMRFACommitGroup
6341 "Emits either the original statement (group size 1) or the merged
6342 metarecord construction (group size >= 2), accumulating in reverse
6343 order onto `acc`. For a merged group also emits one STMT_ASSIGN per
6344 updated field to a fresh local temp before the box statement, and
6345 appends the temp's DAE.VAR declaration to tempVars."
6346 input list<MRFAUpdate> group;
6347 input DAE.Exp baseExp;
6348 input DAE.Type mrecTy;
6349 input list<DAE.Statement> acc;
6350 output list<DAE.Statement> outAcc;
6351 input output list<DAE.Element> tempVars;
6352 protected
6353 DAE.Statement original;
6354 list<DAE.Statement> mergedStmts;
6355 algorithm
6356 (outAcc, tempVars) := match group
6357 2 case {(_, _, original)} then (original :: acc, tempVars);
6358 else
6359 algorithm
6360 // optMRFABuildMerged returns a list of statements: first the
6361 // temp assignments in source order, then the final box. Push
6362 // them onto `acc` in order so reversing acc later yields source
6363 // order.
6364 ✗ (mergedStmts, tempVars) := optMRFABuildMerged(group, baseExp, mrecTy, tempVars);
6365 ✗ then (List.append_reverse(mergedStmts, acc), tempVars);
6366 end match;
6367 end optMRFACommitGroup;
6368
6369 protected function optMRFABuildMerged
6370 "Builds the statements that replace a merged group of N field-update
6371 statements: N STMT_ASSIGN to fresh local temps (one per updated
6372 field, in source order) followed by one STMT_ASSIGN whose rhs is a
6373 METARECORDCALL that builds the record from the temps and from RSUB
6374 reads of the unchanged fields. The temp assignments fix the
6375 evaluation order at the DAE level; the C codegen would otherwise
6376 inline the rhses directly into mmc_mk_box arguments and leave the
6377 order to the C compiler. Appends the temp DAE.VAR declarations to
6378 tempVars; the caller lifts these into the surrounding function's
6379 element list."
6380 input list<MRFAUpdate> group;
6381 input DAE.Exp baseExp;
6382 input DAE.Type mrecTy;
6383 output list<DAE.Statement> outStmts;
6384 input output list<DAE.Element> tempVars;
6385 protected
6386 Absyn.Path path;
6387 Integer index;
6388 list<DAE.Type> typeVars;
6389 list<DAE.Var> fields;
6390 list<DAE.Exp> args = {};
6391 list<String> fieldNames = {};
6392 DAE.Var fv;
6393 String fname, gname, tname;
6394 DAE.Type fty, gty;
6395 DAE.Exp grhs;
6396 Integer pos = 1;
6397 DAE.Exp arg;
6398 DAE.ElementSource src;
6399 DAE.Type baseTy;
6400 list<DAE.Statement> tempAssigns = {};
6401 list<tuple<String, DAE.Exp>> fieldRefs = {};
6402 DAE.ComponentRef tcref;
6403 DAE.Exp tref;
6404 DAE.Element tvar;
6405 algorithm
6406 ✗ (path, index, typeVars) := optMRFAMetaRecordInfo(mrecTy);
6407 ✗ fields := Types.getMetaRecordFields(mrecTy);
6408 // Reuse the element source of the first statement in the group.
6409 ✗ DAE.STMT_ASSIGN(source = src) := Util.tuple33(listHead(group));
6410 // Walk the group in source order: emit one temp assignment per
6411 // updated field, declare the temp's DAE.VAR, and remember the temp's
6412 // CREF so the METARECORDCALL builder below can refer to it.
6413 ✗ for upd in group loop
6414 ✗ (gname, grhs, _) := upd;
6415 ✗ gty := optMRFAFieldType(fields, gname);
6416 ✗ tname := "$mrfa_" + Util.tickStr();
6417 ✗ tcref := DAE.CREF_IDENT(tname, gty, {});
6418 ✗ tref := DAE.CREF(tcref, gty);
6419 ✗ tempAssigns := DAE.STMT_ASSIGN(gty, tref, grhs, src) :: tempAssigns;
6420 ✗ tvar := DAE.VAR(tcref, DAE.VARIABLE(), DAE.BIDIR(), DAE.NON_PARALLEL(),
6421 DAE.PROTECTED(), gty, NONE(), {}, DAE.NON_CONNECTOR(),
6422 src, NONE(), NONE(), Absyn.NOT_INNER_OUTER(), false);
6423 tempVars := tvar :: tempVars;
6424 ✗ fieldRefs := (gname, tref) :: fieldRefs;
6425 end for;
6426 // Build the METARECORDCALL args: temp ref for updated fields, RSUB
6427 // read of the original record for unchanged fields. Field iteration
6428 // order here is the metarecord's declaration order, which is what
6429 // the box constructor needs.
6430 ✗ for fv in fields loop
6431 ✗ DAE.TYPES_VAR(name = fname, ty = fty) := fv;
6432 arg := match optMRFALookupRef(fieldRefs, fname)
6433 case SOME(arg) then arg;
6434 ✗ else DAE.RSUB(baseExp, pos, fname, fty);
6435 end match;
6436 args := arg :: args;
6437 fieldNames := fname :: fieldNames;
6438 ✗ pos := pos + 1;
6439 end for;
6440 ✗ args := listReverse(args);
6441 ✗ fieldNames := listReverse(fieldNames);
6442 ✗ baseTy := Expression.typeof(baseExp);
6443 // tempAssigns is in reverse source order (head = last temp). Prepend
6444 // the box statement to that reverse-ordered list so a single
6445 // listReverse produces [tassign_1, ..., tassign_N, boxStmt].
6446 ✗ tempAssigns := DAE.STMT_ASSIGN(baseTy, baseExp,
6447 DAE.METARECORDCALL(path, args, fieldNames, index, typeVars),
6448 src) :: tempAssigns;
6449 ✗ outStmts := listReverse(tempAssigns);
6450 end optMRFABuildMerged;
6451
6452 protected function optMRFAFieldType
6453 "Looks up the type of `fname` among the metarecord field descriptors."
6454 input list<DAE.Var> fields;
6455 input String fname;
6456 output DAE.Type ty;
6457 protected
6458 String n;
6459 algorithm
6460 ✗ for fv in fields loop
6461 ✗ DAE.TYPES_VAR(name = n, ty = ty) := fv;
6462 ✗ if stringEq(n, fname) then return; end if;
6463 end for;
6464 // Should not happen: the merge pre-checks that the field belongs to
6465 // the metarecord. If we ever get here, fail loudly so we notice.
6466 ✗ Error.addInternalError("optMRFAFieldType: field " + fname + " not found in metarecord", sourceInfo());
6467 ✗ fail();
6468 end optMRFAFieldType;
6469
6470 protected function optMRFALookupRef
6471 "Finds the temp CREF for `fname` in the field-ref list, or NONE() if
6472 the field was not updated by the group."
6473 input list<tuple<String, DAE.Exp>> fieldRefs;
6474 input String fname;
6475 output Option<DAE.Exp> outRef;
6476 protected
6477 String n;
6478 DAE.Exp r;
6479 algorithm
6480 outRef := NONE();
6481 ✗ for fr in fieldRefs loop
6482 ✗ (n, r) := fr;
6483 ✗ if stringEq(n, fname) then
6484 outRef := SOME(r);
6485 ✗ return;
6486 end if;
6487 end for;
6488 end optMRFALookupRef;
6489
6490 protected function optMRFAMetaRecordInfo
6491 "Extracts (path, ctor_index, typeVars) needed to construct a METARECORDCALL
6492 from a T_METARECORD or singleton T_METAUNIONTYPE."
6493 input DAE.Type ty;
6494 output Absyn.Path path;
6495 output Integer index;
6496 output list<DAE.Type> typeVars;
6497 algorithm
6498 (path, index, typeVars) := match ty
6499 local
6500 DAE.Type rec;
6501 DAE.EvaluateSingletonTypeFunction fn;
6502 ✗ case DAE.T_METARECORD() then (ty.path, ty.index, ty.typeVars);
6503 case DAE.T_METAUNIONTYPE(singletonType = DAE.EVAL_SINGLETON_KNOWN_TYPE(ty = rec))
6504 ✗ then optMRFAMetaRecordPieces(rec);
6505 case DAE.T_METAUNIONTYPE(singletonType = DAE.EVAL_SINGLETON_TYPE_FUNCTION(fun = fn))
6506 ✗ then optMRFAMetaRecordPieces(fn());
6507 end match;
6508 end optMRFAMetaRecordInfo;
6509
6510 protected function optMRFAMetaRecordPieces
6511 "Destructures a T_METARECORD into (path, index, typeVars)."
6512 input DAE.Type ty;
6513 output Absyn.Path path;
6514 output Integer index;
6515 output list<DAE.Type> typeVars;
6516 algorithm
6517 ✗ DAE.T_METARECORD(path = path, index = index, typeVars = typeVars) := ty;
6518 end optMRFAMetaRecordPieces;
6519
6520 protected function optMRFAMatch
6521 "Pattern matches a STMT_ASSIGN that updates a single field of a
6522 MetaModelica uniontype/metarecord variable. Returns SOME((base, mrecTy,
6523 fieldName, rhs)) on match, NONE() otherwise. Mirrors the four STMT_ASSIGN
6524 shapes in CodegenCFunctions.tpl that emit the alloc+memcpy+set+reassign C."
6525 input DAE.Statement stmt;
6526 output Option<tuple<DAE.Exp, DAE.Type, String, DAE.Exp>> outMatch;
6527 algorithm
6528 outMatch := match stmt
6529 local
6530 DAE.Exp baseExp, rhs;
6531 DAE.Type t1, identTy;
6532 DAE.ComponentRef topCref;
6533 String fname, ident;
6534 list<DAE.Subscript> subs;
6535
6536 // RSUB-shape on T_METARECORD.
6537 case DAE.STMT_ASSIGN(exp1 = DAE.RSUB(exp = baseExp as DAE.CREF(ty = t1 as DAE.T_METARECORD()),
6538 fieldName = fname), exp = rhs)
6539 ✗ then SOME((baseExp, t1, fname, rhs));
6540
6541 // RSUB-shape on singleton T_METAUNIONTYPE.
6542 case DAE.STMT_ASSIGN(exp1 = DAE.RSUB(exp = baseExp as DAE.CREF(ty = t1 as DAE.T_METAUNIONTYPE(knownSingleton = true)),
6543 fieldName = fname), exp = rhs)
6544 guard optMRFAResolvableSingleton(t1)
6545 2 then SOME((baseExp, t1, fname, rhs));
6546
6547 // CREF_QUAL legacy shape with T_METATYPE(T_METARECORD).
6548 case DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = DAE.CREF_QUAL(ident = ident,
6549 identType = identTy as DAE.T_METATYPE(ty = t1 as DAE.T_METARECORD()),
6550 subscriptLst = subs,
6551 componentRef = DAE.CREF_IDENT(ident = fname))),
6552 exp = rhs)
6553 algorithm
6554 ✗ topCref := DAE.CREF_IDENT(ident, identTy, subs);
6555 ✗ baseExp := DAE.CREF(topCref, identTy);
6556 ✗ then SOME((baseExp, t1, fname, rhs));
6557
6558 // CREF_QUAL legacy shape with T_METATYPE(T_METAUNIONTYPE).
6559 case DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = DAE.CREF_QUAL(ident = ident,
6560 identType = identTy as DAE.T_METATYPE(ty = t1 as DAE.T_METAUNIONTYPE(knownSingleton = true)),
6561 subscriptLst = subs,
6562 componentRef = DAE.CREF_IDENT(ident = fname))),
6563 exp = rhs)
6564 guard optMRFAResolvableSingleton(t1)
6565 algorithm
6566 ✗ topCref := DAE.CREF_IDENT(ident, identTy, subs);
6567 ✗ baseExp := DAE.CREF(topCref, identTy);
6568 ✗ then SOME((baseExp, t1, fname, rhs));
6569
6570 else NONE();
6571 end match;
6572 end optMRFAMatch;
6573
6574 protected function optMRFAResolvableSingleton
6575 "Predicate: a T_METAUNIONTYPE whose singleton record type is resolvable at
6576 codegen time (either a statically known record type or a function that
6577 returns one)."
6578 input DAE.Type ty;
6579 output Boolean ok;
6580 algorithm
6581 ok := match ty
6582 case DAE.T_METAUNIONTYPE(singletonType = DAE.EVAL_SINGLETON_KNOWN_TYPE(ty = DAE.T_METARECORD())) then true;
6583 case DAE.T_METAUNIONTYPE(singletonType = DAE.EVAL_SINGLETON_TYPE_FUNCTION()) then true;
6584 else false;
6585 end match;
6586 end optMRFAResolvableSingleton;
6587
6588 protected function optMRFATryExtend
6589 "Returns true if the head of `rest` is a field-update statement on the
6590 same base cref, writing a field not yet written, and whose rhs does not
6591 observe any previously written field of that base. Side effect: when
6592 returning true, appends the new update to `group` and `writtenFields`.
6593 On false, `group` and `writtenFields` are unchanged and the caller will
6594 close the run."
6595 input list<DAE.Statement> rest;
6596 input DAE.Exp baseExp;
6597 input DAE.Type mrecTy;
6598 input output list<String> writtenFields;
6599 input output list<MRFAUpdate> group;
6600 output Boolean extended;
6601 protected
6602 DAE.Statement stmt;
6603 Option<tuple<DAE.Exp, DAE.Type, String, DAE.Exp>> m;
6604 DAE.Exp base2, rhs;
6605 DAE.Type t2;
6606 String f;
6607 algorithm
6608
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if listEmpty(rest) then
6609 extended := false;
6610 2 return;
6611 end if;
6612 ✗ stmt := listHead(rest);
6613 ✗ m := optMRFAMatch(stmt);
6614 extended := match m
6615 case SOME((base2, t2, f, rhs))
6616 ✗ then optMRFACheckExtend(base2, t2, f, rhs, baseExp, mrecTy, writtenFields);
6617 else false;
6618 end match;
6619 ✗ if extended then
6620 ✗ SOME((_, _, f, rhs)) := m;
6621 ✗ group := (f, rhs, stmt) :: group;
6622 writtenFields := f :: writtenFields;
6623 end if;
6624 end optMRFATryExtend;
6625
6626 protected function optMRFACheckExtend
6627 "Checks same-base, not-yet-written, and rhs-does-not-observe-writes."
6628 input DAE.Exp newBase;
6629 input DAE.Type newMrecTy;
6630 input String newField;
6631 input DAE.Exp newRhs;
6632 input DAE.Exp baseExp;
6633 input DAE.Type mrecTy;
6634 input list<String> writtenFields;
6635 output Boolean ok;
6636 algorithm
6637 ✗ ok := ExpressionBasics.expEqual(newBase, baseExp)
6638 and not listMember(newField, writtenFields)
6639 and optMRFARhsSafe(newRhs, baseExp, writtenFields);
6640 end optMRFACheckExtend;
6641
6642 protected function optMRFARhsSafe
6643 "Returns true if `rhs` never reads a field of `baseExp` that appears in
6644 `writtenFields`, and never reads `baseExp` wholesale. Being conservative
6645 here is fine: a false negative only skips an optimization."
6646 input DAE.Exp rhs;
6647 input DAE.Exp baseExp;
6648 input list<String> writtenFields;
6649 output Boolean safe;
6650 algorithm
6651 ✗ (_, (_, _, safe)) := Expression.traverseExpTopDown(rhs, optMRFARhsCheck, (baseExp, writtenFields, true));
6652 end optMRFARhsSafe;
6653
6654 protected function optMRFARhsCheck
6655 input DAE.Exp inExp;
6656 input tuple<DAE.Exp, list<String>, Boolean> inAcc;
6657 output DAE.Exp outExp = inExp;
6658 output Boolean cont;
6659 output tuple<DAE.Exp, list<String>, Boolean> outAcc;
6660 protected
6661 DAE.Exp baseExp, innerExp;
6662 list<String> writtenFields;
6663 Boolean safe, handled;
6664 String fname;
6665 algorithm
6666 ✗ (baseExp, writtenFields, safe) := inAcc;
6667 ✗ if not safe then
6668 cont := false;
6669 outAcc := inAcc;
6670 ✗ return;
6671 end if;
6672 handled := false;
6673 (safe, handled) := match inExp
6674 // RSUB(baseExp, _, f, _) is a field read of f. If f was written earlier
6675 // in the group, merging would change semantics. Mark unsafe and skip
6676 // descent so the wrapped CREF is not re-interpreted as a wholesale read.
6677 case DAE.RSUB(exp = innerExp, fieldName = fname)
6678 guard ExpressionBasics.expEqual(innerExp, baseExp)
6679 ✗ then (not listMember(fname, writtenFields), true);
6680 case DAE.CREF()
6681 ✗ then (optMRFACheckCrefRead(inExp, baseExp, writtenFields), false);
6682 else (safe, false);
6683 end match;
6684 ✗ cont := safe and not handled;
6685 ✗ outAcc := (baseExp, writtenFields, safe);
6686 end optMRFARhsCheck;
6687
6688 protected function optMRFACheckCrefRead
6689 "For a CREF expression encountered in an rhs, returns true if it is safe
6690 (does not alias a recently-written field of baseExp)."
6691 input DAE.Exp crefExp;
6692 input DAE.Exp baseExp;
6693 input list<String> writtenFields;
6694 output Boolean safe;
6695 protected
6696 DAE.ComponentRef cref, baseCref;
6697 String baseIdent, headIdent, fname;
6698 algorithm
6699 ✗ DAE.CREF(componentRef = cref) := crefExp;
6700 ✗ DAE.CREF(componentRef = baseCref) := baseExp;
6701 safe := match (cref, baseCref)
6702 // Wholesale c -- always disqualify if any field already written.
6703 case (DAE.CREF_IDENT(ident = headIdent), DAE.CREF_IDENT(ident = baseIdent))
6704 ✗ then not (stringEq(headIdent, baseIdent) and not listEmpty(writtenFields));
6705 // c.f -- safe iff f not written yet.
6706 case (DAE.CREF_QUAL(ident = headIdent, componentRef = DAE.CREF_IDENT(ident = fname)),
6707 DAE.CREF_IDENT(ident = baseIdent))
6708 ✗ then not (stringEq(headIdent, baseIdent) and listMember(fname, writtenFields));
6709 // Deeper nesting or other shape -- be conservative, disallow if the
6710 // heads match and there are any prior writes.
6711 case (DAE.CREF_QUAL(ident = headIdent), DAE.CREF_IDENT(ident = baseIdent))
6712 ✗ then not (stringEq(headIdent, baseIdent) and not listEmpty(writtenFields));
6713 else true;
6714 end match;
6715 end optMRFACheckCrefRead;
6716 annotation(__OpenModelica_Interface="frontend_base");
6717 end DAEUtil;
6718