Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 77.9% 720 / 0 / 924
Functions: -% 0 / 1 / 1
Branches: 60.3% 420 / 0 / 696

OMCompiler/Compiler/BackEnd/EvaluateFunctions.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 EvaluateFunctions
37 " file: EvaluateFunctions.mo
38 package: EvaluateFunctions
39 description: This package contains functions to evaluate modelica functions completely or partially"
40
41 public import Absyn;
42 public import BackendDAE;
43 public import DAE;
44 public import BackendVarTransform;
45 public import HashSetExp;
46
47 protected import AbsynUtil;
48 protected import BackendDAEUtil;
49 protected import BackendDump;
50 protected import BackendEquation;
51 protected import BackendVariable;
52 protected import ClassInf;
53 protected import ComponentReference;
54 protected import ComponentReferenceBasics;
55 protected import DAEUtil;
56 protected import AvlTreePathFunction;
57 protected import DAEDump;
58 protected import Expression;
59 protected import ExpressionBasics;
60 protected import ExpressionDump;
61 protected import ExpressionSimplify;
62 protected import Flags;
63 protected import List;
64 protected import RemoveSimpleEquations;
65 protected import Types;
66 protected import Util;
67
68
69 // =============================================================================
70 // TODO:
71 // - evaluation of for-loops
72 // - evaluation of while-loops
73 // - evaluation of xOut := funcCall1(funcCall2(xIn[1])); with funcCall2(xIn[1]) = xIn[1,2] for example have a look at Media.Examples.ReferenceAir.MoistAir
74 // - evaluation of BackendDAE.ARRAY_EQUATION
75 // =============================================================================
76
77 // =============================================================================
78 // type definitions
79 //
80 // =============================================================================
81
82 public uniontype FuncInfo "store informations when traversing the statements and evaluate the function calls"
83 record FUNCINFO
84 BackendVarTransform.VariableReplacements repl;
85 AvlTreePathFunction.Tree funcTree;
86 Integer idx;
87 end FUNCINFO;
88 end FuncInfo;
89
90 public uniontype Variability
91 record CONST end CONST;
92 record VARIABLE end VARIABLE;
93 end Variability;
94
95 public uniontype CallSignature
96 record SIGNATURE
97 Absyn.Path path;
98 list<Variability> inputsVari;//not scalar, take records, arrays, calls as a single input variability
99 Boolean canBeEvaluated;
100 end SIGNATURE;
101 end CallSignature;
102
103 // =============================================================================
104 // caching of already evaluated functions
105 //
106 // =============================================================================
107
108 protected function checkCallSignatureForExp
109 input DAE.Exp expIn;
110 input list<CallSignature> signLst;
111 output Boolean continueEval;
112 protected
113 CallSignature signature;
114 algorithm
115 continueEval := true;
116 30572 signature := getCallSignatureForCall(expIn);
117
2/2
✓ Branch 1 taken 26302 times.
✓ Branch 2 taken 4270 times.
30572 if List.isMemberOnTrue(signature,signLst,callSignatureIsEqual) then
118 4270 SIGNATURE(canBeEvaluated = continueEval) := List.getMemberOnTrue(signature,signLst,callSignatureIsEqual);
119 end if;
120 end checkCallSignatureForExp;
121
122 protected function callSignatureStr "outputs a string representation for the CallSignature"
123 input CallSignature signat;
124 output String str;
125 protected
126 Absyn.Path path;
127 list<Variability> varis;
128 Boolean b;
129 algorithm
130 ✗ SIGNATURE(path=path,inputsVari=varis, canBeEvaluated=b) := signat;
131 ✗ str := AbsynUtil.pathString(path)+"[ "+stringDelimitList(List.map(varis,VariabilityString)," | ")+" ] "+boolString(b);
132 end callSignatureStr;
133
134 protected function VariabilityString "outputs a string representation for the Variability"
135 input Variability var;
136 output String str;
137 algorithm
138 str := match var
139 case CONST()
140 then "CONST";
141 else "VARIABLE";
142 end match;
143 end VariabilityString;
144
145 protected function callSignatureIsEqual"outputs true if 2 CallSignatures are equal"
146 input CallSignature signat1;
147 input CallSignature signat2;
148 output Boolean isEqual;
149 protected
150 Absyn.Path path1,path2;
151 list<Variability> vari1,vari2;
152 algorithm
153 70134 SIGNATURE(path=path1, inputsVari=vari1) := signat1;
154 70134 SIGNATURE(path=path2, inputsVari=vari2) := signat2;
155 isEqual := false;
156
2/2
✓ Branch 1 taken 56320 times.
✓ Branch 2 taken 13814 times.
70134 if AbsynUtil.pathEqual(path1,path2) then
157
2/2
✓ Branch 1 taken 1402 times.
✓ Branch 2 taken 12412 times.
13814 if List.isEqualOnTrue(vari1,vari2,VariabilityIsEqual) then
158 isEqual := true;
159 end if;
160 end if;
161 end callSignatureIsEqual;
162
163 protected function VariabilityIsEqual"outputs true if 2 Variabilites are equal"
164 input Variability vari1;
165 input Variability vari2;
166 output Boolean isEqual;
167 algorithm
168 isEqual := match(vari1,vari2)
169 case(CONST(),CONST())
170 then true;
171 case(VARIABLE(),VARIABLE())
172 then true;
173 else
174 then false;
175 end match;
176 end VariabilityIsEqual;
177
178 protected function getCallSignatureForCall"determines the callSignature for a function call expression"
179 input DAE.Exp callExpIn;
180 output CallSignature signatureOut;
181 protected
182 Absyn.Path path;
183 list<DAE.Exp> expLst;
184 list<Variability> vari;
185 algorithm
186 try
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60423 times.
60423 DAE.CALL(path=path, expLst=expLst) := callExpIn;
188 60423 vari := List.map(expLst,getVariabilityForExp);
189 60423 signatureOut := SIGNATURE(path,vari,true);
190 else
191 ✗ print("evalFunc.getCallSignatureForCall failed for :\n"+ExpressionBasics.printExpStr(callExpIn)+"\n");
192 ✗ fail();
193 end try;
194 end getCallSignatureForCall;
195
196 protected function getVariabilityForExp"determines if the exp is either constant or variable"
197 input DAE.Exp expIn;
198 output Variability variOut;
199 algorithm
200 variOut := match expIn
201 local
202 Variability vari;
203 case DAE.ICONST()
204 then CONST();
205 case DAE.RCONST()
206 then CONST();
207 case DAE.SCONST()
208 then CONST();
209 case DAE.BCONST()
210 then CONST();
211 case DAE.CLKCONST()
212 then CONST();
213 case DAE.ENUM_LITERAL()
214 then CONST();
215 case DAE.CREF()
216 then VARIABLE();
217 case DAE.BINARY()
218 algorithm
219
2/2
✓ Branch 1 taken 9889 times.
✓ Branch 2 taken 214 times.
10103 if Expression.isConst(expIn) then
220 vari := CONST();
221 else
222 vari:=VARIABLE(); end if;
223 then vari;
224 case DAE.UNARY()
225 algorithm
226
1/2
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
208 if Expression.isConst(expIn) then vari := CONST();
227 else vari:=VARIABLE(); end if;
228 then vari;
229 case DAE.LBINARY()
230 algorithm
231 ✗ if Expression.isConst(expIn) then vari := CONST();
232 else vari:=VARIABLE(); end if;
233 then vari;
234 case DAE.LUNARY()
235 algorithm
236 ✗ if Expression.isConst(expIn) then vari := CONST();
237 else vari:=VARIABLE(); end if;
238 then vari;
239 case DAE.RELATION()
240 then VARIABLE();
241 case DAE.IFEXP()
242 then VARIABLE();
243 case DAE.CALL()
244 then VARIABLE();
245 case DAE.RECORD()
246 algorithm
247
2/2
✓ Branch 1 taken 3723 times.
✓ Branch 2 taken 2572 times.
6295 if Expression.isConst(expIn) then vari := CONST();
248 else vari:=VARIABLE(); end if;
249 then vari;
250 case DAE.PARTEVALFUNCTION()
251 then VARIABLE();
252 case DAE.ARRAY()
253 algorithm
254
2/2
✓ Branch 1 taken 1105 times.
✓ Branch 2 taken 716 times.
1821 if Expression.isConst(expIn) then vari := CONST();
255 else vari:=VARIABLE(); end if;
256 then vari;
257 case DAE.MATRIX()
258 algorithm
259
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 if Expression.isConst(expIn) then vari := CONST();
260 else vari:=VARIABLE(); end if;
261 then vari;
262 case DAE.RANGE()
263 algorithm
264
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if Expression.isConst(expIn) then vari := CONST();
265 else vari:=VARIABLE(); end if;
266 then vari;
267 case DAE.TUPLE()
268 algorithm
269 ✗ if Expression.isConst(expIn) then vari := CONST();
270 else vari:=VARIABLE(); end if;
271 then vari;
272 case DAE.CAST()
273 algorithm
274 ✗ if Expression.isConst(expIn) then vari := CONST();
275 else vari:=VARIABLE(); end if;
276 then vari;
277 case DAE.ASUB()
278 algorithm
279 ✗ if Expression.isConst(expIn) then vari := CONST();
280 else vari:=VARIABLE(); end if;
281 then vari;
282 case DAE.TSUB()
283 algorithm
284 ✗ if Expression.isConst(expIn) then vari := CONST();
285 else vari:=VARIABLE(); end if;
286 then vari;
287 case DAE.RSUB()
288 algorithm
289
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if Expression.isConst(expIn) then vari := CONST();
290 else vari:=VARIABLE(); end if;
291 then vari;
292 case DAE.SIZE()
293 then VARIABLE();
294 case DAE.CODE()
295 then VARIABLE();
296 case DAE.EMPTY()
297 then VARIABLE();
298 case DAE.REDUCTION()
299 then VARIABLE();
300 else
301 VARIABLE();
302 end match;
303 end getVariabilityForExp;
304
305 // =============================================================================
306 // evaluate functions
307 //
308 // =============================================================================
309
310 public function evalFunctions "backend optmization module to evaluate functions completely or partially.
311 partial constant outputs are added as extra equations. Therefore removeSimpleEquations is necessary afterwards
312 author:Waurich TUD 2014-04"
313 input BackendDAE.BackendDAE inDAE;
314 output BackendDAE.BackendDAE outDAE;
315 protected
316 Boolean changed;
317 BackendDAE.EqSystems eqSysts;
318 BackendDAE.Shared shared;
319 algorithm
320 try
321 2829 BackendDAE.DAE(eqs=eqSysts, shared=shared) := inDAE;
322 2829 (eqSysts, (shared, _, changed, _)) := List.mapFold(eqSysts, evalFunctions_main, (shared, 1, false, {}));
323
324
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 2773 times.
2829 if changed then
325 56 outDAE := updateVarKinds(RemoveSimpleEquations.fastAcausal(BackendDAE.DAE(eqSysts, shared)));
326 else
327 outDAE := inDAE;
328 end if;
329 else
330 outDAE := inDAE;
331 end try;
332 end evalFunctions;
333
334 protected function evalFunctions_main "traverses the eqSystems for function calls and tries to evaluate them"
335 input BackendDAE.EqSystem eqSysIn;
336 input tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplIn;
337 output BackendDAE.EqSystem eqSysOut;
338 output tuple<BackendDAE.Shared,Integer,Boolean, list<CallSignature>> tplOut;
339 protected
340 Boolean changed;
341 Integer sysIdx;
342 BackendDAE.Shared sharedIn, shared;
343 BackendDAE.EquationArray eqs;
344 list<BackendDAE.Equation> eqLst, addEqs;
345 list<CallSignature> callSign;
346 Integer recursion_limit;
347 algorithm
348 3336 (sharedIn,sysIdx,changed,callSign) := tplIn;
349 3336 BackendDAE.EQSYSTEM(orderedEqs=eqs) := eqSysIn;
350 3336 eqLst := BackendEquation.equationList(eqs);
351
352 //traverse the eqSystem for function calls
353 3336 recursion_limit := Flags.getConfigInt(Flags.EVAL_RECURSION_LIMIT);
354
2/2
✓ Branch 1 taken 3323 times.
✓ Branch 2 taken 13 times.
6659 (eqLst, shared, addEqs, _, changed, callSign) := List.mapFold5(eqLst, function evalFunctions_findFuncs(recursionLimit = recursion_limit), sharedIn, {}, 1, changed, callSign);
355 3336 eqs := BackendEquation.listEquation(listAppend(eqLst, addEqs));
356 3336 eqSysOut := BackendDAEUtil.setEqSystEqs(eqSysIn, eqs);
357
358
2/2
✓ Branch 0 taken 3267 times.
✓ Branch 1 taken 69 times.
6603 tplOut := (shared, sysIdx+1, changed, callSign);
359 end evalFunctions_main;
360
361 protected function evalFunctions_findFuncs "traverses the lhs and rhs exps of an equation and tries to evaluate function calls "
362 input output BackendDAE.Equation eqIn;
363 input output BackendDAE.Shared shared;
364 input output list<BackendDAE.Equation> addEqs;
365 input output Integer idx;
366 input output Boolean changed;
367 input output list<CallSignature> callSign;
368 input Integer recursionLimit;
369 algorithm
370 eqIn := matchcontinue eqIn
371 local
372 Boolean b1,b2, changed1;
373 BackendDAE.Equation eq;
374 BackendDAE.EquationAttributes attr;
375 DAE.Exp exp1,exp2,lhsExp = DAE.ICONST(0),rhsExp = DAE.ICONST(0);
376 DAE.ElementSource source;
377 AvlTreePathFunction.Tree funcs;
378 list<BackendDAE.Equation> addEqs1, addEqs2;
379 case BackendDAE.EQUATION(exp=exp1, scalar=exp2,source=source,attr=attr)
380 algorithm
381 63762 b1 := Expression.containFunctioncall(exp1);
382 63762 b2 := Expression.containFunctioncall(exp2);
383
2/2
✓ Branch 0 taken 50755 times.
✓ Branch 1 taken 13007 times.
63762 true := b1 or b2;
384 13007 funcs := BackendDAEUtil.getFunctions(shared);
385
386
2/2
✓ Branch 0 taken 437 times.
✓ Branch 1 taken 12570 times.
13007 if b1 then
387 437 (rhsExp, lhsExp, addEqs1, funcs, idx, changed1, callSign) :=
388 evaluateConstantFunction(exp1, exp2, funcs, idx, callSign, recursionLimit);
389
3/4
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 243 times.
✓ Branch 2 taken 194 times.
✗ Branch 3 not taken.
437 changed := changed or changed1;
390 437 addEqs := listAppend(addEqs1, addEqs);
391 end if;
392
393
2/2
✓ Branch 0 taken 12610 times.
✓ Branch 1 taken 397 times.
13007 if b2 then
394 12610 (rhsExp, lhsExp, addEqs2, funcs, idx, changed1, callSign) :=
395 evaluateConstantFunction(exp2, exp1, funcs, idx, callSign, recursionLimit);
396
4/4
✓ Branch 0 taken 9874 times.
✓ Branch 1 taken 2736 times.
✓ Branch 2 taken 9827 times.
✓ Branch 3 taken 47 times.
12610 changed := changed or changed1;
397 12610 addEqs := listAppend(addEqs2, addEqs);
398 end if;
399
400 13007 eq := BackendEquation.generateEquation(lhsExp,rhsExp,source,attr);
401 //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if;
402 13007 idx := idx+1;
403 then
404 eq;
405 case BackendDAE.ARRAY_EQUATION()
406 algorithm
407
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 246 times.
246 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
408 ✗ print("this is an array equation. update evalFunctions_findFuncs\n");
409 end if;
410 246 then
411 eqIn;
412 case BackendDAE.COMPLEX_EQUATION(left=exp1, right=exp2, source=source, attr=attr)
413 algorithm
414 554 b1 := Expression.containFunctioncall(exp1);
415 554 b2 := Expression.containFunctioncall(exp2);
416
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 552 times.
554 true := b1 or b2;
417 552 funcs := BackendDAEUtil.getFunctions(shared);
418
419
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 542 times.
552 if b1 then
420 10 (rhsExp, lhsExp, addEqs1, funcs, idx, changed1, callSign) :=
421 evaluateConstantFunction(exp1, exp2, funcs, idx, callSign, recursionLimit);
422
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 changed := changed or changed1;
423 10 addEqs := listAppend(addEqs1, addEqs);
424 end if;
425
426
1/2
✓ Branch 0 taken 552 times.
✗ Branch 1 not taken.
552 if b2 then
427 552 (rhsExp, lhsExp, addEqs1, funcs, idx, changed1, callSign) :=
428 evaluateConstantFunction(exp2, exp1, funcs, idx, callSign, recursionLimit);
429
4/4
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 295 times.
✓ Branch 2 taken 248 times.
✓ Branch 3 taken 9 times.
552 changed := changed or changed1;
430 552 addEqs := listAppend(addEqs1, addEqs);
431 end if;
432
433 552 shared := BackendDAEUtil.setSharedFunctionTree(shared, funcs);
434 552 eq := BackendEquation.generateEquation(lhsExp,rhsExp,source,attr);
435 //since tuple=tuple is not supported, these equations are converted into a list of simple equations
436 552 (eq,addEqs) := convertTupleEquations(eq,addEqs);
437 //if changed then print("FROM EQ "+BackendDump.equationString(eqIn)+"\n");print("GOT EQ "+BackendDump.equationString(eq)+"\n"); end if;
438 552 idx := idx+1;
439 then
440 eq;
441
442 51547 else eqIn;
443 end matchcontinue;
444 end evalFunctions_findFuncs;
445
446 public function evaluateConstantFunctionCallExp"checks if the expression is a call and can be evaluated to a constant value.
447 the output is either a constant expression or the input exp. no partial evaluation is performed in here."
448 input DAE.Exp expIn;
449 input AvlTreePathFunction.Tree funcsIn;
450 input Boolean evalConstArgsOnly;
451 input Integer recursionLimit;
452 output DAE.Exp expOut;
453 algorithm
454 expOut := matchcontinue expIn
455 local
456 Absyn.Path path;
457 BackendVarTransform.VariableReplacements repl;
458 DAE.CallAttributes attr1;
459 DAE.Exp exp;
460 DAE.Function func;
461 list<DAE.ComponentRef> allInputCrefs, outputCrefs, allOutputCrefs, constInputCrefs, constCrefs, constComplexCrefs,varScalarCrefs,constScalarCrefs;
462 list<list<DAE.ComponentRef>> scalarInputs, scalarOutputs;
463 list<DAE.Element> elements, protectVars, algs, allInputs, allOutputs;
464 list<DAE.Exp> exps, exps0, allInputExps, constInputExps, constExps, constComplexExps, constScalarExps;
465 list<DAE.Subscript> sub;
466 list<list<DAE.Exp>> scalarExp;
467
468 case DAE.CALL(path=path, expLst=exps0)
469 algorithm
470
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1986 times.
1988 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
471 2 print("\nStart constant evaluation of expression: "+ExpressionBasics.printExpStr(expIn)+"\n\n");
472 end if;
473
474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1988 times.
1988 if evalConstArgsOnly then
475 ✗ true := Expression.isConstWorkList(exps0);
476 end if;
477
478 // get the elements of the function and the algorithms
479
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1752 times.
1988 SOME(func) := AvlTreePathFunction.get(funcsIn,path);
480 // fail if is an external function!
481
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 1716 times.
1752 false := DAEUtil.isExtFunction(func);
482 1716 elements := DAEUtil.getFunctionElements(func);
483
484 // get the input exps from the call
485
4/4
✓ Branch 0 taken 3607 times.
✓ Branch 1 taken 1716 times.
✓ Branch 2 taken 3607 times.
✓ Branch 3 taken 1716 times.
5323 exps := list(evaluateConstantFunctionCallExp(e, funcsIn, evalConstArgsOnly, recursionLimit) for e in exps0);
486 1716 scalarExp := List.map1(exps, expandComplexExpressions, funcsIn);
487 1716 allInputExps := List.flatten(scalarExp);
488 //print("allInputExps\n"+stringDelimitList(List.map(allInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
489
490
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1716 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1716 if listEmpty(elements) and DAEUtil.funcIsRecord(func) then // its a record
491 //-----------------------its a record-----------------------
492 ✗ expOut := DAE.TUPLE(allInputExps);
493 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("\nIts a record.\n");
494 end if;
495 else
496 //-----------------------its a function call-----------------------
497
498 // get all input crefs (from function body) (scalar and one dimensioanl)
499 1716 allInputs := List.filterOnTrue(elements,DAEUtil.isInputVar);
500 1716 scalarInputs := List.map(allInputs,expandComplexElementsToCrefs);
501 1716 allInputCrefs := List.flatten(scalarInputs);
502 //print("\nallInputCrefs\n"+stringDelimitList(List.map(allInputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
503
504 1716 protectVars := List.filterOnTrue(elements,DAEUtil.isProtectedVar);
505 1716 algs := List.filterOnTrue(elements,DAEUtil.isAlgorithm);
506 1716 algs := listAppend(protectVars,algs);
507
508 // get all output crefs (complex and scalar)
509 1716 allOutputs := List.filterOnTrue(elements,DAEUtil.isOutputVar);
510 1716 outputCrefs := List.map(allOutputs,DAEUtil.varCref);
511 1716 scalarOutputs := List.map(allOutputs,getScalarsForComplexVar);
512 1716 allOutputCrefs := listAppend(outputCrefs,List.flatten(scalarOutputs));
513 //print("\n allOutputs\n"+stringDelimitList(List.map(outputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
514 //print("\nscalarOutputs\n"+stringDelimitList(List.map(List.flatten(scalarOutputs),ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
515
516 // get the constant inputs
517 //print("\nallInputExps\n"+stringDelimitList(List.map(allInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
518 //print("\nall algs "+intString(listLength(algs))+"\n"+DAEDump.dumpElementsStr(algs)+"\n");
519 1716 (constInputExps,constInputCrefs) := List.filterOnTrueSync(allInputExps,Expression.isConst,allInputCrefs);
520 //print("\nconstInputExps\n"+stringDelimitList(List.map(constInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
521 //print("\nconstInputCrefs\n"+stringDelimitList(List.map(constInputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
522 //print("\nall algs "+intString(listLength(algs))+"\n"+DAEDump.dumpElementsStr(algs)+"\n");
523
524 //build replacement rules
525 1626 repl := BackendVarTransform.emptyReplacements();
526 1626 repl := BackendVarTransform.addReplacements(repl,constInputCrefs,constInputExps,NONE());
527 //repl = BackendVarTransform.addReplacements(repl,allInputCrefs,allInputExps,NONE());
528 //BackendVarTransform.dumpReplacements(repl);
529
530 // go through all algorithms and replace the variables with constants if possible, extend the ht after each algorithm, consider bindings of protected vars as well
531 1626 (algs,_,repl,_) := List.mapFold3(algs,function evaluateFunctions_updateAlgElements(recursionLimit = recursionLimit),funcsIn,repl,1);
532 //print("\nall algs after"+intString(listLength(algs))+"\n"+DAEDump.dumpElementsStr(algs)+"\n");
533 //BackendVarTransform.dumpReplacements(repl);
534
535 //get all replacements in order to check for constant outputs
536 1626 (constCrefs,constExps) := BackendVarTransform.getAllReplacements(repl);
537 1626 (constCrefs,constExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,allOutputCrefs,constExps); // extract outputs
538 1626 (constExps,constCrefs) := List.filterOnTrueSync(constExps,Expression.isConst,constCrefs); // extract constant outputs
539
540 //print("all constant crefs \n"+stringDelimitList(List.map(constCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
541 //print("all constant exps:\n"+ExpressionDump.printExpListStr(constExps)+"\n");
542
543 // get the completely constant complex outputs, the constant parts of complex outputs and the variable parts of complex outputs and the expressions
544 1626 (constComplexCrefs,_,constScalarCrefs,varScalarCrefs) := checkIfOutputIsEvaluatedConstant(allOutputs,constCrefs,{},{},{},{});
545 1626 constScalarExps := List.map1r(constScalarCrefs,BackendVarTransform.getReplacement,repl);
546 1626 constComplexExps := List.map1r(constComplexCrefs,BackendVarTransform.getReplacement,repl);
547 1626 (constScalarCrefs,constScalarExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,constScalarCrefs,constExps);
548 1626 (constComplexCrefs,constComplexExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,constComplexCrefs,constExps);
549
550 //print("constComplexCrefs\n"+stringDelimitList(List.map(constComplexCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
551 //print("varComplexCrefs\n"+stringDelimitList(List.map(varComplexCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
552 //print("constScalarCrefs\n"+stringDelimitList(List.map(constScalarCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
553 //print("varScalarCrefs\n"+stringDelimitList(List.map(varScalarCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
554
555
5/6
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1110 times.
✓ Branch 2 taken 269 times.
✓ Branch 3 taken 247 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 269 times.
1626 if listEmpty(varScalarCrefs) and listEmpty(varScalarCrefs) and listEmpty(constComplexCrefs) and not listEmpty(constScalarExps) then
556 // there is a constant scalar expression
557 ✗ if listLength(constScalarCrefs)==1 then expOut := listHead(constScalarExps);
558 ✗ else expOut := DAE.TUPLE(constScalarExps); end if;
559 elseif listEmpty(varScalarCrefs) and listEmpty(varScalarCrefs) and listEmpty(constScalarCrefs) and not listEmpty(constComplexExps) then
560 // there is a constant complex expression
561
1/2
✓ Branch 1 taken 247 times.
✗ Branch 2 not taken.
247 if listLength(constComplexCrefs)==1 then expOut := listHead(constComplexExps);
562 ✗ else expOut := DAE.TUPLE(constComplexExps); end if;
563 else expOut := expIn;
564 end if;
565 end if;
566
567
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1624 times.
1626 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
568 2 print("\nevaluated to: "+ExpressionBasics.printExpStr(expOut)+"\n\n");
569 end if;
570
571 then expOut;
572
573 case DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub)
574 algorithm
575 //this ASUB stuff occurs in the flattened DAE, check this special case because of removeSimpleEquations
576 ✗ exp := evaluateConstantFunctionCallExp(DAE.CALL(path=path, expLst=exps, attr=attr1), funcsIn, evalConstArgsOnly, recursionLimit);
577 ✗ (exp,_) := ExpressionSimplify.simplify(DAE.ASUB(exp,sub));
578 ✗ if not Expression.isConst(exp) then exp := expIn; end if;
579 then exp;
580
581 else
582 // could not evaluate it
583 algorithm
584 then expIn;
585 end matchcontinue;
586 end evaluateConstantFunctionCallExp;
587
588 protected function hasUnknownType" true if one of the crefs in the exp is of unknown type.
589 author: vwaurich 2016-11"
590 input DAE.Exp eIn;
591 output Boolean bOut;
592 algorithm
593 bOut := match eIn
594 local
595 DAE.Type ty;
596 list<DAE.Exp> eLst;
597 case DAE.TUPLE(PR = eLst)
598 algorithm
599 2199 then List.any(eLst,hasUnknownType);
600 case DAE.CREF(ty=DAE.T_UNKNOWN())
601 then true;
602 else
603 then false;
604 end match;
605 end hasUnknownType;
606
607 protected function hasMultipleArrayDimensions
608 "outputs true if the expression type is an array with multiple dimensions."
609 input DAE.Exp eIn;
610 output Boolean bOut;
611 algorithm
612 bOut := match eIn
613 local
614 Boolean b;
615 DAE.Type ty;
616 list<DAE.Exp> eLst;
617 case DAE.TUPLE(PR = eLst)
618 algorithm
619 2199 then List.any(eLst,hasMultipleArrayDimensions);
620 case DAE.CREF(ty=ty)
621 algorithm
622
2/2
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 32544 times.
32621 if Types.isArray(ty) then
623 77 b := intNe(1, listLength(Types.getDimensionSizes(ty)));
624 else
625 b := false;
626 end if;
627 then b;
628 else
629 then false;
630 end match;
631 end hasMultipleArrayDimensions;
632
633 protected function doNotInline
634 "outputs true if the function should not be inlined."
635 input DAE.Function func;
636 output Boolean dontInline;
637 algorithm
638 dontInline := match func
639 case DAE.FUNCTION(inlineType=DAE.NO_INLINE())
640 then true;
641 else
642 then false;
643 end match;
644 end doNotInline;
645
646
647 public function evaluateConstantFunction "Analyses if the rhsExp is a function call. the constant inputs are inserted and it will be checked if the outputs can be evaluated to a constant.
648 If the function can be completely evaluated, the function call will be removed.
649 If its partially constant, the constant assignments are added as additional equations and the former function will be replaced with an updated new one.
650 author: Waurich TUD 2014-04"
651 input DAE.Exp rhsExpIn;
652 input DAE.Exp lhsExpIn;
653 input AvlTreePathFunction.Tree funcsIn;
654 input Integer eqIdx;
655 input list<CallSignature> callSignLstIn;
656 input Integer recursionLimit;
657 output DAE.Exp rhsExpOut;
658 output DAE.Exp lhsExpOut;
659 output list<BackendDAE.Equation> addedEquations;
660 output AvlTreePathFunction.Tree funcsOut;
661 output Integer eqIdxOut;
662 output Boolean changed;
663 output list<CallSignature> callSignLstOut;
664 protected
665 Boolean funcIsConst, funcIsPartConst, isConstRec, hasAssert, hasReturn, hasTerminate, hasReinit, abort, isUnknownType, isNDimArray;
666 Integer idx;
667 Absyn.Path path;
668 BackendVarTransform.VariableReplacements repl;
669 DAE.CallAttributes attr1, attr2;
670 DAE.Exp exp, outputExp;
671 DAE.Function func;
672 AvlTreePathFunction.Tree funcs;
673 DAE.Type ty, singleOutputType;
674 list<BackendDAE.Equation> constEqs;
675 list<DAE.ComponentRef> outputCrefs, allInputCrefs, allOutputCrefs, constInputCrefs, constCrefs, varScalarCrefsInFunc, constScalarCrefsInFunc, constScalarCrefsLhs,constComplexCrefs,varComplexCrefs,varScalarCrefs,constScalarCrefs;
676 list<DAE.Statement> copyOutStmts;
677 list<DAE.Element> elements, algs, allInputs, protectVars, allOutputs, updatedVarOutputs, newOutputVars;
678 list<DAE.Exp> exps, expsIn, allInputExps, constInputExps, constExps, constComplexExps, constScalarExps, lhsExps;
679 list<DAE.Subscript> sub;
680 list<list<DAE.Exp>> scalarExp;
681 list<DAE.Type> outputVarTypes;
682 list<String> outputVarNames;
683 list<list<DAE.ComponentRef>> scalarInputs, scalarOutputs;
684 CallSignature signature;
685 list<CallSignature> callSignLst;
686 Boolean continueEval;
687 algorithm
688 // The recursion limit decreases when calling functions recursively.
689 // Fail when it reaches 0 to try and avoid stack overflows due to infinite recursion.
690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38024 times.
38024 true := recursionLimit > 0;
691
692 (rhsExpOut, lhsExpOut, addedEquations, funcsOut, eqIdxOut, changed, callSignLstOut) :=
693 matchcontinue(rhsExpIn, callSignLstIn)
694 case(DAE.CALL(path=path, expLst=expsIn, attr=attr1), callSignLst)
695 algorithm
696
697
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 29844 times.
29845 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
698 1 print("\nStart function evaluation of:\n"+ExpressionBasics.printExpStr(lhsExpIn)+" := "+ExpressionBasics.printExpStr(rhsExpIn)+"\n\n");
699 end if;
700
701 //------------------------------------------------
702 //Check if this particular call signature has been analysed before
703 //------------------------------------------------
704 //print(stringDelimitList(List.map(callSignLst,callSignatureStr),"\n"));
705 29845 continueEval := checkCallSignatureForExp(rhsExpIn,callSignLst);
706 29845 isUnknownType := hasUnknownType(lhsExpIn);
707 29845 isNDimArray := hasMultipleArrayDimensions(lhsExpIn);
708
709
3/4
✓ Branch 0 taken 3872 times.
✓ Branch 1 taken 25973 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3872 times.
29845 if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if;
710
4/4
✓ Branch 0 taken 25966 times.
✓ Branch 1 taken 3879 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 25965 times.
42965 if not continueEval or isUnknownType or isNDimArray then fail(); end if;
711
712 //------------------------------------------------
713 //Collect all I/O Information for the function call
714 //------------------------------------------------
715
716 // get the elements of the function and the algorithms
717
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 19554 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19554 times.
25965 SOME(func) := AvlTreePathFunction.get(funcsIn,path);
718
719
2/2
✓ Branch 1 taken 824 times.
✓ Branch 2 taken 18730 times.
19554 false := doNotInline(func);
720
721 18730 elements := DAEUtil.getFunctionElements(func);
722 18730 protectVars := List.filterOnTrue(elements,DAEUtil.isProtectedVar);
723 18730 algs := List.filterOnTrue(elements,DAEUtil.isAlgorithm);
724 //algs = listAppend(protectVars,algs);
725 //print("elements: "+DAEDump.dumpElementsStr(elements)+"\n");
726
727 // some exceptions
728
3/4
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 18729 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
18730 if Flags.isSet(Flags.EVAL_FUNC_DUMP) and listEmpty(elements) then
729 ✗ print("Its a Record!\n");
730 ✗ false:=true;
731 elseif Flags.isSet(Flags.EVAL_FUNC_DUMP) and (listEmpty(protectVars) and listEmpty(algs)) then
732 ✗ print("Its a Built-In!\n");
733 ✗ false:=true;
734 end if;
735
736
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18718 times.
18730 false := listEmpty(elements); // its a record
737
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 18706 times.
18718 false := listEmpty(algs); // its a built in function
738
739 // get the input exps from the call
740
4/4
✓ Branch 0 taken 42620 times.
✓ Branch 1 taken 18706 times.
✓ Branch 2 taken 42620 times.
✓ Branch 3 taken 18706 times.
61326 exps := list(evaluateConstantFunctionCallExp(e, funcsIn, false, recursionLimit-1) for e in expsIn);
741 18706 scalarExp := List.map1(exps,expandComplexExpressions,funcsIn);//these exps are evaluated as well
742 18706 allInputExps := List.flatten(scalarExp);
743 //print("allInputExps\n"+stringDelimitList(List.map(allInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
744
745 // get all input crefs (from function body) (scalar and one dimensioanl)
746 18706 allInputs := List.filterOnTrue(elements,DAEUtil.isInputVar);
747 18706 scalarInputs := List.map(allInputs,expandComplexElementsToCrefs);
748 18706 allInputCrefs := List.flatten(scalarInputs);
749 //print("\nallInputCrefs\n"+stringDelimitList(List.map(allInputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
750
751 // get all output crefs (complex and scalar)
752 18706 allOutputs := List.filterOnTrue(elements,DAEUtil.isOutputVar);
753 18706 outputCrefs := List.map(allOutputs,DAEUtil.varCref);
754 18706 scalarOutputs := List.map(allOutputs,getScalarsForComplexVar);
755 18706 allOutputCrefs := listAppend(outputCrefs,List.flatten(scalarOutputs));
756 //print("\ncomplex OutputCrefs\n"+stringDelimitList(List.map(outputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
757 //print("\nscalarOutputs\n"+stringDelimitList(List.map(List.flatten(scalarOutputs),ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
758
759 // get the constant inputs
760 18706 (constInputExps,constInputCrefs) := List.filterOnTrueSync(allInputExps,Expression.isConst,allInputCrefs);
761 //print("\nallInputExps\n"+stringDelimitList(List.map(allInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
762 //print("\nconstInputExps\n"+stringDelimitList(List.map(constInputExps,ExpressionBasics.printExpStr),"\n")+"\n");
763 //print("\nconstInputCrefs\n"+stringDelimitList(List.map(constInputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
764 //print("\nall algs "+intString(listLength(algs))+"\n"+DAEDump.dumpElementsStr(algs)+"\n");
765
766 //------------------------------------------------
767 //evaluate function call
768 //------------------------------------------------
769
770 //build replacement rules
771 17755 repl := BackendVarTransform.emptyReplacements();
772 17755 repl := BackendVarTransform.addReplacements(repl,constInputCrefs,constInputExps,NONE());
773 //repl = BackendVarTransform.addReplacements(repl,allInputCrefs,allInputExps,NONE());
774 //BackendVarTransform.dumpReplacements(repl);
775
776 // recognize if there are statements we cannot evaluate at the moment
777 17755 hasAssert := List.fold(algs,hasAssertFold,false);
778 17755 hasReturn := List.fold(algs,hasReturnFold,false);
779 17755 hasTerminate := List.fold(algs,hasReturnFold,false);
780 17755 hasReinit := List.fold(algs,hasReinitFold,false);
781 17755 abort := hasReturn or hasTerminate or hasReinit;
782 // go through all algorithms and replace the variables with constants if possible, extend the ht after each algorithm
783 17755 (algs,funcs,repl,idx) := List.mapFold3(algs,function evaluateFunctions_updateAlgElements(recursionLimit = recursionLimit-1),funcsIn,repl,eqIdx);
784 //print("\nall algs after"+intString(listLength(algs))+"\n"+DAEDump.dumpElementsStr(algs)+"\n");
785 //BackendVarTransform.dumpReplacements(repl);
786
787 //get all replacements in order to check for constant outputs
788 17754 (constCrefs,constExps) := BackendVarTransform.getAllReplacements(repl);
789 17754 (constCrefs,constExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,allOutputCrefs,constExps); // extract outputs
790 17754 (constExps,constCrefs) := List.filterOnTrueSync(constExps,Expression.isConst,constCrefs); // extract constant outputs
791
792 //print("all constant crefs \n"+stringDelimitList(List.map(constCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
793 //print("all constant exps:\n"+ExpressionDump.printExpListStr(constExps)+"\n");
794
795 // get the completely constant complex outputs, the constant parts of complex outputs and the variable parts of complex outputs and the expressions
796 17754 (constComplexCrefs,varComplexCrefs,constScalarCrefs,varScalarCrefs) := checkIfOutputIsEvaluatedConstant(allOutputs,constCrefs,{},{},{},{});
797 17754 (constScalarCrefs,constScalarExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,constScalarCrefs,constExps);
798 17754 (constComplexCrefs,constComplexExps) := List.filter1OnTrueSync(constCrefs,ComponentReferenceBasics.crefInLst,constComplexCrefs,constExps);
799
800 //print("constComplexCrefs\n"+stringDelimitList(List.map(constComplexCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
801 //print("varComplexCrefs\n"+stringDelimitList(List.map(varComplexCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
802 //print("constScalarCrefs\n"+stringDelimitList(List.map(constScalarCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
803 //print("varScalarCrefs\n"+stringDelimitList(List.map(varScalarCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
804
805 //------------------------------------------------
806 //evaluate the result and build new function call accordingly
807 //------------------------------------------------
808
809 // is it completely constant or partially?
810
7/8
✓ Branch 0 taken 12279 times.
✓ Branch 1 taken 5475 times.
✓ Branch 2 taken 989 times.
✓ Branch 3 taken 11290 times.
✓ Branch 4 taken 973 times.
✓ Branch 5 taken 16 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 973 times.
17754 funcIsConst := listEmpty(varScalarCrefs) and listEmpty(varComplexCrefs) and (not listEmpty(constScalarCrefs) or not listEmpty(constComplexCrefs));
811
9/10
✓ Branch 0 taken 12279 times.
✓ Branch 1 taken 5475 times.
✓ Branch 2 taken 11290 times.
✓ Branch 3 taken 989 times.
✓ Branch 4 taken 12672 times.
✓ Branch 5 taken 4093 times.
✓ Branch 6 taken 473 times.
✓ Branch 7 taken 12199 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 4566 times.
17754 funcIsPartConst := ((not listEmpty(varScalarCrefs)) or (not listEmpty(varComplexCrefs))) and ((not listEmpty(constScalarCrefs)) or (not listEmpty(constComplexCrefs))) and not funcIsConst;
812
7/8
✓ Branch 3 taken 12279 times.
✓ Branch 4 taken 5475 times.
✓ Branch 5 taken 12279 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 989 times.
✓ Branch 8 taken 11290 times.
✓ Branch 9 taken 973 times.
✓ Branch 10 taken 16 times.
17754 isConstRec := intEq(listLength(constScalarCrefs),listLength(List.flatten(scalarOutputs))) and listEmpty(varScalarCrefs) and listEmpty(varComplexCrefs) and listEmpty(constComplexCrefs);
813
814 //bcall1(isConstRec,print,"the function output is completely constant and its a record\n");
815
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 17753 times.
17754 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if funcIsConst then
817 ✗ if hasAssert then
818 ✗ print("the function output is completely constant but there is an assertion\n");
819 else
820 ✗ print("the function output is completely constant\n");
821 end if;
822 elseif not funcIsPartConst then
823 1 print("the function output is not constant in any case\n");
824 end if;
825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if abort then
826 ✗ print("the evaluated function is not used because there is a return or a terminate or a reinit statement\n");
827 end if;
828 end if;
829
3/4
✓ Branch 0 taken 17681 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 17681 times.
✗ Branch 3 not taken.
17754 funcIsConst := if (hasAssert and funcIsConst) or abort then false else funcIsConst; // quit if there is a return or terminate or use partial evaluation if there is an assert
830
1/2
✓ Branch 0 taken 17754 times.
✗ Branch 1 not taken.
17754 funcIsPartConst := if hasAssert and funcIsConst then true else funcIsPartConst;
831
1/2
✓ Branch 0 taken 17754 times.
✗ Branch 1 not taken.
17754 funcIsPartConst := if abort then false else funcIsPartConst; // quit if there is a return or terminate
832
833
2/2
✓ Branch 0 taken 12272 times.
✓ Branch 1 taken 5482 times.
17754 true := funcIsPartConst or funcIsConst;
834
835 5482 signature := getCallSignatureForCall(rhsExpIn);
836 5482 signature.canBeEvaluated := true;
837 callSignLst := signature::callSignLst;
838 changed := funcIsPartConst or funcIsConst;
839
840 // build the new lhs, the new statements for the function, the constant parts...
841 5482 (updatedVarOutputs,outputExp,varScalarCrefsInFunc,constScalarCrefsInFunc,copyOutStmts) := buildVariableFunctionParts(scalarOutputs,constComplexCrefs,varComplexCrefs,constScalarCrefs,varScalarCrefs,allOutputs,lhsExpIn);
842 5476 (constScalarCrefsLhs,constComplexCrefs) := buildConstFunctionCrefs(constScalarCrefs,constComplexCrefs,allOutputCrefs,lhsExpIn);
843 //print("constScalarExps\n"+stringDelimitList(List.map(constScalarExps,ExpressionBasics.printExpStr),"\n")+"\n");
844 //print("constComplexExps\n"+stringDelimitList(List.map(constComplexExps,ExpressionBasics.printExpStr),"\n")+"\n");
845
846
2/2
✓ Branch 0 taken 4560 times.
✓ Branch 1 taken 916 times.
5476 if not funcIsConst then
847 4560 (algs,constEqs) := buildPartialFunction((varScalarCrefsInFunc,algs),(constScalarCrefsInFunc,constScalarExps,constComplexCrefs,constComplexExps,constScalarCrefsLhs),copyOutStmts,repl);
848 else
849 916 constEqs := {};
850 end if;
851
852 // build the new partial function
853 5476 elements := listAppend(protectVars,algs);
854 5476 elements := listAppend(updatedVarOutputs,elements);
855 5476 elements := listAppend(allInputs,elements);
856 5476 elements := List.unique(elements);
857 5476 newOutputVars := List.filterOnTrue(updatedVarOutputs,DAEUtil.isOutputVar);
858 5476 (func,path) := updateFunctionBody(func,elements,idx, newOutputVars, allOutputs);
859
2/2
✓ Branch 0 taken 4560 times.
✓ Branch 1 taken 916 times.
10036 funcs := if funcIsPartConst then AvlTreePathFunction.addDaeFunction({func},funcs) else funcs;
860 5476 idx := if funcIsPartConst or funcIsConst then (idx+1) else idx;
861
862
863 //decide which lhs to take (tuple or 1d)
864
2/2
✓ Branch 0 taken 4560 times.
✓ Branch 1 taken 916 times.
5476 outputExp := if funcIsPartConst then outputExp else lhsExpIn;
865 5476 lhsExps := getCrefsForRecord(lhsExpIn);
866
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 5460 times.
5476 outputExp := if isConstRec then DAE.TUPLE(lhsExps) else outputExp;
867 // which rhs
868 5476 outputVarTypes := List.map(newOutputVars,DAEUtil.getVariableType);
869 5476 outputVarNames := List.map(newOutputVars,DAEUtil.varName);
870 5476 attr2 := DAEUtil.replaceCallAttrType(attr1,DAE.T_TUPLE(outputVarTypes,SOME(outputVarNames)));
871 5476 DAE.CALL_ATTR(ty = singleOutputType) := attr1;
872
2/2
✓ Branch 0 taken 4560 times.
✓ Branch 1 taken 916 times.
5476 singleOutputType := if not listEmpty(newOutputVars) then listHead(outputVarTypes) else singleOutputType;//if the function is evaluated completely
873 5476 attr1 := DAEUtil.replaceCallAttrType(attr1,singleOutputType);
874
2/2
✓ Branch 1 taken 5369 times.
✓ Branch 2 taken 107 times.
5476 attr2 := if intEq(listLength(newOutputVars),1) then attr1 else attr2;
875 //DAEDump.dumpCallAttr(attr2);
876
877
4/4
✓ Branch 2 taken 4119 times.
✓ Branch 3 taken 1357 times.
✓ Branch 4 taken 482 times.
✓ Branch 5 taken 3637 times.
5476 if List.hasOneElement(listAppend(constComplexExps,constScalarExps)) and funcIsConst then
878 482 exp := listHead(listAppend(constComplexExps,constScalarExps)); // either a single equation
879 elseif funcIsConst and not List.hasOneElement(listAppend(constComplexExps,constScalarExps)) then
880 434 exp := DAE.TUPLE(listAppend(constComplexExps,constScalarExps));// or a tuple equation
881 else
882 exp := rhsExpIn;
883 end if;
884
885
2/2
✓ Branch 0 taken 4560 times.
✓ Branch 1 taken 916 times.
5476 exp := if funcIsPartConst then DAE.CALL(path, expsIn, attr2) else exp; //its partially constant and we have to keep a function call to calc the rest
886
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 5460 times.
5476 exp := if isConstRec then DAE.TUPLE(constScalarExps) else exp; // gather all constant record scalars in a tuple
887 5476 outputExp := setRecordTypes(outputExp);
888
889 //BackendDump.dumpEquationList(constEqs,"the additional equations\n");
890 //print("LHS EXP:\n");
891 //ExpressionDump.dumpExp(outputExp);
892 //print("RHS EXP:\n");
893 //ExpressionDump.dumpExp(exp);
894
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5476 times.
5476 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
895 ✗ print("Finish evaluation of:\n"+ExpressionBasics.printExpStr(lhsExpIn)+" := "+ExpressionBasics.printExpStr(rhsExpIn)+"\nto:\n"+ExpressionBasics.printExpStr(outputExp)+" := "+ExpressionBasics.printExpStr(exp)+"\n");
896 ✗ if not listEmpty(constEqs) then
897 ✗ BackendDump.dumpEquationList(constEqs,"including the additional equations:\n");
898 end if;
899 end if;
900 5476 then
901 (exp,outputExp,constEqs,funcs,idx,changed,callSignLst);
902
903 case(DAE.ASUB(DAE.CALL(path=path, expLst=exps, attr=attr1),sub), callSignLst)
904 algorithm
905 727 exp := DAE.CALL(path=path, expLst=exps, attr=attr1);
906
907 //Check if this particular call signature has been analysed before
908 727 continueEval := checkCallSignatureForExp(exp,callSignLst);
909
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 727 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
727 if not continueEval and Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("THIS FUNCTION CALL WITH THIS SPECIFIC SIGNATURE CANNOT BE EVALUTED\n"); end if;
910
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 727 times.
727 if not continueEval then fail(); end if;
911
912 //this ASUB stuff occurs in the flattened DAE, check this special case because of removeSimpleEquations
913 727 exp := evaluateConstantFunctionCallExp(exp,funcsIn, false, recursionLimit);
914 727 (exp,_) := ExpressionSimplify.simplify(DAE.ASUB(exp,sub));
915
916 changed := true;
917
2/2
✓ Branch 1 taken 506 times.
✓ Branch 2 taken 221 times.
727 if not Expression.isConst(exp) then
918 exp := rhsExpIn;
919 changed:=false;
920 end if;
921 then (exp,lhsExpIn,{},funcsIn,eqIdx,changed,callSignLst);
922
923 else
924 algorithm
925 callSignLst := callSignLstIn;
926
2/2
✓ Branch 1 taken 24369 times.
✓ Branch 2 taken 7452 times.
31821 if Expression.isCall(rhsExpIn) then
927 //Add a call signature for the call that could not been evaluated
928 24369 signature := getCallSignatureForCall(rhsExpIn);
929 24369 signature.canBeEvaluated := false;
930
2/2
✓ Branch 1 taken 20497 times.
✓ Branch 2 taken 3872 times.
24369 if not List.isMemberOnTrue(signature,callSignLstIn,callSignatureIsEqual) then
931 callSignLst := signature::callSignLst;
932 end if;
933 end if;
934 then (rhsExpIn,lhsExpIn,{},funcsIn,eqIdx,false,callSignLst);
935 end matchcontinue;
936 end evaluateConstantFunction;
937
938 protected function expandComplexExpressions "gets the complex contents or if its not complex, then the exp itself, if its a call, get the scalar outputs.
939 it would be possible to evaluate the exp before.
940 author:Waurich TUD 2014-05"
941 input DAE.Exp e;
942 input AvlTreePathFunction.Tree funcs;
943 output list<DAE.Exp> eLst;
944 algorithm
945 eLst := matchcontinue e
946 local
947 Absyn.Path path;
948 DAE.Function func;
949 list<DAE.Exp> lst;
950 list<DAE.Element> elements, allOutputs;
951 case DAE.CALL(path=path, expLst=lst)
952 algorithm
953
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 758 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 758 times.
783 SOME(func) := AvlTreePathFunction.get(funcs,path);
954 758 elements := DAEUtil.getFunctionElements(func);
955
1/2
✓ Branch 0 taken 758 times.
✗ Branch 1 not taken.
758 if listEmpty(elements) then
956 // its a record
957 //eLst = lst;
958 else
959 // its a call, get the scalar outputs
960
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 758 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 758 times.
758 SOME(func) := AvlTreePathFunction.get(funcs,path);
961 758 elements := DAEUtil.getFunctionElements(func);
962 758 allOutputs := List.filterOnTrue(elements,DAEUtil.isOutputVar);
963 758 lst := List.map(List.flatten(List.map(allOutputs,getScalarsForComplexVar)),Expression.crefExp);
964 end if;
965 then
966 lst;
967 case _
968 algorithm
969 45469 lst := Expression.getComplexContents(e);
970
2/2
✓ Branch 0 taken 41057 times.
✓ Branch 1 taken 4412 times.
45469 false := listEmpty(lst);
971 then
972 lst;
973 else
974 algorithm
975 //print("Could not scalarize EXP:\n");
976 //print(ExpressionDump.dumpExpStr(e,0)+"\n");
977 then {e};
978 end matchcontinue;
979 end expandComplexExpressions;
980
981 protected function expandComplexElementsToCrefs "gets the complex contents or if its not complex, then the element itself and converts them to crefs.
982 author:Waurich TUD 2014-05"
983 input DAE.Element e;
984 output list<DAE.ComponentRef> eLst;
985 algorithm
986
2/2
✓ Branch 1 taken 40288 times.
✓ Branch 2 taken 5939 times.
46227 eLst := if isNotComplexVar(e) then {DAEUtil.varCref(e)} else getScalarsForComplexVar(e);
987 end expandComplexElementsToCrefs;
988
989 protected function hasAssertFold "fold function to check if a list of stmts has an assert.
990 author:Waurich TUD 2014-04"
991 input DAE.Element stmt;
992 input Boolean bIn;
993 output Boolean bOut;
994 protected
995 list<Boolean> bLst;
996 list<DAE.Statement> stmtLst;
997 algorithm
998 try
999 17755 stmtLst := DAEUtil.getStatement(stmt);
1000 17755 bLst := List.map(stmtLst,DAEUtil.isStmtAssert);
1001
1/2
✓ Branch 0 taken 17755 times.
✗ Branch 1 not taken.
35510 bOut := List.fold(bLst,boolOr,bIn);
1002 else
1003 bOut := false;
1004 end try;
1005 end hasAssertFold;
1006
1007 protected function hasReturnFold "fold function to check if a list of stmts has an return stmt.
1008 author:Waurich TUD 2014-04"
1009 input DAE.Element stmt;
1010 input Boolean bIn;
1011 output Boolean bOut;
1012 protected
1013 list<Boolean> bLst;
1014 list<DAE.Statement> stmtLst;
1015 algorithm
1016 try
1017 35510 stmtLst := DAEUtil.getStatement(stmt);
1018 35510 bLst := List.map(stmtLst,DAEUtil.isStmtReturn);
1019
1/2
✓ Branch 0 taken 35510 times.
✗ Branch 1 not taken.
71020 bOut := List.fold(bLst,boolOr,bIn);
1020 else
1021 bOut := false;
1022 end try;
1023 end hasReturnFold;
1024
1025 protected function hasReinitFold "fold function to check if a list of stmts has an reinit stmt.
1026 author:Waurich TUD 2014-04"
1027 input DAE.Element stmt;
1028 input Boolean bIn;
1029 output Boolean bOut;
1030 protected
1031 list<Boolean> bLst;
1032 list<DAE.Statement> stmtLst;
1033 algorithm
1034 try
1035 17755 stmtLst := DAEUtil.getStatement(stmt);
1036 17755 bLst := List.map(stmtLst,DAEUtil.isStmtReturn);
1037
1/2
✓ Branch 0 taken 17755 times.
✗ Branch 1 not taken.
35510 bOut := List.fold(bLst,boolOr,bIn);
1038 else
1039 bOut := false;
1040 end try;
1041 end hasReinitFold;
1042
1043 protected function setRecordTypes "This is somehow a hack for FourBitBinaryAdder because there are function calls in the daelow on the lhs of a function call and this leads to an error in simcode creation
1044 they are used a s a cast for record types, but they should be a cast instead of a call, aren't they?
1045 func1(x) = func2(y).
1046 this function removes the call and sets the type
1047 author:Waurich TUD 2014-04"
1048 input DAE.Exp inExp;
1049 output DAE.Exp outExp;
1050 algorithm
1051 outExp := matchcontinue inExp
1052 local
1053 DAE.CallAttributes attr;
1054 DAE.ComponentRef cref;
1055 DAE.Exp exp1;
1056 list<DAE.Exp> expLst;
1057 DAE.Type ty;
1058 case DAE.CALL(expLst=expLst,attr=DAE.CALL_ATTR(ty=ty))
1059 algorithm
1060 ✗ true := Expression.isCall(inExp);
1061 ✗ true := listLength(expLst) == 1;
1062 ✗ exp1 := listHead(expLst);
1063 ✗ cref := Expression.expCref(exp1);
1064 ✗ exp1 := Expression.makeCrefExp(cref,ty);
1065 then exp1;
1066 case DAE.TUPLE(PR=expLst)
1067 algorithm
1068 4887 expLst := List.map(expLst,setRecordTypes);
1069 4887 then DAE.TUPLE(expLst);
1070 else
1071 algorithm
1072 then inExp;
1073 end matchcontinue;
1074 end setRecordTypes;
1075
1076 public function getCrefsForRecord "get all crefs of a record exp
1077 author:Waurich TUD 2014-04"
1078 input DAE.Exp e;
1079 output list<DAE.Exp> es;
1080 algorithm
1081 es := match e
1082 local
1083 DAE.ComponentRef cref;
1084 list<DAE.Exp> expLst;
1085 list<DAE.ComponentRef> crefs;
1086 case DAE.CREF(componentRef = cref)
1087 algorithm
1088 4584 crefs := ComponentReference.expandCref(cref,true);
1089 4584 expLst := List.map(crefs,Expression.crefExp);
1090 then
1091 expLst;
1092 else
1093 {};
1094 end match;
1095 end getCrefsForRecord;
1096
1097 protected function scalarRecExpForOneDimRec "if the record contains only 1 scalar value, replace the scalar type definition with the record definition.
1098 author:Waurich TUD 2014-04"
1099 input DAE.Exp expIn;
1100 output DAE.Exp expOut;
1101 algorithm
1102 expOut := matchcontinue expIn
1103 local
1104 DAE.Exp exp;
1105 DAE.ComponentRef cref;
1106 list<DAE.ComponentRef> crefs;
1107 DAE.Type ty;
1108 list<DAE.Var> varLst;
1109 case DAE.CREF(componentRef=cref,ty = DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(),varLst=varLst))
1110 algorithm
1111
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 106 times.
107 true := listLength(varLst)==1;
1112 106 crefs := getRecordScalars(cref);
1113
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
106 true := listLength(crefs)==1;
1114 106 cref := listHead(crefs);
1115 106 exp := Expression.crefExp(cref);
1116 then exp;
1117 else
1118 expIn;
1119 end matchcontinue;
1120 end scalarRecExpForOneDimRec;
1121
1122 protected function scalarRecCrefsForOneDimRec "replace a 1 dimensional record through its scalar value
1123 author:Waurich TUD 2014-04"
1124 input DAE.ComponentRef crefIn;
1125 output DAE.ComponentRef crefOut;
1126 algorithm
1127 crefOut := matchcontinue crefIn
1128 local
1129 DAE.ComponentRef cref;
1130 list<DAE.ComponentRef> crefs;
1131 case _
1132 algorithm
1133 214 crefs := getRecordScalars(crefIn);
1134
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 213 times.
214 true := listLength(crefs)==1;
1135 213 cref := listHead(crefs);
1136 then cref;
1137 else
1138 then crefIn;
1139 end matchcontinue;
1140 end scalarRecCrefsForOneDimRec;
1141
1142 protected function partiallyConstantArrayNeedsExpansion
1143 "if constScalarCrefs are part of an array output cref, this cref needs to be expanded. Thats not supported right now"
1144 input list<DAE.ComponentRef> allOutputCrefsIn;
1145 input list<DAE.ComponentRef> constScalarCrefs;
1146 output Boolean bOut=false;
1147 algorithm
1148
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 107 times.
321 for cref in allOutputCrefsIn loop
1149
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 214 times.
214 if Types.isArray(ComponentReference.crefType(cref)) then
1150 ✗ if List.isMemberOnTrue(cref, constScalarCrefs, ComponentReferenceBasics.crefEqualWithoutSubs) then
1151 bOut := true;
1152 end if;
1153 end if;
1154 end for;
1155 end partiallyConstantArrayNeedsExpansion;
1156
1157 protected function buildVariableFunctionParts "builds the output elements of the new function, the output expression for the new function call (lhs-exp)
1158 and the crefs of the variable outputs of the new function
1159 author: Waurich TUD 2014-04"
1160 input list<list<DAE.ComponentRef>> scalarOutputs; //crefs for all scalar function output elements
1161 input list<DAE.ComponentRef> constComplexCrefs;
1162 input list<DAE.ComponentRef> varComplexCrefs;
1163 input list<DAE.ComponentRef> constScalarCrefs;
1164 input list<DAE.ComponentRef> varScalarCrefs;
1165 input list<DAE.Element> allOutputs; // the complex (or 1-dimensional) output elements
1166 input DAE.Exp lhsExpIn; // the output expression
1167 output list<DAE.Element> varOutputs; // the protected and output variable elements of the function body
1168 output DAE.Exp outputExpOut; // the outputs(lhs) of the function call
1169 output list<DAE.ComponentRef> varScalarCrefsInFunc; // these crefs have to be updated (makeIdentCref) in the function algorithms
1170 output list<DAE.ComponentRef> constScalarCrefsInFunc; // dito for the constant scalars
1171 output list<DAE.Statement> copyOutStmts; // copy the scalars out of the kept complex output
1172 protected
1173 list<Integer> pos;
1174 DAE.ComponentRef lhsCref;
1175 DAE.Exp outputExp;
1176 DAE.Element newOutput, protVar;
1177 DAE.Statement copyStmt;
1178 list<DAE.ComponentRef> varScalarCrefs1, outputCrefs, allOutputCrefs, allOutputCrefs2, protCrefs, scalarizedCrefs;
1179 list<DAE.Element> funcOutputs,funcProts,funcSOutputs,funcSProts;
1180 list<DAE.Exp> expLst, varScalarExps;
1181 algorithm
1182 (varOutputs,outputExpOut,varScalarCrefsInFunc,constScalarCrefsInFunc,copyOutStmts) := matchcontinue(constComplexCrefs, varComplexCrefs, constScalarCrefs, varScalarCrefs, lhsExpIn)
1183 case(_, _, {}, {}, DAE.TUPLE(PR=expLst))
1184 algorithm
1185 // only 1d or complex outputs in a tuple exp
1186 785 varScalarCrefsInFunc := {};
1187 785 allOutputCrefs := List.map(allOutputs,DAEUtil.varCref);
1188 785 (protCrefs,_,outputCrefs) := List.intersection1OnTrue(constComplexCrefs,allOutputCrefs,ComponentReferenceBasics.crefEqual);
1189 785 pos := List.map1(outputCrefs,List.position,allOutputCrefs);
1190 785 varScalarExps := List.map1(pos,List.getIndexFirst,expLst);
1191
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 784 times.
785 outputExp := if List.hasOneElement(varScalarExps) then listHead(varScalarExps) else DAE.TUPLE(varScalarExps);
1192 785 funcOutputs := List.map2(outputCrefs,generateOutputElements,allOutputs,lhsExpIn);
1193 785 funcProts := List.map2(protCrefs,generateProtectedElements,allOutputs,lhsExpIn);
1194 785 varOutputs := listAppend(funcOutputs,funcProts);
1195 785 then (varOutputs,outputExp,varScalarCrefsInFunc,constScalarCrefs,{});
1196 case(_, _, _, _, DAE.LBINARY())
1197 then
1198 ({},lhsExpIn,{},constScalarCrefs,{});
1199 case(_, _, _, _, DAE.TUPLE(PR=expLst))
1200 algorithm
1201 // a tuple including variable and constant parts
1202 // the protected and output variables of the function
1203 107 allOutputCrefs := List.map(allOutputs,DAEUtil.varCref);
1204
1205 //1d records are replaced by their scalar value
1206 107 allOutputCrefs2 := List.map(allOutputCrefs,scalarRecCrefsForOneDimRec);
1207 107 (_,_,varScalarCrefsInFunc) := List.intersection1OnTrue(allOutputCrefs,allOutputCrefs2,ComponentReferenceBasics.crefEqual);
1208 allOutputCrefs := allOutputCrefs2;
1209 //print("\n allOutputCrefs \n"+stringDelimitList(List.map(allOutputCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1210 //print("\n varScalarCrefsInFunc \n"+stringDelimitList(List.map(varScalarCrefsInFunc,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1211
1212
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 107 times.
107 if partiallyConstantArrayNeedsExpansion(allOutputCrefs, constScalarCrefs) then
1213 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("A partially constant array needs expansion. Thats not supported.\n"); end if;
1214 ✗ fail();
1215 end if;
1216
1217 107 (protCrefs,_,outputCrefs) := List.intersection1OnTrue(listAppend(constComplexCrefs,constScalarCrefs),allOutputCrefs,ComponentReferenceBasics.crefEqual);
1218 107 funcOutputs := List.map2(outputCrefs,generateOutputElements,allOutputs,lhsExpIn);
1219 107 funcProts := List.map2(protCrefs,generateProtectedElements,allOutputs,lhsExpIn);
1220 107 varOutputs := listAppend(funcOutputs,funcProts);
1221
1222 //the lhs-exp of the evaluated function call
1223 107 pos := List.map1(outputCrefs,List.position,allOutputCrefs);
1224 107 varScalarExps := List.map1(pos,List.getIndexFirst,expLst);
1225 107 varScalarExps := List.map(varScalarExps,scalarRecExpForOneDimRec);
1226
2/2
✓ Branch 1 taken 106 times.
✓ Branch 2 taken 1 time.
107 outputExp := if List.hasOneElement(varScalarExps) then listHead(varScalarExps) else DAE.TUPLE(varScalarExps);
1227 107 then (varOutputs,outputExp,varScalarCrefsInFunc,constScalarCrefs,{});
1228 case(_, _, _, _, DAE.TUPLE(PR=expLst))
1229 algorithm
1230 ✗ true := listEmpty(List.flatten(scalarOutputs));
1231 ✗ true := not listEmpty(constScalarCrefs);
1232 ✗ varScalarCrefsInFunc := {};
1233 ✗ allOutputCrefs := List.map(allOutputs,DAEUtil.varCref);
1234 ✗ (protCrefs,_,outputCrefs) := List.intersection1OnTrue(constScalarCrefs,allOutputCrefs,ComponentReferenceBasics.crefEqual);
1235 ✗ pos := List.map1(outputCrefs,List.position,allOutputCrefs);
1236 ✗ varScalarExps := List.map1(pos,List.getIndexFirst,expLst);
1237 ✗ outputExp := if List.hasOneElement(varScalarExps) then listHead(varScalarExps) else DAE.TUPLE(varScalarExps);
1238 ✗ funcOutputs := List.map2(outputCrefs,generateOutputElements,allOutputs,lhsExpIn);
1239 ✗ funcProts := List.map2(protCrefs,generateProtectedElements,allOutputs,lhsExpIn);
1240 ✗ varOutputs := listAppend(funcOutputs,funcProts);
1241 ✗ then (varOutputs,outputExp,varScalarCrefsInFunc,constScalarCrefs,{});
1242 case({}, {}, _, {}, _)
1243 algorithm
1244 // only constant scalarOutputs
1245 16 lhsCref := Expression.expCref(lhsExpIn);
1246 16 outputCrefs := List.map(constScalarCrefs,ComponentReference.crefStripFirstIdent);
1247 16 outputCrefs := List.map1(outputCrefs,ComponentReference.joinCrefsR,lhsCref);
1248 16 expLst := List.map(outputCrefs,Expression.crefExp);
1249 16 outputExp := DAE.TUPLE(expLst);
1250 then
1251 ({},outputExp,{},constScalarCrefs,{});
1252 case(_, _, _, _, _)
1253 algorithm
1254 4574 lhsCref := Expression.expCref(lhsExpIn);
1255 4568 funcOutputs := List.map2(varComplexCrefs,generateOutputElements,allOutputs,lhsExpIn);
1256 4568 funcProts := List.map2(constComplexCrefs,generateProtectedElements,allOutputs,lhsExpIn);
1257
1258 // keep the complex parent so the body stays valid however it assigns the record
1259 4568 scalarizedCrefs := listAppend(varScalarCrefs,constScalarCrefs);
1260 funcSProts := {};
1261
2/2
✓ Branch 0 taken 4568 times.
✓ Branch 1 taken 4568 times.
9136 for outVar in allOutputs loop
1262
2/2
✓ Branch 2 taken 4086 times.
✓ Branch 3 taken 482 times.
4568 if List.exist1(scalarizedCrefs,ComponentReferenceBasics.crefFirstIdentEqual,DAEUtil.varCref(outVar)) then
1263 4086 protVar := DAEUtil.setElementVarVisibility(outVar,DAE.PROTECTED());
1264 4086 funcSProts := DAEUtil.setElementVarDirection(protVar,DAE.BIDIR())::funcSProts;
1265 end if;
1266 end for;
1267
1268 funcSOutputs := {};
1269 copyOutStmts := {};
1270
2/2
✓ Branch 0 taken 40364 times.
✓ Branch 1 taken 4568 times.
44932 for cref in varScalarCrefs loop
1271 40364 (newOutput,copyStmt) := generateScalarOutputElement(cref,allOutputs);
1272 funcSOutputs := newOutput::funcSOutputs;
1273 40364 copyOutStmts := copyStmt::copyOutStmts;
1274 end for;
1275 4568 funcSOutputs := listReverse(funcSOutputs);
1276 4568 copyOutStmts := listReverse(copyOutStmts);
1277
1278 4568 varOutputs := List.flatten({funcOutputs, funcSOutputs, funcProts, funcSProts});
1279 4568 varScalarCrefs1 := List.map(varScalarCrefs,ComponentReference.crefStripFirstIdent);
1280 4568 varScalarCrefs1 := List.map1(varScalarCrefs1,ComponentReference.joinCrefsR,lhsCref);
1281 4568 varScalarExps := List.map(varScalarCrefs1,Expression.crefExp);
1282
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4568 times.
4568 outputExp := if List.hasOneElement(varScalarExps) then listHead(varScalarExps) else DAE.TUPLE(varScalarExps);
1283 then
1284 (varOutputs,outputExp,{},{},copyOutStmts);
1285 else
1286 algorithm
1287
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
1288 ✗ print("buildVariableFunctionParts failed!\n");
1289 ✗ print("\n scalarOutputs \n"+stringDelimitList(List.map(List.flatten(scalarOutputs),ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1290 ✗ print("\n constScalarCrefs \n"+stringDelimitList(List.map(constScalarCrefs,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1291 ✗ print("\n allOutputs "+"\n"+DAEDump.dumpElementsStr(allOutputs)+"\n");
1292 ✗ print("\n lhsExpIn "+"\n"+ExpressionDump.dumpExpStr(lhsExpIn,0)+"\n");
1293 end if;
1294 6 then
1295 fail();
1296 end matchcontinue;
1297 end buildVariableFunctionParts;
1298
1299 protected function buildConstFunctionCrefs "builds the new crefs (for example the scalars from a record) for the constant function outputs"
1300 input list<DAE.ComponentRef> constScalarCrefs;
1301 input list<DAE.ComponentRef> constComplCrefs;
1302 input list<DAE.ComponentRef> allOutputCrefs;
1303 input DAE.Exp lhsExpIn;
1304 output list<DAE.ComponentRef> constScalarCrefsOut;
1305 output list<DAE.ComponentRef> constComplCrefsOut;
1306 algorithm
1307 (constScalarCrefsOut,constComplCrefsOut) := matchcontinue(constScalarCrefs, constComplCrefs, lhsExpIn)
1308 local
1309 list<Integer> pos;
1310 DAE.ComponentRef lhsCref;
1311 list<DAE.Exp> expLst, constExps;
1312 list<DAE.ComponentRef> constCrefs;
1313 case(_, {}, _)
1314 algorithm
1315 4103 lhsCref := Expression.expCref(lhsExpIn);
1316 4102 constCrefs := List.map(constScalarCrefs,ComponentReference.crefStripFirstIdent);
1317 4102 constCrefs := List.map1(constCrefs,ComponentReference.joinCrefsR,lhsCref);
1318 then
1319 (constCrefs,{});
1320 case({}, _, DAE.TUPLE(PR=expLst))
1321 algorithm
1322 // tuple equation with only 1d or completely complex outputs
1323 pos := {};
1324
2/2
✓ Branch 0 taken 1679 times.
✓ Branch 1 taken 891 times.
2570 for lhsCref in constComplCrefs loop
1325 1679 pos := List.position1OnTrue(allOutputCrefs, ComponentReferenceBasics.crefEqual,lhsCref)::pos;
1326 end for;
1327 891 pos := listReverse(pos);
1328 891 constExps := List.map1(pos,List.getIndexFirst,expLst);
1329 891 constCrefs := List.map(constExps,Expression.expCref);
1330 then
1331 ({},constCrefs);
1332 else
1333 (constScalarCrefs,constComplCrefs);
1334 end matchcontinue;
1335 end buildConstFunctionCrefs;
1336
1337 protected function checkIfOutputIsEvaluatedConstant
1338 input list<DAE.Element> elements "check this var";
1339 input list<DAE.ComponentRef> constCrefs;
1340 input list<DAE.ComponentRef> constComplexLstIn "completely constant complex or 1d vars";
1341 input list<DAE.ComponentRef> varComplexLstIn "variable complex or 1d vars";
1342 input list<DAE.ComponentRef> constScalarLstIn "partially constant complex var parts";
1343 input list<DAE.ComponentRef> varScalarLstIn "the variable part of the complex var";
1344 output list<DAE.ComponentRef> constComplexLstOut;
1345 output list<DAE.ComponentRef> varComplexLstOut;
1346 output list<DAE.ComponentRef> constScalarLstOut;
1347 output list<DAE.ComponentRef> varScalarLstOut;
1348 algorithm
1349 (constComplexLstOut,varComplexLstOut,constScalarLstOut,varScalarLstOut) := matchcontinue elements
1350 local
1351 Boolean const;
1352 DAE.ComponentRef cref;
1353 DAE.Element elem;
1354 list<DAE.ComponentRef> scalars, constVars, varVars, varCrefs, constCrefs1;
1355 list<DAE.Element> rest;
1356 list<DAE.ComponentRef> constCompl, varCompl, varScalar, constScalar, constScalarCrefs;
1357 case {}
1358 19380 then(constComplexLstIn,varComplexLstIn,constScalarLstIn,varScalarLstIn);
1359 case elem::rest
1360 //check if the given complext output cref appears in the constCrefs
1361 algorithm
1362 22430 cref := DAEUtil.varCref(elem);
1363 //print("the cref\n"+stringDelimitList(List.map({DAEUtil.varCref(elem)},ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1364 22430 (constVars,varVars,constCrefs1) := List.intersection1OnTrue({cref},constCrefs,ComponentReferenceBasics.crefEqual);
1365 //print("constVars\n"+stringDelimitList(List.map(constVars,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1366
2/2
✓ Branch 0 taken 19949 times.
✓ Branch 1 taken 2481 times.
22430 if listEmpty(constVars) then
1367 //try again with the scalars
1368 19949 scalars := getScalarsForComplexVar(elem);
1369
2/2
✓ Branch 0 taken 13341 times.
✓ Branch 1 taken 6608 times.
19949 if listEmpty(scalars) then
1370 // has no scalars, the 1-d element is variable
1371 13341 (constCompl,varCompl,constScalar,varScalar) := (constComplexLstIn,listAppend(varVars,varComplexLstIn),constScalarLstIn,varScalarLstIn);
1372 else
1373 // has scalars, some are variables some are constant
1374 6608 (constVars,varVars,constCrefs1) := List.intersection1OnTrue(scalars,constCrefs,ComponentReferenceBasics.crefEqual);
1375 6608 (constCompl,varCompl,constScalar,varScalar) := (constComplexLstIn,varComplexLstIn,listAppend(constVars,constScalarLstIn),listAppend(varVars,varScalarLstIn));
1376 end if;
1377 else
1378 //this complex var has been found
1379 2481 (constCompl,varCompl,constScalar,varScalar) := (listAppend(constVars,constComplexLstIn),varComplexLstIn,constScalarLstIn,varScalarLstIn);
1380 end if;
1381 22430 (constCompl,varCompl,constScalar,varScalar) := checkIfOutputIsEvaluatedConstant(rest,constCrefs1,constCompl,varCompl,constScalar,varScalar);
1382 then (constCompl,varCompl,constScalar,varScalar);
1383 case elem::rest
1384 algorithm
1385 ✗ scalars := getScalarsForComplexVar(elem);
1386 // function outputs a record, its either constCompl or constScalar and varScalar
1387 //print("the cref\n"+stringDelimitList(List.map({DAEUtil.varCref(elem)},ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1388 //print("scalars to check\n"+stringDelimitList(List.map(scalars,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1389
1390 ✗ false := listEmpty(scalars);
1391 ✗ constVars := List.intersectionOnTrue(scalars,constCrefs,ComponentReferenceBasics.crefEqual);
1392 //print("constVars\n"+stringDelimitList(List.map(constVars,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
1393
1394 ✗ const := intEq(listLength(scalars),listLength(constVars));
1395 ✗ constScalarCrefs := List.filter1OnTrue(constCrefs,ComponentReferenceBasics.crefInLst,constVars);
1396 ✗ (_,varCrefs,_) := List.intersection1OnTrue(scalars,constScalarCrefs,ComponentReferenceBasics.crefEqual);
1397 //constCompl = if_(const,cref::constComplexLstIn,constComplexLstIn);
1398 constCompl := if false then cref::constComplexLstIn else constComplexLstIn;
1399 //varCompl = if_(not const,cref::varComplexLstIn,varComplexLstIn);
1400 varCompl := varComplexLstIn;
1401 //constScalar = if_(not const,listAppend(constScalarCrefs,constScalarLstIn),constScalarLstIn);
1402 ✗ constScalar := if true then listAppend(constScalarCrefs,constScalarLstIn) else constScalarLstIn;
1403
1404 ✗ varScalar := if not const then listAppend(varCrefs,varScalarLstIn) else varScalarLstIn;
1405 ✗ (constCompl,varCompl,constScalar,varScalar) := checkIfOutputIsEvaluatedConstant(rest,constCrefs,constCompl,varCompl,constScalar,varScalar);
1406 then
1407 (constCompl,varCompl,constScalar,varScalar);
1408 case elem::rest
1409 algorithm
1410 ✗ cref := DAEUtil.varCref(elem);
1411 ✗ scalars := getScalarsForComplexVar(elem);
1412 // function output is one dimensional
1413 ✗ true := listEmpty(scalars);
1414 ✗ const := listMember(cref,constCrefs);
1415 ✗ constCompl := if const then cref::constComplexLstIn else constComplexLstIn;
1416 ✗ varCompl := if not const then cref::varComplexLstIn else varComplexLstIn;
1417 ✗ (constCompl,varCompl,constScalar,varScalar) := checkIfOutputIsEvaluatedConstant(rest,constCrefs,constCompl,varCompl,constScalarLstIn,varScalarLstIn);
1418 then
1419 (constCompl,varCompl,constScalar,varScalar);
1420 else
1421 algorithm
1422 ✗ print("checkIfOutputIsEvaluatedConstant failed!\n");
1423 ✗ then
1424 fail();
1425 end matchcontinue;
1426 end checkIfOutputIsEvaluatedConstant;
1427
1428
1429 protected function generateScalarOutputElement
1430 "Makes a scalar output for a part of a complex output and the statement copying it out."
1431 input DAE.ComponentRef cref;
1432 input list<DAE.Element> inFuncOutputs;
1433 output DAE.Element newOutput;
1434 output DAE.Statement copyStmt;
1435 protected
1436 DAE.Type ty;
1437 DAE.ComponentRef newCref;
1438 algorithm
1439 40364 ty := ComponentReference.crefTypeFull(cref);
1440 40364 newCref := ComponentReferenceBasics.makeCrefIdent(flattenCrefIdent(cref),ty,{});
1441 newOutput := match listHead(inFuncOutputs)
1442 local
1443 DAE.Element var;
1444 case var as DAE.VAR()
1445 algorithm
1446 40364 var.componentRef := newCref;
1447 40364 var.ty := ty;
1448 40364 var.dims := {};
1449 40364 var.binding := NONE();
1450 40364 var.direction := DAE.OUTPUT();
1451 40364 var.protection := DAE.PUBLIC();
1452 then var;
1453 end match;
1454 40364 copyStmt := DAE.STMT_ASSIGN(ty,Expression.crefToExp(newCref),Expression.crefToExp(cref),DAE.emptyElementSource);
1455 end generateScalarOutputElement;
1456
1457 protected function flattenCrefIdent
1458 "o.i.b[2] -> o_i_b_2"
1459 input DAE.ComponentRef cref;
1460 output String ident;
1461 algorithm
1462 ident := match cref
1463 local
1464 DAE.ComponentRef rest;
1465 DAE.Ident id;
1466 list<DAE.Subscript> subs;
1467 case DAE.CREF_QUAL(ident=id,subscriptLst=subs,componentRef=rest)
1468 40368 then id + flattenSubscripts(subs) + "_" + flattenCrefIdent(rest);
1469 case DAE.CREF_IDENT(ident=id,subscriptLst=subs)
1470 40364 then id + flattenSubscripts(subs);
1471 end match;
1472 end flattenCrefIdent;
1473
1474 protected function flattenSubscripts
1475 input list<DAE.Subscript> subs;
1476 output String str = "";
1477 algorithm
1478
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 80732 times.
80735 for sub in subs loop
1479 3 str := str + "_" + ExpressionDump.subscriptString(sub);
1480 end for;
1481 end flattenSubscripts;
1482
1483 protected function generateOutputElements "generates the scalar outputs for the new function
1484 author:Waurich TUD 2014-03"
1485 input DAE.ComponentRef cref;
1486 input list<DAE.Element> inFuncOutputs;
1487 input DAE.Exp recId;
1488 output DAE.Element newOutputs;
1489 algorithm
1490 newOutputs := match cref
1491 local
1492 DAE.Ident i1,i2;
1493 DAE.ComponentRef cref1;
1494 DAE.Element var;
1495 DAE.Type typ;
1496 list<DAE.ComponentRef> crefs;
1497 list<DAE.Subscript> sl;
1498 case DAE.CREF_QUAL(subscriptLst=sl)
1499 algorithm
1500 //print("generate output element\n");
1501 106 typ := ComponentReference.crefLastType(cref);
1502 106 cref1 := ComponentReference.crefStripLastIdent(cref);
1503
1504 // if the record is only 1-dimensional, use the scalar value
1505 106 crefs := getRecordScalars(cref);
1506
1/2
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
106 cref1 := if intEq(listLength(crefs),1) then listHead(crefs) else cref1;
1507
1508 // its not possible to use qualified output crefs
1509 106 i1 := ComponentReferenceBasics.crefFirstIdent(cref);
1510 106 i2 := ComponentReferenceBasics.crefLastIdent(cref);
1511 //print("the idents_ "+i1+" and "+i2+"\n");
1512 106 i1 := i1+"_"+i2;
1513 106 cref1 := ComponentReferenceBasics.makeCrefIdent(i1,typ,sl);
1514
1515 //print("the inFuncOutputs \n"+DAEDump.dumpElementsStr(inFuncOutputs)+"\n");
1516 //vars = List.map(inFuncOutputs,DAEUtil.varCref);
1517 //print("all the crefs of the oldoutputs\n"+stringDelimitList(List.map(vars,ComponentReferenceBasics.printComponentRefStr),",")+"\n");
1518 //(vars,oldOutputs2) = List.filter1OnTrueSync(vars,ComponentReferenceBasics.crefEqual,cref1,inFuncOutputs);
1519 //var = listHead(oldOutputs2);
1520 106 var := listHead(inFuncOutputs);
1521 106 var := DAEUtil.replaceCrefandTypeInVar(cref1,typ,var);
1522 //print("the new var id \n"+DAEDump.dumpElementsStr({var})+"\n");
1523 then
1524 var;
1525 case DAE.CREF_IDENT(identType=typ)
1526 algorithm
1527 735 var := listHead(inFuncOutputs);
1528 735 var := DAEUtil.replaceCrefandTypeInVar(cref,typ,var);
1529 then
1530 var;
1531 else
1532 algorithm
1533 ✗ print("generateOutputElements failed!\n");
1534 ✗ then fail();
1535 end match;
1536 end generateOutputElements;
1537
1538 protected function generateProtectedElements "generates a protected variable for the new function
1539 author:Waurich TUD 2014-03"
1540 input DAE.ComponentRef cref;
1541 input list<DAE.Element> inFuncOutputs;
1542 input DAE.Exp recId;
1543 output DAE.Element newProts;
1544 algorithm
1545 newProts := match cref
1546 local
1547 DAE.ComponentRef cref1;
1548 DAE.Ident i1,i2;
1549 DAE.Element var;
1550 DAE.Type typ;
1551 list<DAE.Subscript> sl;
1552 case DAE.CREF_QUAL(subscriptLst=sl)
1553 algorithm
1554 ✗ typ := ComponentReference.crefLastType(cref);
1555 ✗ i1 := ComponentReferenceBasics.crefFirstIdent(cref);
1556 ✗ i2 := ComponentReferenceBasics.crefLastIdent(cref);
1557 ✗ i1 := i1+"_"+i2;
1558 ✗ cref1 := ComponentReferenceBasics.makeCrefIdent(i1,typ,sl);
1559 ✗ var := listHead(inFuncOutputs);
1560 ✗ var := DAEUtil.replaceCrefandTypeInVar(cref1,typ,var);
1561 ✗ var := DAEUtil.setElementVarVisibility(var,DAE.PROTECTED());
1562 ✗ var := DAEUtil.setElementVarDirection(var,DAE.BIDIR());
1563 then
1564 var;
1565 case DAE.CREF_IDENT(identType=typ)
1566 algorithm
1567 2161 var := listHead(inFuncOutputs);
1568 2161 var := DAEUtil.replaceCrefandTypeInVar(cref,typ,var);
1569 2161 var := DAEUtil.setElementVarVisibility(var,DAE.PROTECTED());
1570 2161 var := DAEUtil.setElementVarDirection(var,DAE.BIDIR());
1571 then
1572 var;
1573 else
1574 algorithm
1575 ✗ print("generateProtectedElements failed!\n");
1576 ✗ then fail();
1577 end match;
1578 end generateProtectedElements;
1579
1580 protected function updateFunctionBody
1581 "Updates the function with the new elements, updates the type, and creates a
1582 new path name."
1583 input DAE.Function funcIn;
1584 input list<DAE.Element> body;
1585 input Integer idx;
1586 input list<DAE.Element> outputs;
1587 input list<DAE.Element> origOutputs;
1588 output DAE.Function funcOut = funcIn;
1589 output Absyn.Path pathOut;
1590 algorithm
1591 (funcOut, pathOut) := match funcOut
1592 local
1593 String s;
1594
1595 case DAE.FUNCTION()
1596 algorithm
1597 // Update the path.
1598 5476 s := AbsynUtil.pathLastIdent(funcOut.path);
1599 5476 s := s + "_eval" + intString(idx);
1600 5476 funcOut.path := AbsynUtil.pathSetLastIdent(AbsynUtil.makeNotFullyQualified(funcOut.path), s);
1601
1602 // Update the type.
1603 5476 funcOut.type_ := updateFunctionType(funcOut.type_, outputs, origOutputs);
1604
1605 // Update the function definition.
1606
1/2
✓ Branch 1 taken 5476 times.
✗ Branch 2 not taken.
10952 funcOut.functions := {DAE.FUNCTION_DEF(body)};
1607 then
1608 (funcOut, funcOut.path);
1609
1610 else
1611 algorithm
1612 ✗ Error.terminate(getInstanceName() + " failed", sourceInfo());
1613 ✗ then
1614 fail();
1615
1616 end match;
1617 end updateFunctionBody;
1618
1619 protected function updateFunctionType "sets the resultTypes in the functionType
1620 author:Waurich TUD 2014-05"
1621 input DAE.Type typIn;
1622 input list<DAE.Element> outputs; // the new outputs of the function
1623 input list<DAE.Element> originOutputs; // the original outputs of the function
1624 output DAE.Type typOut;
1625 algorithm
1626 typOut := matchcontinue typIn
1627 local
1628 DAE.Type ty;
1629 list<DAE.Type> outTypeLst;
1630 list<String> outNames;
1631 case ty as DAE.T_FUNCTION()
1632 algorithm
1633 //print("the out types1: "+TypesDump.unparseType(outType)+"\n");
1634
4/4
✓ Branch 0 taken 41205 times.
✓ Branch 1 taken 5476 times.
✓ Branch 2 taken 41205 times.
✓ Branch 3 taken 5476 times.
46681 outTypeLst := list(DAEUtil.getVariableType(o) for o in outputs);
1635
4/4
✓ Branch 0 taken 41205 times.
✓ Branch 1 taken 5476 times.
✓ Branch 2 taken 41205 times.
✓ Branch 3 taken 5476 times.
46681 outNames := list(DAEUtil.varName(o) for o in outputs);
1636
2/2
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 5369 times.
16321 ty.funcResultType := if intEq(listLength(outTypeLst),1) then listHead(outTypeLst) else DAE.T_TUPLE(outTypeLst,SOME(outNames));
1637 //print("the out types2: "+TypesDump.unparseType(outType)+"\n");
1638 then ty;
1639 else
1640 then typIn;
1641 end matchcontinue;
1642 end updateFunctionType;
1643
1644 protected function buildPartialFunction "build a partial function for the variable outputs of a complex function and generate some simple equations for the constant outputs.
1645 author:Waurich TUD 2014-03"
1646 input tuple<list<DAE.ComponentRef>,list<DAE.Element>> varPart;
1647 input tuple<list<DAE.ComponentRef>,list<DAE.Exp>,list<DAE.ComponentRef>,list<DAE.Exp>,list<DAE.ComponentRef>> constPart;
1648 input list<DAE.Statement> copyOutStmts;
1649 input BackendVarTransform.VariableReplacements replIn;
1650 output list<DAE.Element> algsOut;
1651 output list<BackendDAE.Equation> eqsOut;
1652 protected
1653 list<DAE.ComponentRef> constScalarCrefsInFunc, varScalarCrefs, constComplCrefs, constScalarCrefsOut;
1654 list<DAE.Element> funcAlgs;
1655 list<DAE.Exp> constComplExps, constScalarExps, lhsExps1, lhsExps2;
1656 list<DAE.Statement> stmts1;
1657 algorithm
1658 4560 (varScalarCrefs,funcAlgs) := varPart;
1659 4560 (constScalarCrefsInFunc,constScalarExps,constComplCrefs,constComplExps,constScalarCrefsOut) := constPart;
1660
1661 4560 funcAlgs := List.filterOnTrue(funcAlgs,DAEUtil.isAlgorithm);// get only the algs, not protected vars or stuff
1662 // generate the additional equations for the constant scalar values and the constant complex ones
1663 4560 lhsExps1 := List.map(constScalarCrefsOut,Expression.crefExp);
1664 4560 lhsExps2 := List.map(constComplCrefs,Expression.crefExp);
1665 4560 eqsOut := generateConstEqs(lhsExps1,constScalarExps,{});
1666 4560 eqsOut := generateConstEqs(lhsExps2,constComplExps,eqsOut);
1667
1668 // build the partial function algorithm, replace the qualified crefs
1669 4560 stmts1 := List.mapFlatReverse(funcAlgs, DAEUtil.getStatement);
1670 //stmts1 := List.filterOnTrue(stmts1,statementRHSIsNotConst);
1671 // remove the constant values
1672 //stmts1 := traverseStmtsAndUpdate(stmts1,stmtCanBeRemoved,replIn,{});
1673 // stmts1 := listReverse(stmts1);
1674
1675 // build new crefs for the scalars
1676 4560 (stmts1,_) := DAEUtil.traverseDAEEquationsStmts(stmts1,Expression.traverseSubexpressionsHelper,(makeIdentCref,varScalarCrefs));
1677 4560 (stmts1,_) := DAEUtil.traverseDAEEquationsStmts(stmts1,Expression.traverseSubexpressionsHelper,(makeIdentCref,constScalarCrefsInFunc));
1678 4560 stmts1 := listAppend(stmts1,copyOutStmts) annotation(__OpenModelica_DisableListAppendWarning=true);
1679 4560 algsOut := {DAE.ALGORITHM(DAE.ALGORITHM_STMTS(stmts1),DAE.emptyElementSource)};
1680 end buildPartialFunction;
1681
1682 protected function stmtCanBeRemoved "function to be used in traverseStmtsAndUpdate in order
1683 to detect the equations with a constant lhs and constant rhs so that they can be removed.
1684 author:Waurich TUD 2014-04"
1685 input DAE.Statement stmtIn;
1686 input BackendVarTransform.VariableReplacements repl;
1687 output tuple<DAE.Statement,Boolean> tplOut;
1688 replaceable type Type_a subtypeof Any;
1689 algorithm
1690 tplOut := matchcontinue stmtIn
1691 local
1692 Boolean b1,b2;
1693 DAE.Exp e1, e2;
1694 DAE.Statement stmt;
1695 case DAE.STMT_ASSIGN()
1696 algorithm
1697 ✗ ({stmt},_) := BackendVarTransform.replaceStatementLst({stmtIn},repl,NONE(),{},false);
1698 ✗ DAE.STMT_ASSIGN(exp1=e1,exp=e2) := stmt;
1699 ✗ b1 := Expression.isConst(e1);
1700 ✗ b2 := Expression.isConst(e2);
1701 //stmt = if_(b1,stmtIn,stmt);
1702 stmt := stmtIn;
1703 ✗ then
1704 ((stmt,b1 and b2));
1705 else
1706 ✗ then
1707 ((stmtIn,false));
1708 end matchcontinue;
1709 end stmtCanBeRemoved;
1710
1711 protected function traverseStmtsAndUpdate "traverses all assign-statements. the stmts can be updated with the given function.
1712 the Boolean function says if the statement should be deleted"
1713 input list<DAE.Statement> stmtsIn;
1714 input FuncType func;
1715 input Type_a argIn;
1716 input list<DAE.Statement> stmtsFold;
1717 partial function FuncType
1718 input DAE.Statement stmtsIn;
1719 input Type_a argIn;
1720 output tuple<DAE.Statement,Boolean> stmtsOut;
1721 end FuncType;
1722 replaceable type Type_a subtypeof Any;
1723 output list<DAE.Statement> stmtsOut;
1724 algorithm
1725 stmtsOut := matchcontinue stmtsIn
1726 local
1727 Boolean b;
1728 DAE.Else else_;
1729 list<DAE.Statement> stmtLst, xs, rest;
1730 list<list<DAE.Statement>> stmtLstLst;
1731 DAE.Statement x;
1732 case {}
1733 algorithm
1734 ✗ listReverse(stmtsFold);
1735 then
1736 stmtsFold;
1737 case DAE.STMT_IF(statementLst=stmtLst, else_=else_)::rest
1738 algorithm
1739 ✗ x := listHead(stmtsIn);
1740 ✗ stmtLstLst := getDAEelseStatemntLsts(else_,{});
1741 ✗ stmtLstLst := listReverse(stmtLstLst);
1742 ✗ stmtLstLst := List.map3(stmtLstLst,traverseStmtsAndUpdate,func,argIn,{});
1743 ✗ stmtLst := traverseStmtsAndUpdate(stmtLst,func,argIn,{});
1744 stmtLstLst := stmtLst::stmtLstLst;
1745 ✗ x := updateStatementsInIfStmt(stmtLstLst,x);
1746 ✗ xs := traverseStmtsAndUpdate(rest,func,argIn,x::stmtsFold);
1747 then
1748 xs;
1749 case x::rest
1750 algorithm
1751 ✗ (x,b) := func(x,argIn);
1752 ✗ xs := if b then stmtsFold else x::stmtsFold;
1753 ✗ xs := traverseStmtsAndUpdate(rest,func,argIn,xs);
1754 then
1755 xs;
1756 end matchcontinue;
1757 end traverseStmtsAndUpdate;
1758
1759 protected function makeIdentCref "searches only for crefs"
1760 input DAE.Exp inExp;
1761 input list<DAE.ComponentRef> inCrefs;
1762 output DAE.Exp outExp;
1763 output list<DAE.ComponentRef> outCrefs;
1764 algorithm
1765 (outExp,outCrefs) := match (inExp,inCrefs)
1766 local
1767 DAE.ComponentRef cref;
1768 list<DAE.ComponentRef> crefs;
1769 DAE.Exp exp;
1770 DAE.Type ty;
1771 case (DAE.CREF(componentRef=cref,ty=ty),crefs)
1772 algorithm
1773 2832942 cref := makeIdentCref2(cref,crefs);
1774 2832942 exp := DAE.CREF(cref,ty);
1775 then
1776 (exp,crefs);
1777 else (inExp,inCrefs);
1778 end match;
1779 end makeIdentCref;
1780
1781 protected function makeIdentCref2 "appends the crefs of a qualified crefs with the given delimiter
1782 author:Waurich TUD 2014-03"
1783 input DAE.ComponentRef crefIn;
1784 input list<DAE.ComponentRef> changeTheseCrefs;
1785 output DAE.ComponentRef crefOut;
1786 algorithm
1787 crefOut := matchcontinue crefIn
1788 local
1789 DAE.ComponentRef cref1, cref2;
1790 String i1,i2;
1791 case cref1 as DAE.CREF_QUAL(ident=i1,componentRef=cref2)
1792 algorithm
1793
2/2
✓ Branch 1 taken 687682 times.
✓ Branch 2 taken 212 times.
687894 true := List.isMemberOnTrue(cref1,changeTheseCrefs,ComponentReferenceBasics.crefEqual);
1794 212 i2 := ComponentReferenceBasics.crefFirstIdent(cref2);
1795 212 i1 := i1+"_"+i2;
1796 212 cref2 := replaceCrefIdent(cref2,i1);
1797 212 cref2 := makeIdentCref2(cref2,changeTheseCrefs);
1798 then
1799 cref2;
1800 case cref1 as DAE.CREF_IDENT()
1801 then
1802 cref1;
1803 else
1804 crefIn;
1805 end matchcontinue;
1806 end makeIdentCref2;
1807
1808 protected function replaceCrefIdent "replaces the ident of a cref
1809 author:Waurich TUD 2014-03"
1810 input DAE.ComponentRef crefIn;
1811 input String ident;
1812 output DAE.ComponentRef crefOut;
1813 algorithm
1814 crefOut := match crefIn
1815 local
1816 DAE.ComponentRef cref,cref2;
1817 DAE.Type typ;
1818 list<DAE.Subscript> sl;
1819 case DAE.CREF_QUAL(identType=typ,subscriptLst=sl,componentRef=cref2)
1820 algorithm
1821 ✗ cref := DAE.CREF_QUAL(ident,typ,sl,cref2);
1822 then
1823 cref;
1824 case DAE.CREF_IDENT(identType=typ,subscriptLst=sl)
1825 algorithm
1826 212 cref := DAE.CREF_IDENT(ident,typ,sl);
1827 then
1828 cref;
1829 else
1830 then
1831 crefIn;
1832 end match;
1833 end replaceCrefIdent;
1834
1835 protected function statementRHSIsNotConst "checks whether the rhs of a statement is not constant.
1836 author:Waurich TUD 2014-03"
1837 input DAE.Statement stmt;
1838 output Boolean notConst;
1839 algorithm
1840 notConst := match stmt
1841 local
1842 Boolean b;
1843 DAE.Exp rhs;
1844 case DAE.STMT_ASSIGN(exp=rhs)
1845 algorithm
1846 ✗ b := Expression.isConst(rhs);
1847 ✗ then
1848 not b;
1849 else
1850 true;
1851 end match;
1852 end statementRHSIsNotConst;
1853
1854 protected function generateConstEqs "generate a list of BackendDAE.EQUATION.
1855 author:Waurich TUD 2014-03"
1856 input list<DAE.Exp> lhsLst;
1857 input list<DAE.Exp> rhsLst;
1858 input list<BackendDAE.Equation> eqsIn;
1859 output list<BackendDAE.Equation> eqsOut;
1860 algorithm
1861 eqsOut := match(lhsLst, rhsLst)
1862 local
1863 BackendDAE.Equation eq;
1864 list<BackendDAE.Equation> eqs;
1865 DAE.Exp lhs,rhs;
1866 list<DAE.Exp> lrest,rrest;
1867 case({}, {})
1868 then
1869 eqsIn;
1870
1871 // ignore wildcards
1872 // solves ticket #8381
1873 case ((DAE.CREF(componentRef = DAE.WILD()))::lrest, _::rrest)
1874 algorithm
1875 ✗ eqs := generateConstEqs(lrest,rrest,eqsIn);
1876 then
1877 eqs;
1878
1879 case(lhs::lrest, rhs::rrest)
1880 algorithm
1881 7208 eq := BackendDAE.EQUATION(lhs,rhs,DAE.emptyElementSource,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
1882 7208 eqs := generateConstEqs(lrest,rrest,eq::eqsIn);
1883 then
1884 eqs;
1885 else
1886 algorithm
1887 ✗ print("generateConstEqs failed!\n");
1888 ✗ then
1889 fail();
1890 end match;
1891 end generateConstEqs;
1892
1893 protected function addReplacementRuleForAssignment "add a replacement rule according to the simple assigment like cref = const."
1894 input DAE.Statement stmt;
1895 input BackendVarTransform.VariableReplacements replIn;
1896 output BackendVarTransform.VariableReplacements replOut;
1897 algorithm
1898 replOut := match stmt
1899 local
1900 BackendVarTransform.VariableReplacements repl;
1901 DAE.ComponentRef cref;
1902 DAE.Exp lhs,rhs;
1903 case DAE.STMT_ASSIGN(exp1=lhs,exp=rhs)
1904 algorithm
1905 5398 cref := Expression.expCref(lhs);
1906 5398 repl := BackendVarTransform.addReplacement(replIn,cref,rhs,NONE());
1907 then
1908 repl;
1909 else
1910 then replIn;
1911 end match;
1912 end addReplacementRuleForAssignment;
1913
1914 protected function evaluateFunctions_updateAlgElements "gets the statements from an algorithm in order to traverse them and tries to evaluate the binding expressions from protected vars.
1915 author:Waurich TUD 2014-03"
1916 input output DAE.Element element;
1917 input output AvlTreePathFunction.Tree funcTree;
1918 input output BackendVarTransform.VariableReplacements repl;
1919 input output Integer idx;
1920 input Integer recursionLimit;
1921 algorithm
1922 element := match element
1923 local
1924 DAE.Algorithm alg;
1925 DAE.ElementSource source;
1926 DAE.Exp exp;
1927 DAE.ComponentRef cref;
1928 list<DAE.Statement> stmts;
1929 list<DAE.Exp> scalarExps;
1930 list<DAE.ComponentRef> scalars;
1931 case DAE.ALGORITHM(alg,source)
1932 algorithm
1933 19379 stmts := DAEUtil.getStatement(element);
1934 19379 (stmts,funcTree,repl,idx) := evaluateFunctions_updateStatement(stmts,funcTree,repl,idx,{},recursionLimit);
1935 19378 alg := DAE.ALGORITHM_STMTS(stmts);
1936 19378 then DAE.ALGORITHM(alg,source);
1937
1938 case DAE.VAR(componentRef=cref,binding=SOME(exp))
1939 algorithm
1940 643 (exp,_) := BackendVarTransform.replaceExp(exp, repl,NONE());
1941 643 (exp,_) := ExpressionSimplify.simplify(exp);
1942
2/2
✓ Branch 1 taken 203 times.
✓ Branch 2 taken 440 times.
643 if Expression.isConst(exp) then
1943 //add replacement for complex and scalar values
1944 203 repl := BackendVarTransform.addReplacement(repl,cref,exp,NONE());
1945 203 scalars := ComponentReference.expandCref(cref,false);
1946 203 scalarExps := Expression.getComplexContents(exp);
1947
2/2
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 191 times.
203 if listLength(scalars)==listLength(scalarExps) then
1948 12 repl := BackendVarTransform.addReplacements(repl,scalars,scalarExps,NONE());
1949 end if;
1950 end if;
1951 643 then (DAEUtil.replaceBindungInVar(exp,element));
1952 else
1953 then element;
1954 end match;
1955 end evaluateFunctions_updateAlgElements;
1956
1957 protected function unboxExp
1958 "takes an expression and unboxes it if it is boxed"
1959 input DAE.Exp ie;
1960 input Boolean bIn;
1961 output DAE.Exp outExp;
1962 output Boolean bOut;
1963 algorithm
1964 (outExp, bOut) := match ie
1965 local
1966 DAE.Exp e;
1967 115 case DAE.BOX(e) then unboxExp(e,true);
1968 else (ie,bIn);
1969 end match;
1970 end unboxExp;
1971
1972
1973 protected function evaluateFunctions_updateStatement "replaces the statements with regards to the given varReplacements and check for constant assignments.
1974 if there are constant assignments add this replacement rule
1975 author:Waurich TUD 2014-03"
1976 input output list<DAE.Statement> stmts;
1977 input output AvlTreePathFunction.Tree funcTree;
1978 input output BackendVarTransform.VariableReplacements repl;
1979 input output Integer idx;
1980 input list<DAE.Statement> lstIn;
1981 input Integer recursionLimit;
1982 protected
1983 list<list<DAE.Statement>> stmtsList;
1984 algorithm
1985
4/4
✓ Branch 0 taken 362887 times.
✓ Branch 1 taken 49826 times.
✓ Branch 2 taken 362887 times.
✓ Branch 3 taken 49826 times.
412713 stmtsList := list(
1986 match stmt
1987 local
1988 Boolean isCon, isRec, isTpl, predicted, eqDim, isCall, isEval, isArr;
1989 Integer size;
1990 DAE.ComponentRef cref;
1991 DAE.ElementSource source;
1992 DAE.Exp exp0, exp1, exp2, cond, msg, lvl;
1993 DAE.Else else_;
1994 DAE.Statement stmt1;
1995 DAE.Type typ;
1996 list<BackendDAE.Equation> addEqs;
1997 list<DAE.ComponentRef> scalars, varScalars, constScalars, outputs;
1998 list<DAE.Statement> stmts1, stmts2, stmtsIf, addStmts, stmtsNew, allStmts, tplStmts;
1999 list<DAE.Exp> expLst, tplExpsLHS, tplExpsRHS, lhsExps;
2000
2001 case DAE.STMT_ASSIGN(type_=typ, exp1=exp1, exp=exp2, source=source)
2002 algorithm
2003
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 340887 times.
340897 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2004 10 print("assignment:\n"+DAEDump.ppStatementStr(stmt));
2005 end if;
2006 340897 cref := Expression.expCref(exp1);
2007 340897 scalars := getRecordScalars(cref);
2008 340897 (exp2,_) := BackendVarTransform.replaceExp(exp2,repl,NONE());
2009 340897 (exp2,_) := ExpressionSimplify.simplify(exp2);
2010
2011 340897 (exp2,exp1,funcTree,idx,addStmts) := evaluateConstantFunctionCall(exp2,exp1,funcTree,idx,recursionLimit);
2012
2013 340897 (exp2,_) := ExpressionSimplify.simplify(exp2);
2014 340897 (exp2,_) := Expression.traverseExpBottomUp(exp2,unboxExp,false);// for metamodelica/meta/omc
2015 340897 expLst := Expression.getComplexContents(exp2);
2016
2017 // add the replacements for the addStmts and remove the replacements for the variable outputs
2018 340897 repl := List.fold(addStmts,addReplacementRuleForAssignment,repl);
2019 340897 lhsExps := Expression.getComplexContents(exp1);
2020 340897 outputs := List.map(lhsExps,Expression.expCref);
2021 340897 BackendVarTransform.removeReplacements(repl,outputs);
2022
2023 // check if its constant, a record or a tuple
2024
4/4
✓ Branch 1 taken 27361 times.
✓ Branch 2 taken 313536 times.
✓ Branch 4 taken 309 times.
✓ Branch 5 taken 27052 times.
340897 isCon := Expression.isConst(exp2) and not Expression.isCall(exp2);
2025 340897 eqDim := listLength(scalars) == listLength(expLst); // so it can be partly constant
2026
3/4
✓ Branch 1 taken 336179 times.
✓ Branch 2 taken 4718 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 336179 times.
340897 isRec := ComponentReference.isRecord(cref) or Expression.isRecordCall(exp2,funcTree);
2027
4/4
✓ Branch 1 taken 3907 times.
✓ Branch 2 taken 336990 times.
✓ Branch 4 taken 3891 times.
✓ Branch 5 taken 16 times.
340897 isTpl := Expression.isTuple(exp1) and Expression.isTuple(exp2);
2028
2029 // remove the variable crefs and add the constant crefs to the replacements
2030
2/2
✓ Branch 0 taken 340824 times.
✓ Branch 1 taken 73 times.
340897 scalars := if isRec and eqDim then scalars else {};
2031
2/2
✓ Branch 0 taken 340824 times.
✓ Branch 1 taken 73 times.
340897 expLst := if isRec and eqDim then expLst else {};
2032 340897 (_,varScalars) := List.filterOnTrueSync(expLst,Expression.isNotConst,scalars);
2033 340897 (expLst,constScalars) := List.filterOnTrueSync(expLst,Expression.isConst,scalars);
2034
2035
2/2
✓ Branch 0 taken 27026 times.
✓ Branch 1 taken 313871 times.
340897 repl := if isCon and not isRec then BackendVarTransform.addReplacement(repl,cref,exp2,NONE()) else repl;
2036
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 340871 times.
340897 repl := if isCon and isRec then BackendVarTransform.addReplacements(repl,scalars,expLst,NONE()) else repl;
2037
2/2
✓ Branch 0 taken 313845 times.
✓ Branch 1 taken 27052 times.
340897 if not isCon then
2038
2/2
✓ Branch 0 taken 309153 times.
✓ Branch 1 taken 4692 times.
313845 if not isRec then
2039 309153 BackendVarTransform.removeReplacement(repl,cref);
2040 else
2041 4692 BackendVarTransform.removeReplacements(repl,varScalars);
2042 4692 repl := BackendVarTransform.addReplacements(repl,constScalars,expLst,NONE());
2043 end if;
2044 end if;
2045
2046 // build the new statements
2047
2/2
✓ Branch 0 taken 27052 times.
✓ Branch 1 taken 313845 times.
340897 stmt1 := if isCon then DAE.STMT_ASSIGN(typ,exp1,exp2,source) else stmt;
2048
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 340881 times.
340897 tplExpsLHS := if isTpl then Expression.getComplexContents(exp1) else {};
2049
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 340881 times.
340897 tplExpsRHS := if isTpl then Expression.getComplexContents(exp2) else {};
2050 340897 tplStmts := makeAssignmentMap(tplExpsLHS,tplExpsRHS);
2051
2/2
✓ Branch 0 taken 340881 times.
✓ Branch 1 taken 16 times.
340897 stmts1 := if isTpl then tplStmts else {stmt1};
2052
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 340887 times.
340897 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2053 10 print("evaluated assignment to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
2054 end if;
2055 340897 then stmts1;
2056
2057 case DAE.STMT_ASSIGN_ARR(type_=typ, lhs=exp1, exp=exp2, source=source)
2058 algorithm
2059
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 805 times.
805 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2060 ✗ print("Array assignment:\n"+DAEDump.ppStatementStr(stmt));
2061 end if;
2062 // replace, evaluate, simplify the assignment
2063 805 cref := Expression.expCref(exp1);
2064 805 scalars := getRecordScalars(cref);
2065 805 (exp2,_) := BackendVarTransform.replaceExp(exp2,repl,NONE());
2066 805 (exp2,exp1,funcTree,idx,addStmts) := evaluateConstantFunctionCall(exp2,exp1,funcTree,idx,recursionLimit);
2067 805 (exp2,_) := ExpressionSimplify.simplify(exp2);
2068 805 expLst := Expression.getComplexContents(exp2);
2069
2070 // add the replacements for the addStmts and remove the replacements for the variable outputs
2071 805 repl := List.fold(addStmts,addReplacementRuleForAssignment,repl);
2072 805 lhsExps := Expression.getComplexContents(exp1);
2073 805 outputs := List.map(lhsExps,Expression.expCref);
2074 805 BackendVarTransform.removeReplacements(repl,outputs);
2075
2076 // check if its constant, a record or a tuple
2077
3/4
✓ Branch 1 taken 254 times.
✓ Branch 2 taken 551 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 254 times.
805 isCon := Expression.isConst(exp2) and not Expression.isCall(exp2);
2078 805 eqDim := listLength(scalars) == listLength(expLst); // so it can be partly constant
2079 805 isRec := ComponentReference.isRecord(cref);
2080 805 isArr := ComponentReference.isArrayElement(cref);
2081
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 805 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
805 isTpl := Expression.isTuple(exp1) and Expression.isTuple(exp2);
2082
2083 // remove the variable crefs and add the constant crefs to the replacements
2084
3/4
✓ Branch 0 taken 805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 767 times.
805 scalars := if (isRec or isArr) and eqDim then scalars else {};
2085
3/4
✓ Branch 0 taken 805 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 767 times.
✓ Branch 3 taken 38 times.
805 expLst := if (isRec or isArr) and eqDim then expLst else {};
2086 805 (_,varScalars) := List.filterOnTrueSync(expLst,Expression.isNotConst,scalars);
2087 805 (expLst,constScalars) := List.filterOnTrueSync(expLst,Expression.isConst,scalars);
2088
2089
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 551 times.
805 repl := if isCon and not isRec then BackendVarTransform.addReplacement(repl,cref,exp2,NONE()) else repl;
2090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 805 times.
805 repl := if isCon and isRec then BackendVarTransform.addReplacements(repl,scalars,expLst,NONE()) else repl;
2091
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 551 times.
805 repl := if isCon and isArr then BackendVarTransform.addReplacements(repl,scalars,expLst,NONE()) else repl;
2092
2/2
✓ Branch 0 taken 551 times.
✓ Branch 1 taken 254 times.
805 if not isCon then
2093
1/2
✓ Branch 0 taken 551 times.
✗ Branch 1 not taken.
551 if not isRec then
2094 551 BackendVarTransform.removeReplacement(repl,cref);
2095 else
2096 ✗ BackendVarTransform.removeReplacements(repl,varScalars);
2097 ✗ repl := BackendVarTransform.addReplacements(repl,constScalars,expLst,NONE());
2098 end if;
2099 end if;
2100
2101 // build the new statements
2102
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 551 times.
805 stmt1 := if isCon then DAE.STMT_ASSIGN(typ,exp1,exp2,source) else stmt;
2103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 805 times.
805 tplExpsLHS := if isTpl then Expression.getComplexContents(exp1) else {};
2104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 805 times.
805 tplExpsRHS := if isTpl then Expression.getComplexContents(exp2) else {};
2105 805 tplStmts := makeAssignmentMap(tplExpsLHS,tplExpsRHS);
2106
1/2
✓ Branch 0 taken 805 times.
✗ Branch 1 not taken.
805 stmts1 := if isTpl then tplStmts else {stmt1};
2107
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 805 times.
805 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2108 ✗ print("evaluated array assignment to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
2109 end if;
2110 805 then stmts1;
2111
2112 case DAE.STMT_IF(statementLst=stmtsIf, else_=else_)
2113 algorithm
2114
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10947 times.
10950 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2115 3 print("IF-statement:\n"+DAEDump.ppStatementStr(stmt));
2116 end if;
2117
2118 // get all stmts in the function and the assigned crefs (need the outputs in order to remove the replacements if nothing can be evaluated)
2119 10950 stmtsList := getDAEelseStatemntLsts(else_,{});
2120 10950 stmtsList := listReverse(stmtsList);
2121 stmtsList := stmtsIf::stmtsList;
2122 10950 allStmts := List.flatten(stmtsList);
2123 10950 outputs := getStatementsOutputs(allStmts, funcTree);
2124
2125 //check if the conditions can be evaluated, get evaluated stmts
2126 10950 (isEval,stmts1,repl) := evaluateIfStatement(stmt,FUNCINFO(repl,funcTree,idx),recursionLimit);
2127
2128 // if its not definite which case, try to predict a constant output, maybe its partially constant, then remove function outputs replacements
2129
3/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10946 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
10949 if Flags.isSet(Flags.EVAL_FUNC_DUMP) and not isEval then
2130 3 print("-->try to predict the outputs \n");
2131 end if;
2132
2/2
✓ Branch 0 taken 7339 times.
✓ Branch 1 taken 3610 times.
10949 if not isEval then
2133 // Every branch is evaluated, so a speculation doubles what is used of the
2134 // limit; nested speculation runs out of it after a few levels.
2135 7339 ((stmtsNew,addStmts),FUNCINFO(repl,funcTree,idx)) := predictIfOutput(stmt,FUNCINFO(repl,funcTree,idx),max(0, 2*recursionLimit - Flags.getConfigInt(Flags.EVAL_RECURSION_LIMIT) - 1));
2136 else
2137 3610 stmtsNew := stmts1;
2138 3610 addStmts := {};
2139 end if;
2140
5/6
✓ Branch 0 taken 10033 times.
✓ Branch 1 taken 916 times.
✓ Branch 2 taken 793 times.
✓ Branch 3 taken 9240 times.
✓ Branch 4 taken 793 times.
✗ Branch 5 not taken.
10949 predicted := (not listEmpty(addStmts)) or listEmpty(stmtsNew) and not isEval;
2141
3/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10946 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
10949 if Flags.isSet(Flags.EVAL_FUNC_DUMP) and not isEval then
2142
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 print("could it be predicted? "+boolString(predicted)+"\n");
2143 end if;
2144
2145 // if nothing can be done, remove the replacements for the variables assigned in the if stmt
2146
2/2
✓ Branch 0 taken 6423 times.
✓ Branch 1 taken 4526 times.
10949 if not predicted and not isEval then
2147 6423 BackendVarTransform.removeReplacements(repl,outputs);
2148 end if;
2149
2150
2/2
✓ Branch 0 taken 10033 times.
✓ Branch 1 taken 916 times.
10949 stmts1 := if predicted then stmtsNew else stmts1;
2151
2152 10949 (addStmts,funcTree,repl,idx) := evaluateFunctions_updateStatement(addStmts,funcTree,repl,idx,{}, recursionLimit);
2153
2154
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10946 times.
10949 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2155 3 print("evaluated IF-statements to:\n"+stringDelimitList(List.map(listAppend(stmts1,addStmts),DAEDump.ppStatementStr),"\n")+"\n\n");
2156 end if;
2157 10949 then listAppend(stmts1, addStmts);
2158
2159 case DAE.STMT_TUPLE_ASSIGN(expExpLst=expLst, exp=exp0)
2160 algorithm
2161
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2041 times.
2041 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2162 ✗ print("Tuple-statement:\n"+DAEDump.ppStatementStr(stmt));
2163 end if;
2164 2041 (exp1,_) := BackendVarTransform.replaceExp(exp0,repl,NONE());
2165
2166 2041 exp2 := DAE.TUPLE(expLst);
2167 2041 (exp1,exp2,addEqs,funcTree,idx) := evaluateConstantFunction(exp1,exp2,funcTree,idx,{},recursionLimit);
2168 2041 isCon := Expression.isConst(exp1);
2169
2/2
✓ Branch 0 taken 419 times.
✓ Branch 1 taken 1622 times.
2041 exp1 := if isCon then exp1 else exp0;
2170
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2041 times.
2041 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2171 ✗ print("--> is the tuple const? "+boolString(isCon)+"\n");
2172 end if;
2173
2174 // add the replacements
2175 2041 varScalars := List.map(expLst,Expression.expCref);
2176
2/2
✓ Branch 0 taken 1622 times.
✓ Branch 1 taken 419 times.
2041 if not isCon then
2177 1622 BackendVarTransform.removeReplacements(repl,varScalars); // remove the lhs crefs if tis not constant
2178 else
2179 419 repl := addTplReplacements(repl,exp1,exp2); // add all tuple exps to repl if the whole tuple is constant
2180 end if;
2181
2182 // build the new statements
2183 2041 size := DAEUtil.getTupleSize(exp2);
2184 2041 typ := Expression.typeof(exp2);
2185
2186 2041 tplExpsLHS := DAEUtil.getTupleExps(exp2);
2187
2/2
✓ Branch 0 taken 1622 times.
✓ Branch 1 taken 419 times.
2041 tplExpsLHS := if isCon then tplExpsLHS else {};
2188 2041 tplExpsRHS := DAEUtil.getTupleExps(exp1);
2189
2/2
✓ Branch 0 taken 1622 times.
✓ Branch 1 taken 419 times.
2041 tplExpsRHS := if isCon then tplExpsRHS else {};
2190 2041 stmtsNew := makeAssignmentMap(tplExpsLHS,tplExpsRHS); // if the tuple is completely constant
2191
2192
2/2
✓ Branch 0 taken 1622 times.
✓ Branch 1 taken 418 times.
2040 stmtsNew := if isCon then stmtsNew else {stmt};
2193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2040 times.
2040 stmts2 := if intEq(size,0) then {DAE.STMT_ASSIGN(typ,exp2,exp1,DAE.emptyElementSource)} else stmtsNew;
2194 2040 stmts1 := List.map(addEqs,equationToStatement);
2195 2040 stmts1 := listAppend(stmts2,stmts1);
2196
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2040 times.
2040 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2197 ✗ print("evaluated Tuple-statements to (incl. addEqs):\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
2198 end if;
2199 2040 then listReverse(stmts1);
2200
2201 case DAE.STMT_FOR(statementLst=stmts1)
2202 algorithm
2203 // TODO: evaluate for-loops
2204
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 350 times.
350 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2205 ✗ print("For-statement:\n"+DAEDump.ppStatementStr(stmt));
2206 end if;
2207
2208 // lets see if we can evaluate it
2209 350 (stmts1,funcTree,repl,idx) := evaluateForStatement(stmt, funcTree,repl,idx,recursionLimit);
2210
2211
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 350 times.
350 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2212 ✗ print("evaluated for-statements to:\n"+stringDelimitList(List.map(stmts1,DAEDump.ppStatementStr),"\n")+"\n");
2213 end if;
2214 350 then listReverse(stmts1);
2215
2216 case DAE.STMT_WHILE(statementLst=stmts1)
2217 algorithm
2218 // TODO: evaluate while-loops
2219
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 435 times.
439 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2220 4 print("While-statement (not evaluated):\n"+DAEDump.ppStatementStr(stmt));
2221 end if;
2222 439 outputs := getStatementsOutputs(stmts1, funcTree);
2223 439 BackendVarTransform.removeReplacements(repl,outputs);
2224
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 435 times.
439 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2225 4 print("evaluated While-statement to:\n"+DAEDump.ppStatementStr(stmt));
2226 end if;
2227 then {stmt};
2228
2229 case DAE.STMT_ASSERT(cond=cond,msg=msg,level=lvl)
2230 algorithm
2231 7363 (cond,_) := BackendVarTransform.replaceExp(cond,repl,NONE());
2232 7363 cond := evaluateConstantFunctionCallExp(cond,funcTree, false, recursionLimit);
2233 7363 (cond,_) := ExpressionSimplify.simplify(cond);
2234 7363 (msg,_) := BackendVarTransform.replaceExp(msg,repl,NONE());
2235 7363 msg := evaluateConstantFunctionCallExp(msg,funcTree, false, recursionLimit);
2236 7363 (msg,_) := ExpressionSimplify.simplify(msg);
2237
4/6
✓ Branch 1 taken 279 times.
✓ Branch 2 taken 7084 times.
✓ Branch 4 taken 279 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 279 times.
✗ Branch 9 not taken.
7363 if ExpressionBasics.expEqual(cond,DAE.BCONST(false)) and Expression.sconstEnumNameString(lvl)=="AssertionLevel.error" then
2238
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 279 times.
279 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("ERROR: "+ExpressionBasics.printExpStr(msg)+"\n"); end if;
2239 279 fail();
2240 elseif ExpressionBasics.expEqual(cond,DAE.BCONST(false)) and Expression.sconstEnumNameString(lvl)=="AssertionLevel.warning" then
2241 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("WARNING: "+ExpressionBasics.printExpStr(msg)+"\n"); end if;
2242 ✗ fail();
2243 end if;
2244
2245
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7084 times.
7084 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2246 ✗ print("assert-statement:\n"+DAEDump.ppStatementStr(stmt));
2247 end if;
2248 then {stmt};
2249
2250 case DAE.STMT_TERMINATE()
2251 algorithm
2252 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2253 ✗ print("terminate-statement:\n"+DAEDump.ppStatementStr(stmt));
2254 end if;
2255 then {stmt};
2256
2257 case DAE.STMT_REINIT()
2258 algorithm
2259 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2260 ✗ print("reinit-statement:\n"+DAEDump.ppStatementStr(stmt));
2261 end if;
2262 then {stmt};
2263
2264 case DAE.STMT_NORETCALL()
2265 algorithm
2266
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
42 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2267 ✗ print("noretcall-statement (not evaluated):\n"+DAEDump.ppStatementStr(stmt));
2268 end if;
2269 then {stmt};
2270
2271 case DAE.STMT_RETURN()
2272 algorithm
2273 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2274 ✗ print("return-statement:\n"+DAEDump.ppStatementStr(stmt));
2275 end if;
2276 then {stmt};
2277
2278 end match
2279 for stmt in stmts);
2280
2281 49826 stmts := List.flatten(stmtsList);
2282 end evaluateFunctions_updateStatement;
2283
2284
2285 protected function evaluateForStatement"evaluates a for statement. nested for loops wont work"
2286 input DAE.Statement stmtIn;
2287 input AvlTreePathFunction.Tree funcTreeIn;
2288 input BackendVarTransform.VariableReplacements replIn;
2289 input Integer idxIn;
2290 input Integer recursionLimit;
2291 output list<DAE.Statement> stmtsOut;
2292 output AvlTreePathFunction.Tree funcTreeOut;
2293 output BackendVarTransform.VariableReplacements repl;
2294 output Integer idxOut;
2295 protected
2296 Boolean hasNoRepl;
2297 Integer i, start, stop ,step;
2298 DAE.Ident iter;
2299 DAE.Exp range;
2300 list<DAE.ComponentRef> outputs;
2301 list<DAE.Exp> lhsExps;
2302 list<list<DAE.Exp>> lhsExpLst;
2303 list<DAE.Statement> stmts = {},stmtsIn;
2304 algorithm
2305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 350 times.
350 DAE.STMT_FOR(iter=iter, range=range, statementLst=stmtsIn) := stmtIn;
2306 try
2307 350 (range,_) := BackendVarTransform.replaceExp(range,replIn,NONE());
2308 350 (start,stop,step) := getRangeBounds(range);
2309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 278 times.
278 true := intEq(step,1);
2310
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 274 times.
278 true := intGe(stop,start);
2311 274 repl := replIn;
2312 278 for i in start:stop loop
2313 278 repl := BackendVarTransform.addReplacement(repl, ComponentReferenceBasics.makeCrefIdent(iter,DAE.T_INTEGER_DEFAULT,{}),DAE.ICONST(i),NONE());
2314 278 (stmts,_,repl,_) := evaluateFunctions_updateStatement(stmtsIn,funcTreeIn,repl,i,{},recursionLimit);
2315
2316 // check if any variable has been evaluated. If not, skip the loop (this is necessary for testsuite/modelica/linear_systems/problem1.mos)
2317 278 outputs := getStatementsOutputs(stmts, funcTreeIn);
2318 278 hasNoRepl := List.applyAndFold1(outputs,boolAnd,BackendVarTransform.hasNoReplacement,repl,true);
2319
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 4 times.
278 if hasNoRepl then
2320
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
274 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then print("For-loop evaluation is skipped, since the first loop evaluated nothing.\n"); end if;
2321 274 fail();
2322 end if;
2323 end for;
2324 ✗ BackendVarTransform.removeReplacement(repl,ComponentReferenceBasics.makeCrefIdent(iter,DAE.T_INTEGER_DEFAULT,{}));
2325 funcTreeOut := funcTreeIn;
2326 idxOut := idxIn;
2327 ✗ stmtsOut := stmts;
2328 else
2329 // at least remove the replacements for the lhs so we dont declare something as constant which isnt
2330 350 lhsExps := List.fold(stmtsIn,getStatementLHS,{});
2331 350 lhsExps := List.unique(lhsExps);
2332 350 lhsExpLst := List.map(lhsExps,Expression.getComplexContents); //consider arrays etc.
2333 350 lhsExps := listAppend(List.flatten(lhsExpLst),lhsExps);
2334
5/6
✗ Branch 1 not taken.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 527 times.
✓ Branch 4 taken 350 times.
✓ Branch 5 taken 527 times.
✓ Branch 6 taken 350 times.
877 outputs := list(Expression.expCref(e) for e guard Expression.isCref(e) in lhsExps); //remove e.g. ASUBs and consider only the scalar subs
2335 350 repl := replIn;
2336 350 BackendVarTransform.removeReplacements(repl,outputs);
2337 stmtsOut := {stmtIn};
2338 funcTreeOut := funcTreeIn;
2339 idxOut := idxIn;
2340 end try;
2341 end evaluateForStatement;
2342
2343 protected function getRangeBounds
2344 input DAE.Exp range;
2345 output Integer start;
2346 output Integer stop;
2347 output Integer step;
2348 algorithm
2349 (start, stop, step) := match range
2350 local
2351 Integer i1,i2,i3;
2352 case DAE.RANGE(start=DAE.ICONST(i1),step=NONE(),stop=DAE.ICONST(i2))
2353 algorithm
2354 then (i1,i2,1);
2355 case DAE.RANGE(start=DAE.ICONST(i1),step=SOME(DAE.ICONST(i3)),stop=DAE.ICONST(i2))
2356 then (i1,i2,i3);
2357 else
2358 algorithm
2359 //print("getRangeBounds failed!"+ExpressionBasics.printExpStr(range)+"\n");
2360 then fail();
2361 end match;
2362 end getRangeBounds;
2363
2364
2365 protected function evaluateIfStatement "check if the cases are constant and if so evaluate them.
2366 author: Waurich TUD 2014-04"
2367 input DAE.Statement stmtIn;
2368 input FuncInfo info;
2369 input Integer recursionLimit;
2370 output Boolean isEval;
2371 output list<DAE.Statement> stmtsOut;
2372 output BackendVarTransform.VariableReplacements replOut;
2373 algorithm
2374 (isEval,stmtsOut,replOut) := matchcontinue(stmtIn,info)
2375 local
2376 Boolean isIf, isCon, isElse, eval;
2377 Integer idx;
2378 BackendVarTransform.VariableReplacements repl, replIn;
2379 DAE.Else else_;
2380 DAE.Exp expIf,exp1;
2381 AvlTreePathFunction.Tree funcTree;
2382 list<DAE.Statement> stmtsIf,stmts1,stmtsElse;
2383 case(DAE.STMT_IF(exp=expIf, statementLst=stmtsIf, else_=else_),FUNCINFO(repl=replIn, funcTree=funcTree, idx=idx))
2384 algorithm
2385 //check if its the if
2386
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10947 times.
10950 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2387 3 print("-->try to check if its the if case\n");
2388 end if;
2389 10950 (exp1,_) := BackendVarTransform.replaceExp(expIf,replIn,NONE());
2390 10950 exp1 := evaluateConstantFunctionCall(exp1,exp1,funcTree,idx,recursionLimit);
2391 10950 (exp1,_) := BackendVarTransform.replaceExp(exp1,replIn,NONE());
2392 10950 (exp1,_) := ExpressionSimplify.simplify(exp1);
2393 10950 isCon := Expression.isConst(exp1);
2394
2/2
✓ Branch 0 taken 3615 times.
✓ Branch 1 taken 7335 times.
10950 isIf := if isCon then Expression.toBool(exp1) else false;
2395
2396 // check if its the IF case, if true then evaluate:
2397
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10947 times.
10950 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2398
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
9 print("-->is the if const? "+boolString(isCon)+" and is it the if case ? "+boolString(isIf)+"\n");
2399 end if;
2400
2/2
✓ Branch 0 taken 1864 times.
✓ Branch 1 taken 9086 times.
10950 if isIf and isCon then
2401 1864 (stmts1,funcTree,repl,idx) := evaluateFunctions_updateStatement(stmtsIf,funcTree,replIn,idx,{},recursionLimit); // without listIn
2402 else
2403 stmts1 := {stmtIn};
2404 9086 repl := replIn;
2405 end if;
2406
2407 // if its definitly not the if, check the else
2408
3/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10947 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
10950 if Flags.isSet(Flags.EVAL_FUNC_DUMP) and not isIf then
2409 3 print("-->try to check if its another case\n");
2410 end if;
2411
2/2
✓ Branch 0 taken 1751 times.
✓ Branch 1 taken 9199 times.
10950 if isCon and not isIf then
2412 1751 (stmtsElse,isElse) := evaluateElse(else_,info,recursionLimit);
2413 else
2414 stmtsElse := {stmtIn};
2415 9199 isElse := false;
2416 end if;
2417
3/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10947 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
10950 if Flags.isSet(Flags.EVAL_FUNC_DUMP) and not isIf then
2418
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 print("-->is it an other case? "+boolString(isElse)+"\n");
2419 end if;
2420
4/4
✓ Branch 0 taken 3615 times.
✓ Branch 1 taken 7335 times.
✓ Branch 2 taken 1747 times.
✓ Branch 3 taken 1868 times.
10950 if isCon and isElse then
2421 1747 (stmts1,funcTree,repl,idx) := evaluateFunctions_updateStatement(stmtsElse,funcTree,replIn,idx,{},recursionLimit);
2422 else
2423 end if;
2424
6/6
✓ Branch 0 taken 3614 times.
✓ Branch 1 taken 7335 times.
✓ Branch 2 taken 1750 times.
✓ Branch 3 taken 1864 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 1746 times.
10949 eval := isCon and (isIf or isElse);
2425
1/2
✓ Branch 0 taken 10949 times.
✗ Branch 1 not taken.
10949 then
2426 (eval,stmts1,repl);
2427 else
2428 algorithm
2429
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2430 ✗ print("evaluateIfStatement failed \n");
2431 end if;
2432 1 then
2433 fail();
2434 end matchcontinue;
2435 end evaluateIfStatement;
2436
2437 protected function evaluateElse "checks if its one of the elseif cases.
2438 author: Waurich TUD 2014-04"
2439 input DAE.Else elseIn;
2440 input FuncInfo info;
2441 input Integer recursionLimit;
2442 output list<DAE.Statement> stmtsOut;
2443 output Boolean isElse;
2444 algorithm
2445 (stmtsOut,isElse) := match(elseIn,info)
2446 local
2447 Boolean isCon,isElseIf;
2448 Integer idx;
2449 BackendVarTransform.VariableReplacements replIn;
2450 DAE.Exp expIf,exp1;
2451 DAE.Else else_;
2452 AvlTreePathFunction.Tree funcTree;
2453 list<DAE.Statement> stmts;
2454 case(DAE.ELSEIF(exp=expIf,statementLst=stmts,else_=else_),FUNCINFO(repl=replIn, funcTree=funcTree, idx=idx))
2455 algorithm
2456 // check if its the elseif
2457
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2458 ✗ print("-->try to check if its the elseif case\n");
2459 end if;
2460 10 exp1 := evaluateConstantFunctionCall(expIf,expIf,funcTree,idx,recursionLimit);
2461 10 (exp1,_) := BackendVarTransform.replaceExp(exp1,replIn,NONE());
2462 10 (exp1,_) := ExpressionSimplify.simplify(exp1);
2463 10 isCon := Expression.isConst(exp1);
2464
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 isElseIf := if isCon then Expression.toBool(exp1) else false;
2465
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
10 if isCon and not isElseIf then
2466 4 (stmts,isElseIf) := evaluateElse(else_,info,recursionLimit);
2467 end if;
2468 10 then
2469 (stmts,isElseIf);
2470 case(DAE.ELSE(statementLst=stmts),FUNCINFO())
2471 algorithm
2472 // if everything else was const and false, it has to be the else
2473 then
2474 (stmts,true);
2475 case(DAE.NOELSE(),FUNCINFO())
2476 then
2477 ({},true);
2478 end match;
2479 end evaluateElse;
2480
2481 protected function addTplReplacements
2482 input BackendVarTransform.VariableReplacements replIn;
2483 input DAE.Exp e1;
2484 input DAE.Exp e2;
2485 output BackendVarTransform.VariableReplacements replOut;
2486 algorithm
2487 replOut := matchcontinue e2
2488 local
2489 list<DAE.Exp> tplLHS, tplRHS;
2490 list<DAE.ComponentRef> crefs;
2491 BackendVarTransform.VariableReplacements repl;
2492 case _
2493 algorithm
2494 419 tplRHS := DAEUtil.getTupleExps(e1);
2495 419 tplLHS := DAEUtil.getTupleExps(e2);
2496 419 crefs := List.map(tplLHS,Expression.expCref);
2497 419 repl := BackendVarTransform.addReplacements(replIn,crefs,tplRHS,NONE());
2498 //print("add the tpl replacements: "+stringDelimitList(List.map(crefs,ComponentReferenceBasics.printComponentRefStr),",")+stringDelimitList(List.map(tplRHS,ExpressionBasics.printExpStr),",")+"\n");
2499 then
2500 repl;
2501 else
2502 replIn;
2503 end matchcontinue;
2504 end addTplReplacements;
2505
2506 protected function equationToStatement "converts a simple BackendDAE.Equation to a DAE.Statement
2507 author:Waurich TUD 2014-04"
2508 input BackendDAE.Equation eqIn;
2509 output DAE.Statement stmtOut;
2510 algorithm
2511 stmtOut := match eqIn
2512 local
2513 DAE.ElementSource source;
2514 DAE.Exp rhs,lhs;
2515 DAE.Type typ;
2516 case BackendDAE.EQUATION(exp=lhs,scalar=rhs,source=source)
2517 algorithm
2518 735 typ := Expression.typeof(lhs);
2519 735 then
2520 DAE.STMT_ASSIGN(typ,lhs,rhs,source);
2521 else
2522 algorithm
2523 ✗ print("equationToStatement failed!\n");
2524 ✗ then fail();
2525 end match;
2526 end equationToStatement;
2527
2528 protected function replaceExps "mapping function that replaces the expressions. the mapping values are replacement lsts
2529 author:Waurich TUD 2014-04"
2530 input BackendVarTransform.VariableReplacements replIn;
2531 input list<DAE.Exp> expsIn;
2532 output list<DAE.Exp> expsOut;
2533 algorithm
2534 14393 (expsOut,_) := List.map2_2(expsIn,BackendVarTransform.replaceExp,replIn,NONE());
2535 end replaceExps;
2536
2537 protected function getStatementLHS "fold function to get the lhs expressions of a statement
2538 author:Waurich TUD 2014-04"
2539 input DAE.Statement stmt;
2540 input list<DAE.Exp> expsIn;
2541 output list<DAE.Exp> lhs;
2542 algorithm
2543 lhs := match stmt
2544 local
2545 DAE.Else else_;
2546 DAE.Exp exp;
2547 DAE.Statement stmt1;
2548 list<DAE.Exp> expLst;
2549 list<DAE.Statement> stmtLst1,stmtLst2;
2550 list<list<DAE.Statement>> stmtLstLst;
2551 case DAE.STMT_ASSIGN(exp1=exp)
2552 then
2553 exp::expsIn;
2554 case DAE.STMT_TUPLE_ASSIGN(expExpLst=expLst)
2555 858 then listAppend(expLst, expsIn);
2556 case DAE.STMT_ASSIGN_ARR(lhs=exp)
2557 then exp::expsIn;
2558 case DAE.STMT_IF(statementLst=stmtLst1,else_=else_)
2559 algorithm
2560 28523 stmtLstLst := getDAEelseStatemntLsts(else_,{});
2561 28523 stmtLst2 := List.flatten(stmtLstLst);
2562 28523 stmtLst2 := listAppend(stmtLst1,stmtLst2);
2563 28523 expLst := List.fold(stmtLst2,getStatementLHS,expsIn);
2564 then expLst;
2565 case DAE.STMT_FOR(statementLst=stmtLst1)
2566 algorithm
2567 296 expLst := List.fold(stmtLst1,getStatementLHS,expsIn);
2568 then expLst;
2569 case DAE.STMT_PARFOR(statementLst=stmtLst1)
2570 algorithm
2571 ✗ expLst := List.fold(stmtLst1,getStatementLHS,expsIn);
2572 then expLst;
2573 case DAE.STMT_WHILE(statementLst=stmtLst1)
2574 algorithm
2575 32 expLst := List.fold(stmtLst1,getStatementLHS,expsIn);
2576 then expLst;
2577 case DAE.STMT_WHEN(statementLst=stmtLst1,elseWhen=SOME(stmt1))
2578 algorithm
2579 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2580 ✗ print(" check getStatementLHS for WHEN!\n"+DAEDump.ppStatementStr(stmt));
2581 end if;
2582 ✗ expLst := List.fold(stmtLst1,getStatementLHS,expsIn);
2583 ✗ expLst := getStatementLHS(stmt1,expLst);
2584 then expLst;
2585 case DAE.STMT_WHEN(statementLst=stmtLst1,elseWhen=NONE())
2586 algorithm
2587 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2588 ✗ print(" check getStatementLHS for WHEN!\n"+DAEDump.ppStatementStr(stmt));
2589 end if;
2590 ✗ expLst := List.fold(stmtLst1,getStatementLHS,expsIn);
2591 then expLst;
2592 case DAE.STMT_ASSERT()
2593 algorithm
2594 //bcall1(Flags.isSet(Flags.EVAL_FUNC_DUMP),print,"getStatementLHS update for ASSERT!\n"+DAEDump.ppStatementStr(stmt));
2595 then expsIn;
2596 case DAE.STMT_TERMINATE()
2597 algorithm
2598 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2599 ✗ print("getStatementLHS update for TERMINATE!\n"+DAEDump.ppStatementStr(stmt));
2600 end if;
2601 ✗ then fail();
2602 case DAE.STMT_REINIT()
2603 algorithm
2604 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2605 ✗ print("getStatementLHS update for REINIT!\n"+DAEDump.ppStatementStr(stmt));
2606 end if;
2607 ✗ then fail();
2608 case DAE.STMT_NORETCALL()
2609 then expsIn;
2610 case DAE.STMT_RETURN()
2611 algorithm
2612 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2613 ✗ print("getStatementLHS update for RETURN!\n"+DAEDump.ppStatementStr(stmt));
2614 end if;
2615 ✗ then fail();
2616 case DAE.STMT_BREAK()
2617 algorithm
2618 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2619 ✗ print("getStatementLHS update for BREAK!\n"+DAEDump.ppStatementStr(stmt));
2620 end if;
2621 ✗ then fail();
2622 case DAE.STMT_ARRAY_INIT()
2623 algorithm
2624 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2625 ✗ print("getStatementLHS update for ARRAY_INIT!\n"+DAEDump.ppStatementStr(stmt));
2626 end if;
2627 ✗ then fail();
2628 else
2629 algorithm
2630 ✗ print("getStatementLHS update for !\n"+DAEDump.ppStatementStr(stmt));
2631 ✗ then fail();
2632 end match;
2633 end getStatementLHS;
2634
2635 protected function getStatementLHSScalar "fold function to get the assigned scalar lhs expressions of a statement
2636 TODO: move to getStatementLHS
2637 author:Waurich TUD 2014-04"
2638 input DAE.Statement stmt;
2639 input AvlTreePathFunction.Tree funcTree;
2640 input list<DAE.Exp> expsIn;
2641 output list<DAE.Exp> lhs;
2642 algorithm
2643 lhs := matchcontinue stmt
2644 local
2645 Absyn.Path path;
2646 DAE.ComponentRef lhsCref;
2647 DAE.Exp exp;
2648 DAE.Function func;
2649 list<DAE.ComponentRef> outputCrefs;
2650 list<DAE.Element> algs,elements;
2651 list<DAE.Exp> expLst;
2652 list<DAE.Statement> stmtLst1;
2653 list<list<DAE.Statement>> stmtLstLst;
2654 case DAE.STMT_ASSIGN(exp1=exp,exp=DAE.CALL(path=path))
2655 algorithm
2656
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 13857 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13857 times.
19209 SOME(func) := AvlTreePathFunction.get(funcTree,path);
2657 13857 elements := DAEUtil.getFunctionElements(func);
2658 13857 algs := List.filterOnTrue(elements,DAEUtil.isAlgorithm);
2659 13857 stmtLstLst := List.map(algs,DAEUtil.getStatement);
2660 13857 stmtLst1 := List.flatten(stmtLstLst);
2661 13857 expLst := List.fold1(stmtLst1,getStatementLHSScalar,funcTree,{});
2662 13857 outputCrefs := List.map(expLst,Expression.expCref);
2663
2664 13857 lhsCref := Expression.expCref(exp);
2665 13857 outputCrefs := List.filterOnTrue(outputCrefs,ComponentReference.crefIsNotIdent);
2666 13857 outputCrefs := List.map(outputCrefs,ComponentReference.crefStripFirstIdent);
2667 13857 outputCrefs := List.map1(outputCrefs,ComponentReference.joinCrefsR,lhsCref);
2668
2669 13857 expLst := List.map(outputCrefs,Expression.crefExp);
2670 13857 then
2671 listAppend(expLst,expsIn);
2672
2673 case DAE.STMT_ASSIGN_ARR(lhs=exp)
2674 algorithm
2675 7 expLst := Expression.getComplexContents(exp);
2676 7 then
2677 listAppend(expLst, expsIn);
2678
2679 else
2680 algorithm
2681 304448 expLst := getStatementLHS(stmt,{});
2682 304448 then
2683 listAppend(expLst, expsIn);
2684
2685 end matchcontinue;
2686 end getStatementLHSScalar;
2687
2688 function getStatementsOutputs
2689 input list<DAE.Statement> statements;
2690 input AvlTreePathFunction.Tree funcTree;
2691 output list<DAE.ComponentRef> outputs;
2692 protected
2693 list<DAE.Exp> lhs_expl;
2694 HashSetExp.HashSet lhs_set;
2695 algorithm
2696 11667 lhs_expl := List.fold1(statements, getStatementLHSScalar, funcTree, {});
2697
2698 // Use a hash set to get a list of unique elements.
2699 11667 lhs_set := HashSetExp.emptyHashSetSized(Util.nextPrime(listLength(lhs_expl)));
2700 11667 lhs_set := List.fold(lhs_expl, BaseHashSet.add, lhs_set);
2701
2702
4/4
✓ Branch 1 taken 82419 times.
✓ Branch 2 taken 11667 times.
✓ Branch 3 taken 82419 times.
✓ Branch 4 taken 11667 times.
94086 outputs := list(Expression.expCref(e) for e in BaseHashSet.hashSetList(lhs_set));
2703 end getStatementsOutputs;
2704
2705 protected function getDAEelseStatemntLsts "get all statements for every else or elseif clause
2706 author:Waurich TUD 2014"
2707 input DAE.Else elseIn;
2708 input list<list<DAE.Statement>> stmtLstsIn;
2709 output list<list<DAE.Statement>> stmtLstsOut;
2710 algorithm
2711 stmtLstsOut := match elseIn
2712 local
2713 DAE.Else else1;
2714 list<DAE.Statement> stmts;
2715 list<list<DAE.Statement>> stmtsLst;
2716 case DAE.ELSEIF(statementLst=stmts,else_=else1)
2717 algorithm
2718 stmtsLst := stmts::stmtLstsIn;
2719 5625 stmtsLst := getDAEelseStatemntLsts(else1,stmtsLst);
2720 then
2721 stmtsLst;
2722 case DAE.ELSE(statementLst=stmts)
2723 algorithm
2724 stmtsLst := stmts::stmtLstsIn;
2725 then
2726 stmtsLst;
2727 else
2728 stmtLstsIn;
2729 end match;
2730 end getDAEelseStatemntLsts;
2731
2732 protected function evaluateConstantFunctionCall
2733 input DAE.Exp exp;
2734 input DAE.Exp lhs;
2735 input AvlTreePathFunction.Tree funcs;
2736 input Integer eqIdx;
2737 input Integer recursionLimit;
2738 output DAE.Exp outExp;
2739 output DAE.Exp outLhs;
2740 output AvlTreePathFunction.Tree outFuncs;
2741 output Integer outEqIdx;
2742 output list<DAE.Statement> addedStmts;
2743 algorithm
2744
2/2
✓ Branch 4 taken 341702 times.
✓ Branch 5 taken 10960 times.
352662 (outExp, (outLhs, outFuncs, outEqIdx, addedStmts)) :=
2745 Expression.traverseExpTopDown(exp, function evaluateConstantFunction_traverser(recursionLimit = recursionLimit), (lhs, funcs, eqIdx, {}));
2746 end evaluateConstantFunctionCall;
2747
2748 protected function evaluateConstantFunction_traverser
2749 input DAE.Exp inExp;
2750 input tuple<DAE.Exp, AvlTreePathFunction.Tree,Integer,list<DAE.Statement>> inTpl;
2751 input Integer recursionLimit;
2752 output DAE.Exp outExp;
2753 output Boolean cont;
2754 output tuple<DAE.Exp,AvlTreePathFunction.Tree,Integer,list<DAE.Statement>> outTpl;
2755 algorithm
2756 (outExp,cont,outTpl) := matchcontinue(inExp,inTpl)
2757 local
2758 Integer idx;
2759 DAE.Exp rhs, lhs;
2760 AvlTreePathFunction.Tree funcs;
2761 list<BackendDAE.Equation> addEqs;
2762 list<DAE.Statement> stmts,stmtsIn;
2763 tuple<DAE.Exp, AvlTreePathFunction.Tree,Integer,list<DAE.Statement>> tpl;
2764 case (DAE.CALL(),(lhs,funcs,idx,stmtsIn))
2765 algorithm
2766 22374 (rhs,lhs,addEqs,funcs,idx) := evaluateConstantFunction(inExp,lhs,funcs,idx,{},recursionLimit);
2767 22374 stmts := List.map(addEqs,equationToStmt);
2768 22374 then (rhs,true,(lhs,funcs,idx,listAppend(stmts, stmtsIn)));
2769
2770 case (DAE.UNBOX(exp=rhs),_)
2771 algorithm
2772 71 (rhs,_,tpl) := evaluateConstantFunction_traverser(rhs,inTpl,recursionLimit);
2773 71 then (rhs,true,tpl);
2774
2775 else (inExp,false,inTpl);
2776 end matchcontinue;
2777 end evaluateConstantFunction_traverser;
2778
2779 protected function equationToStmt "transforms a backend equation into a statement"
2780 input BackendDAE.Equation eqIn;
2781 output DAE.Statement stmtOut;
2782 algorithm
2783 stmtOut := matchcontinue eqIn
2784 local
2785 DAE.ElementSource source;
2786 DAE.Exp lhs,rhs;
2787 DAE.Type typ;
2788 case BackendDAE.EQUATION(exp=lhs,scalar=rhs,source=source)
2789 algorithm
2790 5398 typ := expType(lhs);
2791 5398 then
2792 DAE.STMT_ASSIGN(typ,lhs,rhs,source);
2793 else
2794 algorithm
2795 ✗ print("equationToStmt failed for: "+BackendDump.dumpEqnsStr({eqIn})+"\n");
2796 ✗ then fail();
2797 end matchcontinue;
2798 end equationToStmt;
2799
2800 protected function expType "gets the type of an expression"
2801 input DAE.Exp eIn;
2802 output DAE.Type tOut;
2803 algorithm
2804 tOut := match eIn
2805 local
2806 DAE.Type t;
2807 case DAE.CREF(ty=t)
2808 then
2809 t;
2810 else
2811 algorithm
2812 ✗ print("expType failed for: "+ExpressionBasics.printExpStr(eIn)+"\n");
2813 ✗ then
2814 fail();
2815 end match;
2816 end expType;
2817
2818 protected function getScalarsForComplexVar "gets the list<ComponentRef> for the scalar values of complex vars and multidimensional vars (at least real) .
2819 author: Waurich TUD 2014-03"
2820 input DAE.Element inElem;
2821 output list<DAE.ComponentRef> crefsOut;
2822 algorithm
2823 crefsOut := matchcontinue inElem
2824 local
2825 list<DAE.Dimension> dims;
2826 list<list<DAE.Subscript>> subslst, subslst1, subslst2;
2827 DAE.ComponentRef cref;
2828 DAE.Dimensions dimensions, dimensions2;
2829 DAE.Type ty;
2830 list<DAE.Var> varLst;
2831 list<DAE.ComponentRef> crefs;
2832 list<list<DAE.ComponentRef>> crefLst;
2833 list<DAE.Type> types;
2834 list<String> names;
2835 case DAE.VAR(componentRef = cref,ty=DAE.T_COMPLEX(varLst = varLst))
2836 algorithm
2837 17600 names := List.map(varLst,DAEUtil.typeVarIdent);
2838 //print("the names for the scalar complex crefs: "+stringDelimitList(names,"\n;")+"\n");
2839 17600 types := List.map(varLst,DAEUtil.varType);
2840 17600 crefs := List.map1(names,ComponentReference.appendStringCref,cref);
2841 17600 crefs := setTypesForScalarCrefs(crefs,types);
2842 17600 crefLst := List.map1(crefs,ComponentReference.expandCref,true);
2843 17600 crefs := List.flatten(crefLst);
2844 then
2845 crefs;
2846
2847 case DAE.VAR(componentRef=cref,ty=DAE.T_REAL(), dims=dims )
2848 algorithm
2849 31237 subslst := expandDimension(dims,{});
2850 31229 crefs := List.map1r(subslst,ComponentReference.subscriptCref,cref);
2851 then
2852 crefs;
2853
2854 case DAE.VAR(componentRef=cref,ty=DAE.T_INTEGER(), dims=dims )
2855 algorithm
2856 1233 subslst := expandDimension(dims,{});
2857 1233 crefs := List.map1r(subslst,ComponentReference.subscriptCref,cref);
2858 then
2859 crefs;
2860
2861 case DAE.VAR(componentRef=cref,ty=DAE.T_ARRAY(ty=DAE.T_ARRAY(ty=ty, dims=dimensions2), dims=dimensions))// a 2-dim array
2862 algorithm
2863 ✗ subslst1 := expandDimension(dimensions,{});
2864 ✗ subslst2 := expandDimension(dimensions2,{});
2865 subslst := {};
2866 ✗ for subs in subslst1 loop
2867 ✗ for subs2 in subslst2 loop
2868 ✗ subslst := listAppend(subs,subs2)::subslst;
2869 end for;
2870 end for;
2871 ✗ crefs := List.map1r(subslst,ComponentReference.subscriptCref,cref);
2872 then
2873 crefs;
2874
2875 case DAE.VAR(componentRef=cref,ty=DAE.T_ARRAY(dims=dimensions))
2876 algorithm
2877 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2878 ✗ print("the array cref before\n"+stringDelimitList(List.map({cref},ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
2879 end if;
2880 ✗ crefs := ComponentReference.expandArrayCref(cref,dimensions);
2881 then
2882 crefs;
2883 case DAE.VAR(componentRef=cref,ty=DAE.T_ENUMERATION())
2884 algorithm
2885 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2886 ✗ print("update getScalarsForComplexVar for enumerations: the enum cref is :"+stringDelimitList(List.map({cref},ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
2887 end if;
2888 then
2889 {};
2890 case DAE.VAR(componentRef=cref,ty=DAE.T_TUPLE())
2891 algorithm
2892 ✗ if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
2893 ✗ print("update getScalarsForComplexVar for tuple types: the tupl cref is :\n"+stringDelimitList(List.map({cref},ComponentReferenceBasics.printComponentRefStr),"\n")+"\n");
2894 end if;
2895 then
2896 {};
2897 else
2898 algorithm
2899 then
2900 {};
2901 end matchcontinue;
2902 end getScalarsForComplexVar;
2903
2904 protected function expandDimension"expands the dimensions. e.g. [3,3] {{1,1},{1,2},{1,3}, {2,1},{2,2},{2,3}, {3,1},{3,2},{3,3}}"
2905 input list<DAE.Dimension> dims;
2906 input list<list<DAE.Subscript>> subsIn;
2907 output list<list<DAE.Subscript>> subsOut;
2908 algorithm
2909 subsOut := match dims
2910 local
2911 Integer size;
2912 list<Integer> range;
2913 DAE.Dimension dim;
2914 DAE.Subscript sub;
2915 list<DAE.Dimension> rest;
2916 list<DAE.Subscript> subs;
2917 list<list<DAE.Subscript>> subsLst, subsLst1, subFold = {};
2918 case dim::rest
2919 algorithm
2920 2566 size := Expression.dimensionSize(dim);
2921 2558 range := List.intRange(size);
2922 2558 subs := List.map(range, Expression.intSubscript);
2923 2558 subsLst := List.map(subs,List.create);
2924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2558 times.
2558 for sub in subsIn loop
2925 ✗ subsLst1 := List.map1r(subsLst,listAppend,sub);
2926 ✗ subFold := listAppend(subFold,subsLst1) annotation(__OpenModelica_DisableListAppendWarning=true);
2927 end for;
2928
1/2
✓ Branch 0 taken 2558 times.
✗ Branch 1 not taken.
2558 if listEmpty(subsIn) then subFold := subsLst; end if;
2929 2558 then expandDimension(rest,subFold);
2930 case {}
2931 algorithm
2932 then subsIn;
2933 end match;
2934 end expandDimension;
2935
2936 protected function subsLstString
2937 input list<DAE.Subscript> subs;
2938 output String s;
2939 algorithm
2940 ✗ s := "{"+stringDelimitList(List.map(subs,ExpressionDump.subscriptString),",")+"}";
2941 end subsLstString;
2942
2943 protected function isNotComplexVar "returns true if the given var is one dimensional (no array,record...).
2944 author: Waurich TUD 2014-03"
2945 input DAE.Element inElem;
2946 output Boolean b;
2947 algorithm
2948 b := matchcontinue inElem
2949 local
2950 list<Integer> dimints;
2951 list<DAE.Dimension> dims;
2952
2953 case DAE.VAR(ty=DAE.T_COMPLEX(_)) then false;
2954
2955 case DAE.VAR(ty=DAE.T_REAL(_), dims=dims)
2956 algorithm
2957 39652 dimints := List.map(dims, Expression.dimensionSize);
2958
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1167 times.
39417 true := listHead(dimints) <> 0;
2959 then
2960 false;
2961
2962 case DAE.VAR(ty=DAE.T_INTEGER(_), dims=dims)
2963 algorithm
2964 935 dimints := List.map(dims, Expression.dimensionSize);
2965
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
935 true := listHead(dimints) <> 0;
2966 then
2967 false;
2968
2969 case DAE.VAR(ty=DAE.T_ARRAY(_)) then false;
2970 else true;
2971 end matchcontinue;
2972 end isNotComplexVar;
2973
2974 protected function setTypesForScalarCrefs
2975 input list<DAE.ComponentRef> allCrefs;
2976 input list<DAE.Type> types;
2977 output list<DAE.ComponentRef> crefsOut;
2978 algorithm
2979
7/8
✓ Branch 0 taken 198987 times.
✓ Branch 1 taken 17600 times.
✓ Branch 2 taken 198987 times.
✓ Branch 3 taken 17600 times.
✓ Branch 4 taken 198987 times.
✓ Branch 5 taken 17600 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 17600 times.
216587 crefsOut := list(ComponentReference.crefSetLastType(cr, ty)
2980 threaded for cr in allCrefs, ty in types);
2981 end setTypesForScalarCrefs;
2982
2983 public function getRecordScalars "gets all crefs from a record"
2984 input DAE.ComponentRef crefIn;
2985 output list<DAE.ComponentRef> crefsOut;
2986 algorithm
2987 try
2988 342128 crefsOut := ComponentReference.expandCref(crefIn, true);
2989 else
2990 crefsOut := {};
2991 end try;
2992 end getRecordScalars;
2993
2994 protected function getScalarExpSize "gets the number of scalars of an expression.
2995 author:Waurich TUD 2014-04"
2996 input DAE.Exp inExp;
2997 output Integer size;
2998 algorithm
2999 size := match inExp
3000 local
3001 DAE.ComponentRef cref;
3002 list<DAE.Exp> exps;
3003 list<DAE.Var> vl;
3004 list<DAE.Type> tyl;
3005 Integer exps_len;
3006
3007 // tuple
3008 case DAE.TUPLE(exps as _ :: _)
3009 algorithm
3010 ✗ exps_len := intAdd(1 for exp guard(Expression.isNotWild(exp)) in exps);
3011 ✗ size := intAdd(getScalarExpSize(exp) for exp in exps);
3012 then
3013 max(size, exps_len);
3014
3015 // record cref
3016 case DAE.CREF(ty = DAE.T_COMPLEX(varLst = vl as _ :: _))
3017 ✗ then intAdd(getScalarVarSize(v) for v in vl);
3018
3019 // array cref
3020 case DAE.CREF(componentRef = cref)
3021 algorithm
3022 ✗ size := if ComponentReference.isArrayElement(cref) then
3023 listLength(ComponentReference.expandCref(cref, true)) else 1;
3024 then
3025 size;
3026
3027 case DAE.CALL(attr = DAE.CALL_ATTR(ty = DAE.T_COMPLEX(varLst = vl as _ :: _)))
3028 ✗ then intAdd(getScalarVarSize(v) for v in vl);
3029
3030 case DAE.CALL(attr = DAE.CALL_ATTR(ty = DAE.T_TUPLE(types = tyl as _ :: _)))
3031 algorithm
3032 size := 0;
3033 ✗ for ty in tyl loop
3034 ✗ vl := getVarLstFromType(ty);
3035
3036 ✗ if not listEmpty(vl) then
3037 ✗ size := size + intAdd(getScalarVarSize(v) for v in vl);
3038 end if;
3039 end for;
3040 then
3041 size;
3042
3043 else 0;
3044 end match;
3045 end getScalarExpSize;
3046
3047 protected function getVarLstFromType "gets the list of DAE.Var from a DAE.Type
3048 author:Waurich TUD 2014-04"
3049 input DAE.Type tyIn;
3050 output list<DAE.Var> varsOut;
3051 algorithm
3052 varsOut := match tyIn
3053 local
3054 list<DAE.Var> varLst;
3055 list<DAE.Type> tyLst;
3056
3057 case DAE.T_TUPLE(types = tyLst as _ :: _)
3058 ✗ then listAppend(getVarLstFromType(ty) for ty in tyLst);
3059
3060 case DAE.T_COMPLEX(varLst = varLst) then varLst;
3061 case DAE.T_SUBTYPE_BASIC(varLst = varLst) then varLst;
3062 else {};
3063 end match;
3064 end getVarLstFromType;
3065
3066 protected function getScalarVarSize "gets the number of scalars of an DAE.Var.
3067 author:Waurich TUD 2014-04"
3068 input DAE.Var inVar;
3069 output Integer size;
3070 algorithm
3071 size := match inVar
3072 local
3073 DAE.Type ty;
3074 list<DAE.Var> vl;
3075
3076 case DAE.TYPES_VAR(ty = DAE.T_COMPLEX(varLst = vl as _ :: _))
3077 ✗ then intAdd(getScalarVarSize(v) for v in vl);
3078
3079 case DAE.TYPES_VAR(ty = ty as DAE.T_ARRAY(_))
3080 ✗ then intMul(sz for sz in DAEUtil.expTypeArrayDimensions(ty));
3081
3082 else 1;
3083 end match;
3084 end getScalarVarSize;
3085
3086
3087 // =============================================================================
3088 // predict if statements
3089 //
3090 // =============================================================================
3091
3092 protected function evaluateFunctions_updateStatementEmptyRepl "replace and update the statements but start with an empty replacement.
3093 author:Waurich TUD 2014-03"
3094 input list<DAE.Statement> algsIn;
3095 input AvlTreePathFunction.Tree inFuncTree;
3096 input Integer inIndex;
3097 input Integer recursionLimit;
3098 output tuple<list<DAE.Statement>,BackendVarTransform.VariableReplacements> mapTplOut;
3099 output AvlTreePathFunction.Tree outFuncTree;
3100 output Integer outIndex;
3101 protected
3102 BackendVarTransform.VariableReplacements repl;
3103 list<DAE.Statement> algsOut;
3104 algorithm
3105 ✗ repl := BackendVarTransform.emptyReplacements();
3106 //print("start new evaluation with empty replacement\n"+stringDelimitList(List.map(algsIn,DAEDump.ppStatementStr),"\n")+"\n");
3107 ✗ (algsOut, outFuncTree, repl, outIndex) := evaluateFunctions_updateStatement(algsIn, inFuncTree, repl, inIndex, {}, recursionLimit);
3108 //print("the new evaluated stmts wit empty repl \n"+stringDelimitList(List.map(algsOut,DAEDump.ppStatementStr),"\n")+"\n");
3109 ✗ mapTplOut := (algsOut, repl);
3110 end evaluateFunctions_updateStatementEmptyRepl;
3111
3112 protected function evaluateFunctions_updateAllStatements "replace and update all statements and use an initial replacement for each branch
3113 author: ptaeuber"
3114 input list<DAE.Statement> stmtsIn;
3115 input list<list<DAE.Statement>> elseStmtsLstIn;
3116 input BackendVarTransform.VariableReplacements replIn;
3117 output list<list<DAE.Statement>> stmtsLstOut;
3118 input output AvlTreePathFunction.Tree funcTree;
3119 input output Integer idx;
3120 input Integer recursionLimit;
3121 protected
3122 BackendVarTransform.VariableReplacements repl;
3123 list<DAE.Statement> stmts;
3124 algorithm
3125 // get constant replacements as copy of replIn
3126 7339 repl := getOnlyConstantReplacements(replIn);
3127
3128 // update if-branch
3129 7339 (stmts, funcTree, _, idx) := evaluateFunctions_updateStatement(stmtsIn, funcTree, repl, idx, {}, recursionLimit);
3130
3131 // update else(if)-branches
3132 stmtsLstOut := {stmts};
3133
2/2
✓ Branch 0 taken 8551 times.
✓ Branch 1 taken 7060 times.
15611 for elseStmts in elseStmtsLstIn loop
3134 // get constant replacements as copy of replIn
3135 8551 repl := getOnlyConstantReplacements(replIn);
3136 // update else(if)-branch
3137 8551 (stmts, funcTree, _, idx) := evaluateFunctions_updateStatement(elseStmts, funcTree, repl, idx, {}, recursionLimit);
3138 stmtsLstOut := stmts::stmtsLstOut;
3139 end for;
3140 7060 stmtsLstOut := listReverse(stmtsLstOut);
3141 end evaluateFunctions_updateAllStatements;
3142
3143 protected function predictIfOutput "evaluate outputs for all if/elseif/else and check if its constant at any time
3144 author: Waurich TUD 2014-04"
3145 input DAE.Statement stmtIn;
3146 input FuncInfo infoIn;
3147 input Integer recursionLimit;
3148 output tuple<list<DAE.Statement>,list<DAE.Statement>> stmtsOut;
3149 output FuncInfo infoOut;
3150 algorithm
3151 (stmtsOut,infoOut) := matchcontinue(stmtIn,infoIn)
3152 local
3153 Integer idx;
3154 list<Integer> constantOutputs;
3155 BackendVarTransform.VariableReplacements replIn;
3156 list<BackendVarTransform.VariableReplacements> replLst;
3157 DAE.Else else_;
3158 AvlTreePathFunction.Tree funcTree;
3159 DAE.Statement stmtNew;
3160 list<DAE.Exp> expLst,outExps,allLHS;
3161 list<list<DAE.Exp>> expLstLst;
3162 list<DAE.Statement> stmts1,addStmts;
3163 list<list<DAE.Statement>> stmtsLst, elseStmtsLst;
3164 case(DAE.STMT_IF(statementLst=stmts1, else_=else_),FUNCINFO(replIn,funcTree,idx))
3165 algorithm
3166 // get a list of all statements for each case
3167 7339 elseStmtsLst := getDAEelseStatemntLsts(else_,{});
3168 7339 elseStmtsLst := listReverse(elseStmtsLst);
3169 // print("all stmts to predict: \n"+stringDelimitList(List.map(List.flatten(stmts1::elseStmtsLst),DAEDump.ppStatementStr),"\n")+"\n");
3170
3171 // replace with the already known stuff and build the new replacements
3172 // repl = getOnlyConstantReplacements(replIn);
3173 // (stmtsLst,_) = List.map4_2(stmtsLst,BackendVarTransform.replaceStatementLstRHS,repl,NONE(),{},false);
3174 // print("al stmts replaced: \n"+stringDelimitList(List.map(List.flatten(stmtsLst),DAEDump.ppStatementStr),"\n")+"\n");
3175 // (tplLst, funcTree, idx) = List.mapFold2(stmtsLst, evaluateFunctions_updateStatementEmptyRepl, funcTree, idx);
3176 // stmtsLst = List.map(tplLst,Util.tuple21);
3177 //
3178 // ptaeuber: Do not do the above, it could lead to wrong results
3179 // a := 0; a := 0;
3180 // if (...) then if (...) then
3181 // a := a + 1; ----> a := 0 + 1;
3182 // b := a; b := 0;
3183 // end if; end if;
3184
3185 7339 (stmtsLst, funcTree, idx) := evaluateFunctions_updateAllStatements(stmts1, elseStmtsLst, replIn, funcTree, idx, recursionLimit);
3186 // print("all evaluated stmts: \n"+stringDelimitList(List.map(List.flatten(stmtsLst),DAEDump.ppStatementStr),"---------\n")+"\n");
3187 7060 replLst := List.map(stmtsLst,collectReplacements);
3188 //replLst = List.map(replLst,getOnlyConstantReplacements);
3189 // List.map_0(replLst,BackendVarTransform.dumpReplacements);
3190
3191 // get the outputs of every case
3192 7060 expLst := List.fold(List.flatten(stmtsLst),getStatementLHS,{});
3193 7060 expLst := List.unique(expLst);
3194 7060 allLHS := listReverse(expLst);
3195 // print("the outputs: "+stringDelimitList(List.map(allLHS,ExpressionBasics.printExpStr),"\n")+"\n");
3196 7060 expLstLst := List.map1(replLst,replaceExps,allLHS);
3197 // print("the outputs replaced: \n"+stringDelimitList(List.map(expLstLst,ExpressionDump.printExpListStr),"\n")+"\n\n");
3198
3199 // compare the constant outputs
3200 7060 constantOutputs := compareConstantExps(expLstLst);
3201 7060 outExps := List.map1(constantOutputs,List.getIndexFirst,allLHS);
3202
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7060 times.
7060 true := List.all(outExps, Expression.isCref);
3203 // print("constantOutputs: "+stringDelimitList(List.map(constantOutputs,intString),",")+"\n");
3204 7060 expLst := List.map1(constantOutputs,List.getIndexFirst,listHead(expLstLst));
3205 // print("the constant shared outputs: "+stringDelimitList(List.map(expLst,ExpressionBasics.printExpStr),"\n")+"\n");
3206 // print("the constant shared output crefs: "+stringDelimitList(List.map(outExps,ExpressionBasics.printExpStr),"\n")+"\n");
3207
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7057 times.
7060 if Flags.isSet(Flags.EVAL_FUNC_DUMP) then
3208 3 print("--> the predicted const outputs:\n"+stringDelimitList(List.map(outExps,ExpressionBasics.printExpStr),"\n"));
3209 end if;
3210
3211 //_ = (not listEmpty(constOutExps)) and listEmpty(varOutExps);
3212 //repl = bcallret3(not predicted, BackendVarTransform.removeReplacements,replIn,varCrefs,NONE(),replIn);
3213 //bcall(not predicted,print,"remove the replacement for: "+stringDelimitList(List.map(varCrefs,ComponentReference.crefStr),"\n")+"\n");
3214 // build the additional statements and update the old one
3215 7060 addStmts := makeAssignmentMap(outExps,expLst);
3216 7060 stmtNew := updateStatementsInIfStmt(stmtsLst,stmtIn);
3217
3218 // print("the new predicted stmts: \n"+stringDelimitList(List.map({stmtNew},DAEDump.ppStatementStr),"\n")+"\nAnd the additional "+stringDelimitList(List.map(addStmts,DAEDump.ppStatementStr),"\n")+"\n");
3219
3220 //repl = BackendVarTransform.addReplacements(replIn,crefs,expLst,NONE());
3221 6470 then
3222 (({stmtNew},addStmts),FUNCINFO(replIn,funcTree,idx));
3223 869 else
3224 (({stmtIn},{}),infoIn);
3225 end matchcontinue;
3226 end predictIfOutput;
3227
3228 protected function collectReplacements "gathers replacement rules for a given set of statements without updating them
3229 author:Waurich TUD 2014-04"
3230 input list<DAE.Statement> stmtsIn;
3231 output BackendVarTransform.VariableReplacements replOut;
3232 protected
3233 BackendVarTransform.VariableReplacements repl;
3234 algorithm
3235 14393 repl := BackendVarTransform.emptyReplacements();
3236 14393 replOut := collectReplacements1(stmtsIn,repl);
3237 end collectReplacements;
3238
3239 protected function collectReplacements1 "author:Waurich TUD 2014-04"
3240 input list<DAE.Statement> stmtsIn;
3241 input BackendVarTransform.VariableReplacements replIn;
3242 output BackendVarTransform.VariableReplacements replOut;
3243 algorithm
3244 replOut := matchcontinue stmtsIn
3245 local
3246 BackendVarTransform.VariableReplacements repl;
3247 DAE.ComponentRef cref;
3248 DAE.Exp lhs,rhs;
3249 DAE.Statement stmt;
3250 list<DAE.ComponentRef> crefs,constCrefs,varCrefs;
3251 list<DAE.Exp> lhsLst,rhsLst,constExps;
3252 list<DAE.Statement> rest;
3253 case {}
3254 then
3255 replIn;
3256 case DAE.STMT_ASSIGN(exp1=lhs,exp=rhs)::rest
3257 algorithm
3258 43062 (rhs,_) := BackendVarTransform.replaceExp(rhs,replIn,NONE());
3259 43062 (rhs,_) := ExpressionSimplify.simplify(rhs);
3260
2/2
✓ Branch 1 taken 33971 times.
✓ Branch 2 taken 9091 times.
43062 true := Expression.isConst(rhs);
3261 9091 cref := Expression.expCref(lhs);
3262 9091 repl := BackendVarTransform.addReplacement(replIn,cref,rhs,NONE());
3263 9091 repl := collectReplacements1(rest,repl);
3264 then
3265 repl;
3266 case DAE.STMT_TUPLE_ASSIGN(expExpLst=lhsLst,exp=rhs)::rest
3267 algorithm
3268 8 (rhs,_) := BackendVarTransform.replaceExp(rhs,replIn,NONE());
3269 8 (rhs,_) := ExpressionSimplify.simplify(rhs);
3270 8 rhsLst := Expression.getComplexContents(rhs);
3271 8 crefs := List.map(lhsLst,Expression.expCref);
3272 8 (constExps,constCrefs) := List.filterOnTrueSync(rhsLst,Expression.isConst,crefs);
3273 4 (_,varCrefs) := List.filterOnTrueSync(rhsLst,Expression.isNotConst,crefs);
3274 4 repl := BackendVarTransform.addReplacements(replIn,constCrefs,constExps,NONE());
3275 4 BackendVarTransform.removeReplacements(repl,varCrefs);
3276 4 repl := collectReplacements1(rest,repl);
3277 then
3278 repl;
3279 case stmt::rest
3280 algorithm
3281 36091 lhsLst := getStatementLHS(stmt,{});
3282 36091 crefs := List.map(lhsLst,Expression.expCref);
3283 36091 BackendVarTransform.removeReplacements(replIn,crefs);
3284 36091 repl := collectReplacements1(rest,replIn);
3285 then
3286 repl;
3287 else
3288 algorithm
3289 ✗ print("collectReplacements failed\n");
3290 ✗ then
3291 fail();
3292 end matchcontinue;
3293 end collectReplacements1;
3294
3295 protected function getOnlyConstantReplacements "removes replacement rules that do not have a constant expression as value
3296 author:Waurich TUD 2014-04"
3297 input BackendVarTransform.VariableReplacements replIn;
3298 output BackendVarTransform.VariableReplacements replOut;
3299 protected
3300 list<DAE.Exp> exps;
3301 list<DAE.ComponentRef> crefs;
3302 BackendVarTransform.VariableReplacements repl;
3303 algorithm
3304 15890 (crefs,exps) := BackendVarTransform.getAllReplacements(replIn);
3305 15890 (exps,crefs) := List.filterOnTrueSync(exps,Expression.isConst,crefs);
3306 15890 repl := BackendVarTransform.emptyReplacements();
3307 15890 replOut := BackendVarTransform.addReplacements(repl,crefs,exps,NONE());
3308 end getOnlyConstantReplacements;
3309
3310 protected function updateStatementsInIfStmt "replaces the statements in the if statement
3311 author:Waurich TUD 2014-04"
3312 input list<list<DAE.Statement>> stmtLstIn;
3313 input DAE.Statement origIf;
3314 output DAE.Statement ifStmtOut;
3315 algorithm
3316 ifStmtOut := match(stmtLstIn,origIf)
3317 local
3318 DAE.Else els;
3319 DAE.Exp exp;
3320 DAE.ElementSource source;
3321 list<DAE.Statement> stmts;
3322 list<list<DAE.Statement>> rest;
3323 case(stmts::rest,DAE.STMT_IF(exp=exp,else_=els,source=source))
3324 algorithm
3325 7060 els := updateStatementsInElse(rest,els);
3326 6470 then
3327 DAE.STMT_IF(exp,stmts,els,source);
3328 end match;
3329 end updateStatementsInIfStmt;
3330
3331 protected function updateStatementsInElse "replaces the statements in else
3332 author:Waurich TUD 2014-04"
3333 input list<list<DAE.Statement>> stmtLstIn;
3334 input DAE.Else origElse;
3335 output DAE.Else elseOut;
3336 algorithm
3337 elseOut := match(stmtLstIn,origElse)
3338 local
3339 DAE.Else els;
3340 DAE.Exp exp;
3341 list<DAE.Statement> stmts;
3342 list<list<DAE.Statement>> rest;
3343 case(stmts::rest,DAE.ELSEIF(exp=exp,else_=els))
3344 algorithm
3345 863 els := updateStatementsInElse(rest,els);
3346 846 then
3347 DAE.ELSEIF(exp,stmts,els);
3348 case(stmts::_,DAE.ELSE())
3349 6470 then
3350 DAE.ELSE(stmts);
3351 case(_::_,DAE.NOELSE())
3352 then
3353 DAE.NOELSE();
3354 end match;
3355 end updateStatementsInElse;
3356
3357 protected function compareConstantExps "compares the lists of expressions if there are the same constants at the same position
3358 author:Waurich TUD 2014-04"
3359 input list<list<DAE.Exp>> expLstLstIn;
3360 output list<Integer> posLstOut = {};
3361 algorithm
3362
2/2
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 7024 times.
35039 for i in 1:listLength(listHead(expLstLstIn)) loop
3363 27979 posLstOut := compareConstantExps2(i, expLstLstIn, posLstOut);
3364 end for;
3365 end compareConstantExps;
3366
3367 protected function compareConstantExps2
3368 input Integer idx;
3369 input list<list<DAE.Exp>> expLstLst;
3370 input output list<Integer> pos;
3371 protected
3372 Boolean b1,b2;
3373 DAE.Exp firstExp;
3374 list<DAE.Exp> expLst,rest;
3375 algorithm
3376 27979 expLst := List.map1(expLstLst,listGet,idx);
3377 27979 b1 := List.all(expLst, Expression.isConst);
3378
2/2
✓ Branch 0 taken 24939 times.
✓ Branch 1 taken 3040 times.
27979 if b1 then
3379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3040 times.
3040 firstExp::rest := expLst;
3380 3040 b2 := List.all(rest, function ExpressionBasics.expEqual(inExp2 = firstExp));
3381
2/2
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 2315 times.
3040 if b2 then
3382 pos := idx::pos;
3383 end if;
3384 end if;
3385 end compareConstantExps2;
3386
3387 protected function makeAssignmentMap "mapping function to build the statements for a list of lhs and rhs exps.
3388 author:Waurich TUD 2014-04"
3389 input list<DAE.Exp> lhs;
3390 input list<DAE.Exp> rhs;
3391 output list<DAE.Statement> stmts;
3392 algorithm
3393
8/8
✓ Branch 0 taken 3301 times.
✓ Branch 1 taken 350802 times.
✓ Branch 2 taken 3300 times.
✓ Branch 3 taken 350803 times.
✓ Branch 4 taken 3300 times.
✓ Branch 5 taken 350803 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 350802 times.
354103 stmts := list(makeAssignment(e1, e2) threaded for e1 in lhs, e2 in rhs);
3394 end makeAssignmentMap;
3395
3396 protected function makeAssignment "makes an DAE.STMT_ASSIGN of the 2 DAE.Exp"
3397 input DAE.Exp lhs;
3398 input DAE.Exp rhs;
3399 output DAE.Statement stmtOut;
3400 protected
3401 DAE.Type ty;
3402 algorithm
3403 3300 ty := Expression.typeof(rhs);
3404 3300 stmtOut := DAE.STMT_ASSIGN(ty,lhs,rhs,DAE.emptyElementSource);
3405 end makeAssignment;
3406
3407 // =============================================================================
3408 // redeclare the varKinds (maybe some state candidates are vanished)
3409 //
3410 // =============================================================================
3411
3412 protected function updateVarKinds "if there is a variable declared as a state that is not longer present inside a der-call or selected as a state, change the status to VARIABLE
3413 author:Waurich TUD 2014-04"
3414 input BackendDAE.BackendDAE inDAE;
3415 output BackendDAE.BackendDAE outDAE;
3416 protected
3417 BackendDAE.EqSystems systs;
3418 BackendDAE.Shared shared;
3419 algorithm
3420 56 BackendDAE.DAE(eqs=systs,shared=shared) := inDAE;
3421 56 systs := List.map1(systs,updateVarKinds_eqSys,shared);
3422 56 outDAE := BackendDAE.DAE(systs,shared);
3423 end updateVarKinds;
3424
3425 protected function updateVarKinds_eqSys "author:Waurich TUD 2014-04"
3426 input BackendDAE.EqSystem sysIn;
3427 input BackendDAE.Shared shared;
3428 output BackendDAE.EqSystem sysOut;
3429 protected
3430 BackendDAE.Variables vars;
3431 list<BackendDAE.Var> states,varLst,ssVarLst;
3432 BackendDAE.EquationArray eqs, initEqs;
3433 list<DAE.ComponentRef> derVars,ssVars,derVarsInit;
3434
3435 algorithm
3436 156 BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqs) := sysIn;
3437 156 varLst := BackendVariable.varList(vars);
3438 156 initEqs := BackendEquation.getInitialEqnsFromShared(shared);
3439 156 states := List.filterOnTrue(varLst, BackendVariable.isStateorStateDerVar);
3440 156 (_, derVarsInit) := BackendDAEUtil.traverseBackendDAEExpsEqns(initEqs, Expression.traverseSubexpressionsHelper, (findDerVarCrefs, {}));
3441 156 (_, derVars) := BackendDAEUtil.traverseBackendDAEExpsEqns(eqs, Expression.traverseSubexpressionsHelper, (findDerVarCrefs, derVarsInit));
3442 //print("derVars\n"+stringDelimitList(List.map(derVars,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n\n");
3443 156 ssVarLst := List.filterOnTrue(varLst, varSSisPreferOrHigher);
3444 156 ssVars := List.map(ssVarLst,BackendVariable.varCref);
3445 //print("ssVars\n"+stringDelimitList(List.map(ssVars,ComponentReferenceBasics.printComponentRefStr),"\n")+"\n\n");
3446 156 derVars := List.unique(listAppend(derVars, ssVars));
3447 156 (vars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(vars, setVarKindForStates, derVars);
3448 156 sysOut := BackendDAEUtil.setEqSystVars(sysIn, vars);
3449 end updateVarKinds_eqSys;
3450
3451 protected function varSSisPreferOrHigher "outputs true if the stateSelect attribute is prefer or always
3452 author:Waurich TUD 2014-04"
3453 input BackendDAE.Var varIn;
3454 output Boolean ssOut;
3455 protected
3456 Integer i;
3457 DAE.StateSelect ss;
3458 algorithm
3459 15340 ss := BackendVariable.varStateSelect(varIn);
3460 15340 i := BackendVariable.stateSelectToInteger(ss);
3461 15340 ssOut := intGe(i,2);
3462 end varSSisPreferOrHigher;
3463
3464 protected function setVarKindForStates "if a state var is a memeber of the list of state-crefs, it remains a state. otherwise it will be changed to VarKind.Variable
3465 waurich TUD 2014-04"
3466 input BackendDAE.Var inVar;
3467 input list<DAE.ComponentRef> inCrefs;
3468 output BackendDAE.Var outVar;
3469 output list<DAE.ComponentRef> outCrefs;
3470 algorithm
3471 (outVar,outCrefs) := matchcontinue (inVar,inCrefs)
3472 local
3473 Boolean isState;
3474 DAE.ComponentRef cr1;
3475 BackendDAE.Var varOld,varNew;
3476 list<DAE.ComponentRef> derVars;
3477 case (varOld as BackendDAE.VAR(varName=cr1,varKind=BackendDAE.STATE()),derVars)
3478 algorithm
3479 1992 isState := List.isMemberOnTrue(cr1,derVars,ComponentReferenceBasics.crefEqual);
3480
2/2
✓ Branch 0 taken 390 times.
✓ Branch 1 taken 1602 times.
1992 varNew := if not isState then BackendVariable.setVarKind(varOld,BackendDAE.VARIABLE()) else varOld;
3481 then (varNew,derVars);
3482 else (inVar,inCrefs);
3483 end matchcontinue;
3484 end setVarKindForStates;
3485
3486 protected function findDerVarCrefs "traverses all the sub expressions and searches for der(var)"
3487 input output DAE.Exp exp;
3488 input list<DAE.ComponentRef> inCrefs;
3489 output list<DAE.ComponentRef> outCrefs;
3490 algorithm
3491 outCrefs := match exp
3492 local
3493 DAE.ComponentRef cr;
3494 case DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})
3495 then cr :: inCrefs;
3496 else inCrefs;
3497 end match;
3498 end findDerVarCrefs;
3499
3500 // =============================================================================
3501 // convert tuple equations to several single equations
3502 //
3503 // =============================================================================
3504
3505 protected function convertTupleEquations "author:Waurich TUD 2014-04
3506 converts an equation tupleExp=tupleExp to several simple equations of exp=const"
3507 input BackendDAE.Equation eqIn;
3508 input list<BackendDAE.Equation> addEqsIn;
3509 output BackendDAE.Equation eqOut;
3510 output list<BackendDAE.Equation> addEqsOut;
3511 algorithm
3512 (eqOut, addEqsOut) := match eqIn
3513 local
3514 list<DAE.Exp> lhs, rhs;
3515 BackendDAE.Equation eq;
3516 list<BackendDAE.Equation> eqs;
3517
3518 case BackendDAE.COMPLEX_EQUATION(left = DAE.TUPLE(lhs), right = DAE.TUPLE(rhs))
3519 algorithm
3520 ✗ lhs := List.mapFlat(lhs, Expression.getComplexContents);
3521 ✗ rhs := List.mapFlat(rhs, Expression.getComplexContents);
3522 ✗ eq :: eqs := list(makeBackendEquation(lh, rh) threaded for lh in lhs, rh in rhs);
3523 ✗ then
3524 (eq, listAppend(eqs, addEqsIn));
3525
3526 else (eqIn, addEqsIn);
3527 end match;
3528 end convertTupleEquations;
3529
3530 protected function makeBackendEquation "author:Waurich TUD 2014-04
3531 builds a backendEquation for the lhs-exp and rhs-exp"
3532 input DAE.Exp ls;
3533 input DAE.Exp rs;
3534 output BackendDAE.Equation eq;
3535 algorithm
3536 ✗ eq := BackendDAE.EQUATION(rs, ls, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
3537 end makeBackendEquation;
3538
3539 annotation(__OpenModelica_Interface="backend");
3540 end EvaluateFunctions;
3541