Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 47.4% 277 / 0 / 584
Functions: -% 0 / 1 / 1
Branches: 45.8% 55 / 0 / 120

OMCompiler/Compiler/FrontEnd/CevalFunction.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 CevalFunction
37 " file: CevalFunction.mo
38 package: CevalFunction
39 description: This module constant evaluates DAE.Function objects, i.e.
40 modelica functions defined by the user.
41
42
43 TODO:
44 * Implement evaluation of MetaModelica statements.
45 * Enable NORETCALL (see comment in evaluateStatement).
46 * Implement terminate and assert(false, ...).
47 * Arrays of records probably doesn't work yet.
48 "
49
50 // Jump table for CevalFunction:
51 // [TYPE] Types.
52 // [EVAL] Constant evaluation functions.
53 // [EENV] Environment extension functions (add variables).
54 // [MENV] Environment manipulation functions (set and get variables).
55 // [DEPS] Function variable dependency handling.
56 // [EOPT] Expression optimization functions.
57
58 // public imports
59 public import Absyn;
60 public import AbsynUtil;
61 public import DAE;
62 public import FCore;
63 public import SCode;
64 public import Values;
65
66 // protected imports
67 protected import Ceval;
68 protected import ClassInf;
69 protected import ComponentReference;
70 protected import ComponentReferenceBasics;
71 protected import DAEDump;
72 protected import DAEUtil;
73 protected import Debug;
74 protected import ElementSource;
75 protected import Error;
76 protected import Expression;
77 protected import Flags;
78 protected import Graph;
79 protected import Lapack;
80 protected import List;
81 protected import Lookup;
82 protected import Types;
83 protected import Util;
84 protected import ValuesUtil;
85 protected import FGraph;
86 protected import FNode;
87 protected import ExpressionBasics;
88
89 // [TYPE] Types
90 protected type FunctionVar = tuple<DAE.Element, Option<Values.Value>>;
91
92 // LoopControl is used to control the functions behaviour in different
93 // situations. All evaluation functions returns a LoopControl variable that
94 // tells the caller whether it should continue evaluating or not.
95 protected uniontype LoopControl
96 record NEXT "Continue to the next statement." end NEXT;
97 record BREAK "Exit the current loop." end BREAK;
98 record RETURN "Exit the function." end RETURN;
99 end LoopControl;
100
101 // [EVAL] Constant evaluation functions.
102
103 public function evaluate
104 "This is the entry point of CevalFunction. This function constant evaluates a
105 function given an instantiated function and a list of function arguments."
106 input FCore.Cache inCache;
107 input FCore.Graph inEnv;
108 input DAE.Function inFunction;
109 input list<Values.Value> inFunctionArguments;
110 output FCore.Cache outCache;
111 output Values.Value outResult;
112 algorithm
113 (outCache, outResult) :=
114 matchcontinue inFunction
115 local
116 Absyn.Path p;
117 DAE.FunctionDefinition func;
118 DAE.Type ty;
119 Values.Value result;
120 String func_name;
121 FCore.Cache cache;
122 Boolean partialPrefix;
123 DAE.ElementSource src;
124
125 // The DAE.FUNCTION structure might contain an optional function derivative
126 // mapping which is why functions below is a list. We only evaluate the
127 // first function, which is hopefully the one we want.
128 case DAE.FUNCTION(
129 path = p,
130 functions = func :: _,
131 type_ = ty,
132 partialPrefix = false,
133 source = src)
134 algorithm
135 38177 func_name := AbsynUtil.pathString(p);
136 38177 (cache, result) := evaluateFunctionDefinition(inCache, inEnv, func_name,
137 func, ty, inFunctionArguments, src);
138 then
139 (cache, result);
140
141 case DAE.FUNCTION(
142 path = p,
143 functions = _ :: _,
144 partialPrefix = partialPrefix)
145 algorithm
146
1/2
✓ Branch 1 taken 226 times.
✗ Branch 2 not taken.
226 true := Flags.isSet(Flags.FAILTRACE);
147 ✗ Debug.traceln("- CevalFunction.evaluate failed for function: " + (if partialPrefix then "partial " else "") + AbsynUtil.pathString(p));
148 ✗ then
149 fail();
150 end matchcontinue;
151 end evaluate;
152
153 protected function evaluateFunctionDefinition
154 "This function constant evaluates a function definition."
155 input FCore.Cache inCache;
156 input FCore.Graph inEnv;
157 input String inFuncName;
158 input DAE.FunctionDefinition inFunc;
159 input DAE.Type inFuncType;
160 input list<Values.Value> inFuncArgs;
161 input DAE.ElementSource inSource;
162 output FCore.Cache outCache;
163 output Values.Value outResult;
164 algorithm
165 (outCache, outResult) :=
166 matchcontinue inFunc
167 local
168 list<DAE.Element> body;
169 list<DAE.Element> vars, output_vars;
170 list<FunctionVar> func_params;
171 FCore.Cache cache;
172 FCore.Graph env;
173 list<Values.Value> return_values;
174 Values.Value return_value;
175 String ext_fun_name;
176 list<DAE.ExtArg> ext_fun_args;
177
178 case DAE.FUNCTION_DEF(body = body)
179 algorithm
180 // Split the definition into function variables and statements.
181 38139 (vars, body) := List.splitOnFirstMatch(body, DAEUtil.isNotVar);
182 38139 vars := List.map(vars, removeSelfReferentialDims);
183
184 // Save the output variables, so that we can return their values when
185 // we're done.
186 38139 output_vars := List.filterOnTrue(vars, DAEUtil.isOutputVar);
187
188 // Pair the input arguments to input parameters and sort the function
189 // variables by dependencies.
190 38139 func_params := pairFuncParamsWithArgs(vars, inFuncArgs);
191 38139 func_params := sortFunctionVarsByDependency(func_params, inSource);
192
193 // Create an environment for the function and add all function variables.
194 38139 (cache, env) :=
195 setupFunctionEnvironment(inCache, inEnv, inFuncName, func_params);
196 // Evaluate the body of the function.
197 38139 (cache, env, _) := evaluateElements(body, cache, env, NEXT());
198 // Fetch the values of the output variables.
199 37947 return_values := List.map1(output_vars, getFunctionReturnValue, env);
200 // If we have several output variables they should be boxed into a tuple.
201 37947 return_value := boxReturnValue(return_values);
202 then
203 (cache, return_value);
204
205 case DAE.FUNCTION_EXT(body = body, externalDecl =
206 DAE.EXTERNALDECL(name = ext_fun_name,
207 args = ext_fun_args))
208 algorithm
209 // Get all variables from the function. Ignore everything else, since
210 // external functions shouldn't have statements.
211 38 (vars, _) := List.splitOnFirstMatch(body, DAEUtil.isNotVar);
212 38 vars := List.map(vars, removeSelfReferentialDims);
213
214 // Save the output variables, so that we can return their values when
215 // we're done.
216 38 output_vars := List.filterOnTrue(vars, DAEUtil.isOutputVar);
217
218 // Pair the input arguments to input parameters and sort the function
219 // variables by dependencies.
220 38 func_params := pairFuncParamsWithArgs(vars, inFuncArgs);
221 38 func_params := sortFunctionVarsByDependency(func_params, inSource);
222
223 // Create an environment for the function and add all function variables.
224 38 (cache, env) :=
225 setupFunctionEnvironment(inCache, inEnv, inFuncName, func_params);
226
227 // Call the function.
228 38 (cache, env) :=
229 evaluateExternalFunc(ext_fun_name, ext_fun_args, cache, env);
230
231 // Fetch the values of the output variables.
232 4 return_values := List.map1(output_vars, getFunctionReturnValue, env);
233 // If we have several output variables they should be boxed into a tuple.
234 4 return_value := boxReturnValue(return_values);
235 then
236 (cache, return_value);
237
238 else
239 algorithm
240
1/2
✓ Branch 1 taken 226 times.
✗ Branch 2 not taken.
226 true := Flags.isSet(Flags.FAILTRACE);
241 ✗ Debug.trace("- CevalFunction.evaluateFunction failed.\n");
242 ✗ then
243 fail();
244 end matchcontinue;
245 end evaluateFunctionDefinition;
246
247 protected function pairFuncParamsWithArgs
248 "This function pairs up the input arguments to the input parameters, so that
249 each input parameter get one input argument. This is done since we sort the
250 function variables by dependencies, and need to keep track of which argument
251 belongs to which parameter."
252 input list<DAE.Element> inElements;
253 input list<Values.Value> inValues;
254 output list<FunctionVar> outFunctionVars;
255 algorithm
256 outFunctionVars := match(inElements, inValues)
257 local
258 DAE.Element var;
259 list<DAE.Element> rest_vars;
260 Values.Value val;
261 list<Values.Value> rest_vals;
262 list<FunctionVar> params;
263
264 case ({}, {}) then {};
265
266 case ((DAE.VAR(direction = DAE.INPUT())) :: _, {})
267 algorithm
268 ✗ true := Flags.isSet(Flags.FAILTRACE);
269 ✗ Debug.trace("- CevalFunction.pairFuncParamsWithArgs failed because of too few input arguments.\n");
270 ✗ then
271 fail();
272
273 case ((var as DAE.VAR(direction = DAE.INPUT())) :: rest_vars, val :: rest_vals)
274 algorithm
275 51711 params := pairFuncParamsWithArgs(rest_vars, rest_vals);
276 51711 then
277 (var, SOME(val)) :: params;
278
279 case (var :: rest_vars, _)
280 algorithm
281 47915 params := pairFuncParamsWithArgs(rest_vars, inValues);
282 47915 then
283 (var, NONE()) :: params;
284
285 end match;
286 end pairFuncParamsWithArgs;
287
288 protected function removeSelfReferentialDims
289 "We can't handle self-referential dimensions in function parameters, i.e.
290 x[:, size(x, 1)], so just replace them with : instead."
291 input DAE.Element inElement;
292 output DAE.Element outElement;
293 algorithm
294 outElement := match inElement
295 local
296 DAE.ComponentRef cref;
297 DAE.VarKind vk;
298 DAE.VarDirection vd;
299 DAE.VarParallelism vp;
300 DAE.VarVisibility vv;
301 DAE.Type ty;
302 Option<DAE.Exp> bind;
303 DAE.InstDims dims;
304 DAE.ConnectorType ct;
305 DAE.ElementSource es;
306 Option<DAE.VariableAttributes> va;
307 Option<SCode.Comment> cmt;
308 Absyn.InnerOuter io;
309 Boolean e;
310 String name;
311
312 case DAE.VAR(cref as DAE.CREF_IDENT(ident = name), vk, vd, vp, vv, ty,
313 bind, dims, ct, es, va, cmt, io, e)
314 algorithm
315 99626 dims := List.map1(dims, removeSelfReferentialDim, name);
316
1/2
✓ Branch 0 taken 99626 times.
✗ Branch 1 not taken.
199252 then
317 DAE.VAR(cref, vk, vd, vp, vv, ty, bind, dims, ct, es, va, cmt, io, e);
318
319 end match;
320 end removeSelfReferentialDims;
321
322 protected function removeSelfReferentialDim
323 input DAE.Dimension inDim;
324 input String inName;
325 output DAE.Dimension outDim;
326 algorithm
327 outDim := matchcontinue inDim
328 local
329 DAE.Exp exp;
330 list<DAE.ComponentRef> crefs;
331
332 case DAE.DIM_EXP(exp = exp)
333 algorithm
334 904 crefs := Expression.extractCrefsFromExp(exp);
335
2/2
✓ Branch 1 taken 896 times.
✓ Branch 2 taken 8 times.
904 true := List.isMemberOnTrue(inName, crefs, isCrefNamed);
336 then
337 DAE.DIM_UNKNOWN();
338
339 else inDim;
340
341 end matchcontinue;
342 end removeSelfReferentialDim;
343
344 protected function isCrefNamed
345 input String inName;
346 input DAE.ComponentRef inCref;
347 output Boolean outIsNamed;
348 algorithm
349 outIsNamed := match inCref
350 local
351 String name;
352
353
4/4
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 864 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 8 times.
905 case DAE.CREF_IDENT(ident = name) then stringEq(inName, name);
354 else false;
355 end match;
356 end isCrefNamed;
357
358 protected function evaluateExtInputArg
359 "Evaluates an external function argument to a value."
360 input DAE.ExtArg inArgument;
361 input FCore.Cache inCache;
362 input FCore.Graph inEnv;
363 output Values.Value outValue;
364 output FCore.Cache outCache;
365 algorithm
366 (outValue, outCache) := matchcontinue(inArgument, inCache)
367 local
368 DAE.ComponentRef cref;
369 DAE.Type ty;
370 DAE.Exp exp;
371 Values.Value val;
372 FCore.Cache cache;
373 String err_str;
374
375 case (DAE.EXTARG(componentRef = cref, type_ = ty), _)
376 algorithm
377 24 val := getVariableValue(cref, ty, inEnv);
378 then
379 (val, inCache);
380
381 case (DAE.EXTARGEXP(exp = exp), cache)
382 algorithm
383 ✗ (cache, val) := cevalExp(exp, cache, inEnv);
384 ✗ then
385 (val, cache);
386
387 case (DAE.EXTARGSIZE(componentRef = cref, exp = exp), cache)
388 algorithm
389 ✗ exp := DAE.SIZE(DAE.CREF(cref, DAE.T_UNKNOWN_DEFAULT), SOME(exp));
390 ✗ (cache, val) := cevalExp(exp, cache, inEnv);
391 ✗ then
392 (val, cache);
393
394 else
395 algorithm
396 ✗ true := Flags.isSet(Flags.FAILTRACE);
397 ✗ err_str := DAEDump.dumpExtArgStr(inArgument);
398 ✗ Debug.traceln("- CevalFunction.evaluateExtInputArg failed on " + err_str);
399 ✗ then
400 fail();
401
402 end matchcontinue;
403 end evaluateExtInputArg;
404
405 protected function evaluateExtIntArg
406 "Evaluates an external function argument to an Integer."
407 input DAE.ExtArg inArg;
408 input FCore.Cache inCache;
409 input FCore.Graph inEnv;
410 output Integer outValue;
411 output FCore.Cache outCache;
412 algorithm
413
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 (Values.INTEGER(outValue), outCache) :=
414 evaluateExtInputArg(inArg, inCache, inEnv);
415 end evaluateExtIntArg;
416
417 protected function evaluateExtRealArg
418 "Evaluates an external function argument to a Real."
419 input DAE.ExtArg inArg;
420 input FCore.Cache inCache;
421 input FCore.Graph inEnv;
422 output Real outValue;
423 output FCore.Cache outCache;
424 algorithm
425 ✗ (Values.REAL(outValue), outCache) :=
426 evaluateExtInputArg(inArg, inCache, inEnv);
427 end evaluateExtRealArg;
428
429 protected function evaluateExtStringArg
430 "Evaluates an external function argument to a String."
431 input DAE.ExtArg inArg;
432 input FCore.Cache inCache;
433 input FCore.Graph inEnv;
434 output String outValue;
435 output FCore.Cache outCache;
436 algorithm
437 ✗ (Values.STRING(outValue), outCache) :=
438 evaluateExtInputArg(inArg, inCache, inEnv);
439 end evaluateExtStringArg;
440
441 protected function evaluateExtIntArrayArg
442 "Evaluates an external function argument to an Integer array."
443 input DAE.ExtArg inArg;
444 input FCore.Cache inCache;
445 input FCore.Graph inEnv;
446 output list<Integer> outValue;
447 output FCore.Cache outCache;
448 protected
449 Values.Value val;
450 algorithm
451 ✗ (val, outCache) :=
452 evaluateExtInputArg(inArg, inCache, inEnv);
453 ✗ outValue := ValuesUtil.arrayValueInts(val);
454 end evaluateExtIntArrayArg;
455
456 protected function evaluateExtRealArrayArg
457 "Evaluates an external function argument to a Real array."
458 input DAE.ExtArg inArg;
459 input FCore.Cache inCache;
460 input FCore.Graph inEnv;
461 output list<Real> outValue;
462 output FCore.Cache outCache;
463 protected
464 Values.Value val;
465 algorithm
466 ✗ (val, outCache) :=
467 evaluateExtInputArg(inArg, inCache, inEnv);
468 ✗ outValue := ValuesUtil.arrayValueReals(val);
469 end evaluateExtRealArrayArg;
470
471 protected function evaluateExtRealMatrixArg
472 "Evaluates an external function argument to a Real matrix."
473 input DAE.ExtArg inArg;
474 input FCore.Cache inCache;
475 input FCore.Graph inEnv;
476 output list<list<Real>> outValue;
477 output FCore.Cache outCache;
478 protected
479 Values.Value val;
480 algorithm
481 8 (val, outCache) :=
482 evaluateExtInputArg(inArg, inCache, inEnv);
483 8 outValue := ValuesUtil.matrixValueReals(val);
484 end evaluateExtRealMatrixArg;
485
486 protected function evaluateExtOutputArg
487 "Returns the component reference to an external function output."
488 input DAE.ExtArg inArg;
489 output DAE.ComponentRef outCref;
490 algorithm
491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 DAE.EXTARG(componentRef = outCref) := inArg;
492 end evaluateExtOutputArg;
493
494 protected function assignExtOutputs
495 "Assigns the outputs from an external function to the correct variables in the
496 environment."
497 input list<DAE.ExtArg> inArgs;
498 input list<Values.Value> inValues;
499 input FCore.Cache inCache;
500 input FCore.Graph inEnv;
501 output FCore.Cache outCache;
502 output FCore.Graph outEnv;
503 algorithm
504 (outCache, outEnv) := match(inArgs, inValues, inCache, inEnv)
505 local
506 DAE.ExtArg arg;
507 Values.Value val;
508 list<DAE.ExtArg> rest_args;
509 list<Values.Value> rest_vals;
510 FCore.Cache cache;
511 FCore.Graph env;
512 DAE.ComponentRef cr;
513
514 case ({}, {}, _, _) then (inCache, inEnv);
515
516 case (arg :: rest_args, val :: rest_vals, cache, env)
517 algorithm
518 16 cr := evaluateExtOutputArg(arg);
519 16 val := unliftExtOutputValue(cr, val, env);
520 16 (cache, env) := assignVariable(cr, val, cache, env);
521 16 (cache, env) := assignExtOutputs(rest_args, rest_vals, cache, env);
522 then
523 (cache, env);
524
525 end match;
526 end assignExtOutputs;
527
528 protected function unliftExtOutputValue
529 "Some external functions don't make much difference between arrays and
530 matrices, so this function converts a matrix value to an array value when
531 needed."
532 input DAE.ComponentRef inCref;
533 input Values.Value inValue;
534 input FCore.Graph inEnv;
535 output Values.Value outValue;
536 algorithm
537 outValue := matchcontinue inValue
538 local
539 DAE.Type ty;
540 list<Values.Value> vals;
541 Integer dim;
542 DAE.Dimensions dims;
543
544 // Matrix value, array type => convert.
545 case Values.ARRAY(valueLst = vals as Values.ARRAY() :: _, dimLst = dim :: _)
546 algorithm
547
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 (DAE.T_ARRAY(ty = ty, dims = dims), _) := getVariableTypeAndBinding(inCref, inEnv);
548
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
8 false := Types.isNonscalarArray(ty, dims);
549 4 vals := List.map(vals, ValuesUtil.arrayScalar);
550 4 then
551 Values.ARRAY(vals, {dim});
552
553 // Otherwise, do nothing.
554 else inValue;
555 end matchcontinue;
556 end unliftExtOutputValue;
557
558 protected function evaluateExternalFunc
559 "This function evaluates an external function, at the moment this means a
560 LAPACK function. This function was automatically generated. No programmers
561 were hurt during the generation of this function."
562 input String inFuncName;
563 input list<DAE.ExtArg> inFuncArgs;
564 input FCore.Cache inCache;
565 input FCore.Graph inEnv;
566 output FCore.Cache outCache;
567 output FCore.Graph outEnv;
568 algorithm
569 (outCache, outEnv) :=
570 match(inFuncName, inFuncArgs, inCache, inEnv)
571 local
572 DAE.ExtArg arg_JOBU, arg_JOBVL, arg_JOBVR, arg_JOBVT, arg_TRANS, arg_INFO, arg_K;
573 DAE.ExtArg arg_KL, arg_KU, arg_LDA, arg_LDAB, arg_LDB, arg_LDU, arg_LDVL;
574 DAE.ExtArg arg_LDVR, arg_LDVT, arg_LWORK, arg_M, arg_N, arg_NRHS, arg_P;
575 DAE.ExtArg arg_RANK, arg_RCOND, arg_IPIV, arg_JPVT, arg_ALPHAI, arg_ALPHAR, arg_BETA;
576 DAE.ExtArg arg_C, arg_D, arg_DL, arg_DU, arg_TAU, arg_WI, arg_WORK;
577 DAE.ExtArg arg_WR, arg_X, arg_A, arg_AB, arg_B, arg_S, arg_U;
578 DAE.ExtArg arg_VL, arg_VR, arg_VT;
579 Values.Value val_INFO, val_RANK, val_IPIV, val_JPVT, val_ALPHAI, val_ALPHAR, val_BETA;
580 Values.Value val_C, val_D, val_DL, val_DU, val_TAU, val_WI, val_WORK;
581 Values.Value val_WR, val_X, val_A, val_AB, val_B, val_S, val_U;
582 Values.Value val_VL, val_VR, val_VT;
583 Integer INFO, K, KL, KU, LDA, LDAB, LDB, LDU, LDVL, LDVR, LDVT, LWORK, M, N, NRHS, P, RANK;
584 Real RCOND;
585 String JOBU, JOBVL, JOBVR, JOBVT, TRANS;
586 list<Integer> IPIV, JPVT;
587 list<Real> ALPHAI, ALPHAR, BETA, C, D, DL, DU, TAU, WI, WORK, WR, X, S;
588 list<list<Real>> A, AB, B, U, VL, VR, VT;
589 list<DAE.ExtArg> arg_out;
590 list<Values.Value> val_out;
591 FCore.Cache cache;
592 FCore.Graph env;
593
594 case("dgeev", {arg_JOBVL, arg_JOBVR, arg_N, arg_A, arg_LDA, arg_WR, arg_WI,
595 arg_VL, arg_LDVL, arg_VR, arg_LDVR, arg_WORK, arg_LWORK, arg_INFO},
596 cache, env)
597 algorithm
598 ✗ (JOBVL, cache) := evaluateExtStringArg(arg_JOBVL, cache, env);
599 ✗ (JOBVR, cache) := evaluateExtStringArg(arg_JOBVR, cache, env);
600 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
601 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
602 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
603 ✗ (LDVL, cache) := evaluateExtIntArg(arg_LDVL, cache, env);
604 ✗ (LDVR, cache) := evaluateExtIntArg(arg_LDVR, cache, env);
605 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
606 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
607 ✗ (A, WR, WI, VL, VR, WORK, INFO) :=
608 Lapack.dgeev(JOBVL, JOBVR, N, A, LDA, LDVL, LDVR, WORK, LWORK);
609 ✗ val_A := ValuesMake.makeRealMatrix(A);
610 ✗ val_WR := ValuesMake.makeRealArray(WR);
611 ✗ val_WI := ValuesMake.makeRealArray(WI);
612 ✗ val_VL := ValuesMake.makeRealMatrix(VL);
613 ✗ val_VR := ValuesMake.makeRealMatrix(VR);
614 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
615 ✗ val_INFO := ValuesMake.makeInteger(INFO);
616 arg_out := {arg_A, arg_WR, arg_WI, arg_VL, arg_VR, arg_WORK, arg_INFO};
617 val_out := {val_A, val_WR, val_WI, val_VL, val_VR, val_WORK, val_INFO};
618 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
619 then
620 (cache, env);
621
622 case("dgegv", {arg_JOBVL, arg_JOBVR, arg_N, arg_A, arg_LDA, arg_B, arg_LDB,
623 arg_ALPHAR, arg_ALPHAI, arg_BETA, arg_VL, arg_LDVL, arg_VR, arg_LDVR,
624 arg_WORK, arg_LWORK, arg_INFO},
625 cache, env)
626 algorithm
627 ✗ (JOBVL, cache) := evaluateExtStringArg(arg_JOBVL, cache, env);
628 ✗ (JOBVR, cache) := evaluateExtStringArg(arg_JOBVR, cache, env);
629 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
630 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
631 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
632 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
633 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
634 ✗ (LDVL, cache) := evaluateExtIntArg(arg_LDVL, cache, env);
635 ✗ (LDVR, cache) := evaluateExtIntArg(arg_LDVR, cache, env);
636 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
637 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
638 ✗ (ALPHAR, ALPHAI, BETA, VL, VR, WORK, INFO) :=
639 Lapack.dgegv(JOBVL, JOBVR, N, A, LDA, B, LDB, LDVL, LDVR, WORK, LWORK);
640 ✗ val_ALPHAR := ValuesMake.makeRealArray(ALPHAR);
641 ✗ val_ALPHAI := ValuesMake.makeRealArray(ALPHAI);
642 ✗ val_BETA := ValuesMake.makeRealArray(BETA);
643 ✗ val_VL := ValuesMake.makeRealMatrix(VL);
644 ✗ val_VR := ValuesMake.makeRealMatrix(VR);
645 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
646 ✗ val_INFO := ValuesMake.makeInteger(INFO);
647 arg_out := {arg_ALPHAR, arg_ALPHAI, arg_BETA, arg_VL, arg_VR, arg_WORK, arg_INFO};
648 val_out := {val_ALPHAR, val_ALPHAI, val_BETA, val_VL, val_VR, val_WORK, val_INFO};
649 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
650 then
651 (cache, env);
652
653 case("dgels", {arg_TRANS, arg_M, arg_N, arg_NRHS, arg_A, arg_LDA, arg_B,
654 arg_LDB, arg_WORK, arg_LWORK, arg_INFO},
655 cache, env)
656 algorithm
657 ✗ (TRANS, cache) := evaluateExtStringArg(arg_TRANS, cache, env);
658 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
659 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
660 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
661 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
662 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
663 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
664 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
665 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
666 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
667 ✗ (A, B, WORK, INFO) :=
668 Lapack.dgels(TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK);
669 ✗ val_A := ValuesMake.makeRealMatrix(A);
670 ✗ val_B := ValuesMake.makeRealMatrix(B);
671 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
672 ✗ val_INFO := ValuesMake.makeInteger(INFO);
673 arg_out := {arg_A, arg_B, arg_WORK, arg_INFO};
674 val_out := {val_A, val_B, val_WORK, val_INFO};
675 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
676 then
677 (cache, env);
678
679 case("dgelsx", {arg_M, arg_N, arg_NRHS, arg_A, arg_LDA, arg_B, arg_LDB,
680 arg_JPVT, arg_RCOND, arg_RANK, arg_WORK, arg_INFO},
681 cache, env)
682 algorithm
683 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
684 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
685 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
686 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
687 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
688 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
689 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
690 ✗ (JPVT, cache) := evaluateExtIntArrayArg(arg_JPVT, cache, env);
691 ✗ (RCOND, cache) := evaluateExtRealArg(arg_RCOND, cache, env);
692 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
693 ✗ (A, B, JPVT, RANK, INFO) :=
694 Lapack.dgelsx(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, WORK);
695 ✗ val_A := ValuesMake.makeRealMatrix(A);
696 ✗ val_B := ValuesMake.makeRealMatrix(B);
697 ✗ val_JPVT := ValuesMake.makeIntArray(JPVT);
698 ✗ val_RANK := ValuesMake.makeInteger(RANK);
699 ✗ val_INFO := ValuesMake.makeInteger(INFO);
700 arg_out := {arg_A, arg_B, arg_JPVT, arg_RANK, arg_INFO};
701 val_out := {val_A, val_B, val_JPVT, val_RANK, val_INFO};
702 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
703 then
704 (cache, env);
705
706 case("dgelsx", {arg_M, arg_N, arg_NRHS, arg_A, arg_LDA, arg_B, arg_LDB,
707 arg_JPVT, arg_RCOND, arg_RANK, arg_WORK, _, arg_INFO},
708 cache, env)
709 algorithm
710 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
711 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
712 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
713 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
714 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
715 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
716 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
717 ✗ (JPVT, cache) := evaluateExtIntArrayArg(arg_JPVT, cache, env);
718 ✗ (RCOND, cache) := evaluateExtRealArg(arg_RCOND, cache, env);
719 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
720 ✗ (A, B, JPVT, RANK, INFO) :=
721 Lapack.dgelsx(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, WORK);
722 ✗ val_A := ValuesMake.makeRealMatrix(A);
723 ✗ val_B := ValuesMake.makeRealMatrix(B);
724 ✗ val_JPVT := ValuesMake.makeIntArray(JPVT);
725 ✗ val_RANK := ValuesMake.makeInteger(RANK);
726 ✗ val_INFO := ValuesMake.makeInteger(INFO);
727 arg_out := {arg_A, arg_B, arg_JPVT, arg_RANK, arg_INFO};
728 val_out := {val_A, val_B, val_JPVT, val_RANK, val_INFO};
729 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
730 then
731 (cache, env);
732
733 case("dgelsy", {arg_M, arg_N, arg_NRHS, arg_A, arg_LDA, arg_B, arg_LDB,
734 arg_JPVT, arg_RCOND, arg_RANK, arg_WORK, arg_LWORK, arg_INFO},
735 cache, env)
736 algorithm
737 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
738 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
739 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
740 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
741 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
742 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
743 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
744 ✗ (JPVT, cache) := evaluateExtIntArrayArg(arg_JPVT, cache, env);
745 ✗ (RCOND, cache) := evaluateExtRealArg(arg_RCOND, cache, env);
746 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
747 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
748 ✗ (A, B, JPVT, RANK, WORK, INFO) :=
749 Lapack.dgelsy(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, WORK, LWORK);
750 ✗ val_A := ValuesMake.makeRealMatrix(A);
751 ✗ val_B := ValuesMake.makeRealMatrix(B);
752 ✗ val_JPVT := ValuesMake.makeIntArray(JPVT);
753 ✗ val_RANK := ValuesMake.makeInteger(RANK);
754 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
755 ✗ val_INFO := ValuesMake.makeInteger(INFO);
756 arg_out := {arg_A, arg_B, arg_JPVT, arg_RANK, arg_WORK, arg_INFO};
757 val_out := {val_A, val_B, val_JPVT, val_RANK, val_WORK, val_INFO};
758 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
759 then
760 (cache, env);
761
762 case("dgesv", {arg_N, arg_NRHS, arg_A, arg_LDA, arg_IPIV, arg_B, arg_LDB,
763 arg_INFO},
764 cache, env)
765 algorithm
766 4 (N, cache) := evaluateExtIntArg(arg_N, cache, env);
767 4 (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
768 4 (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
769 4 (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
770 4 (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
771 4 (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
772 4 (A, IPIV, B, INFO) :=
773 Lapack.dgesv(N, NRHS, A, LDA, B, LDB);
774 4 val_A := ValuesMake.makeRealMatrix(A);
775 4 val_IPIV := ValuesMake.makeIntArray(IPIV);
776 4 val_B := ValuesMake.makeRealMatrix(B);
777 4 val_INFO := ValuesMake.makeInteger(INFO);
778 arg_out := {arg_A, arg_IPIV, arg_B, arg_INFO};
779 val_out := {val_A, val_IPIV, val_B, val_INFO};
780 4 (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
781 then
782 (cache, env);
783
784 case("dgglse", {arg_M, arg_N, arg_P, arg_A, arg_LDA, arg_B, arg_LDB,
785 arg_C, arg_D, arg_X, arg_WORK, arg_LWORK, arg_INFO},
786 cache, env)
787 algorithm
788 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
789 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
790 ✗ (P, cache) := evaluateExtIntArg(arg_P, cache, env);
791 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
792 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
793 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
794 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
795 ✗ (C, cache) := evaluateExtRealArrayArg(arg_C, cache, env);
796 ✗ (D, cache) := evaluateExtRealArrayArg(arg_D, cache, env);
797 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
798 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
799 ✗ (A, B, C, D, X, WORK, INFO) :=
800 Lapack.dgglse(M, N, P, A, LDA, B, LDB, C, D, WORK, LWORK);
801 ✗ val_A := ValuesMake.makeRealMatrix(A);
802 ✗ val_B := ValuesMake.makeRealMatrix(B);
803 ✗ val_C := ValuesMake.makeRealArray(C);
804 ✗ val_D := ValuesMake.makeRealArray(D);
805 ✗ val_X := ValuesMake.makeRealArray(X);
806 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
807 ✗ val_INFO := ValuesMake.makeInteger(INFO);
808 arg_out := {arg_A, arg_B, arg_C, arg_D, arg_X, arg_WORK, arg_INFO};
809 val_out := {val_A, val_B, val_C, val_D, val_X, val_WORK, val_INFO};
810 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
811 then
812 (cache, env);
813
814 case("dgtsv", {arg_N, arg_NRHS, arg_DL, arg_D, arg_DU, arg_B, arg_LDB,
815 arg_INFO},
816 cache, env)
817 algorithm
818 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
819 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
820 ✗ (DL, cache) := evaluateExtRealArrayArg(arg_DL, cache, env);
821 ✗ (D, cache) := evaluateExtRealArrayArg(arg_D, cache, env);
822 ✗ (DU, cache) := evaluateExtRealArrayArg(arg_DU, cache, env);
823 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
824 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
825 ✗ (DL, D, DU, B, INFO) :=
826 Lapack.dgtsv(N, NRHS, DL, D, DU, B, LDB);
827 ✗ val_DL := ValuesMake.makeRealArray(DL);
828 ✗ val_D := ValuesMake.makeRealArray(D);
829 ✗ val_DU := ValuesMake.makeRealArray(DU);
830 ✗ val_B := ValuesMake.makeRealMatrix(B);
831 ✗ val_INFO := ValuesMake.makeInteger(INFO);
832 arg_out := {arg_DL, arg_D, arg_DU, arg_B, arg_INFO};
833 val_out := {val_DL, val_D, val_DU, val_B, val_INFO};
834 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
835 then
836 (cache, env);
837
838 case("dgbsv", {arg_N, arg_KL, arg_KU, arg_NRHS, arg_AB, arg_LDAB, arg_IPIV,
839 arg_B, arg_LDB, arg_INFO},
840 cache, env)
841 algorithm
842 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
843 ✗ (KL, cache) := evaluateExtIntArg(arg_KL, cache, env);
844 ✗ (KU, cache) := evaluateExtIntArg(arg_KU, cache, env);
845 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
846 ✗ (AB, cache) := evaluateExtRealMatrixArg(arg_AB, cache, env);
847 ✗ (LDAB, cache) := evaluateExtIntArg(arg_LDAB, cache, env);
848 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
849 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
850 ✗ (AB, IPIV, B, INFO) :=
851 Lapack.dgbsv(N, KL, KU, NRHS, AB, LDAB, B, LDB);
852 ✗ val_AB := ValuesMake.makeRealMatrix(AB);
853 ✗ val_IPIV := ValuesMake.makeIntArray(IPIV);
854 ✗ val_B := ValuesMake.makeRealMatrix(B);
855 ✗ val_INFO := ValuesMake.makeInteger(INFO);
856 arg_out := {arg_AB, arg_IPIV, arg_B, arg_INFO};
857 val_out := {val_AB, val_IPIV, val_B, val_INFO};
858 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
859 then
860 (cache, env);
861
862 case("dgesvd", {arg_JOBU, arg_JOBVT, arg_M, arg_N, arg_A, arg_LDA, arg_S,
863 arg_U, arg_LDU, arg_VT, arg_LDVT, arg_WORK, arg_LWORK, arg_INFO},
864 cache, env)
865 algorithm
866 ✗ (JOBU, cache) := evaluateExtStringArg(arg_JOBU, cache, env);
867 ✗ (JOBVT, cache) := evaluateExtStringArg(arg_JOBVT, cache, env);
868 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
869 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
870 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
871 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
872 ✗ (LDU, cache) := evaluateExtIntArg(arg_LDU, cache, env);
873 ✗ (LDVT, cache) := evaluateExtIntArg(arg_LDVT, cache, env);
874 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
875 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
876 ✗ (A, S, U, VT, WORK, INFO) :=
877 Lapack.dgesvd(JOBU, JOBVT, M, N, A, LDA, LDU, LDVT, WORK, LWORK);
878 ✗ val_A := ValuesMake.makeRealMatrix(A);
879 ✗ val_S := ValuesMake.makeRealArray(S);
880 ✗ val_U := ValuesMake.makeRealMatrix(U);
881 ✗ val_VT := ValuesMake.makeRealMatrix(VT);
882 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
883 ✗ val_INFO := ValuesMake.makeInteger(INFO);
884 arg_out := {arg_A, arg_S, arg_U, arg_VT, arg_WORK, arg_INFO};
885 val_out := {val_A, val_S, val_U, val_VT, val_WORK, val_INFO};
886 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
887 then
888 (cache, env);
889
890 case("dgetrf", {arg_M, arg_N, arg_A, arg_LDA, arg_IPIV, arg_INFO},
891 cache, env)
892 algorithm
893 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
894 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
895 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
896 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
897 ✗ (A, IPIV, INFO) :=
898 Lapack.dgetrf(M, N, A, LDA);
899 ✗ val_A := ValuesMake.makeRealMatrix(A);
900 ✗ val_IPIV := ValuesMake.makeIntArray(IPIV);
901 ✗ val_INFO := ValuesMake.makeInteger(INFO);
902 arg_out := {arg_A, arg_IPIV, arg_INFO};
903 val_out := {val_A, val_IPIV, val_INFO};
904 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
905 then
906 (cache, env);
907
908 case("dgetrs", {arg_TRANS, arg_N, arg_NRHS, arg_A, arg_LDA, arg_IPIV, arg_B,
909 arg_LDB, arg_INFO},
910 cache, env)
911 algorithm
912 ✗ (TRANS, cache) := evaluateExtStringArg(arg_TRANS, cache, env);
913 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
914 ✗ (NRHS, cache) := evaluateExtIntArg(arg_NRHS, cache, env);
915 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
916 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
917 ✗ (IPIV, cache) := evaluateExtIntArrayArg(arg_IPIV, cache, env);
918 ✗ (B, cache) := evaluateExtRealMatrixArg(arg_B, cache, env);
919 ✗ (LDB, cache) := evaluateExtIntArg(arg_LDB, cache, env);
920 ✗ (B, INFO) :=
921 Lapack.dgetrs(TRANS, N, NRHS, A, LDA, IPIV, B, LDB);
922 ✗ val_B := ValuesMake.makeRealMatrix(B);
923 ✗ val_INFO := ValuesMake.makeInteger(INFO);
924 arg_out := {arg_B, arg_INFO};
925 val_out := {val_B, val_INFO};
926 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
927 then
928 (cache, env);
929
930 case("dgetri", {arg_N, arg_A, arg_LDA, arg_IPIV, arg_WORK, arg_LWORK, arg_INFO},
931 cache, env)
932 algorithm
933 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
934 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
935 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
936 ✗ (IPIV, cache) := evaluateExtIntArrayArg(arg_IPIV, cache, env);
937 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
938 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
939 ✗ (A, WORK, INFO) :=
940 Lapack.dgetri(N, A, LDA, IPIV, WORK, LWORK);
941 ✗ val_A := ValuesMake.makeRealMatrix(A);
942 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
943 ✗ val_INFO := ValuesMake.makeInteger(INFO);
944 arg_out := {arg_A, arg_WORK, arg_INFO};
945 val_out := {val_A, val_WORK, val_INFO};
946 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
947 then
948 (cache, env);
949
950 case("dgeqpf", {arg_M, arg_N, arg_A, arg_LDA, arg_JPVT, arg_TAU, arg_WORK,
951 arg_INFO},
952 cache, env)
953 algorithm
954 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
955 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
956 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
957 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
958 ✗ (JPVT, cache) := evaluateExtIntArrayArg(arg_JPVT, cache, env);
959 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
960 ✗ (A, JPVT, TAU, INFO) :=
961 Lapack.dgeqpf(M, N, A, LDA, JPVT, WORK);
962 ✗ val_A := ValuesMake.makeRealMatrix(A);
963 ✗ val_JPVT := ValuesMake.makeIntArray(JPVT);
964 ✗ val_TAU := ValuesMake.makeRealArray(TAU);
965 ✗ val_INFO := ValuesMake.makeInteger(INFO);
966 arg_out := {arg_A, arg_JPVT, arg_TAU, arg_INFO};
967 val_out := {val_A, val_JPVT, val_TAU, val_INFO};
968 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
969 then
970 (cache, env);
971
972 case("dorgqr", {arg_M, arg_N, arg_K, arg_A, arg_LDA, arg_TAU, arg_WORK,
973 arg_LWORK, arg_INFO},
974 cache, env)
975 algorithm
976 ✗ (M, cache) := evaluateExtIntArg(arg_M, cache, env);
977 ✗ (N, cache) := evaluateExtIntArg(arg_N, cache, env);
978 ✗ (K, cache) := evaluateExtIntArg(arg_K, cache, env);
979 ✗ (A, cache) := evaluateExtRealMatrixArg(arg_A, cache, env);
980 ✗ (LDA, cache) := evaluateExtIntArg(arg_LDA, cache, env);
981 ✗ (TAU, cache) := evaluateExtRealArrayArg(arg_TAU, cache, env);
982 ✗ (WORK, cache) := evaluateExtRealArrayArg(arg_WORK, cache, env);
983 ✗ (LWORK, cache) := evaluateExtIntArg(arg_LWORK, cache, env);
984 ✗ (A, WORK, INFO) :=
985 Lapack.dorgqr(M, N, K, A, LDA, TAU, WORK, LWORK);
986 ✗ val_A := ValuesMake.makeRealMatrix(A);
987 ✗ val_WORK := ValuesMake.makeRealArray(WORK);
988 ✗ val_INFO := ValuesMake.makeInteger(INFO);
989 arg_out := {arg_A, arg_WORK, arg_INFO};
990 val_out := {val_A, val_WORK, val_INFO};
991 ✗ (cache, env) := assignExtOutputs(arg_out, val_out, cache, env);
992 then
993 (cache, env);
994 end match;
995 end evaluateExternalFunc;
996
997 protected function evaluateElements
998 "This function evaluates a list of elements."
999 input list<DAE.Element> inElements;
1000 input FCore.Cache inCache;
1001 input FCore.Graph inEnv;
1002 input LoopControl inLoopControl;
1003 output FCore.Cache outCache;
1004 output FCore.Graph outEnv;
1005 output LoopControl outLoopControl;
1006 algorithm
1007 (outCache, outEnv, outLoopControl) :=
1008 match(inElements, inLoopControl)
1009 local
1010 DAE.Element elem;
1011 list<DAE.Element> rest_elems;
1012 FCore.Cache cache;
1013 FCore.Graph env;
1014 LoopControl loop_ctrl;
1015
1016 case (_, RETURN()) then (inCache, inEnv, inLoopControl);
1017 case ({}, _) then (inCache, inEnv, NEXT());
1018 case (elem :: rest_elems, _)
1019 algorithm
1020 38094 (cache, env, loop_ctrl) := evaluateElement(elem, inCache, inEnv);
1021 37902 (cache, env, loop_ctrl) :=
1022 evaluateElements(rest_elems, cache, env, loop_ctrl);
1023 then
1024 (cache, env, loop_ctrl);
1025 end match;
1026 end evaluateElements;
1027
1028 protected function evaluateElement
1029 "This function evaluates a single element, which should be an algorithm."
1030 input DAE.Element inElement;
1031 input FCore.Cache inCache;
1032 input FCore.Graph inEnv;
1033 output FCore.Cache outCache;
1034 output FCore.Graph outEnv;
1035 output LoopControl outLoopControl;
1036 algorithm
1037 (outCache, outEnv, outLoopControl) := match inElement
1038 local
1039 FCore.Cache cache;
1040 FCore.Graph env;
1041 LoopControl loop_ctrl;
1042 list<DAE.Statement> sl;
1043
1044 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(statementLst = sl))
1045 algorithm
1046 38094 (sl, (_,env)) := DAEUtil.traverseDAEEquationsStmts(sl, Expression.traverseSubexpressionsHelper, (optimizeExpTraverser, inEnv));
1047 38094 (cache, env, loop_ctrl) := evaluateStatements(sl, inCache, env);
1048 then
1049 (cache, env, loop_ctrl);
1050 end match;
1051 end evaluateElement;
1052
1053 protected function evaluateStatement
1054 "This function evaluates a statement."
1055 input DAE.Statement inStatement;
1056 input FCore.Cache inCache;
1057 input FCore.Graph inEnv;
1058 output FCore.Cache outCache;
1059 output FCore.Graph outEnv;
1060 output LoopControl outLoopControl;
1061 algorithm
1062 (outCache, outEnv, outLoopControl) :=
1063 match(inStatement, inCache, inEnv)
1064 local
1065 FCore.Cache cache;
1066 FCore.Graph env;
1067 DAE.Exp lhs, rhs, condition;
1068 DAE.ComponentRef lhs_cref;
1069 Values.Value rhs_val, v;
1070 list<DAE.Exp> exps;
1071 list<Values.Value> vals;
1072 list<DAE.Statement> statements;
1073 LoopControl loop_ctrl;
1074 DAE.TailCall tailCall;
1075 String var;
1076 list<String> vars;
1077
1078 case (DAE.STMT_ASSIGN(exp1 = lhs, exp = rhs), cache, env)
1079 algorithm
1080 77292 (cache, rhs_val) := cevalExp(rhs, cache, env);
1081 77126 lhs_cref := extractLhsComponentRef(lhs);
1082 77122 (cache, env) := assignVariable(lhs_cref, rhs_val, cache, env);
1083 77121 then
1084 (cache, env, NEXT());
1085
1086 case (DAE.STMT_TUPLE_ASSIGN(), _, _)
1087 algorithm
1088 944 (cache, env) :=
1089 evaluateTupleAssignStatement(inStatement, inCache, inEnv);
1090 937 then
1091 (cache, env, NEXT());
1092
1093 case (DAE.STMT_ASSIGN_ARR(lhs = lhs, exp = rhs), _, env)
1094 algorithm
1095 8055 (cache, rhs_val) := cevalExp(rhs, inCache, env);
1096 8055 lhs_cref := extractLhsComponentRef(lhs);
1097 8055 (cache, env) := assignVariable(lhs_cref, rhs_val, cache, env);
1098 8055 then
1099 (cache, env, NEXT());
1100
1101 case (DAE.STMT_IF(), _, _)
1102 algorithm
1103 7694 (cache, env, loop_ctrl) :=
1104 evaluateIfStatement(inStatement, inCache, inEnv);
1105 then
1106 (cache, env, loop_ctrl);
1107
1108 case (DAE.STMT_FOR(), _, _)
1109 algorithm
1110 952 (cache, env, loop_ctrl) :=
1111 evaluateForStatement(inStatement, inCache, inEnv);
1112 then
1113 (cache, env, loop_ctrl);
1114
1115 case (DAE.STMT_WHILE(exp = condition, statementLst = statements), _, _)
1116 algorithm
1117 125 (cache, env, loop_ctrl) :=
1118 evaluateWhileStatement(condition, statements, inCache, inEnv, NEXT());
1119 then
1120 (cache, env, loop_ctrl);
1121
1122 // If the condition is true in the assert, do nothing. If the condition
1123 // is false we should stop the instantiation (depending on the assertion
1124 // level), but we can't really do much about that here. So right now we just
1125 // fail.
1126 case (DAE.STMT_ASSERT(cond = condition), _, _)
1127 algorithm
1128
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 1786 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1780 times.
1786 (cache, Values.BOOL(boolean = true)) :=
1129 cevalExp(condition, inCache, inEnv);
1130 1780 then
1131 (cache, inEnv, NEXT());
1132
1133 case (DAE.STMT_ASSERT(cond = condition), _, _)
1134 algorithm
1135 ✗ (cache, Values.BOOL(boolean = true)) :=
1136 cevalExp(condition, inCache, inEnv);
1137 ✗ then
1138 (cache, inEnv, NEXT());
1139 // Special case for print, and other known calls for now; evaluated even when there is no ST
1140 case (DAE.STMT_NORETCALL(exp = rhs as DAE.CALL( expLst = exps, attr=DAE.CALL_ATTR(tailCall=tailCall))), _, _)
1141 algorithm
1142 69 (cache, vals) := cevalExpList(exps, inCache, inEnv);
1143 68 (cache, v) := cevalExp(rhs, cache, inEnv);
1144 (cache, env, outLoopControl) := match tailCall
1145 60 case DAE.NO_TAIL() then (cache, inEnv, NEXT());
1146 // Handle tail recursion; same as a assigning all outputs followed by a return
1147 ✗ case DAE.TAIL(outVars={}) then (cache, inEnv, RETURN());
1148 case DAE.TAIL(outVars={var})
1149 algorithm
1150 4 (cache, env) := assignVariable(ComponentReference.makeUntypedCrefIdent(var), v, cache, inEnv);
1151 4 then (cache, env, RETURN());
1152 case DAE.TAIL(outVars=vars)
1153 algorithm
1154 ✗ env := inEnv;
1155 ✗ Values.TUPLE(vals) := v;
1156 ✗ for val in vals loop
1157 ✗ var::vars := vars;
1158 ✗ (cache, env) := assignVariable(ComponentReference.makeUntypedCrefIdent(var), val, cache, inEnv);
1159 end for;
1160 ✗ then (cache, env, RETURN());
1161 end match;
1162 64 then
1163 (cache, env, NEXT());
1164
1165 case (DAE.STMT_RETURN(), _, _)
1166 ✗ then
1167 (inCache, inEnv, RETURN());
1168
1169 case (DAE.STMT_BREAK(), _, _)
1170 ✗ then
1171 (inCache, inEnv, BREAK());
1172
1173 else
1174 algorithm
1175
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 true := Flags.isSet(Flags.FAILTRACE);
1176 ✗ Debug.traceln("- CevalFunction.evaluateStatement failed for:");
1177 ✗ Debug.traceln(DAEDump.ppStatementStr(inStatement));
1178 ✗ then
1179 fail();
1180 end match;
1181 end evaluateStatement;
1182
1183 protected function evaluateStatements
1184 "This function evaluates a list of statements. This is just a wrapper for
1185 evaluateStatements2."
1186 input list<DAE.Statement> inStatement;
1187 input FCore.Cache inCache;
1188 input FCore.Graph inEnv;
1189 output FCore.Cache outCache;
1190 output FCore.Graph outEnv;
1191 output LoopControl outLoopControl;
1192 algorithm
1193 47553 (outCache, outEnv, outLoopControl) :=
1194 evaluateStatements2(inStatement, inCache, inEnv, NEXT());
1195 end evaluateStatements;
1196
1197 protected function evaluateStatements2
1198 "This is a helper function to evaluateStatements that evaluates a list of
1199 statements."
1200 input list<DAE.Statement> inStatement;
1201 input FCore.Cache inCache;
1202 input FCore.Graph inEnv;
1203 input LoopControl inLoopControl;
1204 output FCore.Cache outCache;
1205 output FCore.Graph outEnv;
1206 output LoopControl outLoopControl;
1207 algorithm
1208 (outCache, outEnv, outLoopControl) :=
1209 match(inStatement, inLoopControl)
1210 local
1211 DAE.Statement stmt;
1212 list<DAE.Statement> rest_stmts;
1213 FCore.Cache cache;
1214 FCore.Graph env;
1215 LoopControl loop_ctrl;
1216 case (_, BREAK()) then (inCache, inEnv, inLoopControl);
1217 case (_, RETURN()) then (inCache, inEnv, inLoopControl);
1218 case ({}, _) then (inCache, inEnv, inLoopControl);
1219 case (stmt :: rest_stmts, NEXT())
1220 algorithm
1221 96920 (cache, env, loop_ctrl) := evaluateStatement(stmt, inCache, inEnv);
1222 96704 (cache, env, loop_ctrl) :=
1223 evaluateStatements2(rest_stmts, cache, env, loop_ctrl);
1224 then
1225 (cache, env, loop_ctrl);
1226 end match;
1227 end evaluateStatements2;
1228
1229 protected function evaluateTupleAssignStatement
1230 "This function evaluates tuple assignment statements, i.e. assignment
1231 statements where the right hand side expression is a tuple. Ex:
1232 (x, y, z) := fun(...)"
1233 input DAE.Statement inStatement;
1234 input FCore.Cache inCache;
1235 input FCore.Graph inEnv;
1236 output FCore.Cache outCache;
1237 output FCore.Graph outEnv;
1238 algorithm
1239 (outCache, outEnv) := match(inStatement, inEnv)
1240 local
1241 list<DAE.Exp> lhs_expl;
1242 DAE.Exp rhs;
1243 list<Values.Value> rhs_vals;
1244 list<DAE.ComponentRef> lhs_crefs;
1245 FCore.Cache cache;
1246 FCore.Graph env;
1247
1248 case (DAE.STMT_TUPLE_ASSIGN(expExpLst = lhs_expl, exp = rhs), env)
1249 algorithm
1250
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 937 times.
944 (cache, Values.TUPLE(valueLst = rhs_vals)) :=
1251 cevalExp(rhs, inCache, env);
1252 937 lhs_crefs := List.map(lhs_expl, extractLhsComponentRef);
1253 937 (cache, env) := assignTuple(lhs_crefs, rhs_vals, cache, env);
1254 then
1255 (cache, env);
1256 end match;
1257 end evaluateTupleAssignStatement;
1258
1259 protected function evaluateIfStatement
1260 "This function evaluates an if statement."
1261 input DAE.Statement inStatement;
1262 input FCore.Cache inCache;
1263 input FCore.Graph inEnv;
1264 output FCore.Cache outCache;
1265 output FCore.Graph outEnv;
1266 output LoopControl outLoopControl;
1267 algorithm
1268 (outCache, outEnv, outLoopControl) :=
1269 match inStatement
1270 local
1271 DAE.Exp cond;
1272 list<DAE.Statement> stmts;
1273 DAE.Else else_branch;
1274 FCore.Cache cache;
1275 FCore.Graph env;
1276 Boolean bool_cond;
1277 LoopControl loop_ctrl;
1278
1279 case DAE.STMT_IF(exp = cond, statementLst = stmts, else_ = else_branch)
1280 algorithm
1281
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7694 times.
7694 (cache, Values.BOOL(boolean = bool_cond)) :=
1282 cevalExp(cond, inCache, inEnv);
1283 7694 (cache, env, loop_ctrl) := evaluateIfStatement2(bool_cond, stmts,
1284 else_branch, cache, inEnv);
1285 then
1286 (cache, env, loop_ctrl);
1287 end match;
1288 end evaluateIfStatement;
1289
1290 protected function evaluateIfStatement2
1291 "Helper function to evaluateIfStatement."
1292 input Boolean inCondition;
1293 input list<DAE.Statement> inStatements;
1294 input DAE.Else inElse;
1295 input FCore.Cache inCache;
1296 input FCore.Graph inEnv;
1297 output FCore.Cache outCache;
1298 output FCore.Graph outEnv;
1299 output LoopControl outLoopControl;
1300 algorithm
1301 (outCache, outEnv, outLoopControl) :=
1302 match(inCondition, inStatements, inElse, inEnv)
1303 local
1304 FCore.Cache cache;
1305 FCore.Graph env;
1306 list<DAE.Statement> statements;
1307 DAE.Exp condition;
1308 Boolean bool_condition;
1309 DAE.Else else_branch;
1310 LoopControl loop_ctrl;
1311
1312 // If the condition is true, evaluate the statements in the if branch.
1313 case (true, statements, _, env)
1314 algorithm
1315 1905 (cache, env, loop_ctrl) :=
1316 evaluateStatements(statements, inCache, env);
1317 then
1318 (cache, env, loop_ctrl);
1319 // If the condition is false and we have an else, evaluate the statements in
1320 // the else branch.
1321 case (false, _, DAE.ELSE(statementLst = statements), env)
1322 algorithm
1323 2462 (cache, env, loop_ctrl) :=
1324 evaluateStatements(statements, inCache, env);
1325 then
1326 (cache, env, loop_ctrl);
1327 // If the condition is false and we have an else if, call this function
1328 // again recursively.
1329 case (false, _, DAE.ELSEIF(exp = condition, statementLst = statements,
1330 else_ = else_branch), env)
1331 algorithm
1332
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 477 times.
477 (cache, Values.BOOL(boolean = bool_condition)) :=
1333 cevalExp(condition, inCache, env);
1334 477 (cache, env, loop_ctrl) :=
1335 evaluateIfStatement2(bool_condition, statements, else_branch, cache, env);
1336 then
1337 (cache, env, loop_ctrl);
1338 // If the condition is false and we have no else branch, just continue.
1339 3327 case (false, _, DAE.NOELSE(), _) then (inCache, inEnv, NEXT());
1340 end match;
1341 end evaluateIfStatement2;
1342
1343 protected function evaluateForStatement
1344 "This function evaluates for statements."
1345 input DAE.Statement inStatement;
1346 input FCore.Cache inCache;
1347 input FCore.Graph inEnv;
1348 output FCore.Cache outCache;
1349 output FCore.Graph outEnv;
1350 output LoopControl outLoopControl;
1351 algorithm
1352 (outCache, outEnv, outLoopControl) :=
1353 matchcontinue(inStatement, inEnv)
1354 local
1355 DAE.Type ety;
1356 DAE.Type ty;
1357 String iter_name;
1358 DAE.Exp range;
1359 list<DAE.Statement> statements;
1360 list<Values.Value> range_vals;
1361 FCore.Cache cache;
1362 FCore.Graph env;
1363 DAE.ComponentRef iter_cr;
1364 LoopControl loop_ctrl;
1365
1366 // The case where the range is an array.
1367 case (DAE.STMT_FOR(type_ = ety, iter = iter_name,
1368 range = range, statementLst = statements), env)
1369 algorithm
1370
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 952 times.
952 (cache, Values.ARRAY(valueLst = range_vals)) :=
1371 cevalExp(range, inCache, env);
1372 952 (env, ty, iter_cr) := extendEnvWithForScope(iter_name, ety, env);
1373 952 (cache, env, loop_ctrl) := evaluateForLoopArray(cache, env, iter_cr,
1374 ty, range_vals, statements, NEXT());
1375 then
1376 (cache, env, loop_ctrl);
1377
1378 case (DAE.STMT_FOR(range = range), _)
1379 algorithm
1380
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 true := Flags.isSet(Flags.FAILTRACE);
1381 ✗ Debug.traceln("- evaluateForStatement not implemented for:");
1382 ✗ Debug.traceln(ExpressionBasics.printExpStr(range));
1383 ✗ then
1384 fail();
1385 end matchcontinue;
1386 end evaluateForStatement;
1387
1388 protected function evaluateForLoopArray
1389 "This function evaluates a for loop where the range is an array."
1390 input FCore.Cache inCache;
1391 input FCore.Graph inEnv;
1392 input DAE.ComponentRef inIter;
1393 input DAE.Type inIterType;
1394 input list<Values.Value> inValues;
1395 input list<DAE.Statement> inStatements;
1396 input LoopControl inLoopControl;
1397 output FCore.Cache outCache;
1398 output FCore.Graph outEnv;
1399 output LoopControl outLoopControl;
1400 algorithm
1401 (outCache, outEnv, outLoopControl) := match(inEnv, inValues, inLoopControl)
1402 local
1403 Values.Value value;
1404 list<Values.Value> rest_vals;
1405 FCore.Cache cache;
1406 FCore.Graph env;
1407 LoopControl loop_ctrl;
1408
1409 case (_, _, BREAK()) then (inCache, inEnv, NEXT());
1410 case (_, _, RETURN()) then (inCache, inEnv, inLoopControl);
1411 case (_, {}, _) then (inCache, inEnv, inLoopControl);
1412 case (env, value :: rest_vals, NEXT())
1413 algorithm
1414 4032 env := updateVariableBinding(inIter, env, inIterType, value);
1415 4032 (cache, env, loop_ctrl) :=
1416 evaluateStatements(inStatements, inCache, env);
1417 4029 (cache, env, loop_ctrl) := evaluateForLoopArray(cache, env, inIter,
1418 inIterType, rest_vals, inStatements, loop_ctrl);
1419 then
1420 (cache, env, loop_ctrl);
1421 end match;
1422 end evaluateForLoopArray;
1423
1424 protected function evaluateWhileStatement
1425 "This function evaluates a while statement."
1426 input DAE.Exp inCondition;
1427 input list<DAE.Statement> inStatements;
1428 input FCore.Cache inCache;
1429 input FCore.Graph inEnv;
1430 input LoopControl inLoopControl;
1431 output FCore.Cache outCache;
1432 output FCore.Graph outEnv;
1433 output LoopControl outLoopControl;
1434 algorithm
1435 (outCache, outEnv, outLoopControl) :=
1436 match inLoopControl
1437 local
1438 FCore.Cache cache;
1439 FCore.Graph env;
1440 LoopControl loop_ctrl;
1441 Boolean b;
1442
1443 case BREAK() then (inCache, inEnv, NEXT());
1444 case RETURN() then (inCache, inEnv, inLoopControl);
1445 case _
1446 algorithm
1447
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1165 times.
1165 (cache, Values.BOOL(boolean = b)) := cevalExp(inCondition, inCache, inEnv);
1448
2/2
✓ Branch 0 taken 1060 times.
✓ Branch 1 taken 105 times.
1165 if b then
1449 1060 (cache, env, loop_ctrl) := evaluateStatements(inStatements, cache, inEnv);
1450 1040 (cache, env, loop_ctrl) := evaluateWhileStatement(inCondition, inStatements, cache, env, loop_ctrl);
1451 else
1452 105 loop_ctrl := NEXT();
1453 105 env := inEnv;
1454 end if;
1455 1145 then
1456 (cache, env, loop_ctrl);
1457
1458 end match;
1459 end evaluateWhileStatement;
1460
1461 protected function extractLhsComponentRef
1462 "This function extracts a component reference from an expression. It's used to
1463 get the left hand side component reference in simple assignments."
1464 input DAE.Exp inExp;
1465 output DAE.ComponentRef outCref;
1466 algorithm
1467 outCref := match inExp
1468 local
1469 DAE.ComponentRef cref;
1470 case DAE.CREF(componentRef = cref) then cref;
1471 else
1472 algorithm
1473
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 true := Flags.isSet(Flags.FAILTRACE);
1474 ✗ Debug.traceln("- CevalFunction.extractLhsComponentRef failed on " + ExpressionBasics.printExpStr(inExp));
1475 ✗ then
1476 fail();
1477 end match;
1478 end extractLhsComponentRef;
1479
1480 protected function cevalExp
1481 "A wrapper for Ceval with most of the arguments filled in."
1482 input DAE.Exp inExp;
1483 input FCore.Cache inCache;
1484 input FCore.Graph inEnv;
1485 output FCore.Cache outCache;
1486 output Values.Value outValue;
1487 algorithm
1488 129821 (outCache, outValue) := Ceval.ceval(inCache, inEnv, inExp, true, Absyn.MSG(Absyn.dummyInfo), 0);
1489
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 129644 times.
129644 false := valueEq(Values.META_FAIL(), outValue);
1490 end cevalExp;
1491
1492 protected function cevalExpList
1493 "A wrapper for Ceval with most of the arguments filled in."
1494 input list<DAE.Exp> inExpLst;
1495 input FCore.Cache inCache;
1496 input FCore.Graph inEnv;
1497 output FCore.Cache outCache;
1498 output list<Values.Value> outValue;
1499 algorithm
1500 69 (outCache, outValue) := Ceval.cevalList(inCache, inEnv, inExpLst, true, Absyn.MSG(Absyn.dummyInfo), 0);
1501 end cevalExpList;
1502
1503 // [EENV] Environment extension functions (add variables).
1504
1505 protected function setupFunctionEnvironment
1506 "Opens up a new scope for the functions and adds all function variables to it."
1507 input FCore.Cache inCache;
1508 input FCore.Graph inEnv;
1509 input String inFuncName;
1510 input list<FunctionVar> inFuncParams;
1511 output FCore.Cache outCache;
1512 output FCore.Graph outEnv;
1513 algorithm
1514 38177 outEnv := FGraph.openScope(inEnv, SCode.NOT_ENCAPSULATED(), inFuncName, SOME(FCore.FUNCTION_SCOPE()));
1515 38177 (outCache, outEnv) :=
1516 extendEnvWithFunctionVars(inCache, outEnv, inFuncParams);
1517 end setupFunctionEnvironment;
1518
1519 protected function extendEnvWithFunctionVars
1520 "Extends the environment with a list of variables. The list of values is the
1521 input arguments to the function."
1522 input FCore.Cache inCache;
1523 input FCore.Graph inEnv;
1524 input list<FunctionVar> inFuncParams;
1525 output FCore.Cache outCache;
1526 output FCore.Graph outEnv;
1527 algorithm
1528 (outCache, outEnv) := match(inCache, inEnv, inFuncParams)
1529 local
1530 FunctionVar param;
1531 list<FunctionVar> rest_params;
1532 FCore.Cache cache;
1533 FCore.Graph env;
1534
1535 case (_, _, {}) then (inCache, inEnv);
1536
1537 case (cache, env, param :: rest_params)
1538 algorithm
1539 99626 (cache, env) := extendEnvWithFunctionVar(cache, env, param);
1540 99626 (cache, env) := extendEnvWithFunctionVars(cache, env, rest_params);
1541 then
1542 (cache, env);
1543
1544 end match;
1545 end extendEnvWithFunctionVars;
1546
1547 protected function extendEnvWithFunctionVar
1548 input FCore.Cache inCache;
1549 input FCore.Graph inEnv;
1550 input FunctionVar inFuncParam;
1551 output FCore.Cache outCache;
1552 output FCore.Graph outEnv;
1553 algorithm
1554 (outCache, outEnv) := matchcontinue(inEnv, inFuncParam)
1555 local
1556 DAE.Element e;
1557 Option<Values.Value> val;
1558 FCore.Cache cache;
1559 FCore.Graph env;
1560 Option<DAE.Exp> binding_exp;
1561
1562 // Input parameters are assigned their corresponding input argument given to
1563 // the function.
1564 case (env, (e, val as SOME(_)))
1565 algorithm
1566 51711 (cache, env) := extendEnvWithElement(e, val, inCache, env);
1567 then
1568 (cache, env);
1569
1570 // Non-input parameters might have a default binding, so we use that if it's
1571 // available.
1572 case (env, ((e as DAE.VAR(binding = binding_exp)), NONE()))
1573 algorithm
1574 47915 (val, cache) := evaluateBinding(binding_exp, inCache, inEnv);
1575 47915 (cache, env) := extendEnvWithElement(e, val, cache, env);
1576 then
1577 (cache, env);
1578
1579 case (_, (e, _))
1580 algorithm
1581 ✗ true := Flags.isSet(Flags.FAILTRACE);
1582 ✗ Debug.traceln("- CevalFunction.extendEnvWithFunctionVars failed for:");
1583 ✗ Debug.traceln(DAEDump.dumpElementsStr({e}));
1584 ✗ then
1585 fail();
1586 end matchcontinue;
1587 end extendEnvWithFunctionVar;
1588
1589 protected function evaluateBinding
1590 "Evaluates an optional binding expression. If SOME expression is given,
1591 returns SOME value or fails. If NONE expression given, returns NONE value."
1592 input Option<DAE.Exp> inBinding;
1593 input FCore.Cache inCache;
1594 input FCore.Graph inEnv;
1595 output Option<Values.Value> outValue;
1596 output FCore.Cache outCache;
1597 algorithm
1598 (outValue, outCache) := match inBinding
1599 local
1600 DAE.Exp binding_exp;
1601 FCore.Cache cache;
1602 Values.Value val;
1603
1604 case SOME(binding_exp)
1605 algorithm
1606 2829 (cache, val) := cevalExp(binding_exp, inCache, inEnv);
1607 2829 then
1608 (SOME(val), cache);
1609
1610 case NONE() then (NONE(), inCache);
1611 end match;
1612 end evaluateBinding;
1613
1614 protected function extendEnvWithElement
1615 "This function extracts the necessary data from a variable element, and calls
1616 extendEnvWithVar to add a new variable to the environment."
1617 input DAE.Element inElement;
1618 input Option<Values.Value> inBindingValue;
1619 input FCore.Cache inCache;
1620 input FCore.Graph inEnv;
1621 output FCore.Cache outCache;
1622 output FCore.Graph outEnv;
1623 algorithm
1624 (outCache, outEnv) :=
1625 match inElement
1626 local
1627 DAE.ComponentRef cr;
1628 String name;
1629 DAE.Type ty;
1630 DAE.InstDims dims;
1631 FCore.Cache cache;
1632 FCore.Graph env;
1633
1634 case DAE.VAR(componentRef = cr, ty = ty, dims = dims)
1635 algorithm
1636 99626 name := ComponentReference.crefStr(cr);
1637 99626 (cache, env) :=
1638 extendEnvWithVar(name, ty, inBindingValue, dims, inCache, inEnv);
1639 then
1640 (cache, env);
1641 end match;
1642 end extendEnvWithElement;
1643
1644 protected function extendEnvWithVar
1645 "This function does the actual work of extending the environment with a
1646 variable."
1647 input String inName;
1648 input DAE.Type inType;
1649 input Option<Values.Value> inOptValue;
1650 input DAE.InstDims inDims;
1651 input FCore.Cache inCache;
1652 input FCore.Graph inEnv;
1653 output FCore.Cache outCache;
1654 output FCore.Graph outEnv;
1655 algorithm
1656 (outCache, outEnv) :=
1657 matchcontinue inEnv
1658 local
1659 DAE.Type ty;
1660 DAE.Var var;
1661 DAE.Binding binding;
1662 FCore.Cache cache;
1663 FCore.Graph env, record_env;
1664
1665 // Records are special, since they have their own environment with their
1666 // components in them. A record variable is thus always unbound, and their
1667 // values are instead determined by their components values.
1668 case _
1669 algorithm
1670
2/2
✓ Branch 1 taken 129483 times.
✓ Branch 2 taken 5211 times.
134694 true := Types.isRecord(inType);
1671 5211 binding := makeBinding(inOptValue);
1672 5211 (cache, ty) :=
1673 appendDimensions(inType, inOptValue, inDims, inCache, inEnv);
1674 5211 var := makeFunctionVariable(inName, ty, binding);
1675 5211 (cache, record_env) :=
1676 makeRecordEnvironment(inType, inOptValue, cache, inEnv);
1677 5211 env := FGraph.mkComponentNode(
1678 inEnv,
1679 var,
1680 SCode.COMPONENT(
1681 inName,
1682 SCode.defaultPrefixes,
1683 SCode.ATTR({}, SCode.POTENTIAL(), SCode.NON_PARALLEL(), SCode.VAR(), Absyn.BIDIR(),Absyn.NONFIELD()),
1684 Absyn.TPATH(Absyn.IDENT(""), NONE()), SCode.NOMOD(),
1685 SCode.noComment, NONE(), Absyn.dummyInfo),
1686 DAE.NOMOD(),
1687 FCore.VAR_TYPED(),
1688 record_env);
1689 then
1690 (cache, env);
1691
1692 // Normal variables.
1693 else
1694 algorithm
1695 129483 binding := makeBinding(inOptValue);
1696 129483 (cache, ty) :=
1697 appendDimensions(inType, inOptValue, inDims, inCache, inEnv);
1698 129483 var := makeFunctionVariable(inName, ty, binding);
1699 129483 env := FGraph.mkComponentNode(
1700 inEnv,
1701 var,
1702 SCode.COMPONENT(
1703 inName,
1704 SCode.defaultPrefixes,
1705 SCode.ATTR({}, SCode.POTENTIAL(), SCode.NON_PARALLEL(), SCode.VAR(), Absyn.BIDIR(),Absyn.NONFIELD()),
1706 Absyn.TPATH(Absyn.IDENT(""), NONE()), SCode.NOMOD(),
1707 SCode.noComment, NONE(), Absyn.dummyInfo),
1708 DAE.NOMOD(),
1709 FCore.VAR_TYPED(),
1710 FGraph.empty());
1711 then
1712 (cache, env);
1713
1714 end matchcontinue;
1715 end extendEnvWithVar;
1716
1717 protected function makeFunctionVariable
1718 "This function creates a new variable ready to be added to an environment
1719 given a name, type and binding."
1720 input String inName;
1721 input DAE.Type inType;
1722 input DAE.Binding inBinding;
1723 output DAE.Var outVar;
1724 annotation(__OpenModelica_EarlyInline = true);
1725 algorithm
1726 97617 outVar := DAE.TYPES_VAR(inName, DAE.dummyAttrVar, inType, inBinding, false, NONE());
1727 end makeFunctionVariable;
1728
1729 protected function makeBinding
1730 "Creates a binding from an optional value. If some value is given we return a
1731 value bound binding, otherwise an unbound binding."
1732 input Option<Values.Value> inBindingValue;
1733 output DAE.Binding outBinding;
1734 algorithm
1735 outBinding := match inBindingValue
1736 local Values.Value val;
1737 66257 case SOME(val) then DAE.VALBOUND(val, DAE.BINDING_FROM_DEFAULT_VALUE());
1738 case NONE() then DAE.UNBOUND();
1739 end match;
1740 end makeBinding;
1741
1742 protected function makeRecordEnvironment
1743 "This function creates an environment for a record variable by creating a new
1744 environment and adding the records components to it. If an optional value is
1745 supplied it also gives the components a value binding."
1746 input DAE.Type inRecordType;
1747 input Option<Values.Value> inOptValue;
1748 input FCore.Cache inCache;
1749 input FCore.Graph inGraph;
1750 output FCore.Cache outCache;
1751 output FCore.Graph outRecordEnv;
1752 algorithm
1753 (outCache, outRecordEnv) :=
1754 match inRecordType
1755 local
1756 list<DAE.Var> var_lst;
1757 list<Option<Values.Value>> vals;
1758 FCore.Cache cache;
1759 FCore.Graph graph;
1760 FCore.Ref parent, child;
1761 FCore.Node node;
1762
1763 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(),varLst = var_lst)
1764 algorithm
1765 5211 parent := FGraph.lastScopeRef(inGraph);
1766 5211 (graph, node) := FGraph.node(inGraph, FNode.feNodeName, {parent}, FCore.ND(NONE()));
1767 5211 child := FNode.toRef(node);
1768 5211 FNode.addChildRef(parent, FNode.feNodeName, child);
1769 5211 graph := FGraph.pushScopeRef(graph, child);
1770
1771 5211 vals := getRecordValues(inOptValue, inRecordType);
1772
1/2
✓ Branch 2 taken 5211 times.
✗ Branch 3 not taken.
5211 (cache, graph) := List.threadFold(var_lst, vals,
1773 extendEnvWithRecordVar, (inCache, graph));
1774 then
1775 (cache, graph);
1776 end match;
1777 end makeRecordEnvironment;
1778
1779 protected function getRecordValues
1780 "This function returns a list of optional values that will be assigned to a
1781 records components. If some record value is given it returns the list of
1782 values inside it, made into options, otherwise it returns a list of as many
1783 NONE as there are components in the record."
1784 input Option<Values.Value> inOptValue;
1785 input DAE.Type inRecordType;
1786 output list<Option<Values.Value>> outValues;
1787 algorithm
1788 outValues := match(inOptValue, inRecordType)
1789 local
1790 list<Values.Value> vals;
1791 list<Option<Values.Value>> opt_vals;
1792 list<DAE.Var> vars;
1793 Integer n;
1794 case (SOME(Values.RECORD(orderd = vals)), _)
1795 algorithm
1796 1562 opt_vals := List.map(vals, Util.makeOption);
1797 then
1798 opt_vals;
1799
1800 case (NONE(), DAE.T_COMPLEX(varLst = vars))
1801 algorithm
1802 3649 n := listLength(vars);
1803 3649 opt_vals := List.fill(NONE(), n);
1804 then
1805 opt_vals;
1806 end match;
1807 end getRecordValues;
1808
1809 protected function extendEnvWithRecordVar
1810 "This function extends an environment with a record component."
1811 input DAE.Var inVar;
1812 input Option<Values.Value> inOptValue;
1813 input tuple<FCore.Cache, FCore.Graph> inEnv;
1814 output tuple<FCore.Cache, FCore.Graph> outEnv;
1815 algorithm
1816 outEnv := match(inVar, inEnv)
1817 local
1818 String name;
1819 DAE.Type ty;
1820 FCore.Cache cache;
1821 FCore.Graph env;
1822
1823 case (DAE.TYPES_VAR(name = name, ty = ty), (cache, env))
1824 algorithm
1825 35068 (cache, env) :=
1826 extendEnvWithVar(name, ty, inOptValue, {}, cache, env);
1827 35068 outEnv := (cache, env);
1828 then
1829 outEnv;
1830 end match;
1831 end extendEnvWithRecordVar;
1832
1833 protected function extendEnvWithForScope
1834 "This function opens a new for loop scope in the environment by opening a new
1835 scope and adding the given iterator to it. For convenience it also returns the
1836 type and component reference of the iterator."
1837 input String inIterName;
1838 input DAE.Type inIterType;
1839 input FCore.Graph inEnv;
1840 output FCore.Graph outEnv;
1841 output DAE.Type outIterType;
1842 output DAE.ComponentRef outIterCref;
1843 algorithm
1844 952 outIterType := Types.expTypetoTypesType(inIterType);
1845 952 outEnv := FGraph.addForIterator(inEnv, inIterName, outIterType,
1846 DAE.UNBOUND(), SCode.CONST(), SOME(DAE.C_CONST()));
1847 952 outIterCref := ComponentReferenceBasics.makeCrefIdent(inIterName, inIterType, {});
1848 end extendEnvWithForScope;
1849
1850 protected function appendDimensions
1851 "This function appends dimensions to a type. This is needed because DAE.VAR
1852 separates the type and dimensions, while DAE.TYPES_VAR keeps the dimension
1853 information in the type itself. The dimensions can come from two sources:
1854 either they are specified in the variable itself as DAE.InstDims, or if the
1855 variable is declared with unknown dimensions they can be determined from the
1856 variables binding (i.e. input argument to the function)."
1857 input DAE.Type inType;
1858 input Option<Values.Value> inOptBinding;
1859 input DAE.InstDims inDims;
1860 input FCore.Cache inCache;
1861 input FCore.Graph inEnv;
1862 output FCore.Cache outCache;
1863 output DAE.Type outType;
1864 protected
1865 list<Integer> binding_dims;
1866 algorithm
1867 134694 binding_dims := ValuesUtil.valueDimensions(
1868 Util.getOptionOrDefault(inOptBinding, Values.INTEGER(0)));
1869 134694 (outCache, outType) :=
1870 appendDimensions2(inType, inDims, binding_dims, inCache, inEnv);
1871 end appendDimensions;
1872
1873 protected function appendDimensions2
1874 "Helper function to appendDimensions. Appends dimensions to a type. inDims is
1875 the declared dimensions of the variable while inBindingDims is the dimensions
1876 of the variables binding (empty list if it doesn't have a binding)."
1877 input DAE.Type inType;
1878 input DAE.InstDims inDims;
1879 input list<Integer> inBindingDims;
1880 input FCore.Cache inCache;
1881 input FCore.Graph inEnv;
1882 output FCore.Cache outCache;
1883 output DAE.Type outType;
1884 algorithm
1885 (outCache, outType) :=
1886 matchcontinue(inType, inDims, inBindingDims)
1887 local
1888 DAE.InstDims rest_dims;
1889 DAE.Exp dim_exp;
1890 Values.Value dim_val;
1891 Integer dim_int;
1892 DAE.Dimension dim;
1893 DAE.Type ty;
1894 list<Integer> bind_dims;
1895 FCore.Cache cache;
1896
1897 case (ty, {}, _) then (inCache, ty);
1898
1899 case (ty, DAE.DIM_UNKNOWN() :: rest_dims, dim_int :: bind_dims)
1900 algorithm
1901 4847 dim := Expression.intDimension(dim_int);
1902 4847 (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1903 4847 then
1904 (cache, DAE.T_ARRAY(ty, {dim}));
1905
1906 // If the variable is not an input, set the dimension size to 0 (dynamic size).
1907 case (ty, DAE.DIM_UNKNOWN() :: rest_dims, bind_dims)
1908 algorithm
1909 8 (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1910 8 then
1911 (cache, DAE.T_ARRAY(ty, {DAE.DIM_INTEGER(0)}));
1912
1913 case (ty, DAE.DIM_INTEGER(dim_int) :: rest_dims, bind_dims)
1914 algorithm
1915 20095 dim := DAE.DIM_INTEGER(dim_int);
1916 20095 bind_dims := List.restOrEmpty(bind_dims);
1917 20095 (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1918 20095 then
1919 (cache, DAE.T_ARRAY(ty, {dim}));
1920
1921 case (ty, DAE.DIM_BOOLEAN() :: rest_dims, bind_dims)
1922 algorithm
1923 dim := DAE.DIM_INTEGER(2);
1924 ✗ bind_dims := List.restOrEmpty(bind_dims);
1925 ✗ (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1926 ✗ then
1927 (cache, DAE.T_ARRAY(ty, {dim}));
1928
1929 case (ty, DAE.DIM_ENUM(size = dim_int) :: rest_dims, bind_dims)
1930 algorithm
1931 ✗ dim := DAE.DIM_INTEGER(dim_int);
1932 ✗ bind_dims := List.restOrEmpty(bind_dims);
1933 ✗ (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1934 ✗ then
1935 (cache, DAE.T_ARRAY(ty, {dim}));
1936
1937 case (ty, DAE.DIM_EXP(exp = dim_exp) :: rest_dims, bind_dims)
1938 algorithm
1939 896 (cache, dim_val) := cevalExp(dim_exp, inCache, inEnv);
1940 896 dim_int := ValuesUtil.valueInteger(dim_val);
1941 896 dim := DAE.DIM_INTEGER(dim_int);
1942 896 bind_dims := List.restOrEmpty(bind_dims);
1943 896 (cache, ty) := appendDimensions2(ty, rest_dims, bind_dims, inCache, inEnv);
1944 896 then
1945 (cache, DAE.T_ARRAY(ty, {dim}));
1946
1947 case (_, _ :: _, _)
1948 algorithm
1949 ✗ true := Flags.isSet(Flags.FAILTRACE);
1950 ✗ Debug.trace("- CevalFunction.appendDimensions2 failed\n");
1951 ✗ then
1952 fail();
1953 end matchcontinue;
1954 end appendDimensions2;
1955
1956 // [MENV] Environment manipulation functions (set and get variables).
1957
1958 protected function assignVariable
1959 "This function assigns a variable in the environment a new value."
1960 input DAE.ComponentRef inCref;
1961 input Values.Value inNewValue;
1962 input FCore.Cache inCache;
1963 input FCore.Graph inEnv;
1964 output FCore.Cache outCache;
1965 output FCore.Graph outEnv;
1966 algorithm
1967 (outCache, outEnv) :=
1968 matchcontinue inCref
1969 local
1970 DAE.ComponentRef cr, cr_rest;
1971 FCore.Cache cache;
1972 FCore.Graph env;
1973 list<DAE.Subscript> subs;
1974 DAE.Type ty;
1975 DAE.Type ety;
1976 Values.Value val;
1977 DAE.Var var;
1978 FCore.Status inst_status;
1979 String id, comp_id;
1980
1981 // Wildcard, no need to assign anything.
1982 case DAE.WILD() then (inCache, inEnv);
1983
1984 // A record assignment.
1985 case DAE.CREF_IDENT(ident = id, subscriptLst = {}, identType = ety as
1986 DAE.T_COMPLEX(complexClassType = ClassInf.RECORD()))
1987 algorithm
1988 2417 (_, var, _, _, inst_status, env) :=
1989 Lookup.lookupIdentLocal(inCache, inEnv, id);
1990 2417 (cache, env) := assignRecord(ety, inNewValue, inCache, env);
1991 2417 var := updateRecordBinding(var, inNewValue);
1992 2417 env := FGraph.updateComp(inEnv, var, inst_status, env);
1993 then
1994 (cache, env);
1995
1996 // If we get a scalar we just update the value.
1997 case cr as DAE.CREF_IDENT(subscriptLst = {})
1998 algorithm
1999 66905 ty := Types.unflattenArrayType(Expression.typeof(ValuesUtil.valueExp(inNewValue))); // In case of zero-dimensions, update the dimensions; they are all known now
2000 66905 env := updateVariableBinding(cr, inEnv, ty, inNewValue);
2001 then
2002 (inCache, env);
2003
2004 // If we get a vector we first get the old value and update the relevant
2005 // part of it, and then update the variables value.
2006 case DAE.CREF_IDENT(subscriptLst = subs)
2007 algorithm
2008 26680 cr := ComponentReference.crefStripSubs(inCref);
2009 26680 (ty, val) := getVariableTypeAndValue(cr, inEnv);
2010 26680 (cache, val) := assignVector(inNewValue, val, subs, inCache, inEnv);
2011 26680 env := updateVariableBinding(cr, inEnv, ty, val);
2012 then
2013 (cache, env);
2014
2015 // A qualified component reference is a record component, so first lookup
2016 // the records environment, and then assign the variable in that environment.
2017 case DAE.CREF_QUAL(ident = id, subscriptLst = {},
2018 componentRef = cr_rest)
2019 algorithm
2020 9874 (_, var, _, _, inst_status, env) :=
2021 Lookup.lookupIdentLocal(inCache, inEnv, id);
2022 9874 (cache, env) := assignVariable(cr_rest, inNewValue, inCache, env);
2023 9874 comp_id := ComponentReferenceBasics.crefFirstIdent(cr_rest);
2024 9874 var := updateRecordComponentBinding(var, comp_id, inNewValue);
2025 9874 env := FGraph.updateComp(inEnv, var, inst_status, env);
2026 then
2027 (cache, env);
2028 end matchcontinue;
2029 end assignVariable;
2030
2031 protected function assignTuple
2032 "This function assign a tuple by calling assignVariable for each tuple
2033 component."
2034 input list<DAE.ComponentRef> inLhsCrefs;
2035 input list<Values.Value> inRhsValues;
2036 input FCore.Cache inCache;
2037 input FCore.Graph inEnv;
2038 output FCore.Cache outCache;
2039 output FCore.Graph outEnv;
2040 algorithm
2041 (outCache, outEnv) :=
2042 match(inLhsCrefs, inRhsValues, inCache, inEnv)
2043 local
2044 DAE.ComponentRef cr;
2045 list<DAE.ComponentRef> rest_crefs;
2046 Values.Value value;
2047 list<Values.Value> rest_vals;
2048 FCore.Cache cache;
2049 FCore.Graph env;
2050 case ({}, _, cache, env) then (cache, env);
2051 case (cr :: rest_crefs, value :: rest_vals, cache, env)
2052 algorithm
2053 1880 (cache, env) := assignVariable(cr, value, cache, env);
2054 1880 (cache, env) := assignTuple(rest_crefs, rest_vals, cache, env);
2055 then
2056 (cache, env);
2057 end match;
2058 end assignTuple;
2059
2060 protected function assignRecord
2061 input DAE.Type inType;
2062 input Values.Value inValue;
2063 input FCore.Cache inCache;
2064 input FCore.Graph inEnv;
2065 output FCore.Cache outCache;
2066 output FCore.Graph outEnv;
2067 algorithm
2068 (outCache, outEnv) := match(inType, inValue)
2069 local
2070 list<Values.Value> values;
2071 list<DAE.Var> vars;
2072 FCore.Cache cache;
2073 FCore.Graph env;
2074 case (DAE.T_COMPLEX(varLst = vars), Values.RECORD(orderd = values))
2075 algorithm
2076 2417 (cache, env) := assignRecordComponents(vars, values, inCache, inEnv);
2077 then
2078 (cache, env);
2079 end match;
2080 end assignRecord;
2081
2082 protected function assignRecordComponents
2083 input list<DAE.Var> inVars;
2084 input list<Values.Value> inValues;
2085 input FCore.Cache inCache;
2086 input FCore.Graph inEnv;
2087 output FCore.Cache outCache;
2088 output FCore.Graph outEnv;
2089 algorithm
2090 (outCache, outEnv) := match(inVars, inValues)
2091 local
2092 list<DAE.Var> rest_vars;
2093 Values.Value val;
2094 list<Values.Value> rest_vals;
2095 String name;
2096 DAE.ComponentRef cr;
2097 DAE.Type ty;
2098 FCore.Cache cache;
2099 FCore.Graph env;
2100
2101 case ({}, {}) then (inCache, inEnv);
2102
2103 case (DAE.TYPES_VAR(name = name, ty = ty) :: rest_vars, val :: rest_vals)
2104 algorithm
2105 8926 cr := ComponentReferenceBasics.makeCrefIdent(name, ty, {});
2106 8926 (cache, env) := assignVariable(cr, val, inCache, inEnv);
2107 8926 (cache, env) := assignRecordComponents(rest_vars, rest_vals, cache, env);
2108 then
2109 (cache, env);
2110 end match;
2111 end assignRecordComponents;
2112
2113 public function assignVector
2114 "This function assigns a part of a vector by replacing the parts indicated by
2115 the subscripts in the old value with the new value."
2116 input Values.Value inNewValue;
2117 input Values.Value inOldValue;
2118 input list<DAE.Subscript> inSubscripts;
2119 input FCore.Cache inCache;
2120 input FCore.Graph inEnv;
2121 output FCore.Cache outCache;
2122 output Values.Value outResult;
2123 algorithm
2124 (outCache, outResult) :=
2125 matchcontinue(inNewValue, inOldValue, inSubscripts)
2126 local
2127 DAE.Exp e;
2128 Values.Value index, val;
2129 list<Values.Value> values, values2;
2130 list<Values.Value> old_values, old_values2, indices;
2131 list<Integer> dims;
2132 Integer i;
2133 DAE.Subscript sub;
2134 list<DAE.Subscript> rest_subs;
2135 FCore.Cache cache;
2136
2137 // No subscripts, we have either reached the end of the recursion or the
2138 // whole vector was assigned.
2139 case (_, _, {}) then (inCache, inNewValue);
2140
2141 // An index subscript. Extract the indicated vector element and update it
2142 // with assignVector, and then put it back in the list of old values.
2143 case (_, Values.ARRAY(valueLst = values, dimLst = dims), DAE.INDEX(exp = e) :: rest_subs)
2144 algorithm
2145 27658 (cache, index) := cevalExp(e, inCache, inEnv);
2146 27658 i := ValuesUtil.valueInteger(index);
2147 27658 val := listGet(values, i);
2148 27658 (cache, val) := assignVector(inNewValue, val, rest_subs, cache, inEnv);
2149 27658 values := List.replaceAt(val, i, values);
2150 27658 then
2151 (cache, Values.ARRAY(values, dims));
2152
2153 // A slice.
2154 case (Values.ARRAY(valueLst = values), Values.ARRAY(valueLst = old_values, dimLst = dims), DAE.SLICE(exp = e) :: rest_subs)
2155 algorithm
2156 // Evaluate the slice range to a list of values.
2157
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
5 (cache, Values.ARRAY(valueLst = (indices as (Values.INTEGER(integer = i) :: _)))) :=
2158 cevalExp(e, inCache, inEnv);
2159 // Split the list of old values at the first slice index.
2160 5 (old_values, old_values2) := List.splitr(old_values, i - 1);
2161 // Update the rest of the old value with assignSlice.
2162 5 (cache, values2) :=
2163 assignSlice(values, old_values2, indices, rest_subs, i, cache, inEnv);
2164 // Assemble the list of values again.
2165 5 values := List.append_reverse(old_values, values2);
2166 5 then
2167 (cache, Values.ARRAY(values, dims));
2168
2169 // A : (whole dimension).
2170 case (Values.ARRAY(valueLst = values), Values.ARRAY(valueLst = values2, dimLst = dims), DAE.WHOLEDIM() :: rest_subs)
2171 algorithm
2172 9 (cache, values) :=
2173 assignWholeDim(values, values2, rest_subs, inCache, inEnv);
2174 9 then
2175 (cache, Values.ARRAY(values, dims));
2176
2177 case (_, _, sub :: _)
2178 algorithm
2179 ✗ true := Flags.isSet(Flags.FAILTRACE);
2180 ✗ print("- CevalFunction.assignVector failed on: ");
2181 ✗ print(ExpressionBasics.printSubscriptStr(sub) + "\n");
2182 ✗ then
2183 fail();
2184 end matchcontinue;
2185 end assignVector;
2186
2187 protected function assignSlice
2188 "This function assigns a slice of a vector given a list of new and old values
2189 and a list of indices."
2190 input list<Values.Value> inNewValues;
2191 input list<Values.Value> inOldValues;
2192 input list<Values.Value> inIndices;
2193 input list<DAE.Subscript> inSubscripts;
2194 input Integer inIndex;
2195 input FCore.Cache inCache;
2196 input FCore.Graph inEnv;
2197 output FCore.Cache outCache;
2198 output list<Values.Value> outResult;
2199 algorithm
2200 (outCache, outResult) :=
2201 matchcontinue(inNewValues, inOldValues, inIndices)
2202 local
2203 Values.Value v1, v2, index;
2204 list<Values.Value> vl1, vl2, rest_indices;
2205 FCore.Cache cache;
2206
2207 case (_, _, {}) then (inCache, inOldValues);
2208
2209 // Skip indices that are smaller than the next index in the slice.
2210 case (vl1, v2 :: vl2, index :: _)
2211 algorithm
2212
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 7 times.
28 true := (inIndex < ValuesUtil.valueInteger(index));
2213 7 (cache, vl1) := assignSlice(vl1, vl2, inIndices, inSubscripts,
2214 inIndex + 1, inCache, inEnv);
2215 7 then
2216 (cache, v2 :: vl1);
2217
2218 case (v1 :: vl1, v2 :: vl2, _ :: rest_indices)
2219 algorithm
2220 21 (cache, v1) := assignVector(v1, v2, inSubscripts, inCache, inEnv);
2221 21 (cache, vl1) := assignSlice(vl1, vl2, rest_indices, inSubscripts,
2222 inIndex + 1, inCache, inEnv);
2223 21 then
2224 (cache, v1 :: vl1);
2225 end matchcontinue;
2226 end assignSlice;
2227
2228 protected function assignWholeDim
2229 "This function assigns a whole dimension of a vector."
2230 input list<Values.Value> inNewValues;
2231 input list<Values.Value> inOldValues;
2232 input list<DAE.Subscript> inSubscripts;
2233 input FCore.Cache inCache;
2234 input FCore.Graph inEnv;
2235 output FCore.Cache outCache;
2236 output list<Values.Value> outResult;
2237 algorithm
2238 (outCache, outResult) :=
2239 match(inNewValues, inOldValues)
2240 local
2241 Values.Value v1, v2;
2242 list<Values.Value> vl1, vl2;
2243 FCore.Cache cache;
2244 case ({}, _) then (inCache, {});
2245 case (v1 :: vl1, v2 :: vl2)
2246 algorithm
2247 25 (cache, v1) := assignVector(v1, v2, inSubscripts, inCache, inEnv);
2248 25 (cache, vl1) := assignWholeDim(vl1, vl2, inSubscripts, inCache, inEnv);
2249 25 then
2250 (cache, v1 :: vl1);
2251 end match;
2252 end assignWholeDim;
2253
2254 protected function updateVariableBinding
2255 "This function updates a variables binding in the environment."
2256 input DAE.ComponentRef inVariableCref;
2257 input FCore.Graph inEnv;
2258 input DAE.Type inType;
2259 input Values.Value inNewValue;
2260 output FCore.Graph outEnv;
2261 protected
2262 String var_name;
2263 DAE.Var var;
2264 algorithm
2265 97617 var_name := ComponentReference.crefStr(inVariableCref);
2266 97617 var := makeFunctionVariable(var_name, inType,
2267 DAE.VALBOUND(inNewValue, DAE.BINDING_FROM_DEFAULT_VALUE()));
2268 97617 outEnv := FGraph.updateComp(inEnv, var, FCore.VAR_TYPED(), FGraph.empty());
2269 end updateVariableBinding;
2270
2271 protected function updateRecordBinding
2272 "Updates the binding of a record variable."
2273 input DAE.Var inVar;
2274 input Values.Value inValue;
2275 output DAE.Var outVar;
2276 protected
2277 algorithm
2278 outVar := inVar;
2279 2417 outVar.binding := DAE.VALBOUND(inValue, DAE.BINDING_FROM_DEFAULT_VALUE());
2280 end updateRecordBinding;
2281
2282 protected function updateRecordComponentBinding
2283 "Updates the binding of a record component."
2284 input DAE.Var inVar;
2285 input String inComponentId;
2286 input Values.Value inValue;
2287 output DAE.Var outVar;
2288 protected
2289 Values.Value val;
2290 algorithm
2291 outVar := inVar;
2292 9874 val := getBindingOrDefault(outVar.binding, outVar.ty);
2293 9874 val := updateRecordComponentValue(inComponentId, inValue, val);
2294 9874 outVar.binding := DAE.VALBOUND(val, DAE.BINDING_FROM_DEFAULT_VALUE());
2295 end updateRecordComponentBinding;
2296
2297 protected function updateRecordComponentValue
2298 input String inComponentId;
2299 input Values.Value inComponentValue;
2300 input Values.Value inRecordValue;
2301 output Values.Value outRecordValue;
2302 protected
2303 Absyn.Path name;
2304 list<Values.Value> vals;
2305 list<String> comps;
2306 Integer pos;
2307 algorithm
2308
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9874 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9874 times.
9874 Values.RECORD(name, vals, comps, -1) := inRecordValue;
2309 9874 pos := List.position(inComponentId, comps);
2310 9874 vals := List.replaceAt(inComponentValue, pos, vals);
2311 9874 outRecordValue := Values.RECORD(name, vals, comps, -1);
2312 end updateRecordComponentValue;
2313
2314 protected function getVariableTypeAndBinding
2315 "This function looks a variable up in the environment, and returns it's type
2316 and binding."
2317 input DAE.ComponentRef inCref;
2318 input FCore.Graph inEnv;
2319 output DAE.Type outType;
2320 output DAE.Binding outBinding;
2321 algorithm
2322 62802 (_, _, outType, outBinding, _, _, _, _, _) :=
2323 Lookup.lookupVar(FCore.emptyCache(), inEnv, inCref);
2324 end getVariableTypeAndBinding;
2325
2326 protected function getVariableTypeAndValue
2327 "This function looks a variable up in the environment, and returns it's type
2328 and value. If it doesn't have a value, then a default value will be returned."
2329 input DAE.ComponentRef inCref;
2330 input FCore.Graph inEnv;
2331 output DAE.Type outType;
2332 output Values.Value outValue;
2333 protected
2334 DAE.Binding binding;
2335 algorithm
2336 62794 (outType, binding) := getVariableTypeAndBinding(inCref, inEnv);
2337 62794 outValue := getBindingOrDefault(binding, outType);
2338 end getVariableTypeAndValue;
2339
2340 protected function getBindingValueOpt
2341 "Returns the value in a binding, or NONE()."
2342 input DAE.Binding inBinding;
2343 output Option<Values.Value> outValue;
2344 algorithm
2345 outValue := match inBinding
2346 local
2347 Values.Value val;
2348 case DAE.VALBOUND(valBound = val) then SOME(val);
2349 case DAE.EQBOUND(evaluatedExp = SOME(val)) then SOME(val);
2350 else NONE();
2351 end match;
2352 end getBindingValueOpt;
2353
2354 protected function getBindingOrDefault
2355 "Returns the value in a binding, or a default value if binding isn't a value
2356 binding."
2357 input DAE.Binding inBinding;
2358 input DAE.Type inType;
2359 output Values.Value outValue;
2360 algorithm
2361 outValue := match inBinding
2362 local
2363 Values.Value val;
2364 case DAE.VALBOUND(valBound = val) then val;
2365 case DAE.EQBOUND(evaluatedExp = SOME(val)) then val;
2366 11624 else generateDefaultBinding(inType);
2367 end match;
2368 end getBindingOrDefault;
2369
2370 protected function generateDefaultBinding
2371 "This function generates a default value for a type. This is needed when
2372 assigning parts of an array, since we can only assign parts of an already
2373 existing array. The value will be the types equivalence to zero."
2374 input DAE.Type inType;
2375 output Values.Value outValue;
2376 algorithm
2377 outValue := matchcontinue inType
2378 local
2379 DAE.Dimension dim;
2380 Integer int_dim;
2381 list<Integer> dims;
2382 DAE.Type ty;
2383 list<Values.Value> values;
2384 Values.Value value;
2385 Absyn.Path path;
2386 list<DAE.Var> vars;
2387 list<String> var_names;
2388
2389 case DAE.T_INTEGER() then Values.INTEGER(0);
2390 case DAE.T_REAL() then Values.REAL(0.0);
2391 case DAE.T_STRING() then Values.STRING("");
2392 case DAE.T_BOOL() then Values.BOOL(false);
2393 case DAE.T_ENUMERATION()
2394 then Values.ENUM_LITERAL(Absyn.IDENT(""), 0);
2395
2396 case DAE.T_ARRAY(dims = {dim}, ty = ty)
2397 algorithm
2398 1540 int_dim := Expression.dimensionSize(dim);
2399 1540 value := generateDefaultBinding(ty);
2400 1540 values := List.fill(value, int_dim);
2401 1540 dims := ValuesUtil.valueDimensions(value);
2402 1540 then
2403 Values.ARRAY(values, int_dim :: dims);
2404
2405 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path = path), varLst = vars)
2406 algorithm
2407 709 (values, var_names) := List.map_2(vars, getRecordVarBindingAndName);
2408 709 then
2409 Values.RECORD(path, values, var_names, -1);
2410
2411 else
2412 algorithm
2413 ✗ true := Flags.isSet(Flags.FAILTRACE);
2414 ✗ Debug.trace("- CevalFunction.generateDefaultBinding failed\n");
2415 ✗ then
2416 fail();
2417 end matchcontinue;
2418 end generateDefaultBinding;
2419
2420 protected function getRecordVarBindingAndName
2421 input DAE.Var inVar;
2422 output Values.Value outBinding;
2423 output String outName;
2424 algorithm
2425 (outBinding, outName) := matchcontinue inVar
2426 local
2427 String name;
2428 DAE.Type ty;
2429 DAE.Binding binding;
2430 Values.Value val;
2431
2432 case DAE.TYPES_VAR(name = name, ty = ty, binding = binding)
2433 algorithm
2434 9386 val := getBindingOrDefault(binding, ty);
2435 then
2436 (val, name);
2437
2438 case DAE.TYPES_VAR(name = name)
2439 algorithm
2440 ✗ true := Flags.isSet(Flags.FAILTRACE);
2441 ✗ Debug.traceln("- CevalFunction.getRecordVarBindingAndName failed on variable "
2442 + name + "\n");
2443 ✗ then
2444 fail();
2445 end matchcontinue;
2446 end getRecordVarBindingAndName;
2447
2448 protected function getFunctionReturnValue
2449 "This function fetches one return value for the function, given an output
2450 variable and an environment."
2451 input DAE.Element inOutputVar;
2452 input FCore.Graph inEnv;
2453 output Values.Value outValue;
2454 algorithm
2455 outValue := match inOutputVar
2456 local
2457 DAE.ComponentRef cr;
2458 DAE.Type ty;
2459 Values.Value val;
2460 case DAE.VAR(componentRef = cr, ty = ty)
2461 algorithm
2462 38876 val := getVariableValue(cr, ty, inEnv);
2463 then
2464 val;
2465 end match;
2466 end getFunctionReturnValue;
2467
2468 protected function getVariableValue
2469 "Helper function to getFunctionReturnValue. Fetches a variables value from the
2470 environment."
2471 input DAE.ComponentRef inCref;
2472 input DAE.Type inType;
2473 input FCore.Graph inEnv;
2474 output Values.Value outValue;
2475 algorithm
2476 outValue := matchcontinue inType
2477 local
2478 Values.Value val;
2479 Absyn.Path p;
2480
2481 // A record doesn't have a value, but an environment with it's components.
2482 // So we need to assemble the records value.
2483 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD())
2484 algorithm
2485 2787 p := ComponentReference.crefToPath(inCref);
2486 2787 val := getRecordValue(p, inType, inEnv);
2487 then
2488 val;
2489
2490 // All other variables we can just look up in the environment.
2491 else
2492 algorithm
2493 36114 (_, val) := getVariableTypeAndValue(inCref, inEnv);
2494 36114 then
2495 val;
2496 end matchcontinue;
2497 end getVariableValue;
2498
2499 protected function getRecordValue
2500 "Looks up the value of a record by looking up the record components in the
2501 records environment and assembling a record value."
2502 input Absyn.Path inRecordName;
2503 input DAE.Type inType;
2504 input FCore.Graph inEnv;
2505 output Values.Value outValue;
2506 algorithm
2507 outValue := match(inRecordName, inType)
2508 local
2509 list<DAE.Var> vars;
2510 list<Values.Value> vals;
2511 list<String> var_names;
2512 String id;
2513 Absyn.Path p;
2514 FCore.Graph env;
2515 case (Absyn.IDENT(name = id), DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(path = p),
2516 varLst = vars))
2517 algorithm
2518 2795 (_, _, _, _, _, env) :=
2519 Lookup.lookupIdentLocal(FCore.emptyCache(), inEnv, id);
2520 2795 vals := List.map1(vars, getRecordComponentValue, env);
2521 2794 var_names := List.map(vars, TypesDump.getVarName);
2522 2794 then
2523 Values.RECORD(p, vals, var_names, -1);
2524 end match;
2525 end getRecordValue;
2526
2527 protected function getRecordComponentValue
2528 "Looks up the value for a record component."
2529 input DAE.Var inVars;
2530 input FCore.Graph inEnv;
2531 output Values.Value outValues;
2532 algorithm
2533 outValues := match inVars
2534 local
2535 Values.Value val;
2536 Option<Values.Value> oval;
2537 String id;
2538 DAE.Type ty;
2539 DAE.Binding binding, tvbinding;
2540
2541 // The component is a record itself.
2542 case DAE.TYPES_VAR(
2543 name = id,
2544 ty = ty as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD()))
2545 algorithm
2546 8 val := getRecordValue(Absyn.IDENT(id), ty, inEnv);
2547 then
2548 val;
2549
2550 // A non-record variable.
2551 case DAE.TYPES_VAR(name = id, ty = ty, binding = tvbinding)
2552 algorithm
2553 14256 (_, DAE.TYPES_VAR(binding = binding), _, _, _, _) :=
2554 Lookup.lookupIdentLocal(FCore.emptyCache(), inEnv, id);
2555 14255 oval := getBindingValueOpt(binding);
2556
2557 // if no binding from env then use the typesvar binding.
2558
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14255 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 14213 times.
14255 if isNone(oval) then
2559 42 oval := getBindingValueOpt(tvbinding);
2560 end if;
2561
2562 // if there is still no binding in the typesvar then generated default
2563 // binding. IDK if this is a good idea. It is like generating a default
2564 // equation for a variable if in a model. But this is how it was done.
2565
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14255 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 14213 times.
14255 if isSome(oval) then
2566 14213 SOME(val) := oval;
2567 else
2568 42 val := generateDefaultBinding(ty);
2569 end if;
2570
2571 then
2572 val;
2573 end match;
2574 end getRecordComponentValue;
2575
2576 protected function boxReturnValue
2577 "This function takes a list of return values, and return either a NORETCALL, a
2578 single value or a tuple with the values depending on how many return variables
2579 there are."
2580 input list<Values.Value> inReturnValues;
2581 output Values.Value outValue;
2582 algorithm
2583 outValue := match inReturnValues
2584 local
2585 Values.Value val;
2586
2587 case {} then Values.NORETCALL();
2588 case {val} then val;
2589 961 case _ :: _ then Values.TUPLE(inReturnValues);
2590 end match;
2591 end boxReturnValue;
2592
2593 // [DEPS] Function variable dependency handling.
2594
2595 protected function sortFunctionVarsByDependency
2596 "A functions variables might depend on each other, for example by defining
2597 dimensions that depend on the size of another variable. This function sorts
2598 the list of variables so that any dependencies to a variable will be before
2599 the variable in resulting list."
2600 input list<FunctionVar> inFuncVars;
2601 input DAE.ElementSource inSource;
2602 output list<FunctionVar> outFuncVars;
2603 protected
2604 list<tuple<FunctionVar, list<FunctionVar>>> cycles;
2605 algorithm
2606 38177 (outFuncVars, cycles) := Graph.topologicalSort(
2607 Graph.buildGraph(inFuncVars, getElementDependencies, inFuncVars),
2608 isElementEqual);
2609 38177 checkCyclicalComponents(cycles, inSource);
2610 end sortFunctionVarsByDependency;
2611
2612 protected function getElementDependencies
2613 "Returns the dependencies given an element."
2614 input FunctionVar inElement;
2615 input list<FunctionVar> inAllElements;
2616 output list<FunctionVar> outDependencies;
2617 type Arg = tuple<list<FunctionVar>, list<FunctionVar>, list<DAE.Ident>>;
2618 algorithm
2619 outDependencies := matchcontinue inElement
2620 local
2621 DAE.Exp bind_exp;
2622 list<FunctionVar> deps;
2623 list<DAE.Dimension> dims;
2624 Arg arg;
2625
2626 case (DAE.VAR(binding = SOME(bind_exp), dims = dims), _)
2627 algorithm
2628 7874 (_, arg as (_, deps, _)) := Expression.traverseExpBidir(
2629 bind_exp,
2630 getElementDependenciesTraverserEnter,
2631 getElementDependenciesTraverserExit,
2632 (inAllElements, {}, {}));
2633 7874 (_, (_, deps, _)) := List.mapFold(dims,
2634 getElementDependenciesFromDims, arg);
2635 then
2636 deps;
2637
2638 case (DAE.VAR(dims = dims), _)
2639 algorithm
2640 91752 (_, (_, deps, _)) := List.mapFold(dims,
2641 getElementDependenciesFromDims, (inAllElements, {}, {}));
2642 then
2643 deps;
2644
2645 else {};
2646 end matchcontinue;
2647 end getElementDependencies;
2648
2649 protected function getElementDependenciesFromDims
2650 "Helper function to getElementDependencies that gets the dependencies from the
2651 dimensions of a variable."
2652 input DAE.Dimension inDimension;
2653 input Arg inArg;
2654 output DAE.Dimension outDimension;
2655 output Arg outArg;
2656 type Arg = tuple<list<FunctionVar>, list<FunctionVar>, list<DAE.Ident>>;
2657 algorithm
2658 (outDimension, outArg) := matchcontinue inArg
2659 local
2660 Arg arg;
2661 DAE.Exp dim_exp;
2662
2663 case _
2664 algorithm
2665 25846 dim_exp := Expression.dimensionSizeExp(inDimension);
2666 20991 (_, arg) := Expression.traverseExpBidir(
2667 dim_exp,
2668 getElementDependenciesTraverserEnter,
2669 getElementDependenciesTraverserExit,
2670 inArg);
2671 20991 then
2672 (inDimension, arg);
2673
2674 else (inDimension, inArg);
2675 end matchcontinue;
2676 end getElementDependenciesFromDims;
2677
2678 protected function getElementDependenciesTraverserEnter
2679 "Traverse function used by getElementDependencies to collect all dependencies
2680 for an element. The extra arguments are a list of all elements, a list of
2681 accumulated depencies and a list of iterators from enclosing for-loops."
2682 input DAE.Exp inExp;
2683 input Arg inArg;
2684 output DAE.Exp outExp;
2685 output Arg outArg;
2686 type Arg = tuple<list<FunctionVar>, list<FunctionVar>, list<DAE.Ident>>;
2687 algorithm
2688 (outExp, outArg) := matchcontinue(inExp, inArg)
2689 local
2690 DAE.Exp exp;
2691 DAE.ComponentRef cref;
2692 list<FunctionVar> all_el, accum_el;
2693 FunctionVar e;
2694 DAE.Ident iter;
2695 list<DAE.Ident> iters;
2696 DAE.ReductionIterators riters;
2697
2698 // Check if the crefs matches any of the iterators that might shadow a
2699 // function variable, and don't add it as a dependency if that's the case.
2700 case (exp as DAE.CREF(componentRef = DAE.CREF_IDENT(ident = iter)),
2701 (all_el, accum_el, iters as _ :: _))
2702 algorithm
2703
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 40 times.
68 true := List.isMemberOnTrue(iter, iters, stringEqual);
2704 40 then
2705 (exp, (all_el, accum_el, iters));
2706
2707 // Otherwise, try to delete the cref from the list of all elements. If that
2708 // succeeds, add it to the list of dependencies. Since we have deleted the
2709 // element from the list of all variables this ensures that the dependency
2710 // list only contains unique elements.
2711 case (exp as DAE.CREF(componentRef = cref), (all_el, accum_el, iters))
2712 algorithm
2713
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 8604 times.
✓ Branch 3 taken 5460 times.
✓ Branch 4 taken 3144 times.
8604 (all_el, SOME(e)) := List.deleteMemberOnTrue(cref, all_el,
2714 isElementNamed);
2715 3144 then
2716 (exp, (all_el, e :: accum_el, iters));
2717
2718 // If we encounter a reduction, add the iterator to the iterator list so
2719 // that we know which iterators shadow function variables.
2720 case (exp as DAE.REDUCTION(iterators = riters), (all_el, accum_el, iters))
2721 algorithm
2722 28 iters := listAppend(List.map(riters, Expression.reductionIterName), iters);
2723 28 then
2724 (exp, (all_el, accum_el, iters));
2725
2726 else (inExp, inArg);
2727 end matchcontinue;
2728 end getElementDependenciesTraverserEnter;
2729
2730 protected function getElementDependenciesTraverserExit
2731 "Exit traversal function used by getElementDependencies."
2732 input DAE.Exp inExp;
2733 input Arg inArg;
2734 output DAE.Exp outExp;
2735 output Arg outArg;
2736 type Arg = tuple<list<FunctionVar>, list<FunctionVar>, list<DAE.Ident>>;
2737 algorithm
2738 (outExp, outArg) := match(inExp, inArg)
2739 local
2740 DAE.Exp exp;
2741 list<FunctionVar> all_el, accum_el;
2742 list<DAE.Ident> iters;
2743 DAE.ReductionIterators riters;
2744
2745 // If we encounter a reduction, make sure that its iterator matches the
2746 // first iterator in the iterator list, and if so remove it from the list.
2747 case (exp as DAE.REDUCTION(iterators = riters), (all_el, accum_el, iters))
2748 algorithm
2749 28 iters := compareIterators(listReverse(riters), iters);
2750 28 then
2751 (exp, (all_el, accum_el, iters));
2752
2753 else (inExp, inArg);
2754 end match;
2755 end getElementDependenciesTraverserExit;
2756
2757 protected function compareIterators
2758 input DAE.ReductionIterators inRiters;
2759 input list<String> inIters;
2760 output list<String> outIters;
2761 algorithm
2762 outIters := matchcontinue(inRiters,inIters)
2763 local
2764 String id1,id2;
2765 DAE.ReductionIterators riters;
2766 list<String> iters;
2767
2768 case (DAE.REDUCTIONITER(id = id1) :: riters, id2 :: iters)
2769 algorithm
2770
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 true := stringEqual(id1, id2);
2771 28 then
2772 compareIterators(riters, iters);
2773
2774 case ({}, _) then inIters;
2775
2776 // This should never happen, print an error if it does.
2777 else
2778 algorithm
2779 ✗ Error.addMessage(Error.INTERNAL_ERROR,
2780 {"Different iterators in CevalFunction.compareIterators."});
2781 ✗ then
2782 fail();
2783
2784 end matchcontinue;
2785 end compareIterators;
2786
2787 protected function isElementNamed
2788 "Checks if a function parameter has the given name."
2789 input DAE.ComponentRef inName;
2790 input FunctionVar inElement;
2791 output Boolean isNamed;
2792 protected
2793 DAE.ComponentRef name;
2794 algorithm
2795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49722 times.
49722 (DAE.VAR(componentRef = name), _) := inElement;
2796 49722 isNamed := ComponentReferenceBasics.crefEqualWithoutSubs(name, inName);
2797 end isElementNamed;
2798
2799 protected function isElementEqual
2800 "Checks if two function parameters are equal, i.e. have the same name."
2801 input FunctionVar inElement1;
2802 input FunctionVar inElement2;
2803 output Boolean isEqual;
2804 protected
2805 DAE.ComponentRef cr1, cr2;
2806 algorithm
2807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9425 times.
9425 (DAE.VAR(componentRef = cr1), _) := inElement1;
2808
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9425 times.
9425 (DAE.VAR(componentRef = cr2), _) := inElement2;
2809 9425 isEqual := ComponentReferenceBasics.crefEqualWithoutSubs(cr1, cr2);
2810 end isElementEqual;
2811
2812 protected function checkCyclicalComponents
2813 "Checks the return value from Graph.topologicalSort. If the list of cycles is
2814 not empty, print an error message and fail, since it's not allowed for
2815 constants or parameters to have cyclic dependencies."
2816 input list<tuple<FunctionVar, list<FunctionVar>>> inCycles;
2817 input DAE.ElementSource inSource;
2818 algorithm
2819 () := match inCycles
2820 local
2821 list<list<FunctionVar>> cycles;
2822 list<list<DAE.Element>> elements;
2823 list<list<DAE.ComponentRef>> crefs;
2824 list<list<String>> names;
2825 list<String> cycles_strs;
2826 String cycles_str, scope_str;
2827 SourceInfo info;
2828
2829 case {} then ();
2830
2831 else
2832 algorithm
2833 ✗ cycles := Graph.findCycles(inCycles, isElementEqual);
2834 ✗ elements := List.mapList(cycles, Util.tuple21);
2835 ✗ crefs := List.mapList(elements, DAEUtil.varCref);
2836 ✗ names := List.mapList(crefs,
2837 ComponentReferenceBasics.printComponentRefStr);
2838 ✗ cycles_strs := List.map1(names, stringDelimitList, ",");
2839 ✗ cycles_str := stringDelimitList(cycles_strs, "}, {");
2840 ✗ cycles_str := "{" + cycles_str + "}";
2841 scope_str := "";
2842 ✗ info := ElementSource.getElementSourceFileInfo(inSource);
2843 ✗ Error.addSourceMessage(Error.CIRCULAR_COMPONENTS, {scope_str, cycles_str}, info);
2844 ✗ then
2845 fail();
2846
2847 end match;
2848 end checkCyclicalComponents;
2849
2850 // [EOPT] Expression optimization functions.
2851
2852 protected function optimizeExpTraverser
2853 "This function optimizes expressions in a function. So far this is only used
2854 to transform ASUB expressions to CREFs so that this doesn't need to be done
2855 while evaluating the function. But it's possible that more forms of
2856 optimization can be done too."
2857 input DAE.Exp inExp;
2858 input FCore.Graph inEnv;
2859 output DAE.Exp outExp;
2860 output FCore.Graph outEnv;
2861 algorithm
2862 (outExp,outEnv) := match (inExp,inEnv)
2863 local
2864 DAE.ComponentRef cref;
2865 DAE.Type ety;
2866 list<DAE.Subscript> subs;
2867 FCore.Graph env;
2868 DAE.Exp exp;
2869
2870 case (DAE.ASUB(exp = DAE.CREF(componentRef = cref, ty = ety), sub = subs), env)
2871 algorithm
2872 6 cref := ComponentReference.subscriptCref(cref, subs);
2873 6 exp := Expression.makeCrefExp(cref, ety);
2874 then (exp, env);
2875
2876 case (DAE.TSUB(exp = DAE.TUPLE(exp::_), ix = 1), env)
2877 then (exp, env);
2878
2879 else (inExp,inEnv);
2880 end match;
2881 end optimizeExpTraverser;
2882
2883 annotation(__OpenModelica_Interface="frontend");
2884 end CevalFunction;
2885