Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 55.5% 558 / 0 / 1005
Functions: -% 0 / 1 / 1
Branches: 51.6% 207 / 0 / 401

OMCompiler/Compiler/BackEnd/BackendDAECreate.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 BackendDAECreate
37 " file: BackendDAECreate.mo
38 package: BackendDAECreate
39 description: This file contains all functions for transforming the DAE structure to the BackendDAE.
40
41
42 "
43
44 public import Absyn;
45 public import BackendDAE;
46 public import DAE;
47 public import FCore;
48
49 protected
50
51 import AbsynUtil;
52 import BackendDAEUtil;
53 import BackendDump;
54 import BackendEquation;
55 import BackendVariable;
56 import BackendVarTransform;
57 import BaseHashTable;
58 import CheckModel;
59 import ComponentReference;
60 import ConnectUtil;
61 import ComponentReferenceBasics;
62 import Config;
63 import ClassInf;
64 import DAEDump;
65 import DAEUtil;
66 import Debug;
67 import ElementSource;
68 import Error;
69 import ErrorExt;
70 import Expression;
71 protected import ExpressionBasics;
72 import ExpressionDump;
73 import ExpressionSimplify;
74 import ExpressionSolve;
75 import Flags;
76 import Global;
77 import HashTableExpToExp;
78 import HashTable;
79 import HashTableCrToExpSourceTpl;
80 import Inline;
81 import List;
82 import ExecStat.execStat;
83 import SCode;
84 import StackOverflow;
85 import System;
86 import Types;
87 import UnorderedMap;
88 import Util;
89 import VarTransform;
90 import Vectorization;
91 import ZeroCrossings;
92
93 public function lower "This function translates a DAE, which is the result from instantiating a
94 class, into a more precise form, called BackendDAE.BackendDAE defined in this module.
95 The BackendDAE.BackendDAE representation splits the DAE into equations and variables
96 and further divides variables into known and unknown variables and the
97 equations into simple and nonsimple equations.
98 The variables are inserted into a hash table. This gives a lookup cost of
99 O(1) for finding a variable. The equations are put in an expandable
100 array. Where adding a new equation can be done in O(1) time if space
101 is available.
102 inputs: lst: DAE.DAElist, inCache: FCore.Cache, inEnv: FCore.Graph
103 outputs: BackendDAE.BackendDAE"
104 input DAE.DAElist lst;
105 input FCore.Cache inCache;
106 input FCore.Graph inEnv;
107 input BackendDAE.ExtraInfo inExtraInfo;
108 output BackendDAE.BackendDAE outBackendDAE;
109 protected
110 list<BackendDAE.Var> varlst, globalKnownVarLst, extvarlst;
111 BackendDAE.Variables vars, globalKnownVars, localKnownVars, vars_1, extVars, aliasVars, extAliasVars;
112 list<BackendDAE.Equation> eqns, reqns, ieqns;
113 list<DAE.Constraint> constrs;
114 list<DAE.ClassAttributes> clsAttrs;
115 BackendDAE.EquationArray eqnarr, reqnarr, ieqnarr;
116 BackendDAE.ExternalObjectClasses extObjCls;
117 BackendDAE.SymbolicJacobians symjacs;
118 BackendDAE.EventInfo einfo;
119 list<DAE.Element> elems, aliaseqns;
120 AvlTreePathFunction.Tree functionTree;
121 list<BackendDAE.TimeEvent> timeEvents;
122 Integer numCheckpoints;
123 BackendDAE.EqSystem syst;
124 algorithm
125 1097 numCheckpoints:=ErrorExt.getNumCheckpoints();
126 try
127 1097 StackOverflow.clearStacktraceMessages();
128 // reset dumped file sequence number
129 1097 System.tmpTickResetIndex(0, Global.backendDAE_fileSequence);
130 1097 System.tmpTickResetIndex(1, Global.backendDAE_cseIndex);
131 1097 System.tmpTickResetIndex(0, Global.strongComponent_index);
132 1097 functionTree := FCore.getFunctionTree(inCache);
133 //deactivated because of some codegen errors: functionTree := renameFunctionParameter(functionTree);
134 1097 functionTree := lowerFunctions(functionTree);
135 1097 (DAE.DAE(elems), functionTree, timeEvents) := processBuiltinExpressions(lst, functionTree);
136 1097 (varlst, globalKnownVarLst, extvarlst, eqns, reqns, ieqns, constrs, clsAttrs, extObjCls, aliaseqns, _) :=
137 lower2(listReverse(elems), functionTree, HashTableExpToExp.emptyHashTable());
138
139 1095 globalKnownVars := BackendVariable.listVar(globalKnownVarLst);
140 1095 localKnownVars := BackendVariable.emptyVars();
141 1095 extVars := BackendVariable.listVar(extvarlst);
142 1095 aliasVars := BackendVariable.emptyVars();
143
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1095 times.
1095 if Flags.isSet(Flags.VECTORIZE) then
144 ✗ (varlst,eqns) := Vectorization.collectForLoops(varlst,eqns);
145 end if;
146 1095 vars := BackendVariable.listVar(varlst);
147 1095 vars := setReinitStateSelect(reqns, vars);
148
149 // handle alias equations
150 1095 (vars, globalKnownVars, extVars, aliasVars, eqns, reqns, ieqns) := handleAliasEquations(aliaseqns, vars, globalKnownVars, extVars, aliasVars, eqns, reqns, ieqns);
151 1095 (ieqns, eqns, reqns, extAliasVars, globalKnownVars, extVars) := getExternalObjectAlias(ieqns, eqns, reqns, globalKnownVars, extVars);
152 1095 aliasVars := BackendVariable.addVariables(extAliasVars,aliasVars);
153
154 1095 (globalKnownVarLst, eqns, reqns, ieqns) := patchRecordBindings(varlst, extvarlst, globalKnownVarLst, eqns, reqns, ieqns);
155
156 1095 vars_1 := detectImplicitDiscrete(vars, globalKnownVars, eqns); // ieqns don't need to be searched because they can't contain when equations
157 1095 eqnarr := BackendEquation.listEquation(eqns);
158 1095 reqnarr := BackendEquation.listEquation(reqns);
159 1095 ieqnarr := BackendEquation.listEquation(ieqns);
160 1095 einfo := BackendDAE.EVENT_INFO(timeEvents, ZeroCrossings.new(), ZeroCrossings.new(), ZeroCrossings.new(), 0);
161 symjacs := {(NONE(), ({}, {}, ({}, {}), -1), {}, ({}, {}, ({}, {}), -1)),
162 (NONE(), ({}, {}, ({}, {}), -1), {}, ({}, {}, ({}, {}), -1)),
163 (NONE(), ({}, {}, ({}, {}), -1), {}, ({}, {}, ({}, {}), -1)),
164 (NONE(), ({}, {}, ({}, {}), -1), {}, ({}, {}, ({}, {}), -1))};
165 1095 syst := BackendDAEUtil.createEqSystem(vars_1, eqnarr, {}, BackendDAE.UNKNOWN_PARTITION(), reqnarr);
166 1095 outBackendDAE := BackendDAE.DAE(syst::{},
167 BackendDAE.SHARED(globalKnownVars,
168 localKnownVars,
169 extVars,
170 aliasVars,
171 ieqnarr,
172 BackendEquation.emptyEqns(),
173 constrs,
174 clsAttrs,
175 inCache,
176 inEnv,
177 functionTree,
178 einfo,
179 extObjCls,
180 BackendDAE.SIMULATION(),
181 symjacs,inExtraInfo,
182 BackendDAEUtil.emptyPartitionsInfo(),
183 BackendDAE.emptyDAEModeData,
184 NONE(),
185 NONE(),
186 {}
187 ));
188 1095 BackendDAEUtil.checkBackendDAEWithErrorMsg(outBackendDAE);
189 1095 BackendDAEUtil.checkAdjacencyMatrixSolvability(syst, functionTree,BackendDAEUtil.isInitializationDAE(outBackendDAE.shared));
190
2/2
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 1032 times.
1091 if Flags.isSet(Flags.DUMP_BACKENDDAE_INFO) then
191 118 Error.addSourceMessage(Error.BACKENDDAEINFO_LOWER,{
192 String(BackendEquation.equationArraySize(syst.orderedEqs)),
193 String(BackendVariable.varsSize(syst.orderedVars))},
194 Absyn.dummyInfo);
195 end if;
196 1091 execStat("Generate backend data structure");
197 1091 return;
198 else
199 ✗ setGlobalRoot(Global.stackoverFlowIndex, NONE());
200 ✗ ErrorExt.rollbackNumCheckpoints(ErrorExt.getNumCheckpoints()-numCheckpoints);
201 ✗ Error.addInternalError(StackOverflow.errorPrefix() + " in "+getInstanceName()+"...\n"+stringDelimitList(StackOverflow.readableStacktraceMessages(), "\n"), sourceInfo());
202 /* Do not fail or we can loop too much */
203 ✗ StackOverflow.clearStacktraceMessages();
204 end try annotation(__OpenModelica_stackOverflowCheckpoint=true);
205 ✗ fail();
206 end lower;
207
208 protected type Functiontuple = tuple<Option<AvlTreePathFunction.Tree>,list<DAE.InlineType>>;
209
210 protected type ArrayBindingList = list<tuple<list<Integer>,DAE.Exp>>;
211
212 function printArrayBindingList
213 input ArrayBindingList arrayBindingList;
214 output String str = "";
215 protected
216 list<Integer> subscriptLst;
217 DAE.Exp bindingExp;
218 algorithm
219 ✗ for tpl in arrayBindingList loop
220 ✗ (subscriptLst, bindingExp) := tpl;
221 ✗ str := str + "[";
222 ✗ for subscript in subscriptLst loop
223 ✗ str := str + intString(subscript) + " ";
224 end for;
225 ✗ str := str + "]";
226 ✗ str := str + " : " + ExpressionDump.dumpExpStr(bindingExp, 0);
227 end for;
228 end printArrayBindingList;
229
230 public function patchRecordBindings
231 "Propagate record bindings from attributes to their parent record types in all crefs of all equations O(n) (?)
232 For ticket #9036."
233 input list<BackendDAE.Var> varlst;
234 input list<BackendDAE.Var> extvarlst;
235 input output list<BackendDAE.Var> globalKnownVarLst;
236 input output list<BackendDAE.Equation> eqns;
237 input output list<BackendDAE.Equation> reqns;
238 input output list<BackendDAE.Equation> ieqns;
239 protected
240 UnorderedMap<DAE.ComponentRef, DAE.Type> map;
241 UnorderedMap<DAE.ComponentRef, ArrayBindingList> arrayMap;
242 Boolean debug = false;
243 algorithm
244 // 1. Collect all possible record types from equations and globalKnownVars
245 // (the frontend does not keep correct types at the variables so they have to be grabbed from eqns beforehand
246 // I don't like it but thats how it is).
247 2180 map := UnorderedMap.new<DAE.Type>(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
248 2180 collectRecordTypesVarLst(map, globalKnownVarLst);
249 2180 eqns := List.map(eqns, function collectRecordTypesEqn(map = map));
250 2180 reqns := List.map(reqns, function collectRecordTypesEqn(map = map));
251 2180 ieqns := List.map(ieqns, function collectRecordTypesEqn(map = map));
252
253 // 2. Collect bindings from variables and update in types
254 2180 arrayMap := UnorderedMap.new<ArrayBindingList>(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
255
256 2180 List.apply(varlst, function collectRecordElementBindings(map = map, arrayMap = arrayMap));
257 2180 List.apply(globalKnownVarLst, function collectRecordElementBindings(map = map, arrayMap = arrayMap));
258 2180 List.apply(extvarlst, function collectRecordElementBindings(map = map, arrayMap = arrayMap));
259
260 2180 map := collapseArrayBindings(arrayMap, map);
261
262 if (debug) then
263 print("patchRecordBindings arrayMap:\n");
264 print(UnorderedMap.toString(arrayMap, ComponentReferenceBasics.printComponentRefStr, printArrayBindingList) + "\n");
265 print("\npatchRecordBindings map\n");
266 print(UnorderedMap.toString(map, ComponentReferenceBasics.printComponentRefStr, TypesDump.printTypeStr) + "\n\n");
267 end if;
268
269 // 3. Replace the types in equations and globalKnownVars
270 2180 globalKnownVarLst := updateRecordTypesVarLst(map, globalKnownVarLst);
271 2180 eqns := List.map(eqns, function updateRecordTypesEqn(map = map));
272 2180 reqns := List.map(reqns, function updateRecordTypesEqn(map = map));
273 2180 ieqns := List.map(ieqns, function updateRecordTypesEqn(map = map));
274 end patchRecordBindings;
275
276 protected function collectRecordElementBindings
277 input BackendDAE.Var var;
278 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
279 input UnorderedMap<DAE.ComponentRef, ArrayBindingList> arrayMap;
280 protected
281 DAE.ComponentRef rec_cref;
282 Boolean is_rec;
283 algorithm
284 402583 (rec_cref, is_rec) := ComponentReference.crefGetFirstRec(var.varName);
285 () := match var.bindExp
286 local
287 DAE.Exp binding;
288 DAE.Type ty;
289
290 DAE.ComponentRef arrayCref;
291 ArrayBindingList arrayBindingExpList;
292 list<DAE.Subscript> subscriptLst;
293 list<Integer> intSubLst;
294
295 case SOME(binding) guard(is_rec and UnorderedMap.contains(rec_cref, map) and Expression.isConst(binding)) algorithm
296
297
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 4 times.
28 if ComponentReference.isArrayElement(var.varName) then
298 24 arrayCref := ComponentReference.crefStripSubsExceptModelSubs(var.varName);
299 24 arrayBindingExpList := UnorderedMap.getOrDefault(arrayCref, arrayMap, {});
300
301 24 subscriptLst := ComponentReferenceBasics.crefSubs(var.varName);
302
4/4
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 24 times.
60 intSubLst := list(match subscript
303 local
304 Integer i;
305 case DAE.INDEX(DAE.ICONST(i)) then i;
306 else algorithm
307 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because index not integer."});
308 ✗ then fail();
309 end match for subscript in subscriptLst);
310 48 UnorderedMap.add(arrayCref, (intSubLst, binding)::arrayBindingExpList, arrayMap);
311 else
312
313 ty := match UnorderedMap.getSafe(rec_cref, map, sourceInfo())
314 case ty as DAE.T_COMPLEX() algorithm
315
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 4 times.
20 ty.varLst := list(updateConstantRecordElementBinding(v, binding, ComponentReferenceBasics.crefLastIdent(var.varName)) for v in ty.varLst);
316 then ty;
317 else algorithm
318 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because the type is not T_COMPLEX."});
319 ✗ then fail();
320 end match;
321 4 UnorderedMap.add(rec_cref, ty, map);
322 end if;
323 then ();
324 else ();
325 end match;
326 end collectRecordElementBindings;
327
328 function updateConstantRecordElementBinding
329 input output DAE.Var var;
330 input DAE.Exp binding;
331 input String name;
332 protected
333 DAE.Const const;
334 algorithm
335
6/6
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 14 times.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 10 times.
32 if DAEUtil.isConstVar(var) and var.name == name then
336
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 const := if Expression.isConst(binding) then DAE.C_CONST() else DAE.C_VAR();
337 20 var.binding := DAE.EQBOUND(binding, NONE(), const, DAE.BINDING_FROM_DEFAULT_VALUE());
338 end if;
339 end updateConstantRecordElementBinding;
340
341 protected function collectRecordTypesVarLst
342 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
343 input list<BackendDAE.Var> varLst;
344 algorithm
345
2/2
✓ Branch 0 taken 194768 times.
✓ Branch 1 taken 2180 times.
196948 for var in varLst loop
346 194768 collectRecordTypesVar(map, var);
347 end for;
348 end collectRecordTypesVarLst;
349
350 protected function collectRecordTypesVar
351 "Collect record types from variable binding.
352 Add record tpye to map."
353 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
354 input BackendDAE.Var var;
355 algorithm
356 () := match var.bindExp
357 local
358 DAE.Exp exp;
359 case SOME(exp) algorithm
360 192545 Expression.traverseExpTopDown(exp, collectRecordTypesExp, map);
361 then();
362 else();
363 end match;
364 end collectRecordTypesVar;
365
366 protected function collectRecordTypesEqn
367 input output BackendDAE.Equation eqn;
368 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
369 algorithm
370 272779 (eqn, _) := BackendEquation.traverseExpsOfEquation(eqn, function Expression.traverseExpTopDown(func=collectRecordTypesExp), map);
371 end collectRecordTypesEqn;
372
373 protected function collectRecordTypesExp
374 "Collect all crefs with record type and at least one constant record component.
375 Add them to map."
376 input output DAE.Exp exp;
377 output Boolean cont;
378 input output UnorderedMap<DAE.ComponentRef, DAE.Type> map;
379 algorithm
380 cont := match exp
381 local
382 DAE.ComponentRef cref;
383 case DAE.CREF(componentRef = cref) guard(Types.isRecord(exp.ty) and Types.recordHasConstVar(exp.ty)) algorithm
384 5 UnorderedMap.add(cref, exp.ty, map);
385 then false;
386 else true;
387 end match;
388 end collectRecordTypesExp;
389
390 protected function updateRecordTypesEqn
391 input output BackendDAE.Equation eqn;
392 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
393 algorithm
394 272779 (eqn, _) := BackendEquation.traverseExpsOfEquation(eqn, function Expression.traverseExpTopDown(func=updateRecordTypesExp), map);
395 end updateRecordTypesEqn;
396
397 protected function updateRecordTypesExp
398 input output DAE.Exp exp;
399 output Boolean cont;
400 input output UnorderedMap<DAE.ComponentRef, DAE.Type> map;
401 algorithm
402 (exp, cont) := match exp
403 local
404 DAE.ComponentRef cref;
405 case DAE.CREF(componentRef = cref) guard(UnorderedMap.contains(cref, map)) algorithm
406 5 exp.ty := UnorderedMap.getSafe(cref, map, sourceInfo());
407 then (exp, false);
408 else (exp, true);
409 end match;
410 end updateRecordTypesExp;
411
412 protected function compareArrayBindingExp
413 input tuple<list<Integer>,DAE.Exp> inElement1;
414 input tuple<list<Integer>,DAE.Exp> inElement2;
415 output Boolean inRes=false "True if left element is smaller or equal";
416 protected
417 list<Integer> indiceLstElem1, indiceLstElem2;
418 list<Integer> rest_e2;
419 Integer e2;
420 algorithm
421 25 (indiceLstElem1, _) := inElement1;
422 25 (indiceLstElem2, _) := inElement2;
423
424
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 if listLength(indiceLstElem1) <> listLength(indiceLstElem2) then
425 ✗ Error.addInternalError(getInstanceName() + " failed because lists have different lengths.", sourceInfo());
426 ✗ fail();
427 end if;
428
429 rest_e2 := indiceLstElem2;
430
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 for e1 in indiceLstElem1 loop
431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 e2 :: rest_e2 := rest_e2;
432
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 18 times.
31 if e1 < e2 then
433 inRes := true;
434 13 return;
435 elseif e1 > e2 then
436 inRes := false;
437 12 return;
438 end if;
439 end for;
440
441 // Lists are equal
442 inRes := true;
443 ✗ return;
444 end compareArrayBindingExp;
445
446 protected function collapseArrayBindings
447 input UnorderedMap<DAE.ComponentRef, ArrayBindingList> arrayMap;
448 input output UnorderedMap<DAE.ComponentRef, DAE.Type> map;
449 protected
450 DAE.ComponentRef cref;
451 DAE.ComponentRef rec_cref;
452 ArrayBindingList arrayBindingExpList;
453 list<Integer> subscriptLst = {};
454 DAE.Exp binding;
455 DAE.Exp scalarBinding;
456 list<DAE.Exp> expLst;
457 DAE.Type ty;
458 list<DAE.Dimension> dims;
459 Integer firstDim;
460 algorithm
461
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2180 times.
2186 for pair in UnorderedMap.toList(arrayMap) loop
462 6 (cref, arrayBindingExpList) := pair;
463 6 arrayBindingExpList := List.sort(arrayBindingExpList, compareArrayBindingExp);
464
465 expLst := {};
466
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for scalBind in arrayBindingExpList loop
467 24 (subscriptLst, scalarBinding) := scalBind;
468 expLst := scalarBinding :: expLst;
469 end for;
470
471 binding := match listLength(subscriptLst)
472 local
473 list<list<DAE.Exp>> matLst;
474 4 case 1 then DAE.ARRAY(ComponentReference.crefTypeFull(cref), true, expLst);
475 case 2 algorithm
476 2 dims := TypesDump.getDimensions(ComponentReference.crefLastType(cref));
477 firstDim := match listHead(dims)
478 case DAE.DIM_INTEGER(firstDim) then firstDim;
479 end match;
480 try
481 2 matLst := List.splitEqualParts(expLst, firstDim);
482 else
483 ✗ Error.addInternalError(getInstanceName() + " failed to reshape matrix.", sourceInfo());
484 ✗ fail();
485 end try;
486 2 then DAE.MATRIX(ComponentReference.crefTypeFull(cref), firstDim, matLst);
487 else algorithm
488 ✗ Error.addInternalError(getInstanceName() + "failed. Array of dimension greater 2 not yet supported. Open a ticket about it.", sourceInfo());
489 ✗ then fail();
490 end match;
491
492 // Update binding in map
493
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 (rec_cref, true) := ComponentReference.crefGetFirstRec(cref);
494 ty := match UnorderedMap.getSafe(rec_cref, map, sourceInfo())
495 case ty as DAE.T_COMPLEX() algorithm
496
4/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 6 times.
32 ty.varLst := list(updateConstantRecordElementBinding(v, binding, ComponentReferenceBasics.crefLastIdent(cref)) for v in ty.varLst);
497 then ty;
498 else algorithm
499 ✗ Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed because the type is not T_COMPLEX."});
500 ✗ then fail();
501 end match;
502 6 UnorderedMap.add(rec_cref, ty, map);
503 end for;
504 end collapseArrayBindings;
505
506 protected function updateRecordTypesVarLst
507 input UnorderedMap<DAE.ComponentRef, DAE.Type> map;
508 input output list<BackendDAE.Var> varLst;
509 algorithm
510
4/4
✓ Branch 0 taken 194768 times.
✓ Branch 1 taken 2180 times.
✓ Branch 2 taken 194768 times.
✓ Branch 3 taken 2180 times.
196948 varLst := list(match var.bindExp
511 local
512 DAE.Exp exp;
513 case SOME(exp) algorithm
514 192545 (exp, _) := Expression.traverseExpTopDown(exp, updateRecordTypesExp, map);
515 192545 var.bindExp := SOME(exp);
516 then(var);
517 else(var);
518 end match
519 for var in varLst);
520 end updateRecordTypesVarLst;
521
522 protected function getExternalObjectAlias "Checks equations if there is an alias equation for external objects.
523 If yes, assign alias var, replace equations, remove alias equation.
524 author: waurich TUD 2016-10"
525 input list<BackendDAE.Equation> inInitEqs;
526 input list<BackendDAE.Equation> inEqs;
527 input list<BackendDAE.Equation> inRemEqs;
528 input BackendDAE.Variables globalVarsIn;
529 input BackendDAE.Variables extVars;
530 output list<BackendDAE.Equation> oInitEqs;
531 output list<BackendDAE.Equation> oEqs;
532 output list<BackendDAE.Equation> oRemEqs;
533 output BackendDAE.Variables extAliasVars;
534 output BackendDAE.Variables globalVarsOut;
535 output BackendDAE.Variables extVarsOut;
536 protected
537 list<DAE.ComponentRef> extCrefs;
538 list<BackendDAE.Equation> aliasEqs;
539 list<BackendDAE.Var> aliasVarLst;
540 BackendVarTransform.VariableReplacements repl;
541 algorithm
542 //get the crefs of the external vars
543 1095 extCrefs := BackendVariable.getAllCrefFromVariables(extVars);
544
545 // get alias equations for external objects
546 1095 (oEqs,aliasEqs) := List.fold1(inEqs,getExternalObjectAlias2,extCrefs,({},{}));
547 1095 (oInitEqs,aliasEqs) := List.fold1(inInitEqs,getExternalObjectAlias2,extCrefs,({},aliasEqs));
548 1095 (oRemEqs,aliasEqs) := List.fold1(inRemEqs,getExternalObjectAlias2,extCrefs,({},aliasEqs));
549
550
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1094 times.
1095 if (not listEmpty(aliasEqs)) then
551 1 Error.addCompilerWarning("Alias equations of external objects are not Modelica compliant as in:\n "+stringDelimitList(List.map(aliasEqs,BackendDump.equationString),"\n ")+"\n");
552 end if;
553
554 //assign aliasVariables and set new binding
555 1095 repl := BackendVarTransform.emptyReplacements();
556 1095 (aliasVarLst,repl) := List.fold1(aliasEqs,getExternalObjectAlias3,extVars,({},repl));
557 1095 extAliasVars := BackendVariable.listVar1(aliasVarLst);
558
559 //remove alias from extVarArray
560 1095 extVarsOut := BackendVariable.deleteVars(extAliasVars,extVars);
561 1095 extVarsOut := removeExtAliasBinding(extVarsOut,repl);
562
563 //replace in equations
564 1095 (oEqs,_) := BackendVarTransform.replaceEquations(oEqs,repl,NONE());
565 1095 (oInitEqs,_) := BackendVarTransform.replaceEquations(oInitEqs,repl,NONE());
566 1095 (oRemEqs,_) := BackendVarTransform.replaceEquations(oRemEqs,repl,NONE());
567 1095 (globalVarsOut, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(globalVarsIn, BackendVarTransform.replaceVarTraverser, repl);
568
569 1095 oEqs := listReverse(oEqs);
570 1095 oInitEqs := listReverse(oInitEqs);
571 1095 oRemEqs := listReverse(oRemEqs);
572 end getExternalObjectAlias;
573
574
575 protected function removeExtAliasBinding "Removes the binding of an external variable if the binding cref ist already detected as an alias variable.
576 author: Waurich TUD 2020-05"
577 input BackendDAE.Variables extVarsIn;
578 input BackendVarTransform.VariableReplacements repl;
579 output BackendDAE.Variables extVarsOut;
580 protected
581 list<BackendDAE.Var> varLst,extVarLst;
582 DAE.ComponentRef cref;
583 algorithm
584 1095 varLst := BackendVariable.varList(extVarsIn);
585 extVarLst := {};
586
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 1095 times.
1157 for var in varLst loop
587 var := match var
588 case BackendDAE.VAR(bindExp = SOME(DAE.CREF(componentRef=cref)))
589 algorithm
590 ✗ if BackendVarTransform.hasReplacement(repl,cref) then
591 ✗ var.bindExp := NONE();
592 end if;
593 then var;
594 else var;
595 end match;
596 extVarLst := var::extVarLst;
597 end for;
598 1095 extVarsOut := BackendVariable.listVar(extVarLst);
599 end removeExtAliasBinding;
600
601 protected function getExternalObjectAlias3 "Gets the alias var and sim var for the given alias equation and adds a replacement rule"
602 input BackendDAE.Equation eqIn;
603 input BackendDAE.Variables extVars;
604 input tuple<list<BackendDAE.Var>,BackendVarTransform.VariableReplacements> tplIn;
605 output tuple<list<BackendDAE.Var>,BackendVarTransform.VariableReplacements> tplOut;
606 protected
607 BackendDAE.Equation eq;
608 list<DAE.ComponentRef> crefs_lhs, crefs_rhs;
609 list<BackendDAE.Var> extAliasVars;
610 BackendVarTransform.VariableReplacements repl;
611 algorithm
612 13 (extAliasVars,repl) := tplIn;
613
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
13 ({eq},_) := BackendVarTransform.replaceEquations({eqIn},repl,NONE());
614 try
615 //get alias and sim var
616 13 (crefs_lhs, crefs_rhs) := BackendEquation.equationCrefsSolved(eq);
617 // check if there are arrays involved and expand them if needed
618 (extAliasVars,repl) := match (crefs_lhs, crefs_rhs)
619 local
620 DAE.ComponentRef lhs, rhs;
621 case ({lhs}, {rhs}) algorithm
622 // no arrays, but crefs might be arrays to expand
623 13 crefs_lhs := ComponentReference.expandCref(lhs, true);
624 13 crefs_rhs := ComponentReference.expandCref(rhs, true);
625 13 (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl);
626 then (extAliasVars,repl);
627 case ({lhs}, _) algorithm
628 // only expand lhs
629 ✗ crefs_lhs := ComponentReference.expandCref(lhs, true);
630 ✗ (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl);
631 then (extAliasVars,repl);
632 case (_, {rhs}) algorithm
633 // only expand rhs
634 ✗ crefs_rhs := ComponentReference.expandCref(rhs, true);
635 ✗ (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl);
636 then (extAliasVars,repl);
637 else algorithm
638 // expand nothing
639 ✗ (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl);
640 then (extAliasVars,repl);
641 end match;
642 13 tplOut := (extAliasVars,repl);
643 else
644 ✗ Error.addInternalError(getInstanceName() + " failed for " + BackendDump.equationString(eqIn), sourceInfo());
645 tplOut := tplIn;
646 end try;
647 end getExternalObjectAlias3;
648
649 function addExternalObjectReplacementRules
650 "add multiple external object replacement rules"
651 input list<DAE.ComponentRef> crefs_lhs;
652 input list<DAE.ComponentRef> crefs_rhs;
653 input BackendDAE.Variables extVars;
654 input output list<BackendDAE.Var> extAliasVars;
655 input output BackendVarTransform.VariableReplacements repl;
656 protected
657 DAE.ComponentRef lhs, rhs;
658 BackendDAE.Var v1, v2, simVar, aliasVar;
659 algorithm
660
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 if listLength(crefs_lhs) == listLength(crefs_rhs) then
661
2/2
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 13 times.
26 for tpl in List.zip(crefs_lhs, crefs_rhs) loop
662 13 (lhs, rhs) := tpl;
663
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
13 ({v1}, _) := BackendVariable.getVar(lhs, extVars);
664
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
13 ({v2}, _) := BackendVariable.getVar(rhs, extVars);
665 13 (simVar,aliasVar) := chooseExternalAlias(v1,v2);
666 13 extAliasVars := aliasVar::extAliasVars;
667 13 repl := BackendVarTransform.addReplacement(repl, BackendVariable.varCref(aliasVar), Expression.crefExp(BackendVariable.varCref(simVar)), NONE());
668 end for;
669 else
670 ✗ fail();
671 end if;
672 end addExternalObjectReplacementRules;
673
674 protected function chooseExternalAlias "Chooses a alias variable depending on which variable has a binding
675 author: waurich TUD 2016-10"
676 input BackendDAE.Var var1;
677 input BackendDAE.Var var2;
678 output BackendDAE.Var simVar;
679 output BackendDAE.Var aliasVar;
680 algorithm
681
3/4
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 12 times.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
13 if BackendVariable.varHasBindExp(var1) and not BackendVariable.varHasBindExp(var2)then
682 simVar := var1;
683 2 aliasVar := BackendVariable.setBindExp(var2, SOME(Expression.crefExp(BackendVariable.varCref(simVar))));
684 elseif BackendVariable.varHasBindExp(var2) and not BackendVariable.varHasBindExp(var1)then
685 simVar := var2;
686 ✗ aliasVar := BackendVariable.setBindExp(var1, SOME(Expression.crefExp(BackendVariable.varCref(simVar))));
687 elseif BackendVariable.varHasBindExp(var2) and BackendVariable.varHasBindExp(var1) then
688 ✗ if Expression.isCall(BackendVariable.varBindExp(var1)) then
689 simVar := var1;
690 ✗ aliasVar := BackendVariable.setBindExp(var2, SOME(Expression.crefExp(BackendVariable.varCref(simVar))));
691 else
692 simVar := var2;
693 ✗ aliasVar := BackendVariable.setBindExp(var1, SOME(Expression.crefExp(BackendVariable.varCref(simVar))));
694 end if;
695 else
696 simVar := var1;
697 24 aliasVar := BackendVariable.setBindExp(var2, SOME(Expression.crefExp(BackendVariable.varCref(simVar))));
698 end if;
699 end chooseExternalAlias;
700
701 protected function getExternalObjectAlias2 "Traverser for equations to check if an external alias assignment can be made
702 author: waurich TUD 2016-10"
703 input BackendDAE.Equation eqIn;
704 input list<DAE.ComponentRef> extCrefs;
705 input tuple<list<BackendDAE.Equation>, list<BackendDAE.Equation>> eqTplIn; //nonAlias and aliasEqs
706 output tuple<list<BackendDAE.Equation>, list<BackendDAE.Equation>> eqTplOut;
707 algorithm
708 eqTplOut := matchcontinue(eqIn, eqTplIn)
709 local
710 list<BackendDAE.Equation> noAliasEqs, aliasEqs;
711 DAE.ComponentRef cr1,cr2;
712 DAE.Exp left, right;
713 case(BackendDAE.COMPLEX_EQUATION(left = DAE.CREF(componentRef=cr1), right = DAE.CREF(componentRef=cr2)), (noAliasEqs,aliasEqs))
714 algorithm
715
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
13 true := List.exist1(extCrefs,ComponentReferenceBasics.crefEqual,cr1) and List.exist1(extCrefs,ComponentReferenceBasics.crefEqual,cr2);
716 13 then (noAliasEqs,eqIn::aliasEqs);
717
718 case(BackendDAE.EQUATION(exp = DAE.CREF(componentRef = cr1, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ())),
719 scalar = DAE.CREF(componentRef = cr2, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()))), (noAliasEqs,aliasEqs))
720 algorithm
721 ✗ true := List.exist1(extCrefs,ComponentReferenceBasics.crefEqual,cr1) and List.exist1(extCrefs,ComponentReferenceBasics.crefEqual,cr2);
722 ✗ then (noAliasEqs,eqIn::aliasEqs);
723
724 // Cases for array equations (cref = arr), (cref = cref), (arr = cref)
725 case(BackendDAE.ARRAY_EQUATION(_,
726 DAE.CREF(ty = DAE.T_ARRAY(ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) )),
727 DAE.ARRAY()), (noAliasEqs,aliasEqs))
728 ✗ then (noAliasEqs,eqIn::aliasEqs);
729
730 case(BackendDAE.ARRAY_EQUATION(_,
731 DAE.CREF(ty = DAE.T_ARRAY(ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) )),
732 DAE.CREF(ty = DAE.T_ARRAY(ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) ))), _)
733 then fail();
734
735 case(BackendDAE.ARRAY_EQUATION(_,
736 DAE.ARRAY(),
737 DAE.CREF(ty = DAE.T_ARRAY(ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) ))), _)
738 then fail();
739
740 // Case (arr = arr) ?
741
742 else
743 algorithm
744 165054 (noAliasEqs,aliasEqs) := eqTplIn;
745 165054 then (eqIn::noAliasEqs,aliasEqs);
746 end matchcontinue;
747 end getExternalObjectAlias2;
748
749 protected function lower2
750 input list<DAE.Element> inElements;
751 input AvlTreePathFunction.Tree inFunctions;
752 input HashTableExpToExp.HashTable inInlineHT "Workaround to speed up inlining of array parameters.";
753 input list<BackendDAE.Var> inVars = {};
754 input list<BackendDAE.Var> inGlobalKnownVars = {};
755 input list<BackendDAE.Var> inExVars = {};
756 input list<BackendDAE.Equation> inEqns = {};
757 input list<BackendDAE.Equation> inREqns = {};
758 input list<BackendDAE.Equation> inIEqns = {};
759 input list<DAE.Constraint> inConstraints = {};
760 input list<DAE.ClassAttributes> inClassAttributes = {};
761 input list<BackendDAE.ExternalObjectClass> inExtObjClasses = {};
762 input list<DAE.Element> inAliasEqns = {};
763 output list<BackendDAE.Var> outVars = inVars "Time dependent variables.";
764 output list<BackendDAE.Var> outGlobalKnownVars = inGlobalKnownVars "Time independent variables.";
765 output list<BackendDAE.Var> outExVars = inExVars "External variables.";
766 output list<BackendDAE.Equation> outEqns = inEqns "Dynamic equations/algorithms.";
767 output list<BackendDAE.Equation> outREqns = inREqns "Algebraic equations.";
768 output list<BackendDAE.Equation> outIEqns = inIEqns "Initial equations.";
769 output list<DAE.Constraint> outConstraints = inConstraints;
770 output list<DAE.ClassAttributes> outClassAttributes = inClassAttributes;
771 output list<BackendDAE.ExternalObjectClass> outExtObjClasses = inExtObjClasses;
772 output list<DAE.Element> outAliasEqns = inAliasEqns "List with all EqualityEquations.";
773 output HashTableExpToExp.HashTable outInlineHT = inInlineHT;
774 protected
775 Absyn.Path path;
776 DAE.ElementSource src;
777 list<DAE.Element> dae_elts;
778 DAE.ClassAttributes class_attrs;
779 DAE.Constraint constraints;
780 DAE.Element el;
781 BackendDAE.EquationAttributes eq_attrs;
782 Integer whenClkCnt = 1;
783 DAE.Exp e;
784 list<BackendDAE.Equation> eqns, reqns;
785 algorithm
786
25/30
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 349858 times.
✓ Branch 2 taken 68707 times.
✓ Branch 3 taken 1765 times.
✓ Branch 4 taken 50134 times.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3009 times.
✓ Branch 8 taken 21 times.
✓ Branch 9 taken 13197 times.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 38 times.
✓ Branch 13 taken 361 times.
✓ Branch 14 taken 147 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 226 times.
✓ Branch 17 taken 61 times.
✓ Branch 18 taken 1097 times.
✓ Branch 19 taken 2037 times.
✓ Branch 20 taken 29 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 49 times.
✓ Branch 24 taken 1 time.
✓ Branch 25 taken 3 times.
✓ Branch 26 taken 13 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 490800 times.
✓ Branch 29 taken 2236 times.
493036 for el in inElements loop
787 () := match el
788 // class for external object
789 case DAE.EXTOBJECTCLASS(path, src)
790 algorithm
791 29 outExtObjClasses := BackendDAE.EXTOBJCLASS(path, src) :: outExtObjClasses;
792 then
793 ();
794
795 // variables
796 case DAE.VAR()
797 algorithm
798 349858 (outVars, outGlobalKnownVars, outExVars, outEqns, outREqns, outInlineHT) :=
799 lowerVar(el, inFunctions, outVars, outGlobalKnownVars, outExVars, outEqns, outREqns, outInlineHT);
800 then
801 ();
802
803 // scalar equations
804 case DAE.EQUATION()
805 algorithm
806 68707 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
807 then
808 ();
809
810 // initial equations
811 case DAE.INITIALEQUATION()
812 algorithm
813 1765 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
814 then
815 ();
816
817 // effort variable equality equations, separated to generate alias // variables
818 case DAE.EQUEQUATION()
819 algorithm
820 50134 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
821 then
822 ();
823
824 // a solved equation
825 case DAE.DEFINE()
826 algorithm
827 5 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
828 then
829 ();
830
831 // a initial solved equation
832 case DAE.INITIALDEFINE()
833 algorithm
834 ✗ (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
835 then
836 ();
837
838 // complex equations
839 case DAE.COMPLEX_EQUATION()
840 algorithm
841 3009 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
842 then
843 ();
844
845 // complex initial equations
846 case DAE.INITIAL_COMPLEX_EQUATION()
847 algorithm
848 21 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
849 then
850 ();
851
852 // array equations
853 case DAE.ARRAY_EQUATION()
854 algorithm
855 13197 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
856 then
857 ();
858
859 // for equation
860 case DAE.FOR_EQUATION()
861 algorithm
862 9 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
863 then
864 ();
865
866 // for equation
867 case DAE.INITIAL_FOR_EQUATION()
868 algorithm
869 ✗ (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
870 then
871 ();
872
873 // initial array equations
874 case DAE.INITIAL_ARRAY_EQUATION()
875 algorithm
876 38 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
877 then
878 ();
879
880 // when equations
881 case DAE.WHEN_EQUATION(condition = e, equations = dae_elts)
882 algorithm
883
4/4
✓ Branch 1 taken 360 times.
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 46 times.
✓ Branch 6 taken 314 times.
361 if Config.synchronousFeaturesAllowed() and Types.isClockOrSubTypeClock(Expression.typeof(e)) then
884
885 46 (outEqns, outVars, eq_attrs) := createWhenClock(whenClkCnt, e, outEqns, outVars);
886 46 whenClkCnt := whenClkCnt + 1;
887
888 46 ( outVars, outGlobalKnownVars, outExVars, eqns, reqns, outIEqns, outConstraints, outClassAttributes,
889 outExtObjClasses, outAliasEqns, outInlineHT ) :=
890 lower2( dae_elts, inFunctions, outInlineHT, outVars, outGlobalKnownVars, outExVars, {}, {}, outIEqns,
891 outConstraints, outClassAttributes, outExtObjClasses, outAliasEqns );
892
893 46 outEqns := listAppend(List.map1(eqns, BackendEquation.setEquationAttributes, eq_attrs), outEqns);
894 46 outREqns := listAppend(List.map1(reqns, BackendEquation.setEquationAttributes, eq_attrs), outREqns);
895 else
896 315 (eqns, reqns, outVars) := lowerWhenEqn(el, inFunctions, {}, {}, outVars);
897 314 reqns := listAppend(lowerWhenEqnStmts(el), reqns);
898 314 outEqns := listAppend(outEqns, eqns) annotation(__OpenModelica_DisableListAppendWarning=true);
899 314 outREqns := listAppend(outREqns, reqns) annotation(__OpenModelica_DisableListAppendWarning=true);
900 end if;
901 then
902 ();
903
904 // if equation
905 case DAE.IF_EQUATION()
906 algorithm
907 147 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, false);
908 then
909 ();
910
911 // initial if equation
912 case DAE.INITIAL_IF_EQUATION()
913 algorithm
914 4 (outEqns, outREqns, outIEqns) := lowerEqn(el, inFunctions, outEqns, outREqns, outIEqns, true);
915 then
916 ();
917
918 // algorithm
919 case DAE.ALGORITHM()
920 algorithm
921 226 (outEqns, outREqns, outIEqns) :=
922 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.EXPAND(), false);
923 then
924 ();
925
926 // initial algorithm
927 case DAE.INITIALALGORITHM()
928 algorithm
929 61 (outEqns, outREqns, outIEqns) :=
930 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.EXPAND(), true);
931 then
932 ();
933
934 // flat class / COMP
935 case DAE.COMP(dAElist = dae_elts)
936 algorithm
937 1097 (outVars, outGlobalKnownVars, outExVars, outEqns, outREqns, outIEqns, outConstraints,
938 outClassAttributes, outExtObjClasses, outAliasEqns, outInlineHT)
939 := lower2(listReverse(dae_elts), inFunctions, outInlineHT, outVars,
940 outGlobalKnownVars, outExVars, outEqns, outREqns, outIEqns, outConstraints,
941 outClassAttributes, outExtObjClasses, outAliasEqns);
942 then
943 ();
944
945 // assert in equation section is converted to ALGORITHM
946 case DAE.ASSERT()
947 algorithm
948 2037 (outEqns, outREqns, outIEqns) :=
949 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), false);
950 then
951 ();
952
953 case DAE.INITIAL_ASSERT()
954 algorithm
955 29 (outEqns, outREqns, outIEqns) :=
956 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), true);
957 then
958 ();
959
960 // terminate in equation section is converted to ALGORITHM
961 case DAE.TERMINATE()
962 algorithm
963 ✗ (outEqns, outREqns, outIEqns) :=
964 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), false);
965 then
966 ();
967
968 case DAE.INITIAL_TERMINATE()
969 algorithm
970 ✗ (outEqns, outREqns, outIEqns) := lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), true);
971 then
972 ();
973
974 case DAE.NORETCALL()
975 algorithm
976 49 (outEqns, outREqns, outIEqns) :=
977 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), false);
978 then
979 ();
980
981 // assert in equation section is converted to ALGORITHM
982 case DAE.INITIAL_NORETCALL()
983 algorithm
984 1 (outEqns, outREqns, outIEqns) :=
985 lowerAlgorithm(el, inFunctions, outEqns, outREqns, outIEqns, DAE.NOT_EXPAND(), true);
986 then
987 ();
988
989 // constraint (Optimica). Just pass the constraints for now. Should
990 // anything more be done here?
991 case DAE.CONSTRAINT(constraints = constraints)
992 algorithm
993 3 outConstraints := constraints :: outConstraints;
994 then
995 ();
996
997 case DAE.CLASS_ATTRIBUTES(classAttrs = class_attrs)
998 algorithm
999 13 outClassAttributes := class_attrs :: outClassAttributes;
1000 then
1001 ();
1002
1003 else
1004 algorithm
1005 ✗ true := Flags.isSet(Flags.FAILTRACE);
1006 ✗ Debug.traceln(getInstanceName() + " failed on: " + DAEDump.dumpElementsStr({el}));
1007 ✗ then
1008 fail();
1009 end match;
1010 end for;
1011 end lower2;
1012
1013 // =============================================================================
1014 // section for processing builtin expressions
1015 //
1016 // Insert a unique index (starting with 1) before the first arguments of some
1017 // builtin calls. Equal calls will get the same index.
1018 // - delay(expr, delayTime, delayMax)
1019 // => delay(index, expr, delayTime, delayMax)
1020 // - sample(start, interval)
1021 // => sample(index, start, interval)
1022 // =============================================================================
1023
1024 protected function processBuiltinExpressions "author: lochel
1025 Assign some builtin calls with a unique id argument."
1026 input DAE.DAElist inDAE;
1027 input AvlTreePathFunction.Tree functionTree;
1028 output DAE.DAElist outDAE;
1029 output AvlTreePathFunction.Tree outTree;
1030 output list<BackendDAE.TimeEvent> outTimeEvents;
1031 protected
1032 UnorderedMap<DAE.Exp, Integer> ht;
1033 algorithm
1034 1097 ht := UnorderedMap.new<Integer>(ExpressionBasics.hashExp, ExpressionBasics.expEqual);
1035
1/2
✓ Branch 3 taken 1097 times.
✗ Branch 4 not taken.
1097 (outDAE, outTree, (_, (_, _, _, _, outTimeEvents))) := DAEUtil.traverseDAE(inDAE, functionTree, Expression.traverseSubexpressionsHelper, (transformBuiltinExpression, (ht, 0, 0, 0, {})));
1036 end processBuiltinExpressions;
1037
1038 protected function transformBuiltinExpression "author: lochel
1039 Helper for transformBuiltinExpressions"
1040 input DAE.Exp inExp;
1041 input tuple<UnorderedMap<DAE.Exp, Integer>, Integer /*iDelay*/, Integer /*iSample*/, Integer /*iSpatial*/, list<BackendDAE.TimeEvent>> inTuple;
1042 output DAE.Exp outExp;
1043 output tuple<UnorderedMap<DAE.Exp, Integer>, Integer /*iDelay*/, Integer /*iSample*/, Integer /*iSpatial*/, list<BackendDAE.TimeEvent>> outTuple;
1044 algorithm
1045 (outExp,outTuple) := match (inExp, inTuple)
1046 local
1047 DAE.Exp start, interval;
1048 list<DAE.Exp> es;
1049 UnorderedMap<DAE.Exp, Integer> ht;
1050 Integer iDelay, iSample, iSpatial;
1051 list<BackendDAE.TimeEvent> timeEvents;
1052 DAE.CallAttributes attr;
1053
1054 // delay [already in ht]
1055 case (DAE.CALL(Absyn.IDENT("delay"), es, attr), (ht, _, _, _, _)) guard(UnorderedMap.contains(inExp, ht))
1056 ✗ then (DAE.CALL(Absyn.IDENT("delay"), DAE.ICONST(UnorderedMap.getOrFail(inExp, ht))::es, attr), inTuple);
1057
1058 // delay [not yet in ht]
1059 case (DAE.CALL(Absyn.IDENT("delay"), es, attr), (ht, iDelay, iSample, iSpatial, timeEvents)) algorithm
1060 27 UnorderedMap.add(inExp, iDelay+1, ht);
1061 54 then (DAE.CALL(Absyn.IDENT("delay"), DAE.ICONST(iDelay)::es, attr), (ht, iDelay+1, iSample, iSpatial, timeEvents));
1062
1063 // spatialDistribution [already in ht]
1064 case (DAE.CALL(Absyn.IDENT("spatialDistribution"), es, attr), (ht, _, _, _, _)) guard(UnorderedMap.contains(inExp, ht))
1065 ✗ then (DAE.CALL(Absyn.IDENT("spatialDistribution"), DAE.ICONST(UnorderedMap.getOrFail(inExp, ht))::es, attr), inTuple);
1066
1067 // spatialDistribution [not yet in ht]
1068 case (DAE.CALL(Absyn.IDENT("spatialDistribution"), es, attr), (ht, iDelay, iSample, iSpatial, timeEvents)) algorithm
1069 8 UnorderedMap.add(inExp, iSpatial+1, ht);
1070 16 then (DAE.CALL(Absyn.IDENT("spatialDistribution"), DAE.ICONST(iSpatial)::es, attr), (ht, iDelay, iSample, iSpatial+1, timeEvents));
1071
1072 // sample [already in ht]
1073 case (DAE.CALL(Absyn.IDENT("sample"), es as {_, interval}, attr), (ht, _, _, _, _))
1074 guard (not Types.isClockOrSubTypeClock(Expression.typeof(interval)) and UnorderedMap.contains(inExp, ht)) algorithm
1075 10 then (DAE.CALL(Absyn.IDENT("sample"), DAE.ICONST(UnorderedMap.getOrFail(inExp, ht))::es, attr), inTuple);
1076
1077 // sample [not yet in ht]
1078 case (DAE.CALL(Absyn.IDENT("sample"), es as {start, interval}, attr), (ht, iDelay, iSample, iSpatial, timeEvents))
1079 guard (not Types.isClockOrSubTypeClock(Expression.typeof(interval))) algorithm
1080 150 iSample := iSample+1;
1081 150 timeEvents := List.appendElt(BackendDAE.SAMPLE_TIME_EVENT(iSample, start, interval, NONE()), timeEvents);
1082 150 UnorderedMap.add(inExp, iSample, ht);
1083 300 then (DAE.CALL(Absyn.IDENT("sample"), DAE.ICONST(iSample)::es, attr), (ht, iDelay, iSample, iSpatial, timeEvents));
1084
1085 else (inExp,inTuple);
1086 end match;
1087 end transformBuiltinExpression;
1088
1089 /*
1090 * lower all variables
1091 */
1092
1093 public function lowerVars
1094 input list<DAE.Element> inElements;
1095 input AvlTreePathFunction.Tree functionTree;
1096 input list<BackendDAE.Var> inVars = {} "The time depend Variables";
1097 input list<BackendDAE.Var> inGlobalKnownVars = {} "The time independend Variables";
1098 input list<BackendDAE.Var> inExVars = {} "The external Variables";
1099 input list<BackendDAE.Equation> inEqns = {} "The dynamic Equations/Algoritms";
1100 input list<BackendDAE.Equation> inREqns = {};
1101 output list<BackendDAE.Var> outVars = inVars;
1102 output list<BackendDAE.Var> outGlobalKnownVars = inGlobalKnownVars;
1103 output list<BackendDAE.Var> outExVars = inExVars;
1104 output list<BackendDAE.Equation> outEqns = inEqns;
1105 output list<BackendDAE.Equation> outREqns = inREqns;
1106 protected
1107 DAE.ComponentRef cr;
1108 DAE.Type arr_ty;
1109 list<DAE.ComponentRef> crefs;
1110 list<DAE.Element> new_vars;
1111 HashTableExpToExp.HashTable inline_ht = HashTableExpToExp.emptyHashTable();
1112 algorithm
1113
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 225 times.
275 for el in inElements loop
1114 try
1115
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
50 DAE.VAR(componentRef = cr, ty = DAE.T_ARRAY(ty = arr_ty)) := el;
1116 ✗ crefs := ComponentReference.expandCref(cr, false);
1117 ✗ el := DAEUtil.replaceTypeInVar(arr_ty, el);
1118 ✗ new_vars := list(DAEUtil.replaceCrefInVar(c, el) for c in crefs);
1119 ✗ (outVars, outGlobalKnownVars, outExVars, outEqns, outREqns) :=
1120 lowerVars(new_vars, functionTree, outVars, outGlobalKnownVars, outExVars, outEqns, outREqns);
1121 else
1122 50 (outVars, outGlobalKnownVars, outExVars, outEqns, outREqns) := lowerVar(el, functionTree,
1123 outVars, outGlobalKnownVars, outExVars, outEqns, outREqns, inline_ht);
1124 end try;
1125 end for;
1126 end lowerVars;
1127
1128 protected function lowerVar
1129 input DAE.Element inElement;
1130 input AvlTreePathFunction.Tree inFunctions;
1131 input list<BackendDAE.Var> inVars;
1132 input list<BackendDAE.Var> inGlobalKnownVars;
1133 input list<BackendDAE.Var> inExVars;
1134 input list<BackendDAE.Equation> inEqns;
1135 input list<BackendDAE.Equation> inREqns;
1136 input HashTableExpToExp.HashTable inInlineHT;
1137 output list<BackendDAE.Var> outVars = inVars;
1138 output list<BackendDAE.Var> outGlobalKnownVars = inGlobalKnownVars;
1139 output list<BackendDAE.Var> outExVars = inExVars;
1140 output list<BackendDAE.Equation> outEqns = inEqns;
1141 output list<BackendDAE.Equation> outREqns = inREqns;
1142 output HashTableExpToExp.HashTable outInlineHT = inInlineHT;
1143 algorithm
1144 () := matchcontinue inElement
1145 local
1146 DAE.ComponentRef cr;
1147 DAE.ElementSource src;
1148 DAE.Exp e1, e2;
1149 DAE.Dimensions dims;
1150 DAE.Type tp;
1151 BackendDAE.EquationAttributes attr;
1152 BackendDAE.Var var;
1153 Option<Integer> recordSize;
1154
1155 // external object variables
1156 case DAE.VAR(ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()))
1157 algorithm
1158 75 outExVars := lowerExtObjVar(inElement, inFunctions) :: outExVars;
1159 then
1160 ();
1161
1162 // variables: states and algebraic variables with binding equation
1163 case DAE.VAR(componentRef = cr, binding = SOME(e2), source = src) guard(isStateOrAlgvar(inElement))
1164 algorithm
1165 // Add the binding as an equation and remove the binding from the variable.
1166 21886 outVars := lowerDynamicVar(inElement, inFunctions) :: outVars;
1167 attr := BackendDAE.EQ_ATTR_DEFAULT_BINDING;
1168 21834 (tp, dims) := ComponentReference.crefTypeFull2(cr);
1169 21834 tp := DAEUtil.expTypeElementType(tp);
1170
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 21834 times.
21834 if DAEUtil.expTypeComplex(tp) then
1171 ✗ recordSize := SOME(Expression.sizeOf(tp));
1172 else
1173 recordSize := NONE();
1174 end if;
1175 // remove fill from binding exp to avoid expansion if not scalarizing, treating like each
1176 e2 := match(Flags.isSet(Flags.NF_SCALARIZE), listEmpty(dims), e2)
1177 case (false, false, DAE.CALL(path = Absyn.IDENT("fill"), expLst = {e1, _})) then
1178 e1;
1179 else
1180 e2;
1181 end match;
1182 21834 e1 := Expression.crefExp(cr);
1183
2/2
✓ Branch 0 taken 21830 times.
✓ Branch 1 taken 4 times.
21834 if listEmpty(dims) then
1184 21830 outEqns := BackendDAE.EQUATION(e1, e2, src, attr) :: outEqns;
1185 else
1186 4 outEqns := BackendDAE.ARRAY_EQUATION(Expression.dimensionsSizes(dims), e1, e2, src, attr, recordSize) :: outEqns;
1187 end if;
1188 then
1189 ();
1190
1191 // variables: states and algebraic variables without binding equation
1192 case DAE.VAR(binding = NONE()) guard(isStateOrAlgvar(inElement))
1193 algorithm
1194 186006 outVars := lowerDynamicVar(inElement, inFunctions) :: outVars;
1195 then
1196 ();
1197
1198 // known variables: parameters and constants
1199 case DAE.VAR()
1200 algorithm
1201 142138 (var, outInlineHT, outREqns) :=
1202 lowerKnownVar(inElement, inFunctions, outInlineHT, outREqns);
1203 outGlobalKnownVars := var :: outGlobalKnownVars;
1204 then
1205 ();
1206
1207 else
1208 algorithm
1209 ✗ Error.addMessage(Error.INTERNAL_ERROR,
1210 {"BackendDAECreate.lowerVar failed for " + DAEDump.dumpElementsStr({inElement})});
1211 ✗ then
1212 fail();
1213
1214 end matchcontinue;
1215 end lowerVar;
1216
1217 protected function isStateOrAlgvar
1218 "@author adrpo
1219 check if this variable is a state or algebraic"
1220 input DAE.Element e;
1221 output Boolean out;
1222 algorithm
1223 out := match e
1224 case DAE.VAR(kind = DAE.VARIABLE()) then true;
1225 case DAE.VAR(kind = DAE.DISCRETE()) then true;
1226 else false;
1227 end match;
1228 end isStateOrAlgvar;
1229
1230 protected function lowerDynamicVar
1231 "Transforms a DAE variable to DAE variable.
1232 Includes changing the ComponentRef name to a simpler form
1233 \'a\'.\'b\'{2}\'c\'{5} becomes
1234 \'a.b{2}.c\' (as CREF_IDENT(\"a.b.c\", {2}) )
1235 inputs: DAE.Element
1236 outputs: Var"
1237 input DAE.Element inElement;
1238 input AvlTreePathFunction.Tree functionTree;
1239 output BackendDAE.Var outVar;
1240 algorithm
1241 outVar := match inElement
1242 local
1243 list<DAE.Dimension> dims;
1244 DAE.ComponentRef name;
1245 BackendDAE.VarKind kind_1;
1246 DAE.VarKind kind;
1247 DAE.VarDirection dir;
1248 DAE.VarParallelism prl;
1249 BackendDAE.Type tp;
1250 DAE.ConnectorType ct;
1251 DAE.ElementSource source;
1252 Option<DAE.VariableAttributes> dae_var_attr;
1253 Option<BackendDAE.TearingSelect> ts;
1254 Option<DAE.Exp> hideResult;
1255 Option<SCode.Comment> comment;
1256 DAE.Type t;
1257 DAE.VarVisibility protection;
1258 Boolean b;
1259 Absyn.InnerOuter io;
1260 Boolean encrypted;
1261
1262 case DAE.VAR(componentRef = name,
1263 kind = kind,
1264 direction = dir,
1265 parallelism = prl,
1266 protection = protection,
1267 ty = t,
1268 dims = dims,
1269 connectorType = ct,
1270 source = source,
1271 variableAttributesOption = dae_var_attr,
1272 comment = comment,
1273 innerOuter = io,
1274 encrypted = encrypted)
1275 algorithm
1276 207892 kind_1 := lowerVarkind(kind, t, name, dir, ct, dae_var_attr, protection);
1277 207695 tp := lowerType(t);
1278 207695 b := DAEUtil.boolVarVisibility(protection);
1279 207695 dae_var_attr := DAEUtil.setProtectedAttr(dae_var_attr, b);
1280 207695 dae_var_attr := setMinMaxFromEnumeration(t, dae_var_attr);
1281 // remove fill from binding exp to avoid expansion if not scalarizing, treating like each
1282
4/4
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 207657 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 19 times.
207695 if not Flags.isSet(Flags.NF_SCALARIZE) and not listEmpty(dims) then
1283 19 dae_var_attr := replaceFillWithExpInAttributes(dae_var_attr);
1284 end if;
1285 207695 ts := BackendDAEUtil.setTearingSelectAttribute(comment);
1286 207695 hideResult := BackendDAEUtil.setHideResultAttribute(comment, name);
1287
1/2
✓ Branch 0 taken 207695 times.
✗ Branch 1 not taken.
415390 then
1288 (BackendDAE.VAR(name, kind_1, dir, prl, tp, NONE(), NONE(), dims, source, dae_var_attr, ts, hideResult, comment, ct, DAEUtil.toDAEInnerOuter(io), false, false, encrypted));
1289 end match;
1290 end lowerDynamicVar;
1291
1292 protected function lowerKnownVar
1293 "Helper function to lower2"
1294 input DAE.Element inElement;
1295 input AvlTreePathFunction.Tree functionTree;
1296 input HashTableExpToExp.HashTable iInlineHT "workaround to speed up inlining of array parameters";
1297 input list<BackendDAE.Equation> assrtEqIn;
1298 output BackendDAE.Var outVar;
1299 output HashTableExpToExp.HashTable oInlineHT "workaround to speed up inlining of array parameters";
1300 output list<BackendDAE.Equation> assrtEqOut;
1301 algorithm
1302 (outVar,oInlineHT,assrtEqOut) := matchcontinue inElement
1303 local
1304 list<DAE.Dimension> dims;
1305 DAE.ComponentRef name;
1306 BackendDAE.VarKind kind_1;
1307 Option<DAE.Exp> bind;
1308 DAE.VarKind kind;
1309 DAE.VarDirection dir;
1310 DAE.VarParallelism prl;
1311 BackendDAE.Type tp;
1312 DAE.ConnectorType ct;
1313 DAE.ElementSource source;
1314 Option<DAE.VariableAttributes> dae_var_attr;
1315 Option<BackendDAE.TearingSelect> ts;
1316 Option<DAE.Exp> hideResult;
1317 Option<SCode.Comment> comment;
1318 DAE.Type t;
1319 DAE.VarVisibility protection;
1320 Boolean b;
1321 String str;
1322 list<BackendDAE.Equation> eqLst;
1323 Absyn.InnerOuter io;
1324 Boolean encrypted;
1325 case DAE.VAR(componentRef = name,
1326 kind = kind,
1327 direction = dir,
1328 parallelism = prl,
1329 protection = protection,
1330 ty = t,
1331 binding = bind,
1332 dims = dims,
1333 connectorType = ct,
1334 source = source,
1335 variableAttributesOption = dae_var_attr,
1336 comment = comment,
1337 innerOuter = io,
1338 encrypted = encrypted)
1339 algorithm
1340 142138 kind_1 := lowerKnownVarkind(kind, name, dir, ct, protection);
1341 // bind = fixParameterStartBinding(bind, t, dae_var_attr, kind_1);
1342 // remove fill from binding exp to avoid expansion if not scalarizing, treating like each
1343
4/4
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 142114 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 16 times.
142138 if not Flags.isSet(Flags.NF_SCALARIZE) and not listEmpty(dims) then
1344 8 bind := replaceFillWithExp(bind);
1345 8 dae_var_attr := replaceFillWithExpInAttributes(dae_var_attr);
1346 end if;
1347 142138 tp := lowerType(t);
1348 142138 b := DAEUtil.boolVarVisibility(protection);
1349 142138 dae_var_attr := DAEUtil.setProtectedAttr(dae_var_attr, b);
1350 142138 dae_var_attr := setMinMaxFromEnumeration(t, dae_var_attr);
1351 // build algorithms for the inlined asserts
1352 142138 eqLst := buildAssertAlgorithms({},source,assrtEqIn);
1353 // building an algorithm of the assert
1354 ts := NONE();
1355 142138 hideResult := BackendDAEUtil.setHideResultAttribute(comment, name);
1356
1/2
✓ Branch 0 taken 142138 times.
✗ Branch 1 not taken.
284276 then
1357 (BackendDAE.VAR(name, kind_1, dir, prl, tp, bind, NONE(), dims, source, dae_var_attr, ts, hideResult, comment, ct, DAEUtil.toDAEInnerOuter(io), false, false, encrypted), iInlineHT, eqLst);
1358
1359 else
1360 algorithm
1361 ✗ str := "BackendDAECreate.lowerKnownVar failed for " + DAEDump.dumpElementsStr({inElement});
1362 ✗ Error.addMessage(Error.INTERNAL_ERROR, {str});
1363 ✗ then fail();
1364 end matchcontinue;
1365 end lowerKnownVar;
1366
1367 public function lowerKnownVarSingle
1368 "author: kabdelhak
1369 lowers a single known variable (used for function bodies)"
1370 input DAE.Element element;
1371 output Option<BackendDAE.Var> var_opt;
1372 algorithm
1373 var_opt := match element
1374 local
1375 DAE.Element elem;
1376 Boolean visibility;
1377 BackendDAE.Var var;
1378 case elem as DAE.VAR() guard(DAEUtil.isParamOrConstVarKind(elem.kind))
1379 algorithm
1380 25 visibility := DAEUtil.boolVarVisibility(elem.protection);
1381 25 var := BackendDAE.VAR(
1382 varName = elem.componentRef,
1383 varKind = lowerKnownVarkind(elem.kind, elem.componentRef, elem.direction, elem.connectorType, elem.protection),
1384 varDirection = elem.direction,
1385 varParallelism = elem.parallelism,
1386 varType = lowerType(elem.ty),
1387 bindExp = elem.binding,
1388 tplExp = NONE(),
1389 arryDim = element.dims,
1390 source = element.source,
1391 values = setMinMaxFromEnumeration(elem.ty, DAEUtil.setProtectedAttr(elem.variableAttributesOption, visibility)),
1392 tearingSelectOption = NONE(),
1393 hideResult = BackendDAEUtil.setHideResultAttribute(element.comment, elem.componentRef),
1394 comment = element.comment,
1395 connectorType = element.connectorType,
1396 innerOuter = DAEUtil.toDAEInnerOuter(element.innerOuter),
1397 unreplaceable = false,
1398 initNonlinear = false,
1399 encrypted = elem.encrypted
1400 );
1401 then SOME(var);
1402 else NONE();
1403 end match;
1404 end lowerKnownVarSingle;
1405
1406 protected function replaceFillWithExpInAttributes "
1407 replaces fill(exp, dims) with exp in variable attributes assuming each qualifier"
1408 input output Option<DAE.VariableAttributes> attr;
1409 algorithm
1410 attr :=
1411 match attr
1412 local
1413 Option<DAE.Exp> q,u,du,i,f,n,min,max;
1414 Option<DAE.StartOrigin> so;
1415 Option<DAE.StateSelect> ss;
1416 Option<DAE.Uncertainty> unc;
1417 Option<DAE.Distribution> distOpt;
1418 Option<DAE.Exp> eb;
1419 Option<Boolean> ip,fn;
1420
1421 case SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,ip,fn,so))
1422 algorithm
1423 27 q := replaceFillWithExp(q);
1424 27 u := replaceFillWithExp(u);
1425 27 du := replaceFillWithExp(du);
1426 27 min := replaceFillWithExp(min);
1427 27 max := replaceFillWithExp(max);
1428 27 i := replaceFillWithExp(i);
1429 27 f := replaceFillWithExp(f);
1430 27 n := replaceFillWithExp(n);
1431 27 then SOME(DAE.VAR_ATTR_REAL(q,u,du,min,max,i,f,n,ss,unc,distOpt,eb,ip,fn,so));
1432 case SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,ip,fn,so))
1433 algorithm
1434 ✗ q := replaceFillWithExp(q);
1435 ✗ min := replaceFillWithExp(min);
1436 ✗ max := replaceFillWithExp(max);
1437 ✗ i := replaceFillWithExp(i);
1438 ✗ f := replaceFillWithExp(f);
1439 ✗ then SOME(DAE.VAR_ATTR_INT(q,min,max,i,f,unc,distOpt,eb,ip,fn,so));
1440 case SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,ip,fn,so))
1441 algorithm
1442 ✗ q := replaceFillWithExp(q);
1443 ✗ i := replaceFillWithExp(i);
1444 ✗ f := replaceFillWithExp(f);
1445 ✗ then SOME(DAE.VAR_ATTR_BOOL(q,i,f,eb,ip,fn,so));
1446 case SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,ip,fn,so))
1447 algorithm
1448 ✗ q := replaceFillWithExp(q);
1449 ✗ i := replaceFillWithExp(i);
1450 ✗ f := replaceFillWithExp(f);
1451 ✗ then SOME(DAE.VAR_ATTR_STRING(q,i,f,eb,ip,fn,so));
1452 case SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,ip,fn,so))
1453 algorithm
1454 ✗ q := replaceFillWithExp(q);
1455 ✗ min := replaceFillWithExp(min);
1456 ✗ max := replaceFillWithExp(max);
1457 ✗ u := replaceFillWithExp(u);
1458 ✗ du := replaceFillWithExp(du);
1459 ✗ then SOME(DAE.VAR_ATTR_ENUMERATION(q,min,max,u,du,eb,ip,fn,so));
1460 else
1461 attr;
1462 end match;
1463 end replaceFillWithExpInAttributes;
1464
1465 protected function replaceFillWithExp "
1466 replaces fill(exp, dims) with exp in binding expression assuming each qualifier"
1467 input output Option<DAE.Exp> bind;
1468 protected
1469 DAE.Exp e1;
1470 algorithm
1471 bind := match bind
1472 case SOME(DAE.CALL(path = Absyn.IDENT("fill"), expLst = {e1, _})) then
1473 SOME(e1);
1474 else
1475 bind;
1476 end match;
1477 end replaceFillWithExp;
1478
1479 protected function buildAssertAlgorithms "builds BackendDAE.ALGORITHM out of the given assert statements
1480 author:Waurich TUD 2013-10"
1481 input list<DAE.Statement> assrtIn;
1482 input DAE.ElementSource source;
1483 input list<BackendDAE.Equation> eqIn;
1484 output list<BackendDAE.Equation> eqOut = eqIn;
1485 algorithm
1486
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 142138 times.
142138 for assrt in assrtIn loop
1487 ✗ eqOut := BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({assrt}), source,
1488 DAE.EXPAND(), BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC) :: eqOut;
1489 end for;
1490 end buildAssertAlgorithms;
1491
1492
1493 protected function inlineExpOpt
1494 "author Frenkel TUD 2013-02"
1495 input Option<DAE.Exp> iOptExp;
1496 input Functiontuple fnstpl;
1497 input DAE.ElementSource iSource;
1498 input HashTableExpToExp.HashTable iInlineHT "workaround to speed up inlining of array parameters";
1499 output Option<DAE.Exp> oOptExp;
1500 output DAE.ElementSource oSource;
1501 output HashTableExpToExp.HashTable oInlineHT "workaround to speed up inlining of array parameters";
1502 output list<DAE.Statement> assrtLstOut;
1503 algorithm
1504 (oOptExp,oSource,oInlineHT,assrtLstOut) := match iOptExp
1505 local
1506 DAE.Exp e;
1507 DAE.ElementSource source;
1508 HashTableExpToExp.HashTable inlineHT;
1509 list<DAE.Statement> assrtLst;
1510 case NONE() then (iOptExp,iSource,iInlineHT,{});
1511 case SOME(e)
1512 algorithm
1513 ✗ (e, source, inlineHT,assrtLst) := inlineExpOpt1(e, fnstpl, iSource, iInlineHT);
1514 ✗ then (SOME(e),source,inlineHT,assrtLst);
1515 end match;
1516 end inlineExpOpt;
1517
1518 protected function inlineExpOpt1
1519 "author Frenkel TUD 2013-02"
1520 input DAE.Exp iExp;
1521 input Functiontuple fnstpl;
1522 input DAE.ElementSource iSource;
1523 input HashTableExpToExp.HashTable iInlineHT "workaround to speed up inlining of array parameters";
1524 output DAE.Exp oExp;
1525 output DAE.ElementSource oSource;
1526 output HashTableExpToExp.HashTable oInlineHT "workaround to speed up inlining of array parameters";
1527 output list<DAE.Statement> assrtLstOut;
1528 algorithm
1529 (oExp,oSource,oInlineHT,assrtLstOut) := matchcontinue iExp
1530 local
1531 DAE.Exp e,e1;
1532 list<DAE.Subscript> elst;
1533 DAE.ElementSource source;
1534 HashTableExpToExp.HashTable inlineHT;
1535 Boolean inlined;
1536 list<DAE.Statement> assrtLst,assrtLst1,assrtLst2;
1537 case DAE.CALL()
1538 algorithm
1539 ✗ e1 := BaseHashTable.get(iExp,iInlineHT);
1540 // print("use chache Inline\n" + ExpressionBasics.printExpStr(iExp) + "\n");
1541 ✗ source := ElementSource.addSymbolicTransformation(iSource,DAE.OP_INLINE(DAE.PARTIAL_EQUATION(iExp),DAE.PARTIAL_EQUATION(e1)));
1542 then (e1,source,iInlineHT,{});
1543 case DAE.CALL()
1544 algorithm
1545 // print("add chache Inline\n" + ExpressionBasics.printExpStr(iExp) + "\n");
1546 ✗ (e1, source, inlined,_) := Inline.inlineExp(iExp, fnstpl, iSource);
1547 ✗ inlineHT := if inlined then BaseHashTable.add((iExp,e1), iInlineHT) else iInlineHT;
1548 ✗ then (e1,source,inlineHT,{});
1549 case DAE.ASUB(e,elst)
1550 algorithm
1551 ✗ e1 := BaseHashTable.get(e,iInlineHT);
1552 // print("use chache Inline\n" + ExpressionBasics.printExpStr(iExp) + "\n");
1553 ✗ source := ElementSource.addSymbolicTransformation(iSource,DAE.OP_INLINE(DAE.PARTIAL_EQUATION(e),DAE.PARTIAL_EQUATION(e1)));
1554 ✗ (e, source, _,_) := Inline.inlineExp(DAE.ASUB(e1,elst), fnstpl, source);
1555 ✗ then (e,source,iInlineHT,{});
1556 case DAE.ASUB(e,elst)
1557 algorithm
1558 // print("add chache Inline(1)\n" + ExpressionBasics.printExpStr(iExp) + "\n");
1559 ✗ (e1, _, inlined,assrtLst1) := Inline.inlineExp(e, fnstpl, iSource);
1560 ✗ inlineHT := if inlined then BaseHashTable.add((e,e1), iInlineHT) else iInlineHT;
1561 ✗ (e, source, _,assrtLst2) := Inline.inlineExp(DAE.ASUB(e1,elst), fnstpl, iSource);
1562 ✗ assrtLst := listAppend(assrtLst1,assrtLst2);
1563 ✗ then (e,source,inlineHT,assrtLst);
1564 case _
1565 algorithm
1566 // print("no chache Inline\n" + ExpressionBasics.printExpStr(iExp) + "\n");
1567 ✗ (e, source, _,_) := Inline.inlineExp(iExp, fnstpl, iSource);
1568 ✗ then (e,source,iInlineHT,{});
1569 end matchcontinue;
1570 end inlineExpOpt1;
1571
1572 protected function setMinMaxFromEnumeration
1573 input DAE.Type inType;
1574 input Option<DAE.VariableAttributes> inVarAttr;
1575 output Option<DAE.VariableAttributes> outVarAttr;
1576 algorithm
1577 outVarAttr := match inType
1578 local
1579 Option<DAE.Exp> min, max;
1580 list<String> names;
1581 Absyn.Path path;
1582 case DAE.T_ENUMERATION(path=path, names = names)
1583 algorithm
1584 3187 (min, max) := DAEUtil.getMinMaxValues(inVarAttr);
1585 3187 then
1586 setMinMaxFromEnumeration1(min, max, inVarAttr, path, names);
1587 else inVarAttr;
1588 end match;
1589 end setMinMaxFromEnumeration;
1590
1591 protected function setMinMaxFromEnumeration1
1592 input Option<DAE.Exp> inMin;
1593 input Option<DAE.Exp> inMax;
1594 input Option<DAE.VariableAttributes> inVarAttr;
1595 input Absyn.Path inPath;
1596 input list<String> inNames;
1597 output Option<DAE.VariableAttributes> outVarAttr;
1598 algorithm
1599 outVarAttr := matchcontinue (inMin, inMax)
1600 local
1601 Integer i;
1602 Absyn.Path namee1, nameen;
1603 String s1, sn;
1604 case (NONE(), NONE())
1605 algorithm
1606 3187 i := listLength(inNames);
1607 3187 s1 := listHead(inNames);
1608 3187 namee1 := AbsynUtil.joinPaths(inPath, Absyn.IDENT(s1));
1609 3187 sn := listGet(inNames, i);
1610 3187 nameen := AbsynUtil.joinPaths(inPath, Absyn.IDENT(sn));
1611 6374 then
1612 DAEUtil.setMinMax(inVarAttr, SOME(DAE.ENUM_LITERAL(namee1, 1)), SOME(DAE.ENUM_LITERAL(nameen, i)));
1613 case (NONE(), SOME(_))
1614 algorithm
1615 ✗ s1 := listHead(inNames);
1616 ✗ namee1 := AbsynUtil.joinPaths(inPath, Absyn.IDENT(s1));
1617 ✗ then
1618 DAEUtil.setMinMax(inVarAttr, SOME(DAE.ENUM_LITERAL(namee1, 1)), inMax);
1619 case (SOME(_), NONE())
1620 algorithm
1621 ✗ i := listLength(inNames);
1622 ✗ sn := listGet(inNames, i);
1623 ✗ nameen := AbsynUtil.joinPaths(inPath, Absyn.IDENT(sn));
1624 ✗ then
1625 DAEUtil.setMinMax(inVarAttr, inMin, SOME(DAE.ENUM_LITERAL(nameen, i)));
1626 else inVarAttr;
1627 end matchcontinue;
1628 end setMinMaxFromEnumeration1;
1629
1630 // protected function fixParameterStartBinding
1631 // input Option<DAE.Exp> bind;
1632 // input DAE.Type ty;
1633 // input Option<DAE.VariableAttributes> attr;
1634 // input BackendDAE.VarKind kind;
1635 // output Option<DAE.Exp> outBind;
1636 // algorithm
1637 // outBind := matchcontinue (bind, ty, attr, kind)
1638 // local
1639 // DAE.Exp exp;
1640 // case (NONE(), DAE.T_REAL(source=_), _, BackendDAE.PARAM())
1641 // equation
1642 // exp = DAEUtil.getStartAttr(attr);
1643 // then SOME(exp);
1644 // else bind;
1645 // end matchcontinue;
1646 // end fixParameterStartBinding;
1647
1648 protected function lowerVarkind
1649 "Helper function to lowerVar.
1650 inputs: (DAE.VarKind,
1651 Type,
1652 DAE.ComponentRef,
1653 DAE.VarDirection, /* input/output/bidir */
1654 DAE.ConnectorType)
1655 outputs VarKind
1656 NOTE: Fails for not states that are not algebraic
1657 variables, e.g. parameters and constants"
1658 input DAE.VarKind inVarKind;
1659 input DAE.Type inType;
1660 input DAE.ComponentRef inComponentRef;
1661 input DAE.VarDirection inVarDirection;
1662 input DAE.ConnectorType inConnectorType;
1663 input Option<DAE.VariableAttributes> daeAttr;
1664 input DAE.VarVisibility protection;
1665 output BackendDAE.VarKind outVarKind;
1666 algorithm
1667 outVarKind := match(inVarKind, daeAttr)
1668 // variable -> artificial state if have stateSelect = StateSelect.always
1669 case (DAE.VARIABLE(), SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.ALWAYS()))))
1670 guard(not Types.isDiscreteType(inType))
1671 then BackendDAE.STATE(1, NONE(), false);
1672
1673 // variable -> artificial state if have stateSelect = StateSelect.prefer
1674 case (DAE.VARIABLE(), SOME(DAE.VAR_ATTR_REAL(stateSelectOption = SOME(DAE.PREFER()))))
1675 guard(not Types.isDiscreteType(inType))
1676 then BackendDAE.STATE(1, NONE(), false);
1677
1678 else
1679 algorithm
1680 /* Consider toplevel inputs as known unless they are protected. Ticket #5591 */
1681
2/2
✓ Branch 1 taken 197 times.
✓ Branch 2 taken 206421 times.
206618 false := ConnectUtil.topLevelInput(inComponentRef, inVarDirection, inConnectorType, protection);
1682 then
1683 match (inVarKind, inType)
1684 case (DAE.VARIABLE(), DAE.T_BOOL()) then BackendDAE.DISCRETE();
1685 case (DAE.VARIABLE(), DAE.T_INTEGER()) then BackendDAE.DISCRETE();
1686 case (DAE.VARIABLE(), DAE.T_ENUMERATION()) then BackendDAE.DISCRETE();
1687 case (DAE.VARIABLE(), _) then BackendDAE.VARIABLE();
1688 case (DAE.DISCRETE(), _) then BackendDAE.DISCRETE();
1689 end match;
1690 end match;
1691 end lowerVarkind;
1692
1693 protected function lowerKnownVarkind
1694 "Helper function to lowerKnownVar.
1695 NOTE: Fails for everything but parameters and constants and top level inputs"
1696 input DAE.VarKind varKind;
1697 input DAE.ComponentRef componentRef;
1698 input DAE.VarDirection varDirection;
1699 input DAE.ConnectorType connectorType;
1700 input DAE.VarVisibility visibility;
1701 output BackendDAE.VarKind outVarKind;
1702 algorithm
1703 outVarKind := matchcontinue varKind
1704
1705 case DAE.PARAM() then BackendDAE.PARAM();
1706 case DAE.CONST() then BackendDAE.CONST();
1707 case DAE.VARIABLE()
1708 algorithm
1709
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 197 times.
197 true := ConnectUtil.topLevelInput(componentRef, varDirection, connectorType, visibility);
1710 then
1711 BackendDAE.VARIABLE();
1712 // adrpo: topLevelInput might fail!
1713 // case (DAE.VARIABLE(), cr, dir, flowPrefix)
1714 // then
1715 // BackendDAE.VARIABLE();
1716 else
1717 algorithm
1718 ✗ Error.addInternalError("function lowerKnownVarkind failed", sourceInfo());
1719 ✗ then
1720 fail();
1721 end matchcontinue;
1722 end lowerKnownVarkind;
1723
1724 protected function lowerType
1725 "Transforms a DAE.Type to Type"
1726 input DAE.Type inType;
1727 output BackendDAE.Type outType;
1728 algorithm
1729 outType := match inType
1730 local
1731 case DAE.T_REAL() then DAE.T_REAL_DEFAULT;
1732 case DAE.T_INTEGER() then DAE.T_INTEGER_DEFAULT;
1733 case DAE.T_BOOL() then DAE.T_BOOL_DEFAULT;
1734 case DAE.T_STRING() then DAE.T_STRING_DEFAULT;
1735 case DAE.T_CLOCK() then DAE.T_CLOCK_DEFAULT;
1736 case DAE.T_ENUMERATION() then inType;
1737 case DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) then inType;
1738 case DAE.T_COMPLEX(complexClassType = ClassInf.RECORD()) then inType;
1739 case DAE.T_ARRAY() then inType;
1740 case DAE.T_FUNCTION() then inType;
1741 ✗ else algorithm print("lowerType: " + TypesDump.printTypeStr(inType) + " failed\n"); then fail();
1742 end match;
1743 end lowerType;
1744
1745 protected function lowerExtObjVar
1746 " Helper function to lower2
1747 Fails for all variables except external object instances."
1748 input DAE.Element inElement;
1749 input AvlTreePathFunction.Tree functionTree;
1750 output BackendDAE.Var outVar;
1751 algorithm
1752 outVar:=
1753 match inElement
1754 local
1755 list<DAE.Dimension> dims;
1756 DAE.ComponentRef name;
1757 BackendDAE.VarKind kind_1;
1758 Option<DAE.Exp> bind;
1759 DAE.VarDirection dir;
1760 DAE.VarParallelism prl;
1761 BackendDAE.Type tp;
1762 DAE.ConnectorType ct;
1763 DAE.ElementSource source;
1764 Option<DAE.VariableAttributes> dae_var_attr;
1765 Option<BackendDAE.TearingSelect> ts;
1766 Option<DAE.Exp> hideResult;
1767 Option<SCode.Comment> comment;
1768 DAE.Type t;
1769 Absyn.InnerOuter io;
1770 Boolean encrypted;
1771
1772 case DAE.VAR(componentRef = name,
1773 direction = dir,
1774 parallelism = prl,
1775 ty = t,
1776 binding = bind,
1777 dims = dims,
1778 connectorType = ct,
1779 source = source,
1780 variableAttributesOption = dae_var_attr,
1781 comment = comment,
1782 innerOuter=io,
1783 encrypted=encrypted)
1784 algorithm
1785 75 kind_1 := lowerExtObjVarkind(t);
1786 75 tp := lowerType(t);
1787 ts := NONE();
1788 hideResult := NONE();
1789
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
150 then
1790 BackendDAE.VAR(name, kind_1, dir, prl, tp, bind, NONE(), dims, source, dae_var_attr, ts, hideResult, comment, ct, DAEUtil.toDAEInnerOuter(io), false, false, encrypted);
1791 end match;
1792 end lowerExtObjVar;
1793
1794 protected function lowerExtObjVarkind
1795 " Helper function to lowerExtObjVar.
1796 NOTE: Fails for everything but External objects"
1797 input DAE.Type inType;
1798 output BackendDAE.VarKind outVarKind;
1799 protected
1800 Absyn.Path path;
1801 algorithm
1802
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 75 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 75 times.
75 DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ(path = path)) := inType;
1803 75 outVarKind := BackendDAE.EXTOBJ(path);
1804 end lowerExtObjVarkind;
1805
1806 /*
1807 * lower all equation types
1808 */
1809
1810 protected function lowerEqn
1811 "Helper function to lower2.
1812 Transforms a DAE.Element to Equation."
1813 input DAE.Element inElement;
1814 input AvlTreePathFunction.Tree functionTree;
1815 input list<BackendDAE.Equation> inEquations;
1816 input list<BackendDAE.Equation> inREquations;
1817 input list<BackendDAE.Equation> inIEquations;
1818 input Boolean inInitialization;
1819 output list<BackendDAE.Equation> outEquations;
1820 output list<BackendDAE.Equation> outREquations;
1821 output list<BackendDAE.Equation> outIEquations;
1822 algorithm
1823 (outEquations,outREquations,outIEquations) := match inElement
1824 local
1825 DAE.Exp e1, e1_1, e2, e2_1, msg;
1826 DAE.ComponentRef cr1, cr2;
1827 DAE.ElementSource source;
1828 Boolean b1;
1829 DAE.Dimensions dims;
1830 list<DAE.Exp> explst, explst1;
1831 list<list<DAE.Element>> eqnslstlst;
1832 list<DAE.Element> eqnslst,daeElts;
1833 String s;
1834 list<BackendDAE.Equation> eqns,reqns,ieqns;
1835 Absyn.Path path;
1836
1837 // tuple-tuple assignments are split into one equation for each tuple
1838 // element, i.e. (i1, i2) = (4, 6) => i1 = 4; i2 = 6;
1839 case DAE.EQUATION(DAE.TUPLE(explst), DAE.TUPLE(explst1), source)
1840 algorithm
1841 ✗ eqns := lowerTupleAssignment(explst,explst1,source,functionTree,inEquations);
1842 ✗ then
1843 (eqns,inREquations,inIEquations);
1844 case DAE.INITIALEQUATION(DAE.TUPLE(explst), DAE.TUPLE(explst1), source)
1845 algorithm
1846 ✗ eqns := lowerTupleAssignment(explst,explst1,source,functionTree,inIEquations);
1847 ✗ then
1848 (inEquations,inREquations,eqns);
1849
1850 // Only succeds for tuple equations, i.e. (a,b,c) = foo(x,y,z) or foo(x,y,z) = (a,b,c)
1851
1852 case DAE.EQUATION(e1 as DAE.TUPLE(_),e2 as DAE.CALL(),source)
1853 algorithm
1854
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 171 times.
171 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1855 171 eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,functionTree,inEquations);
1856 171 then
1857 (eqns,inREquations,inIEquations);
1858
1859 case DAE.EQUATION(e2 as DAE.CALL(),e1 as DAE.TUPLE(_),source)
1860 algorithm
1861 ✗ (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1862 ✗ eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,functionTree,inEquations);
1863 ✗ then
1864 (eqns,inREquations,inIEquations);
1865
1866 // Only succeds for initial tuple equations, i.e. (a,b,c) = foo(x,y,z) or foo(x,y,z) = (a,b,c)
1867 case DAE.INITIALEQUATION(e1 as DAE.TUPLE(_),e2 as DAE.CALL(),source)
1868 algorithm
1869
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1870 12 eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_INITIAL,functionTree,inIEquations);
1871 12 then
1872 (inEquations,inREquations,eqns);
1873
1874 case DAE.INITIALEQUATION(e2 as DAE.CALL(), e1 as DAE.TUPLE(_),source)
1875 algorithm
1876 ✗ (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1877 ✗ eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_INITIAL,functionTree,inIEquations);
1878 ✗ then
1879 (inEquations,inREquations,eqns);
1880
1881 case DAE.EQUATION(exp = e1,scalar = e2,source = source)
1882 algorithm
1883
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 70209 times.
70209 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1884 140418 then
1885 (BackendDAE.EQUATION(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inEquations,inREquations,inIEquations);
1886
1887 case DAE.INITIALEQUATION(exp1 = e1,exp2 = e2,source = source)
1888 algorithm
1889
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1755 times.
1755 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1890 3510 then
1891 (inEquations,inREquations,BackendDAE.EQUATION(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_INITIAL)::inIEquations);
1892
1893 case DAE.EQUEQUATION(cr1 = cr1, cr2 = cr2,source = source)
1894 algorithm
1895
2/2
✓ Branch 1 taken 50205 times.
✓ Branch 2 taken 2 times.
50207 if Flags.isSet(Flags.NF_SCALARIZE) then
1896 50205 e1 := Expression.crefExp(cr1);
1897 50205 e2 := Expression.crefExp(cr2);
1898 else
1899 // consider array dimensions
1900 2 e1 := Expression.crefToExp(cr1);
1901 2 e2 := Expression.crefToExp(cr2);
1902 end if;
1903 50207 eqns := lowerExtendedRecordEqn(e1,e2,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,functionTree,inEquations);
1904 50207 then
1905 (eqns,inREquations,inIEquations);
1906
1907 case DAE.DEFINE(componentRef = cr1, exp = e2, source = source)
1908 algorithm
1909 5 e1 := Expression.crefExp(cr1);
1910
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1911 10 then
1912 (BackendDAE.EQUATION(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inEquations,inREquations,inIEquations);
1913
1914 case DAE.INITIALDEFINE(componentRef = cr1, exp = e2, source = source)
1915 algorithm
1916 ✗ e1 := Expression.crefExp(cr1);
1917 ✗ (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1918 ✗ then
1919 (inEquations,inREquations,BackendDAE.EQUATION(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inIEquations);
1920
1921 case DAE.COMPLEX_EQUATION(lhs = e1,rhs = e2,source = source)
1922 algorithm
1923 //TODO: remove inline
1924
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3029 times.
6058 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := Inline.simplifyAndForceInlineEquationExp(DAE.EQUALITY_EXPS(e1,e2), (SOME(functionTree), {DAE.NORM_INLINE(), DAE.DEFAULT_INLINE()}), source);
1925 3029 eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,functionTree,inEquations);
1926 3029 then
1927 (eqns,inREquations,inIEquations);
1928
1929 case DAE.INITIAL_COMPLEX_EQUATION(lhs = e1,rhs = e2,source = source)
1930 algorithm
1931 //TODO: remove inline
1932
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
42 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := Inline.simplifyAndForceInlineEquationExp(DAE.EQUALITY_EXPS(e1,e2), (SOME(functionTree), {DAE.NORM_INLINE(), DAE.DEFAULT_INLINE()}), source);
1933 21 eqns := lowerExtendedRecordEqn(e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,functionTree,inIEquations);
1934 21 then
1935 (inEquations,inREquations,eqns);
1936
1937 // equalityConstraint equations, moved to removed equations
1938 case DAE.ARRAY_EQUATION(dimension=dims, exp = e1 as DAE.ARRAY(array={}),array = e2 as DAE.CALL(path=path),source = source)
1939 algorithm
1940 ✗ (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1941 ✗ b1 := stringEq(AbsynUtil.pathLastIdent(path),"equalityConstraint");
1942 eqns := if b1 then inREquations else inEquations;
1943 ✗ eqns := lowerArrayEqn(dims,e1_1, e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,eqns);
1944 ✗ (eqns,_) := if b1 then (inEquations,eqns) else (eqns,inREquations);
1945 ✗ then
1946 (eqns,inREquations,inIEquations);
1947
1948 case DAE.ARRAY_EQUATION(dimension=dims,exp = e1,array = e2,source = source)
1949 algorithm
1950
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 13201 times.
13201 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1951 13201 eqns := lowerArrayEqn(dims,e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,inEquations);
1952 13201 then
1953 (eqns,inREquations,inIEquations);
1954
1955 case DAE.INITIAL_ARRAY_EQUATION(dimension=dims,exp = e1,array = e2,source = source)
1956 algorithm
1957
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
38 (DAE.EQUALITY_EXPS(e1_1,e2_1), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(e1,e2),source);
1958 38 eqns := lowerArrayEqn(dims,e1_1,e2_1,source,BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC,inIEquations);
1959 38 then
1960 (inEquations,inREquations,eqns);
1961
1962 case DAE.FOR_EQUATION(iter = s, range = e1, equations = eqnslst)
1963 algorithm
1964 // create one backend for-equation for each equation element in the loop
1965 10 (eqns, reqns, ieqns) := lowerEqns(eqnslst, functionTree, {}, {}, {}, inInitialization);
1966 10 eqns := listAppend(List.map2(eqns, lowerForEquation, s, e1), inEquations);
1967 10 reqns := listAppend(List.map2(reqns, lowerForEquation, s, e1), inREquations);
1968 10 ieqns := listAppend(List.map2(ieqns, lowerForEquation, s, e1), inIEquations);
1969 10 then
1970 (eqns, reqns, ieqns);
1971
1972 case DAE.INITIAL_FOR_EQUATION(iter = s, range = e1, equations = eqnslst)
1973 algorithm
1974 // create one backend for-equation for each equation element in the loop
1975 ✗ (eqns, reqns, ieqns) := lowerEqns(eqnslst, functionTree, {}, {}, {}, inInitialization);
1976 ✗ eqns := listAppend(List.map2(eqns, lowerForEquation, s, e1), inEquations);
1977 ✗ reqns := listAppend(List.map2(reqns, lowerForEquation, s, e1), inREquations);
1978 ✗ ieqns := listAppend(List.map2(ieqns, lowerForEquation, s, e1), inIEquations);
1979 ✗ then
1980 (eqns, reqns, ieqns);
1981
1982 // if equation that cannot be translated to if expression but have initial() as condition
1983 case DAE.IF_EQUATION(condition1 = {DAE.CALL(path=Absyn.IDENT("initial"))},equations2={eqnslst},equations3={})
1984 algorithm
1985 ✗ (eqns,reqns,ieqns) := lowerEqns(eqnslst,functionTree,{},{},{},inInitialization);
1986 ✗ ieqns := List.flatten({eqns,reqns,ieqns,inIEquations});
1987 ✗ then
1988 (inEquations,inREquations,ieqns);
1989
1990 case DAE.IF_EQUATION(condition1=explst,equations2=eqnslstlst,equations3=eqnslst,source=source)
1991 algorithm
1992 // move out assert, terminate, message stuff from if equation
1993 165 (eqnslstlst,eqnslst,daeElts) := lowerIfEquationAsserts(explst,eqnslstlst,eqnslst,{},{},{});
1994 165 (eqns,reqns,ieqns) := lowerEqns(daeElts,functionTree,inEquations,inREquations,inIEquations,inInitialization);
1995 165 eqns := lowerIfEquation(explst,eqnslstlst,eqnslst,{},{},source,functionTree,eqns);
1996 165 then
1997 (eqns,reqns,ieqns);
1998
1999 case DAE.INITIAL_IF_EQUATION(condition1=explst,equations2=eqnslstlst,equations3=eqnslst,source = source)
2000 algorithm
2001 4 eqns := lowerIfEquation(explst,eqnslstlst,eqnslst,{},{},source,functionTree,inIEquations);
2002 4 then
2003 (inEquations,inREquations,eqns);
2004
2005 // algorithm
2006 case DAE.ALGORITHM()
2007 algorithm
2008 ✗ (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.EXPAND(), false);
2009 then
2010 (eqns,reqns,ieqns);
2011
2012 // initial algorithm
2013 case DAE.INITIALALGORITHM()
2014 algorithm
2015 ✗ (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.EXPAND(), true);
2016 then
2017 (eqns,reqns,ieqns);
2018
2019
2020 case DAE.ASSERT()
2021 algorithm
2022 20 (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.NOT_EXPAND(), inInitialization);
2023 then
2024 (eqns,reqns,ieqns);
2025
2026 case DAE.INITIAL_ASSERT()
2027 algorithm
2028 2 (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.NOT_EXPAND(), inInitialization);
2029 then
2030 (eqns,reqns,ieqns);
2031
2032 case DAE.TERMINATE(message=msg,source=source)
2033 ✗ then
2034 (inEquations, BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg,source)}), source, DAE.NOT_EXPAND(), BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inREquations, inIEquations);
2035
2036 case DAE.INITIAL_TERMINATE(message=msg, source=source)
2037 3 then
2038 (inEquations, inREquations, BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg,source)}), source, DAE.NOT_EXPAND(), BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inIEquations);
2039
2040 case DAE.NORETCALL()
2041 algorithm
2042 ✗ (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.NOT_EXPAND(), false);
2043 then
2044 (eqns,reqns,ieqns);
2045
2046 case DAE.INITIAL_NORETCALL()
2047 algorithm
2048 ✗ (eqns,reqns,ieqns) := lowerAlgorithm(inElement,functionTree,inEquations,inREquations,inIEquations, DAE.NOT_EXPAND(), true);
2049 then
2050 (eqns,reqns,ieqns);
2051
2052 else
2053 algorithm
2054 ✗ s := "BackendDAECreate.lowerEqn failed for " + DAEDump.dumpElementsStr({inElement});
2055 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {s}, ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(inElement)));
2056 ✗ then fail();
2057
2058 end match;
2059 end lowerEqn;
2060
2061 protected
2062 function lowerForEquation
2063 "Wrap one equation into a for-equation.
2064 author: rfranke"
2065 input BackendDAE.Equation eq;
2066 input DAE.Ident iter;
2067 input DAE.Exp range;
2068 output BackendDAE.Equation forEq;
2069 protected
2070 DAE.Exp iterExp, start, stop;
2071 DAE.Type ty;
2072 algorithm
2073
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 DAE.RANGE(ty=ty, start=start, stop=stop) := range;
2074 11 ty := Types.unliftArray(ty);
2075 11 iterExp := DAE.CREF(DAE.CREF_IDENT(iter, ty, {}), ty);
2076 11 forEq := BackendDAE.FOR_EQUATION(iterExp, start, stop, eq,
2077 BackendEquation.equationSource(eq),
2078 BackendEquation.getEquationAttributes(eq));
2079 end lowerForEquation;
2080
2081 protected function lowerIfEquation
2082 input list<DAE.Exp> conditions;
2083 input list<list<DAE.Element>> theneqns;
2084 input list<DAE.Element> elseenqs;
2085 input list<DAE.Exp> conditions1;
2086 input list<list<DAE.Element>> theneqns1;
2087 input DAE.ElementSource inSource;
2088 input AvlTreePathFunction.Tree functionTree;
2089 input list<BackendDAE.Equation> inEquations;
2090 output list<BackendDAE.Equation> outEquations;
2091 algorithm
2092 outEquations := matchcontinue(conditions, theneqns, conditions1, theneqns1)
2093 local
2094 DAE.Exp e;
2095 list<DAE.Exp> explst;
2096 list<list<DAE.Element>> eqnslst;
2097 list<DAE.Element> eqns;
2098 DAE.ElementSource source;
2099 list<list<BackendDAE.Equation>> beqnslst;
2100 list<BackendDAE.Equation> beqns,breqns,bieqns;
2101
2102 // no true case left with condition<>false
2103 case ({}, {}, {}, {})
2104 algorithm
2105 ✗ (beqns,breqns,bieqns) := lowerEqns(elseenqs,functionTree,{},{},{},false);
2106 ✗ beqns := List.flatten({beqns,breqns,bieqns,inEquations});
2107 then
2108 beqns;
2109
2110 // true case left with condition<>false
2111 case ({}, {}, _, _)
2112 algorithm
2113 169 explst := listReverse(conditions1);
2114 169 beqnslst := lowerEqnsLst(theneqns1,functionTree,{},false);
2115 169 (beqns,breqns,bieqns) := lowerEqns(elseenqs,functionTree,{},{},{},false);
2116 338 beqns := List.flatten({beqns,breqns,bieqns});
2117 169 then
2118 BackendDAE.IF_EQUATION(explst, beqnslst, beqns, inSource, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)::inEquations;
2119
2120 // all other cases
2121 case(e::explst, eqns::eqnslst, _, _)
2122 algorithm
2123
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 447 times.
447 (DAE.PARTIAL_EQUATION(e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e),inSource);
2124 447 then
2125 lowerIfEquation1(e,explst,eqns,eqnslst,elseenqs,conditions1,theneqns1,source,functionTree,inEquations);
2126 end matchcontinue;
2127 end lowerIfEquation;
2128
2129 protected function lowerIfEquation1
2130 input DAE.Exp cond;
2131 input list<DAE.Exp> conditions;
2132 input list<DAE.Element> theneqn;
2133 input list<list<DAE.Element>> theneqns;
2134 input list<DAE.Element> elseenqs;
2135 input list<DAE.Exp> conditions1;
2136 input list<list<DAE.Element>> theneqns1;
2137 input DAE.ElementSource source;
2138 input AvlTreePathFunction.Tree functionTree;
2139 input list<BackendDAE.Equation> inEqns;
2140 output list<BackendDAE.Equation> outEqns;
2141 algorithm
2142 outEqns := matchcontinue(cond, conditions1, theneqns1)
2143 local
2144 list<DAE.Exp> explst;
2145 list<list<BackendDAE.Equation>> beqnslst;
2146 list<BackendDAE.Equation> beqns,breqns,bieqns;
2147
2148 // if true use it if it is the first one
2149 case(DAE.BCONST(true), {}, {})
2150 algorithm
2151 ✗ (beqns,breqns,bieqns) := lowerEqns(theneqn,functionTree,{},{},{},false);
2152 ✗ beqns := List.flatten({beqns,breqns,bieqns,inEqns});
2153 then
2154 beqns;
2155
2156 // if true use it as new else if it is not the first one
2157 case(DAE.BCONST(true), {}, {})
2158 algorithm
2159 ✗ explst := listReverse(conditions1);
2160 ✗ beqnslst := lowerEqnsLst(theneqns1,functionTree,{},false);
2161 ✗ (beqns,breqns,bieqns) := lowerEqns(theneqn,functionTree,{},{},{},false);
2162 ✗ beqns := List.flatten({beqns,breqns,bieqns});
2163 ✗ then
2164 BackendDAE.IF_EQUATION(explst, beqnslst, beqns, source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)::inEqns;
2165
2166 // if false skip it
2167 case(DAE.BCONST(false), _, _)
2168 1 then
2169 lowerIfEquation(conditions, theneqns, elseenqs, conditions1, theneqns1, source, functionTree, inEqns);
2170 // all other cases
2171 case(_, _, _)
2172 446 then
2173 lowerIfEquation(conditions, theneqns, elseenqs, cond::conditions1, theneqn::theneqns1, source, functionTree, inEqns);
2174 end matchcontinue;
2175 end lowerIfEquation1;
2176
2177 protected function lowerEqns "author: Frenkel TUD 2012-06"
2178 input list<DAE.Element> inElements;
2179 input AvlTreePathFunction.Tree functionTree;
2180 input list<BackendDAE.Equation> inEquations;
2181 input list<BackendDAE.Equation> inREquations;
2182 input list<BackendDAE.Equation> inIEquations;
2183 input Boolean inInitialization;
2184 output list<BackendDAE.Equation> outEquations;
2185 output list<BackendDAE.Equation> outREquations;
2186 output list<BackendDAE.Equation> outIEquations;
2187 algorithm
2188 (outEquations,outREquations,outIEquations) := match inElements
2189 local
2190 DAE.Element element;
2191 list<DAE.Element> elements;
2192 list<BackendDAE.Equation> eqns,reqns,ieqns;
2193 case {} then (inEquations,inREquations,inIEquations);
2194 case element::elements
2195 algorithm
2196 1814 (eqns,reqns,ieqns) := lowerEqn(element,functionTree,inEquations,inREquations,inIEquations, inInitialization);
2197 1814 (eqns,reqns,ieqns) := lowerEqns(elements,functionTree,eqns,reqns,ieqns, inInitialization);
2198 then
2199 (eqns,reqns,ieqns);
2200 end match;
2201 end lowerEqns;
2202
2203 protected function lowerEqnsLst "author: Frenkel TUD 2012-06"
2204 input list<list<DAE.Element>> inElements;
2205 input AvlTreePathFunction.Tree functionTree;
2206 input list<list<BackendDAE.Equation>> inEquations;
2207 input Boolean inInitialization;
2208 output list<list<BackendDAE.Equation>> outEquations;
2209 algorithm
2210 outEquations := match inElements
2211 local
2212 list<DAE.Element> element;
2213 list<list<DAE.Element>> elements;
2214 list<BackendDAE.Equation> eqns,reqns,ieqns;
2215 case {} then inEquations;
2216 case element::elements
2217 algorithm
2218 446 (eqns,reqns,ieqns) := lowerEqns(element,functionTree,{},{},{},inInitialization);
2219 892 eqns := List.flatten({eqns,reqns,ieqns});
2220 446 then
2221 lowerEqnsLst(elements,functionTree,eqns::inEquations,inInitialization);
2222 end match;
2223 end lowerEqnsLst;
2224
2225 protected function lowerIfEquationAsserts "author: Frenkel TUD 2012-10
2226 lowar all asserts in if equations"
2227 input list<DAE.Exp> conditions;
2228 input list<list<DAE.Element>> theneqns;
2229 input list<DAE.Element> elseenqs;
2230 input list<DAE.Exp> conditions1;
2231 input list<list<DAE.Element>> theneqns1;
2232 input list<DAE.Element> inEqns;
2233 output list<list<DAE.Element>> otheneqns;
2234 output list<DAE.Element> oelseenqs;
2235 output list<DAE.Element> outEqns;
2236 algorithm
2237 (otheneqns, oelseenqs, outEqns) := match(conditions, theneqns)
2238 local
2239 DAE.Exp e;
2240 list<DAE.Exp> explst;
2241 list<DAE.Element> eqns, eqns1, beqns;
2242 list<list<DAE.Element>> eqnslst, eqnslst1;
2243
2244 case (_, {})
2245 algorithm
2246 165 (beqns, eqns) := lowerIfEquationAsserts1(elseenqs, NONE(), conditions1, {}, inEqns);
2247
1/2
✓ Branch 1 taken 165 times.
✗ Branch 2 not taken.
165 then
2248 (listReverse(theneqns1), beqns, eqns);
2249 case (e::explst, eqns::eqnslst)
2250 algorithm
2251 443 (beqns, eqns) := lowerIfEquationAsserts1(eqns, SOME(e), conditions1, {}, inEqns);
2252 443 (eqnslst1, eqns1, eqns) := lowerIfEquationAsserts(explst, eqnslst, elseenqs, e::conditions1, beqns::theneqns1, eqns);
2253 then
2254 (eqnslst1, eqns1, eqns);
2255 end match;
2256 end lowerIfEquationAsserts;
2257
2258 protected function lowerIfEquationAsserts1 "author: Frenkel TUD 2012-10
2259 helper for lowerIfEquationAsserts"
2260 input list<DAE.Element> brancheqns;
2261 input Option<DAE.Exp> condition;
2262 input list<DAE.Exp> conditions "reversed";
2263 input list<DAE.Element> brancheqns1;
2264 input list<DAE.Element> inEqns;
2265 output list<DAE.Element> obrancheqns;
2266 output list<DAE.Element> outEqns;
2267 algorithm
2268 (obrancheqns, outEqns) := match(brancheqns, condition)
2269 local
2270 DAE.Exp e, exp, cond, msg, level;
2271 DAE.Element eqn;
2272 list<DAE.Element> eqns, beqns;
2273 DAE.ElementSource source;
2274 case ({}, _)
2275 608 then
2276 (listReverse(brancheqns1), inEqns);
2277 case (DAE.ASSERT(condition=cond, message=msg, level=level, source=source)::eqns, NONE())
2278 algorithm
2279 ✗ e := List.fold(conditions, makeIfExp, cond);
2280 ✗ (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ASSERT(e, msg, level, source)::inEqns);
2281 then
2282 (beqns, eqns);
2283 case (DAE.ASSERT(condition=cond, message=msg, level=level, source=source)::eqns, SOME(e))
2284 algorithm
2285 20 e := DAE.IFEXP(e, cond, DAE.BCONST(true));
2286 20 e := List.fold(conditions, makeIfExp, e);
2287 40 (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ASSERT(e, msg, level, source)::inEqns);
2288 then
2289 (beqns, eqns);
2290 case (DAE.TERMINATE(message=msg, source=source)::eqns, NONE())
2291 algorithm
2292 ✗ e := List.fold(conditions, makeIfExp, DAE.BCONST(true));
2293 ✗ (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ALGORITHM(DAE.ALGORITHM_STMTS({DAE.STMT_IF(e, {DAE.STMT_TERMINATE(msg, source)}, DAE.NOELSE(), source)}), source)::inEqns);
2294 then
2295 (beqns, eqns);
2296 case (DAE.TERMINATE(message=msg, source=source)::eqns, SOME(e))
2297 algorithm
2298 ✗ e := List.fold(conditions, makeIfExp, e);
2299 ✗ (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ALGORITHM(DAE.ALGORITHM_STMTS({DAE.STMT_IF(e, {DAE.STMT_TERMINATE(msg, source)}, DAE.NOELSE(), source)}), source)::inEqns);
2300 then
2301 (beqns, eqns);
2302 case (DAE.NORETCALL(exp=exp, source=source)::eqns, NONE())
2303 algorithm
2304 // _ = List.fold(conditions, makeIfExp, DAE.BCONST(true)); // TODO: Does this do anything?
2305 ✗ (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ALGORITHM(DAE.ALGORITHM_STMTS({DAE.STMT_IF(exp, {DAE.STMT_NORETCALL(exp, source)}, DAE.NOELSE(), source)}), source)::inEqns);
2306 then
2307 (beqns, eqns);
2308 case (DAE.NORETCALL(exp=exp, source=source)::eqns, SOME(e))
2309 algorithm
2310 ✗ e := List.fold(conditions, makeIfExp, e);
2311 ✗ (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, brancheqns1, DAE.ALGORITHM(DAE.ALGORITHM_STMTS({DAE.STMT_IF(e, {DAE.STMT_NORETCALL(exp, source)}, DAE.NOELSE(), source)}), source)::inEqns);
2312 then
2313 (beqns, eqns);
2314 case (eqn::eqns, _)
2315 algorithm
2316 1791 (beqns, eqns) := lowerIfEquationAsserts1(eqns, condition, conditions, eqn::brancheqns1, inEqns);
2317 then
2318 (beqns, eqns);
2319 end match;
2320 end lowerIfEquationAsserts1;
2321
2322 protected function makeIfExp
2323 input DAE.Exp cond;
2324 input DAE.Exp else_;
2325 output DAE.Exp oExp;
2326 algorithm
2327 ✗ oExp := DAE.IFEXP(cond, DAE.BCONST(true), else_);
2328 end makeIfExp;
2329
2330 protected function lowerExtendedRecordEqns "author: Frenkel TUD 2012-06"
2331 input list<DAE.Exp> explst1;
2332 input list<DAE.Exp> explst2;
2333 input DAE.ElementSource source;
2334 input BackendDAE.EquationAttributes inEqAttributes;
2335 input AvlTreePathFunction.Tree functionTree;
2336 input list<BackendDAE.Equation> inEqns;
2337 output list<BackendDAE.Equation> outEqns;
2338 algorithm
2339 outEqns := match(explst1, explst2)
2340 local
2341 DAE.Exp e1, e2;
2342 list<DAE.Exp> elst1, elst2;
2343 list<BackendDAE.Equation> eqns;
2344 case({}, {}) then inEqns;
2345 case(e1::elst1, e2::elst2)
2346 algorithm
2347 5831 eqns := lowerExtendedRecordEqn(e1, e2, source, inEqAttributes, functionTree, inEqns);
2348 5831 then
2349 lowerExtendedRecordEqns(elst1, elst2, source, inEqAttributes, functionTree, eqns);
2350 end match;
2351 end lowerExtendedRecordEqns;
2352
2353 protected function lowerExtendedRecordEqn "author: Frenkel TUD 2012-06"
2354 input DAE.Exp inExp1;
2355 input DAE.Exp inExp2;
2356 input DAE.ElementSource source;
2357 input BackendDAE.EquationAttributes inEqAttributes;
2358 input AvlTreePathFunction.Tree functionTree;
2359 input list<BackendDAE.Equation> inEqns;
2360 output list<BackendDAE.Equation> outEqns;
2361 algorithm
2362 outEqns := matchcontinue inEqns
2363 local
2364 DAE.Type tp;
2365 Integer size;
2366 DAE.Dimensions dims;
2367 list<DAE.Exp> explst1, explst2;
2368 Boolean b1, b2, b3;
2369
2370 // a, Record(), CAST(Record())
2371 case _
2372 algorithm
2373 59271 explst1 := Expression.splitRecord(inExp1, Expression.typeof(inExp1));
2374 3037 explst2 := Expression.splitRecord(inExp2, Expression.typeof(inExp2));
2375 2556 then
2376 lowerExtendedRecordEqns(explst1, explst2, source, inEqAttributes, functionTree, inEqns);
2377
2378 // complex types to complex equations
2379 case _
2380 algorithm
2381 56715 tp := Expression.typeof(inExp1);
2382
2/2
✓ Branch 1 taken 56221 times.
✓ Branch 2 taken 494 times.
56715 true := DAEUtil.expTypeComplex(tp);
2383 494 size := Expression.sizeOf(tp);
2384 494 then
2385 BackendDAE.COMPLEX_EQUATION(size, inExp1, inExp2, source, inEqAttributes)::inEqns;
2386
2387 // array types to array equations
2388 case _
2389 algorithm
2390 56221 tp := Expression.typeof(inExp1);
2391
2/2
✓ Branch 1 taken 54920 times.
✓ Branch 2 taken 1301 times.
56221 true := DAEUtil.expTypeArray(tp);
2392 1301 dims := Expression.arrayDimension(tp);
2393 1301 then
2394 lowerArrayEqn(dims, inExp1, inExp2, source, inEqAttributes, inEqns);
2395
2396 // tuple types to complex equations
2397 case _
2398 algorithm
2399 54920 tp := Expression.typeof(inExp1);
2400
2/2
✓ Branch 1 taken 54737 times.
✓ Branch 2 taken 183 times.
54920 true := Types.isTuple(tp);
2401 183 size := Expression.sizeOf(tp);
2402 183 then
2403 BackendDAE.COMPLEX_EQUATION(size, inExp1, inExp2, source, inEqAttributes)::inEqns;
2404
2405 // other types
2406 case _
2407 algorithm
2408 54737 tp := Expression.typeof(inExp1);
2409 54737 b1 := DAEUtil.expTypeComplex(tp);
2410 54737 b2 := DAEUtil.expTypeArray(tp);
2411 54737 b3 := Types.isTuple(tp);
2412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54737 times.
54737 false := b1 or b2 or b3;
2413 //Error.assertionOrAddSourceMessage(not b1, Error.INTERNAL_ERROR, {str}, Absyn.dummyInfo);
2414 54737 then
2415 BackendDAE.EQUATION(inExp1, inExp2, source, inEqAttributes)::inEqns;
2416 else
2417 algorithm
2418 // show only on failtrace!
2419 ✗ true := Flags.isSet(Flags.FAILTRACE);
2420 ✗ Debug.traceln("- BackendDAECreate.lowerExtendedRecordEqn failed on: " + ExpressionBasics.printExpStr(inExp1) + " = " + ExpressionBasics.printExpStr(inExp2) + "\n");
2421 ✗ then
2422 fail();
2423 end matchcontinue;
2424 end lowerExtendedRecordEqn;
2425
2426 protected function lowerArrayEqn "author: Frenkel TUD 2012-06"
2427 input DAE.Dimensions dims;
2428 input DAE.Exp e1;
2429 input DAE.Exp e2;
2430 input DAE.ElementSource source;
2431 input BackendDAE.EquationAttributes inEqAttributes;
2432 input list<BackendDAE.Equation> iAcc;
2433 output list<BackendDAE.Equation> outEqsLst;
2434 protected
2435 list<Integer> dimensions;
2436 list<DAE.Exp> ea1,ea2;
2437 DAE.Type tp;
2438 Integer recordSize;
2439 algorithm
2440 14540 tp := Expression.typeof(e1);
2441 14540 tp := DAEUtil.expTypeElementType(tp);
2442
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 14538 times.
14540 if DAEUtil.expTypeComplex(tp) then
2443 2 recordSize := Expression.sizeOf(tp);
2444 2 dimensions := Expression.dimensionsSizes(dims);
2445 2 outEqsLst := BackendDAE.ARRAY_EQUATION(dimensions, e1, e2, source, inEqAttributes,SOME(recordSize))::iAcc;
2446 elseif (Expression.isArray(e1) or Expression.isMatrix(e1)) and (Expression.isArray(e2) or Expression.isMatrix(e2)) then
2447 ✗ ea1 := Expression.flattenArrayExpToList(e1);
2448 ✗ ea2 := Expression.flattenArrayExpToList(e2);
2449 ✗ outEqsLst := generateEquations(ea1, ea2, source, inEqAttributes, iAcc);
2450 else
2451 14538 dimensions := Expression.dimensionsSizes(dims);
2452 14538 outEqsLst := BackendDAE.ARRAY_EQUATION(dimensions, e1, e2, source, inEqAttributes, NONE())::iAcc;
2453 end if;
2454 end lowerArrayEqn;
2455
2456 protected function generateEquations "author: Frenkel TUD 2012-06"
2457 input list<DAE.Exp> iE1lst;
2458 input list<DAE.Exp> iE2lst;
2459 input DAE.ElementSource source;
2460 input BackendDAE.EquationAttributes inEqAttributes;
2461 input list<BackendDAE.Equation> iAcc;
2462 output list<BackendDAE.Equation> oEqns;
2463 algorithm
2464 oEqns := match(iE1lst, iE2lst)
2465 local
2466 DAE.Exp e1, e2;
2467 list<DAE.Exp> e1lst, e2lst;
2468 case ({}, {}) then iAcc;
2469 case (e1::e1lst, e2::e2lst)
2470 ✗ then generateEquations(e1lst, e2lst, source, inEqAttributes, BackendDAE.EQUATION(e1, e2, source, inEqAttributes)::iAcc);
2471 end match;
2472 end generateEquations;
2473
2474 protected function createWhenClock
2475 input Integer whenClkCnt;
2476 input DAE.Exp e;
2477 input list<BackendDAE.Equation> inEqs;
2478 input list<BackendDAE.Var> inVars;
2479 output list<BackendDAE.Equation> outEqs;
2480 output list<BackendDAE.Var> outVars;
2481 output BackendDAE.EquationAttributes outEqAttrs;
2482 protected
2483 DAE.ComponentRef cr;
2484 algorithm
2485 46 cr := DAE.CREF_IDENT(BackendDAE.WHENCLK_PRREFIX + intString(whenClkCnt), DAE.T_CLOCK_DEFAULT, {});
2486 46 outVars := BackendDAE.VAR (
2487 varName = cr, varKind = BackendDAE.VARIABLE(),
2488 varDirection = DAE.BIDIR(), varParallelism = DAE.NON_PARALLEL(),
2489 varType = DAE.T_CLOCK_DEFAULT, bindExp = NONE(), tplExp = NONE(),
2490 arryDim = {}, source = DAE.emptyElementSource,
2491 values = NONE(), tearingSelectOption = SOME(BackendDAE.DEFAULT()), hideResult = NONE(),
2492 comment = NONE(), connectorType = DAE.NON_CONNECTOR(),
2493 innerOuter = DAE.NOT_INNER_OUTER(), unreplaceable = true, initNonlinear = false, encrypted = false) :: inVars;
2494 46 outEqs := BackendDAE.EQUATION( exp = DAE.CREF(componentRef = cr, ty = DAE.T_CLOCK_DEFAULT),
2495 scalar = e, source = DAE.emptyElementSource,
2496 attr = BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC ) :: inEqs;
2497 46 outEqAttrs := BackendEquation.defaultClockedEqAttr(whenClkCnt);
2498 end createWhenClock;
2499
2500
2501 protected function lowerWhenEqn
2502 "This function lowers a when eqn."
2503 input DAE.Element inElement;
2504 input AvlTreePathFunction.Tree functionTree;
2505 input list<BackendDAE.Equation> inEquationLst;
2506 input list<BackendDAE.Equation> inREquationLst;
2507 input list<BackendDAE.Var> inVars;
2508 output list<BackendDAE.Equation> outEquationLst;
2509 output list<BackendDAE.Equation> outREquationLst;
2510 output list<BackendDAE.Var> outVars = inVars;
2511 protected
2512 //Inline.Functiontuple fns = (SOME(functionTree), {DAE.NORM_INLINE()});
2513 Integer numErrors = Error.getNumErrorMessages();
2514 algorithm
2515 (outEquationLst, outREquationLst):= matchcontinue inElement
2516 local
2517 list<BackendDAE.Equation> res, rEqns;
2518 list<BackendDAE.Equation> trueEqnLst;
2519 list<BackendDAE.Equation> trueREqns;
2520 DAE.Exp cond;
2521 list<DAE.Element> eqnl;
2522 DAE.Element elsePart;
2523 String str;
2524 DAE.ElementSource source;
2525
2526 case DAE.WHEN_EQUATION(condition = cond, equations = eqnl, elsewhen_ = NONE(), source = source)
2527 algorithm
2528
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 315 times.
315 (DAE.PARTIAL_EQUATION(cond), _) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(cond),source);
2529 315 (res, rEqns, outVars) := lowerWhenEqn2(listReverse(eqnl), cond, functionTree, {}, {}, outVars);
2530 314 res := mergeWhenEqns(inEquationLst, res, {});
2531 314 rEqns := mergeWhenEqns(inREquationLst, rEqns, {});
2532 then
2533 (res, rEqns);
2534
2535
2536 case DAE.WHEN_EQUATION(condition = cond, equations = eqnl, elsewhen_ = SOME(elsePart), source = source)
2537 algorithm
2538
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 (DAE.PARTIAL_EQUATION(cond), _) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(cond),source);
2539 7 (trueEqnLst, trueREqns, outVars) := lowerWhenEqn2(listReverse(eqnl), cond, functionTree, {}, {}, outVars);
2540 7 res := mergeWhenEqns(inEquationLst, trueEqnLst, {});
2541 7 rEqns := mergeWhenEqns(inREquationLst, trueREqns, {});
2542 7 (res, rEqns, outVars) := lowerWhenEqn(elsePart, functionTree, res, rEqns, outVars);
2543 7 then
2544 (res, rEqns);
2545
2546 else
2547 algorithm
2548 // only report an internal error if nothing more specific was reported
2549
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if Error.getNumErrorMessages() == numErrors then
2550 ✗ source := ElementSource.getElementSource(inElement);
2551 ✗ str := "BackendDAECreate.lowerWhenEqn: equation not handled:\n" +
2552 DAEDump.dumpElementsStr({inElement});
2553 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, ElementSource.getElementSourceFileInfo(source));
2554 end if;
2555 1 then
2556 fail();
2557 end matchcontinue;
2558 end lowerWhenEqn;
2559
2560 protected function lowerWhenEqnStmts
2561 "Function calls, asserts, terminate and reinit inside if-equations of a when
2562 equation cannot be expressed as when-assignments like the assignments in the
2563 same branches (lowerWhenIfEqns), so they are collected into a when-algorithm
2564 with the same conditions and elsewhen chain instead."
2565 input DAE.Element whenEqn;
2566 output list<BackendDAE.Equation> algs = {};
2567 protected
2568 Option<DAE.Statement> stmt;
2569 DAE.ElementSource source;
2570 algorithm
2571 314 stmt := lowerWhenEqnStmts2(whenEqn);
2572
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 314 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 312 times.
314 if isSome(stmt) then
2573 2 source := ElementSource.getElementSource(whenEqn);
2574 4 algs := {BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({Util.getOption(stmt)}),
2575 source, DAE.NOT_EXPAND(), BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)};
2576 end if;
2577 end lowerWhenEqnStmts;
2578
2579 protected function lowerWhenEqnStmts2
2580 input DAE.Element whenEqn;
2581 output Option<DAE.Statement> stmt;
2582 protected
2583 list<DAE.Statement> stmts;
2584 Option<DAE.Statement> elseWhen;
2585 algorithm
2586 stmt := match whenEqn
2587 case DAE.WHEN_EQUATION()
2588 algorithm
2589 321 stmts := listReverse(List.fold(whenEqn.equations, lowerWhenIfEqnStmt, {}));
2590
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 321 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 314 times.
321 elseWhen := if isSome(whenEqn.elsewhen_)
2591 then lowerWhenEqnStmts2(Util.getOption(whenEqn.elsewhen_)) else NONE();
2592
4/8
✓ Branch 0 taken 318 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 318 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 318 times.
321 then
2593 if listEmpty(stmts) and isNone(elseWhen) then NONE()
2594 else SOME(DAE.STMT_WHEN(whenEqn.condition, {}, false, stmts, elseWhen, whenEqn.source));
2595 else NONE();
2596 end match;
2597 end lowerWhenEqnStmts2;
2598
2599 protected function lowerWhenIfEqnStmt
2600 "Prepends the statement part of an if-equation inside a when equation, if any.
2601 Other elements are handled by lowerWhenEqn2."
2602 input DAE.Element el;
2603 input output list<DAE.Statement> stmts;
2604 protected
2605 Option<DAE.Statement> stmt;
2606 algorithm
2607 stmts := match el
2608 case DAE.IF_EQUATION()
2609 algorithm
2610 5 stmt := lowerIfEqnStmts(el.condition1, el.equations2, el.equations3, el.source);
2611
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 time.
5 then
2612 if isSome(stmt) then Util.getOption(stmt) :: stmts else stmts;
2613 else stmts;
2614 end match;
2615 end lowerWhenIfEqnStmt;
2616
2617 protected function lowerIfEqnStmts
2618 "The if-statement with the function calls, asserts, terminate and reinit of
2619 the branches of an if-equation, NONE() if there are none. Empty branches are
2620 kept so the else branches stay exclusive."
2621 input list<DAE.Exp> conditions;
2622 input list<list<DAE.Element>> branches;
2623 input list<DAE.Element> elseBranch;
2624 input DAE.ElementSource source;
2625 output Option<DAE.Statement> stmt = NONE();
2626 protected
2627 list<list<DAE.Statement>> stmtsl;
2628 list<DAE.Statement> stmts;
2629 list<DAE.Exp> conds;
2630 DAE.Exp cond;
2631 DAE.Else else_;
2632 algorithm
2633
4/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 5 times.
12 stmtsl := list(lowerEqnsToStmts(b) for b in branches);
2634 5 stmts := lowerEqnsToStmts(elseBranch);
2635
3/4
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
5 if List.all(stmtsl, listEmpty) and listEmpty(stmts) then
2636 1 return;
2637 end if;
2638
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
4 else_ := if listEmpty(stmts) then DAE.NOELSE() else DAE.ELSE(stmts);
2639
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 cond :: conds := listReverse(conditions);
2640
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 stmts :: stmtsl := listReverse(stmtsl);
2641
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 4 times.
5 for c in conds loop
2642 1 else_ := DAE.ELSEIF(cond, stmts, else_);
2643 cond := c;
2644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 stmts :: stmtsl := stmtsl;
2645 end for;
2646 4 stmt := SOME(DAE.STMT_IF(cond, stmts, else_, source));
2647 end lowerIfEqnStmts;
2648
2649 protected function lowerEqnsToStmts
2650 "The function calls, asserts, terminate and reinit among the given equations
2651 (recursively for if-equations) as statements, in order."
2652 input list<DAE.Element> elements;
2653 output list<DAE.Statement> stmts = {};
2654 protected
2655 Option<DAE.Statement> stmt;
2656 algorithm
2657
8/8
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 9 times.
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 12 times.
30 for el in elements loop
2658 stmts := match el
2659 5 case DAE.NORETCALL() then DAE.STMT_NORETCALL(el.exp, el.source) :: stmts;
2660 1 case DAE.ASSERT() then DAE.STMT_ASSERT(el.condition, el.message, el.level, el.source) :: stmts;
2661 1 case DAE.TERMINATE() then DAE.STMT_TERMINATE(el.message, el.source) :: stmts;
2662 1 case DAE.REINIT() then DAE.STMT_REINIT(Expression.crefExp(el.componentRef), el.exp, el.source) :: stmts;
2663 1 case DAE.IF_EQUATION() then lowerWhenIfEqnStmt(el, stmts);
2664 else stmts;
2665 end match;
2666 end for;
2667 12 stmts := listReverse(stmts);
2668 end lowerEqnsToStmts;
2669
2670 protected function setReinitStateSelect
2671 "MLS (version 3.6) section 3.7.5: [The first argument of `reinit`] is
2672 implicitly defined to have `StateSelect.always`.
2673 https://github.com/OpenModelica/OpenModelica/issues/13247"
2674 input list<BackendDAE.Equation> eqns;
2675 input output BackendDAE.Variables vars;
2676 protected
2677 Option<BackendDAE.WhenEquation> when_eq;
2678 list<BackendDAE.WhenOperator> ops;
2679 Option<list<BackendDAE.Var>> var_opt;
2680 algorithm
2681
2/2
✓ Branch 0 taken 2161 times.
✓ Branch 1 taken 1095 times.
3256 for eq in eqns loop
2682 when_eq := match eq
2683 55 case BackendDAE.WHEN_EQUATION() then SOME(eq.whenEquation);
2684 else NONE();
2685 end match;
2686
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2217 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 2161 times.
2217 while isSome(when_eq) loop
2687 56 SOME(BackendDAE.WHEN_STMTS(whenStmtLst = ops, elsewhenPart = when_eq)) := when_eq;
2688
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 for op in ops loop
2689 () := match op
2690 case BackendDAE.REINIT()
2691 algorithm
2692 36 var_opt := BackendVariable.getVarTryHard(op.stateVar, vars);
2693
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 if isSome(var_opt) then
2694
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 36 times.
72 for var in Util.getOption(var_opt) loop
2695 36 vars := BackendVariable.addVar(BackendVariable.setVarStateSelect(var, DAE.StateSelect.ALWAYS()), vars);
2696 end for;
2697 end if;
2698 then ();
2699 else ();
2700 end match;
2701 end for;
2702 end while;
2703 end for;
2704 end setReinitStateSelect;
2705
2706 protected function lowerWhenEqn2
2707 "Helper function to lowerWhenEqn. Lowers the equations inside a when clause"
2708 input list<DAE.Element> inDAEElementLst "The List of equations inside a when clause";
2709 input DAE.Exp inCond;
2710 input AvlTreePathFunction.Tree functionTree;
2711 input list<BackendDAE.Equation> iEquationLst;
2712 input list<BackendDAE.Equation> iREquationLst;
2713 input list<BackendDAE.Var> inVar_lst;
2714 output list<BackendDAE.Equation> outEquationLst;
2715 output list<BackendDAE.Equation> outREquationLst;
2716 output list<BackendDAE.Var> outVar_lst = inVar_lst;
2717 protected
2718 //Inline.Functiontuple fns = (SOME(functionTree), {DAE.NORM_INLINE()});
2719 algorithm
2720 (outEquationLst, outREquationLst) := matchcontinue inDAEElementLst
2721 local
2722 Integer size;
2723 list<BackendDAE.Equation> eqnl;
2724 list<BackendDAE.Equation> reqnl;
2725 DAE.Exp cre, e, lhs, cond, level;
2726 DAE.ComponentRef cr, cr2;
2727 list<DAE.Element> xs, eqns;
2728 DAE.Element el;
2729 DAE.ElementSource source;
2730 DAE.Dimensions ds;
2731 DAE.Type ty;
2732 list<DAE.Exp> expl;
2733 list<list<DAE.Element>> eqnslst;
2734 HashTableCrToExpSourceTpl.HashTable ht;
2735 list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> crexplst;
2736 BackendDAE.Equation eq;
2737 BackendDAE.WhenEquation whenEq;
2738 BackendDAE.WhenOperator whenOp;
2739
2740 case {} then (iEquationLst, iREquationLst);
2741 case DAE.EQUEQUATION(cr1 = cr, cr2 = cr2, source = source)::xs
2742 algorithm
2743 119 e := Expression.crefExp(cr2);
2744 119 whenOp := BackendDAE.ASSIGN(Expression.crefExp(cr), e, source);
2745 119 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2746 119 eq := BackendDAE.WHEN_EQUATION(1, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2747 119 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eq::iEquationLst, iREquationLst, outVar_lst);
2748 119 then
2749 (eqnl, reqnl);
2750
2751 case DAE.DEFINE(componentRef = cr, exp = e, source = source)::xs
2752 algorithm
2753 ✗ (e, _) := ExpressionSolve.solve(Expression.crefExp(cr), e, Expression.crefExp(cr), NONE());
2754 ✗ (DAE.PARTIAL_EQUATION(e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e),source);
2755 ✗ whenOp := BackendDAE.ASSIGN(Expression.crefExp(cr), e, source);
2756 ✗ whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2757 ✗ eq := BackendDAE.WHEN_EQUATION(1, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2758 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eq::iEquationLst, iREquationLst, outVar_lst);
2759 ✗ then
2760 (eqnl, reqnl);
2761
2762 // if a function call includes external functions, it is not allowed to expand the left hand side since the call will be evaluated multiple times. That's an unintended behaviour.
2763 case DAE.EQUATION(exp = lhs as DAE.TUPLE(), scalar = e as DAE.CALL(_), source = source)::xs
2764 algorithm
2765 //print("Do not lower equations with function calls that solve tuples "+DAEDump.dumpEquationStr(listHead(inDAEElementLst))+"\n");
2766 6 ty := Expression.typeof(lhs);
2767 6 size := Expression.sizeOf(ty);
2768 12 eq := BackendDAE.WHEN_EQUATION(size, BackendDAE.WHEN_STMTS(inCond, {BackendDAE.ASSIGN(lhs, e, source)},NONE()), source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2769 eqnl := eq::iEquationLst;
2770 6 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eqnl, iREquationLst, outVar_lst);
2771 6 then
2772 (eqnl, reqnl);
2773
2774 case DAE.EQUATION(exp = DAE.TUPLE(PR=expl), scalar = e, source = source)::xs
2775 algorithm
2776 ✗ eqnl := lowerWhenTupleEqn(expl, inCond, e, source, 1, iEquationLst);
2777 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eqnl, iREquationLst, outVar_lst);
2778 ✗ then
2779 (eqnl, reqnl);
2780
2781 case (el as DAE.EQUATION(exp = (cre as DAE.CREF()), scalar = e, source = source))::xs algorithm
2782 try
2783 304 e := ExpressionSolve.solve(cre, e, cre, NONE());
2784 else
2785 ✗ Error.addCompilerError("Failed to solve " + DAEDump.dumpElementsStr({el}));
2786 ✗ fail();
2787 end try;
2788
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 304 times.
304 (DAE.PARTIAL_EQUATION(e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e),source);
2789 304 whenOp := BackendDAE.ASSIGN(cre, e, source);
2790 304 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2791 304 eq := BackendDAE.WHEN_EQUATION(1, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2792 304 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eq::iEquationLst, iREquationLst, outVar_lst);
2793 304 then (eqnl, reqnl);
2794
2795 case DAE.COMPLEX_EQUATION(lhs = (cre as DAE.CREF()), rhs = e, source = source)::xs
2796 algorithm
2797 ✗ (DAE.EQUALITY_EXPS(_,e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(cre,e),source);
2798 ✗ size := Expression.sizeOf(Expression.typeof(cre));
2799 ✗ whenOp := BackendDAE.ASSIGN(cre, e, source);
2800 ✗ whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2801 ✗ eq := BackendDAE.WHEN_EQUATION(size, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2802 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eq::iEquationLst, iREquationLst, outVar_lst);
2803 ✗ then
2804 (eqnl, reqnl);
2805
2806 case DAE.COMPLEX_EQUATION(lhs = cre as DAE.TUPLE(PR=expl), rhs = e, source = source)::xs
2807 algorithm
2808 ✗ (DAE.EQUALITY_EXPS(_,e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(cre,e),source);
2809 ✗ eqnl := lowerWhenTupleEqn(expl, inCond, e, source, 1, iEquationLst);
2810 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eqnl, iREquationLst, outVar_lst);
2811 ✗ then
2812 (eqnl, reqnl);
2813
2814 case DAE.IF_EQUATION(condition1=expl, equations2=eqnslst, equations3=eqns, source = source)::xs
2815 algorithm
2816 //(expl, source, _) = Inline.inlineExps(expl, fns, source);
2817 // transform if eqution
2818 // if .. then a=.. elseif .. then a=... else a=.. end if;
2819 // to
2820 // a=if .. then .. else if .. then else ..;
2821 5 ht := HashTableCrToExpSourceTpl.emptyHashTable();
2822 try
2823 5 ht := lowerWhenIfEqnsElse(eqns, functionTree, ht);
2824 5 ht := lowerWhenIfEqns(listReverse(expl), listReverse(eqnslst), functionTree, ht);
2825 else
2826 // a variable assigned in one branch but not in the others (or no else branch)
2827 1 Error.addSourceMessage(Error.WHEN_IF_VARIABLE_MISMATCH, {}, ElementSource.getElementSourceFileInfo(source));
2828 1 fail();
2829 end try;
2830 4 crexplst := BaseHashTable.hashTableList(ht);
2831 4 eqnl := lowerWhenIfEqns2(crexplst, inCond, source, iEquationLst);
2832 4 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eqnl, iREquationLst, outVar_lst);
2833 4 then
2834 (eqnl, reqnl);
2835
2836 case DAE.ARRAY_EQUATION(dimension=ds, exp = (cre as DAE.CREF()), array = e, source = source)::xs
2837 algorithm
2838 ✗ (DAE.EQUALITY_EXPS(_,e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(cre,e),source);
2839 ✗ size := List.fold(Expression.dimensionsSizes(ds), intMul, 1);
2840 ✗ whenOp := BackendDAE.ASSIGN(cre, e, source);
2841 ✗ whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2842 ✗ eq := BackendDAE.WHEN_EQUATION(size, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2843 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eq::iEquationLst, iREquationLst, outVar_lst);
2844 ✗ then
2845 (eqnl, reqnl);
2846
2847 case DAE.ARRAY_EQUATION(exp = cre as DAE.TUPLE(PR=expl), array = e, source = source)::xs
2848 algorithm
2849 ✗ (DAE.EQUALITY_EXPS(_,e), source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(cre,e),source);
2850 ✗ eqnl := lowerWhenTupleEqn(expl, inCond, e, source, 1, iEquationLst);
2851 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, eqnl, iREquationLst, outVar_lst);
2852 ✗ then
2853 (eqnl, reqnl);
2854
2855 case DAE.ASSERT(condition=cond, message = e, level = level, source = source)::xs
2856 algorithm
2857 7 whenOp := BackendDAE.ASSERT(cond, e, level, source);
2858 7 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2859 7 eq := BackendDAE.WHEN_EQUATION(0, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2860 7 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, iEquationLst, eq::iREquationLst, outVar_lst);
2861 7 then
2862 (eqnl, reqnl);
2863
2864 case DAE.REINIT(componentRef = cr, exp = e, source = source)::xs
2865 algorithm
2866 36 whenOp := BackendDAE.REINIT(cr, e, source);
2867 36 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2868 36 eq := BackendDAE.WHEN_EQUATION(0, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2869 36 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, iEquationLst, eq::iREquationLst, outVar_lst);
2870 36 then
2871 (eqnl, reqnl);
2872
2873 case DAE.TERMINATE(message = e, source = source)::xs
2874 algorithm
2875 8 whenOp := BackendDAE.TERMINATE(e, source);
2876 8 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2877 8 eq := BackendDAE.WHEN_EQUATION(0, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2878 8 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, iEquationLst, eq::iREquationLst, outVar_lst);
2879 8 then
2880 (eqnl, reqnl);
2881
2882 case DAE.NORETCALL(exp=e, source=source)::xs
2883 algorithm
2884 5 whenOp := BackendDAE.NORETCALL(e, source);
2885 5 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2886 5 eq := BackendDAE.WHEN_EQUATION(0, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2887 5 (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, iEquationLst, eq::iREquationLst, outVar_lst);
2888 5 then
2889 (eqnl, reqnl);
2890
2891 // failure
2892 case el::_
2893 algorithm
2894
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 true := Flags.isSet(Flags.FAILTRACE);
2895 ✗ Debug.traceln("- BackendDAECreate.lowerWhenEqn2 failed on:" + DAEDump.dumpElementsStr({el}));
2896 ✗ then
2897 fail();
2898
2899 // adrpo: 2010-09-26
2900 // allow to continue when checking the model
2901 // just ignore this equation.
2902 case _::xs
2903 algorithm
2904
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 true := Flags.getConfigBool(Flags.CHECK_MODEL);
2905 ✗ (eqnl, reqnl, outVar_lst) := lowerWhenEqn2(xs, inCond, functionTree, iEquationLst, iREquationLst, outVar_lst);
2906 ✗ then
2907 (eqnl, reqnl);
2908 end matchcontinue;
2909 end lowerWhenEqn2;
2910
2911 protected function lowerWhenTupleEqn
2912 input list<DAE.Exp> explst;
2913 input DAE.Exp inCond;
2914 input DAE.Exp e;
2915 input DAE.ElementSource source;
2916 input Integer i;
2917 input list<BackendDAE.Equation> iEquationLst;
2918 output list<BackendDAE.Equation> outEquationLst;
2919 algorithm
2920 outEquationLst := match explst
2921 local
2922 DAE.ComponentRef cr;
2923 list<DAE.Exp> rest;
2924 Integer size;
2925 DAE.Type ty;
2926 BackendDAE.WhenEquation whenEq;
2927 BackendDAE.WhenOperator whenOp;
2928
2929 case {} then iEquationLst;
2930 case DAE.CREF(componentRef = cr, ty=ty)::rest
2931 algorithm
2932 ✗ size := Expression.sizeOf(ty);
2933 ✗ whenOp := BackendDAE.ASSIGN(Expression.crefExp(cr), DAE.TSUB(e, i, ty), source);
2934 ✗ whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2935 ✗ then
2936 lowerWhenTupleEqn(rest, inCond, e, source, i+1, BackendDAE.WHEN_EQUATION(size, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC) ::iEquationLst);
2937 end match;
2938 end lowerWhenTupleEqn;
2939
2940 protected function lowerWhenIfEqns2
2941 "author: Frenkel TUD 2012-11
2942 helper for lowerWhen"
2943 input list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> crexplst;
2944 input DAE.Exp inCond;
2945 input DAE.ElementSource iSource;
2946 input list<BackendDAE.Equation> inEqns;
2947 output list<BackendDAE.Equation> outEqns;
2948 algorithm
2949 outEqns := match crexplst
2950 local
2951 DAE.ComponentRef cr;
2952 DAE.Exp e;
2953 DAE.ElementSource source;
2954 list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> rest;
2955 Integer size;
2956 BackendDAE.WhenEquation whenEq;
2957 BackendDAE.WhenOperator whenOp;
2958
2959 case {}
2960 then
2961 inEqns;
2962 case (cr, (e, source))::rest
2963 algorithm
2964 3 source := ElementSource.mergeSources(iSource, source);
2965 3 size := Expression.sizeOf(Expression.typeof(e));
2966 3 whenOp := BackendDAE.ASSIGN(Expression.crefExp(cr), e, source);
2967 3 whenEq := BackendDAE.WHEN_STMTS(inCond, {whenOp}, NONE());
2968 6 then
2969 lowerWhenIfEqns2(rest, inCond, iSource, BackendDAE.WHEN_EQUATION(size, whenEq, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::inEqns);
2970 end match;
2971 end lowerWhenIfEqns2;
2972
2973 protected function lowerWhenIfEqns
2974 "author: Frenkel TUD 2012-11
2975 helper for lowerWhen"
2976 input list<DAE.Exp> conditions;
2977 input list<list<DAE.Element>> theneqns;
2978 input AvlTreePathFunction.Tree functionTree;
2979 input HashTableCrToExpSourceTpl.HashTable iHt;
2980 output HashTableCrToExpSourceTpl.HashTable oHt;
2981 algorithm
2982 oHt := match(conditions, theneqns)
2983 local
2984 HashTableCrToExpSourceTpl.HashTable ht;
2985 DAE.Exp c;
2986 list<DAE.Exp> explst;
2987 list<DAE.Element> eqns;
2988 list<list<DAE.Element>> rest;
2989 case ({}, {})
2990 then
2991 iHt;
2992 case (c::explst, eqns::rest)
2993 algorithm
2994 8 ht := lowerWhenIfEqns1(c, eqns, functionTree, iHt);
2995 7 then
2996 lowerWhenIfEqns(explst, rest, functionTree, ht);
2997 end match;
2998 end lowerWhenIfEqns;
2999
3000 protected function lowerWhenIfEqns1
3001 "author: Frenkel TUD 2012-11
3002 helper for lowerWhenIfEqns"
3003 input DAE.Exp condition;
3004 input list<DAE.Element> brancheqns;
3005 input AvlTreePathFunction.Tree functionTree;
3006 input HashTableCrToExpSourceTpl.HashTable iHt;
3007 output HashTableCrToExpSourceTpl.HashTable oHt;
3008 algorithm
3009 oHt := match brancheqns
3010 local
3011 DAE.ComponentRef cr, cr2;
3012 DAE.Exp e, exp;
3013 DAE.ElementSource source, source1;
3014 HashTableCrToExpSourceTpl.HashTable ht;
3015 list<DAE.Element> rest, eqns;
3016 list<list<DAE.Element>> eqnslst;
3017 list<DAE.Exp> expl;
3018 list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> crexplst;
3019 case {}
3020 then
3021 iHt;
3022 case DAE.EQUEQUATION(cr1=cr, cr2=cr2, source=source)::rest
3023 algorithm
3024 2 e := Expression.crefExp(cr2);
3025
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 false := Expression.expHasCrefNoPreorDer(e, cr);
3026 2 (exp, source1) := BaseHashTable.get(cr, iHt);
3027 2 exp := DAE.IFEXP(condition, e, exp);
3028 2 source := ElementSource.mergeSources(source, source1);
3029 2 ht := BaseHashTable.add((cr, (exp, source)), iHt);
3030 2 then
3031 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3032 case DAE.DEFINE(componentRef=cr, exp=e, source=source)::rest
3033 algorithm
3034 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3035 ✗ (exp, source1) := BaseHashTable.get(cr, iHt);
3036 ✗ exp := DAE.IFEXP(condition, e, exp);
3037 ✗ source := ElementSource.mergeSources(source, source1);
3038 ✗ ht := BaseHashTable.add((cr, (exp, source)), iHt);
3039 ✗ then
3040 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3041 case DAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e, source=source)::rest
3042 algorithm
3043
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 false := Expression.expHasCrefNoPreorDer(e, cr);
3044 5 (exp, source1) := BaseHashTable.get(cr, iHt);
3045 4 exp := DAE.IFEXP(condition, e, exp);
3046 4 source := ElementSource.mergeSources(source, source1);
3047 4 ht := BaseHashTable.add((cr, (exp, source)), iHt);
3048 4 then
3049 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3050 case DAE.COMPLEX_EQUATION(lhs=DAE.CREF(componentRef=cr), rhs=e, source=source)::rest
3051 algorithm
3052 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3053 ✗ (exp, source1) := BaseHashTable.get(cr, iHt);
3054 ✗ exp := DAE.IFEXP(condition, e, exp);
3055 ✗ source := ElementSource.mergeSources(source, source1);
3056 ✗ ht := BaseHashTable.add((cr, (exp, source)), iHt);
3057 ✗ then
3058 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3059 case DAE.ARRAY_EQUATION(exp=DAE.CREF(componentRef=cr), array=e, source=source)::rest
3060 algorithm
3061 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3062 ✗ (exp, source1) := BaseHashTable.get(cr, iHt);
3063 ✗ exp := DAE.IFEXP(condition, e, exp);
3064 ✗ source := ElementSource.mergeSources(source, source1);
3065 ✗ ht := BaseHashTable.add((cr, (exp, source)), iHt);
3066 ✗ then
3067 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3068 case DAE.IF_EQUATION(condition1=expl, equations2=eqnslst, equations3=eqns, source = source)::rest
3069 algorithm
3070 1 ht := HashTableCrToExpSourceTpl.emptyHashTable();
3071 1 ht := lowerWhenIfEqnsElse(eqns, functionTree, ht);
3072 1 ht := lowerWhenIfEqns(listReverse(expl), listReverse(eqnslst), functionTree, ht);
3073 1 crexplst := BaseHashTable.hashTableList(ht);
3074 1 ht := lowerWhenIfEqnsMergeNestedIf(crexplst, condition, source, iHt);
3075 1 then
3076 lowerWhenIfEqns1(condition, rest, functionTree, ht);
3077 // collected into a when-algorithm by lowerWhenEqnStmts
3078 4 case DAE.NORETCALL()::rest then lowerWhenIfEqns1(condition, rest, functionTree, iHt);
3079 1 case DAE.ASSERT()::rest then lowerWhenIfEqns1(condition, rest, functionTree, iHt);
3080 1 case DAE.TERMINATE()::rest then lowerWhenIfEqns1(condition, rest, functionTree, iHt);
3081 1 case DAE.REINIT()::rest then lowerWhenIfEqns1(condition, rest, functionTree, iHt);
3082 end match;
3083 end lowerWhenIfEqns1;
3084
3085 protected function lowerWhenIfEqnsMergeNestedIf
3086 "author: Frenkel TUD 2012-11
3087 helper for lowerWhenIfEqns"
3088 input list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> crexplst;
3089 input DAE.Exp inCond;
3090 input DAE.ElementSource iSource;
3091 input HashTableCrToExpSourceTpl.HashTable iHt;
3092 output HashTableCrToExpSourceTpl.HashTable oHt;
3093 algorithm
3094 oHt := match crexplst
3095 local
3096 DAE.ComponentRef cr;
3097 DAE.Exp e, exp;
3098 DAE.ElementSource source;
3099 list<tuple<DAE.ComponentRef, tuple<DAE.Exp, DAE.ElementSource>>> rest;
3100 HashTableCrToExpSourceTpl.HashTable ht;
3101 case {}
3102 then
3103 iHt;
3104 case (cr, (e, source))::rest
3105 algorithm
3106 ✗ (exp, _) := BaseHashTable.get(cr, iHt);
3107 ✗ exp := DAE.IFEXP(inCond, e, exp);
3108 ✗ source := ElementSource.mergeSources(iSource, source);
3109 ✗ ht := BaseHashTable.add((cr, (exp, source)), iHt);
3110 ✗ then
3111 lowerWhenIfEqnsMergeNestedIf(rest, inCond, iSource, ht);
3112 end match;
3113 end lowerWhenIfEqnsMergeNestedIf;
3114
3115 protected function lowerWhenIfEqnsElse
3116 "author: Frenkel TUD 2012-11
3117 helper for lowerWhenIfEqns"
3118 input list<DAE.Element> elseenqs;
3119 input AvlTreePathFunction.Tree functionTree;
3120 input HashTableCrToExpSourceTpl.HashTable iHt;
3121 output HashTableCrToExpSourceTpl.HashTable oHt;
3122 algorithm
3123 oHt := match elseenqs
3124 local
3125 DAE.ComponentRef cr, cr2;
3126 DAE.Exp e;
3127 DAE.ElementSource source;
3128 HashTableCrToExpSourceTpl.HashTable ht;
3129 list<DAE.Element> rest, eqns;
3130 list<list<DAE.Element>> eqnslst;
3131 list<DAE.Exp> expl;
3132 case {}
3133 then
3134 iHt;
3135 case DAE.EQUEQUATION(cr1=cr, cr2=cr2, source=source)::rest guard not BaseHashTable.hasKey(cr, iHt)
3136 algorithm
3137 2 e := Expression.crefExp(cr2);
3138
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 false := Expression.expHasCrefNoPreorDer(e, cr);
3139 2 ht := BaseHashTable.add((cr, (e, source)), iHt);
3140 2 then
3141 lowerWhenIfEqnsElse(rest, functionTree, ht);
3142 case DAE.DEFINE(componentRef=cr, exp=e, source=source)::rest guard not BaseHashTable.hasKey(cr, iHt)
3143 algorithm
3144 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3145 ✗ ht := BaseHashTable.add((cr, (e, source)), iHt);
3146 ✗ then
3147 lowerWhenIfEqnsElse(rest, functionTree, ht);
3148 case DAE.EQUATION(exp=DAE.CREF(componentRef=cr), scalar=e, source=source)::rest guard not BaseHashTable.hasKey(cr, iHt)
3149 algorithm
3150
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 false := Expression.expHasCrefNoPreorDer(e, cr);
3151 1 ht := BaseHashTable.add((cr, (e, source)), iHt);
3152 1 then
3153 lowerWhenIfEqnsElse(rest, functionTree, ht);
3154 case DAE.COMPLEX_EQUATION(lhs=DAE.CREF(componentRef=cr), rhs=e, source=source)::rest guard not BaseHashTable.hasKey(cr, iHt)
3155 algorithm
3156 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3157 ✗ ht := BaseHashTable.add((cr, (e, source)), iHt);
3158 ✗ then
3159 lowerWhenIfEqnsElse(rest, functionTree, ht);
3160 case DAE.ARRAY_EQUATION(exp=DAE.CREF(componentRef=cr), array=e, source=source)::rest guard not BaseHashTable.hasKey(cr, iHt)
3161 algorithm
3162 ✗ false := Expression.expHasCrefNoPreorDer(e, cr);
3163 ✗ ht := BaseHashTable.add((cr, (e, source)), iHt);
3164 ✗ then
3165 lowerWhenIfEqnsElse(rest, functionTree, ht);
3166 case DAE.IF_EQUATION(condition1=expl, equations2=eqnslst, equations3=eqns)::rest
3167 algorithm
3168 ✗ ht := lowerWhenIfEqnsElse(eqns, functionTree, iHt);
3169 ✗ ht := lowerWhenIfEqns(listReverse(expl), listReverse(eqnslst), functionTree, ht);
3170 ✗ then
3171 lowerWhenIfEqnsElse(rest, functionTree, ht);
3172 // collected into a when-algorithm by lowerWhenEqnStmts
3173 1 case DAE.NORETCALL()::rest then lowerWhenIfEqnsElse(rest, functionTree, iHt);
3174 ✗ case DAE.ASSERT()::rest then lowerWhenIfEqnsElse(rest, functionTree, iHt);
3175 ✗ case DAE.TERMINATE()::rest then lowerWhenIfEqnsElse(rest, functionTree, iHt);
3176 ✗ case DAE.REINIT()::rest then lowerWhenIfEqnsElse(rest, functionTree, iHt);
3177 end match;
3178 end lowerWhenIfEqnsElse;
3179
3180 protected function mergeWhenEqns
3181 " merges the true part end the elsewhen part of a set of when equations.
3182 For each equation in trueEqnList, find an equation in elseEqnList solving
3183 the same variable and put it in the else elseWhenPart of the first equation."
3184 input list<BackendDAE.Equation> trueEqnList "List of equations in the true part of the when clause.";
3185 input list<BackendDAE.Equation> elseEqnList "List of equations in the elsewhen part of the when clause.";
3186 input list<BackendDAE.Equation> inEquationLst;
3187 output list<BackendDAE.Equation> outEquationLst;
3188 algorithm
3189 outEquationLst := matchcontinue (trueEqnList, elseEqnList, inEquationLst)
3190 local
3191 DAE.Exp cond;
3192 BackendDAE.Equation res, inEqn;
3193 list<BackendDAE.Equation> trueEqns, elseEqnsRest, result;
3194 DAE.ElementSource source;
3195 Integer size;
3196 BackendDAE.EquationAttributes attr;
3197 list<BackendDAE.WhenOperator> whenStmtLst;
3198 BackendDAE.WhenEquation whenEq, whenEqRes;
3199 Option<BackendDAE.WhenEquation> whenElsePart;
3200 Boolean added;
3201
3202 case ({}, {}, _)
3203 then inEquationLst;
3204
3205 case (_, {}, {})
3206 then trueEqnList;
3207
3208 case ({}, _, {})
3209 then elseEqnList;
3210
3211 case ({}, _, _)
3212 ✗ then listAppend(inEquationLst, elseEqnList);
3213
3214 case (_, {}, _)
3215 ✗ then listAppend(inEquationLst, trueEqnList);
3216
3217 case ((inEqn as BackendDAE.WHEN_EQUATION(size=size, whenEquation=(whenEq as BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst = whenStmtLst, elsewhenPart=whenElsePart)), source=source, attr=attr))::trueEqns, _, _)
3218 algorithm
3219 //print(" Start mergeWhen: \n" + BackendDump.equationString(inEqn) + "\n");
3220 result := inEquationLst;
3221 elseEqnsRest := {};
3222 added := false;
3223
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 8 times.
17 for eqn in elseEqnList loop
3224 //print(" check when equation: \n" + BackendDump.equationString(eqn) + "\n");
3225 () := match eqn
3226 local
3227 BackendDAE.WhenEquation eq;
3228 list<BackendDAE.WhenOperator> whenStmtLst2;
3229 case BackendDAE.WHEN_EQUATION(whenEquation=eq as BackendDAE.WHEN_STMTS(whenStmtLst=whenStmtLst2) ) algorithm
3230
4/5
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 9 times.
18 for elem in whenStmtLst loop
3231 () := match elem
3232 local
3233 DAE.ComponentRef crleft;
3234 DAE.Exp eleft;
3235 case BackendDAE.ASSIGN(left=eleft) algorithm
3236
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for stmt in whenStmtLst2 loop
3237 () := matchcontinue stmt
3238 local
3239 DAE.Exp eleft2;
3240 case BackendDAE.ASSIGN(left=eleft2) algorithm
3241
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 7 times.
8 true := ExpressionBasics.expEqual(eleft, eleft2);
3242 //print(" added when else case: \n" + BackendDump.whenEquationString(eq, true) + "\n");
3243 7 whenEqRes := BackendEquation.setWhenElsePart(whenEq, eq);
3244 7 res := BackendDAE.WHEN_EQUATION(size, whenEqRes, source, attr);
3245 result := res::result;
3246 added := true;
3247 then ();
3248 else algorithm
3249 elseEqnsRest := eqn::elseEqnsRest;
3250 then ();
3251 end matchcontinue;
3252 end for;
3253 then ();
3254 case BackendDAE.REINIT(stateVar=crleft) algorithm
3255 ✗ for stmt in whenStmtLst2 loop
3256 () := matchcontinue stmt
3257 local
3258 DAE.ComponentRef crleft2;
3259 case BackendDAE.REINIT(stateVar=crleft2) algorithm
3260 ✗ true := ComponentReferenceBasics.crefEqualNoStringCompare(crleft, crleft2);
3261 //print(" added when else case: \n" + BackendDump.whenEquationString(eq, true) + "\n");
3262 ✗ whenEqRes := BackendEquation.setWhenElsePart(whenEq, eq);
3263 ✗ res := BackendDAE.WHEN_EQUATION(size, whenEqRes, source, attr);
3264 result := res::result;
3265 added := true;
3266 then ();
3267 else algorithm
3268 elseEqnsRest := eqn::elseEqnsRest;
3269 then ();
3270 end matchcontinue;
3271 end for;
3272 then ();
3273 else algorithm
3274 1 whenEqRes := BackendEquation.setWhenElsePart(whenEq, eq);
3275 1 res := BackendDAE.WHEN_EQUATION(size, whenEqRes, source, attr);
3276 result := res::result;
3277 added := true;
3278 then ();
3279 end match;
3280 end for;
3281 then ();
3282 else algorithm
3283 ✗ res := BackendDAE.WHEN_EQUATION(size, BackendDAE.WHEN_STMTS(cond, whenStmtLst, whenElsePart), source, attr);
3284 result := res::result;
3285 then ();
3286 end match;
3287 end for;
3288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if not added then
3289 result := inEqn::result;
3290 end if;
3291 //print("Result: :\n");
3292 //BackendDump.printEquationList(result);
3293 8 result := mergeWhenEqns(trueEqns, elseEqnsRest, result);
3294 then result;
3295
3296 else algorithm
3297 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"BackendDAECreate.mergeWhenEqns: Error in mergeWhenEqns."});
3298 ✗ then fail();
3299 end matchcontinue;
3300 end mergeWhenEqns;
3301
3302 protected function lowerTupleAssignment
3303 "Used by lower2 to split a tuple-tuple assignment into one equation for each
3304 tuple-element"
3305 input list<DAE.Exp> target_expl;
3306 input list<DAE.Exp> source_expl;
3307 input DAE.ElementSource inEq_source;
3308 input AvlTreePathFunction.Tree funcs;
3309 input list<BackendDAE.Equation> iEqns;
3310 output list<BackendDAE.Equation> oEqns;
3311 algorithm
3312 oEqns := match(target_expl, source_expl)
3313 local
3314 DAE.Exp target, source;
3315 list<DAE.Exp> rest_targets, rest_sources;
3316 list<BackendDAE.Equation> eqns;
3317 DAE.ElementSource eq_source;
3318
3319 case ({}, {}) then iEqns;
3320 // skip CREF(WILD())
3321 case (DAE.CREF(componentRef = DAE.WILD())::rest_targets, _::rest_sources)
3322 ✗ then
3323 lowerTupleAssignment(rest_targets, rest_sources, inEq_source, funcs, iEqns);
3324 // case for complex equations, array equations and equations
3325 case (target::rest_targets, source::rest_sources)
3326 algorithm
3327 ✗ (DAE.EQUALITY_EXPS(target,source), eq_source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.EQUALITY_EXPS(target,source),inEq_source);
3328 ✗ eqns := lowerExtendedRecordEqn(target, source, inEq_source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN, funcs, iEqns);
3329 ✗ then
3330 lowerTupleAssignment(rest_targets, rest_sources, eq_source, funcs, eqns);
3331 end match;
3332 end lowerTupleAssignment;
3333
3334 /*
3335 * lower algorithms
3336 */
3337
3338 protected function lowerAlgorithm
3339 "Helper function to lower2.
3340 Transforms a DAE.Element to BackEnd.ALGORITHM.
3341 NOTE: inCrefExpansionStrategy is needed if we translate equations to algorithms as
3342 we should not expand array crefs to full dimensions in that case because that
3343 is wrong. Expansion of array crefs to full dimensions SHOULD HAPPEN ONLY IN REAL FULL ALGORITHMS!"
3344 input DAE.Element inElement;
3345 input AvlTreePathFunction.Tree functionTree;
3346 input list<BackendDAE.Equation> inEquations;
3347 input list<BackendDAE.Equation> inREquations;
3348 input list<BackendDAE.Equation> inIEquations;
3349 input DAE.Expand inCrefExpansion "this is needed if we translate equations to algorithms as we should not expand array crefs to full dimensions in that case";
3350 input Boolean inInitialization;
3351 output list<BackendDAE.Equation> outEquations;
3352 output list<BackendDAE.Equation> outREquations;
3353 output list<BackendDAE.Equation> outIEquations;
3354 algorithm
3355 (outEquations, outREquations, outIEquations) := matchcontinue inElement
3356 local
3357 DAE.Exp cond, msg, level,e;
3358 DAE.Algorithm alg;
3359 DAE.ElementSource source;
3360 Integer size;
3361 list<DAE.ComponentRef> crefLst;
3362 String str;
3363 list<BackendDAE.Equation> eqns, reqns, ieqns;
3364 BackendDAE.EquationAttributes eqAttributes = if inInitialization then BackendDAE.EQ_ATTR_DEFAULT_INITIAL else BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC;
3365
3366 // skip empty algorithms
3367 case DAE.ALGORITHM(algorithm_=DAE.ALGORITHM_STMTS(statementLst={}))
3368 then (inEquations, inREquations, inIEquations);
3369
3370 // skip empty initial algorithms
3371 case DAE.INITIALALGORITHM(algorithm_=DAE.ALGORITHM_STMTS(statementLst={}))
3372 then (inEquations, inREquations, inIEquations);
3373
3374 case DAE.ALGORITHM(algorithm_=alg, source=source) algorithm
3375 // calculate the size of the algorithm by collecting the left hand sites of the statemens
3376 224 crefLst := CheckModel.checkAndGetAlgorithmOutputs(alg, source, inCrefExpansion);
3377 224 size := listLength(crefLst);
3378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
224 if inInitialization then
3379 ✗ ieqns := BackendDAE.ALGORITHM(size, alg, source, inCrefExpansion, eqAttributes) :: inIEquations;
3380 eqns := inEquations;
3381 reqns := inREquations;
3382 else
3383
2/2
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 6 times.
224 if size > 0 then
3384 218 eqns := BackendDAE.ALGORITHM(size, alg, source, inCrefExpansion, eqAttributes) :: inEquations;
3385 reqns := inREquations;
3386 else
3387 eqns := inEquations;
3388 6 reqns := BackendDAE.ALGORITHM(size, alg, source, inCrefExpansion, eqAttributes) :: inREquations;
3389 end if;
3390 ieqns := inIEquations;
3391 end if;
3392 then (eqns, reqns, ieqns);
3393
3394 case DAE.INITIALALGORITHM(algorithm_=alg, source=source) algorithm
3395 // calculate the size of the algorithm by collecting the left hand sites of the statemens
3396 61 crefLst := CheckModel.checkAndGetAlgorithmOutputs(alg, source, inCrefExpansion);
3397 61 size := listLength(crefLst);
3398 61 then (inEquations, inREquations, BackendDAE.ALGORITHM(size, alg, source, inCrefExpansion, eqAttributes)::inIEquations);
3399
3400 // skip asserts with condition=true
3401 case DAE.ASSERT(condition=DAE.BCONST(true))
3402 then (inEquations, inREquations, inIEquations);
3403
3404 case DAE.INITIAL_ASSERT(condition=DAE.BCONST(true))
3405 then (inEquations, inREquations, inIEquations);
3406
3407 case DAE.ASSERT(condition=cond, message=msg, level=level, source=source) algorithm
3408 2050 BackendDAEUtil.checkAssertCondition(cond, msg, level, ElementSource.getElementSourceFileInfo(source));
3409 4098 alg := DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond, msg, level, source)});
3410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2049 times.
2049 if inInitialization then
3411 reqns := inREquations;
3412 ✗ ieqns := BackendDAE.ALGORITHM(0, alg, source, inCrefExpansion, eqAttributes)::inIEquations;
3413 else
3414 2049 reqns := BackendDAE.ALGORITHM(0, alg, source, inCrefExpansion, eqAttributes)::inREquations;
3415 ieqns := inIEquations;
3416 end if;
3417 then (inEquations, reqns, ieqns);
3418
3419 case DAE.INITIAL_ASSERT(condition=cond, message=msg, level=level, source=source) algorithm
3420 31 BackendDAEUtil.checkAssertCondition(cond, msg, level, ElementSource.getElementSourceFileInfo(source));
3421 62 alg := DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond, msg, level, source)});
3422 31 then (inEquations, inREquations, BackendDAE.ALGORITHM(0, alg, source, inCrefExpansion, BackendDAE.EQ_ATTR_DEFAULT_INITIAL)::inIEquations);
3423
3424 case DAE.TERMINATE(message=msg, source=source)
3425 ✗ then (inEquations, BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg, source)}), source, inCrefExpansion, eqAttributes)::inREquations, inIEquations);
3426
3427 case DAE.INITIAL_TERMINATE(message=msg, source=source)
3428 ✗ then (inEquations, inREquations, BackendDAE.ALGORITHM(0, DAE.ALGORITHM_STMTS({DAE.STMT_TERMINATE(msg, source)}), source, inCrefExpansion, eqAttributes)::inIEquations);
3429
3430 case DAE.NORETCALL(exp=e, source=source) algorithm
3431 98 alg := DAE.ALGORITHM_STMTS({DAE.STMT_NORETCALL(e, source)});
3432 49 then (inEquations, BackendDAE.ALGORITHM(0, alg, source, inCrefExpansion, eqAttributes)::inREquations, inIEquations);
3433
3434 case DAE.INITIAL_NORETCALL(exp=e, source=source) algorithm
3435 2 alg := DAE.ALGORITHM_STMTS({DAE.STMT_NORETCALL(e, source)});
3436 1 then (inEquations, inREquations, BackendDAE.ALGORITHM(0, alg, source, inCrefExpansion, eqAttributes)::inIEquations);
3437
3438 else algorithm
3439 // only report error if no other error is in the queue!
3440
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1 0 := Error.getNumErrorMessages();
3441 ✗ str := "BackendDAECreate.lowerAlgorithm failed for:\n" + DAEDump.dumpElementsStr({inElement});
3442 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, ElementSource.getElementSourceFileInfo(ElementSource.getElementSource(inElement)));
3443 ✗ then fail();
3444 end matchcontinue;
3445 end lowerAlgorithm;
3446
3447 /*
3448 * alias Equations
3449 */
3450
3451 protected function handleAliasEquations
3452 "author Frenkel TUD 2012-09"
3453 input list<DAE.Element> iAliasEqns;
3454 input BackendDAE.Variables iVars;
3455 input BackendDAE.Variables inGlobalKnownVars;
3456 input BackendDAE.Variables iExtVars;
3457 input BackendDAE.Variables iAVars;
3458 input list<BackendDAE.Equation> iEqns;
3459 input list<BackendDAE.Equation> iREqns;
3460 input list<BackendDAE.Equation> iIEqns;
3461 output BackendDAE.Variables oVars;
3462 output BackendDAE.Variables outGlobalKnownVars;
3463 output BackendDAE.Variables oExtVars;
3464 output BackendDAE.Variables oAVars;
3465 output list<BackendDAE.Equation> oEqns;
3466 output list<BackendDAE.Equation> oREqns;
3467 output list<BackendDAE.Equation> oIEqns;
3468 algorithm
3469 (oVars, outGlobalKnownVars, oExtVars, oAVars, oEqns, oREqns, oIEqns) :=
3470 match iAliasEqns
3471 local
3472 BackendDAE.Variables vars, globalKnownVars, extvars, avars;
3473 list<BackendDAE.Equation> eqns, reqns, ieqns;
3474 1095 case {} then (iVars, inGlobalKnownVars, iExtVars, iAVars, iEqns, iREqns, iIEqns);
3475 case _
3476 algorithm
3477 ✗ (vars, globalKnownVars, extvars, avars, eqns, reqns, ieqns) := handleAliasEquations1(iAliasEqns, iVars, inGlobalKnownVars, iExtVars, iAVars, iEqns, iREqns, iIEqns);
3478 then
3479 (vars, globalKnownVars, extvars, avars, eqns, reqns, ieqns);
3480 end match;
3481 end handleAliasEquations;
3482
3483 protected function handleAliasEquations1
3484 "author Frenkel TUD 2012-09"
3485 input list<DAE.Element> iAliasEqns;
3486 input BackendDAE.Variables iVars;
3487 input BackendDAE.Variables inGlobalKnownVars;
3488 input BackendDAE.Variables iExtVars;
3489 input BackendDAE.Variables iAVars;
3490 input list<BackendDAE.Equation> iEqns;
3491 input list<BackendDAE.Equation> iREqns;
3492 input list<BackendDAE.Equation> iIEqns;
3493 output BackendDAE.Variables oVars;
3494 output BackendDAE.Variables outGlobalKnownVars;
3495 output BackendDAE.Variables oExtVars;
3496 output BackendDAE.Variables oAVars;
3497 output list<BackendDAE.Equation> oEqns;
3498 output list<BackendDAE.Equation> oREqns;
3499 output list<BackendDAE.Equation> oIEqns;
3500 protected
3501 BackendVarTransform.VariableReplacements repl;
3502 algorithm
3503 ✗ repl := BackendVarTransform.emptyReplacements();
3504 // get alias vars and replacements
3505 ✗ (oVars, outGlobalKnownVars, oExtVars, oAVars, repl, oEqns) := handleAliasEquations2(iAliasEqns, iVars, inGlobalKnownVars, iExtVars, iAVars, repl, iEqns);
3506 // replace alias bindings
3507 ✗ (oAVars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(oAVars, replaceAliasVarTraverser, repl);
3508 // compress vars array
3509 ✗ oVars := BackendVariable.rehashVariables(oVars);
3510 // perform replacements
3511 ✗ (oEqns, _) := BackendVarTransform.replaceEquations(oEqns, repl, NONE());
3512 ✗ (oREqns, _) := BackendVarTransform.replaceEquations(iREqns, repl, NONE());
3513 ✗ (oIEqns, _) := BackendVarTransform.replaceEquations(iIEqns, repl, NONE());
3514 end handleAliasEquations1;
3515
3516 protected function replaceAliasVarTraverser
3517 input BackendDAE.Var inVar;
3518 input BackendVarTransform.VariableReplacements inRepl;
3519 output BackendDAE.Var outVar;
3520 output BackendVarTransform.VariableReplacements repl;
3521 algorithm
3522 (outVar,repl) := matchcontinue (inVar,inRepl)
3523 local
3524 BackendDAE.Var v, v1;
3525 DAE.Exp e, e1;
3526 Boolean b;
3527 case (v as BackendDAE.VAR(bindExp=SOME(e)), repl)
3528 algorithm
3529 ✗ (e1, true) := BackendVarTransform.replaceExp(e, repl, NONE());
3530 ✗ b := Expression.isConst(e1);
3531 ✗ v1 := if not b then BackendVariable.setBindExp(v, SOME(e1)) else v;
3532 then (v1, repl);
3533 else (inVar,inRepl);
3534 end matchcontinue;
3535 end replaceAliasVarTraverser;
3536
3537 protected function handleAliasEquations2
3538 "author Frenkel TUD 2012-09"
3539 input list<DAE.Element> iAliasEqns;
3540 input BackendDAE.Variables iVars;
3541 input BackendDAE.Variables inGlobalKnownVars;
3542 input BackendDAE.Variables iExtVars;
3543 input BackendDAE.Variables iAVars;
3544 input BackendVarTransform.VariableReplacements iRepl;
3545 input list<BackendDAE.Equation> iEqns;
3546 output BackendDAE.Variables oVars;
3547 output BackendDAE.Variables outGlobalKnownVars;
3548 output BackendDAE.Variables oExtVars;
3549 output BackendDAE.Variables oAVars;
3550 output BackendVarTransform.VariableReplacements oRepl;
3551 output list<BackendDAE.Equation> oEqns;
3552 algorithm
3553 (oVars, outGlobalKnownVars, oExtVars, oAVars, oRepl, oEqns) := match iAliasEqns
3554 local
3555 BackendDAE.Variables vars, globalKnownVars, extvars, avars;
3556 list<DAE.Element> aliaseqns;
3557 BackendVarTransform.VariableReplacements repl;
3558 DAE.ComponentRef cr1, cr2;
3559 DAE.ElementSource source;
3560 list<BackendDAE.Equation> eqns;
3561 DAE.Exp ecr1, ecr2;
3562 case {} then (iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3563 case DAE.EQUEQUATION(cr1=cr1, cr2=cr2, source=source)::aliaseqns
3564 algorithm
3565 // perform replacements
3566 ✗ ecr1 := Expression.crefExp(cr1);
3567 ✗ (ecr1, _) := BackendVarTransform.replaceExp(ecr1, iRepl, NONE());
3568 ✗ ecr2 := Expression.crefExp(cr2);
3569 ✗ (ecr2, _) := BackendVarTransform.replaceExp(ecr2, iRepl, NONE());
3570 // select alias
3571 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAlias(ecr1, ecr2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3572 // next
3573 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := handleAliasEquations2(aliaseqns, vars, globalKnownVars, extvars, avars, repl, eqns);
3574 then
3575 (vars, globalKnownVars, extvars, avars, repl, eqns);
3576 end match;
3577 end handleAliasEquations2;
3578
3579 protected function selectAlias
3580 input DAE.Exp exp1;
3581 input DAE.Exp exp2;
3582 input DAE.ElementSource source;
3583 input BackendDAE.Variables iVars;
3584 input BackendDAE.Variables inGlobalKnownVars;
3585 input BackendDAE.Variables iExtVars;
3586 input BackendDAE.Variables iAVars;
3587 input BackendVarTransform.VariableReplacements iRepl;
3588 input list<BackendDAE.Equation> iEqns;
3589 output BackendDAE.Variables oVars;
3590 output BackendDAE.Variables outGlobalKnownVars;
3591 output BackendDAE.Variables oExtVars;
3592 output BackendDAE.Variables oAVars;
3593 output BackendVarTransform.VariableReplacements oRepl;
3594 output list<BackendDAE.Equation> oEqns;
3595 algorithm
3596 (oVars, outGlobalKnownVars, oExtVars, oAVars, oRepl, oEqns) := matchcontinue (exp1, exp2)
3597 local
3598 BackendDAE.Variables vars, globalKnownVars, extvars, avars;
3599 BackendVarTransform.VariableReplacements repl;
3600 list<BackendDAE.Equation> eqns;
3601 DAE.ComponentRef cr1, cr2;
3602 list<DAE.Exp> explst1, explst2;
3603 list<list<DAE.Exp>> explstlst1, explstlst2;
3604 list<DAE.ComponentRef> crefs1, crefs2;
3605 DAE.Dimensions dims1, dims2;
3606 Integer arrayTyp1, arrayTyp2, i1, i2;
3607 BackendDAE.Var v1, v2;
3608 // array array case
3609 case (DAE.ARRAY(array=explst1), DAE.ARRAY(array=explst2))
3610 algorithm
3611 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3612 then
3613 (vars, globalKnownVars, extvars, avars, repl, eqns);
3614 // cref-array array case
3615 case (DAE.CREF(componentRef=cr1, ty=DAE.T_ARRAY(dims = dims1)), DAE.ARRAY(array=explst2))
3616 algorithm
3617 ✗ crefs1 := ComponentReference.expandArrayCref(cr1, dims1);
3618 ✗ explst1 := List.map(crefs1, Expression.crefExp);
3619 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3620 then
3621 (vars, globalKnownVars, extvars, avars, repl, eqns);
3622 // array cref-array case
3623 case (DAE.ARRAY(array=explst1), DAE.CREF(componentRef=cr2, ty=DAE.T_ARRAY(dims = dims2)))
3624 algorithm
3625 ✗ crefs2 := ComponentReference.expandArrayCref(cr2, dims2);
3626 ✗ explst2 := List.map(crefs2, Expression.crefExp);
3627 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3628 then
3629 (vars, globalKnownVars, extvars, avars, repl, eqns);
3630 // cref-array cref-array case
3631 case (DAE.CREF(componentRef=cr1, ty=DAE.T_ARRAY(dims = dims1)), DAE.CREF(componentRef=cr2, ty=DAE.T_ARRAY(dims = dims2)))
3632 algorithm
3633 ✗ crefs1 := ComponentReference.expandArrayCref(cr1, dims1);
3634 ✗ explst1 := List.map(crefs1, Expression.crefExp);
3635 ✗ crefs2 := ComponentReference.expandArrayCref(cr2, dims2);
3636 ✗ explst2 := List.map(crefs2, Expression.crefExp);
3637 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3638 then
3639 (vars, globalKnownVars, extvars, avars, repl, eqns);
3640
3641 // matrix matrix case
3642 case (DAE.MATRIX(matrix=explstlst1), DAE.MATRIX(matrix=explstlst2))
3643 algorithm
3644 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(List.flatten(explstlst1), List.flatten(explstlst2), source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3645 then
3646 (vars, globalKnownVars, extvars, avars, repl, eqns);
3647 // scalar case
3648 case (DAE.CREF(componentRef=cr1), DAE.CREF(componentRef=cr2))
3649 algorithm
3650 ✗ (v1, i1, arrayTyp1) := getVar(cr1, iVars, inGlobalKnownVars, iExtVars);
3651 ✗ (v2, i2, arrayTyp2) := getVar(cr2, iVars, inGlobalKnownVars, iExtVars);
3652 ✗ (vars, globalKnownVars, extvars, avars, repl) := selectAliasVar(v1, i1, arrayTyp1, exp1, v2, i2, arrayTyp2, exp2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl);
3653 ✗ then
3654 (vars, globalKnownVars, extvars, avars, repl, iEqns);
3655 // complex
3656 case (_, _)
3657 algorithm
3658 // Create a list of crefs from names
3659 ✗ explst1 := Expression.splitRecord(exp1, Expression.typeof(exp1));
3660 ✗ explst2 := Expression.splitRecord(exp2, Expression.typeof(exp2));
3661 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3662 then
3663 (vars, globalKnownVars, extvars, avars, repl, eqns);
3664 // if no alias selectable add as equation
3665 case (_, _)
3666 ✗ then (iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, BackendDAE.EQUATION(exp1, exp2, source, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC)::iEqns);
3667 end matchcontinue;
3668 end selectAlias;
3669
3670 protected function getVar
3671 input DAE.ComponentRef cr;
3672 input BackendDAE.Variables iVars;
3673 input BackendDAE.Variables inGlobalKnownVars;
3674 input BackendDAE.Variables iExtVars;
3675 output BackendDAE.Var oVar;
3676 output Integer index;
3677 output Integer varrArray;
3678 algorithm
3679 (oVar, index, varrArray) := matchcontinue iExtVars
3680 local
3681 BackendDAE.Var v;
3682 Integer i;
3683 case _
3684 algorithm
3685 ✗ (v, i) := BackendVariable.getVarSingle(cr, iVars);
3686 ✗ then
3687 (v, i, 1);
3688 case _
3689 algorithm
3690 ✗ (v, i) := BackendVariable.getVarSingle(cr, inGlobalKnownVars);
3691 ✗ then
3692 (v, i, 2);
3693 case _
3694 algorithm
3695 ✗ (v, i) := BackendVariable.getVarSingle(cr, iExtVars);
3696 ✗ then
3697 (v, i, 3);
3698 end matchcontinue;
3699 end getVar;
3700
3701 protected function selectAliasLst
3702 input list<DAE.Exp> iexplst1;
3703 input list<DAE.Exp> iexplst2;
3704 input DAE.ElementSource source;
3705 input BackendDAE.Variables iVars;
3706 input BackendDAE.Variables inGlobalKnownVars;
3707 input BackendDAE.Variables iExtVars;
3708 input BackendDAE.Variables iAVars;
3709 input BackendVarTransform.VariableReplacements iRepl;
3710 input list<BackendDAE.Equation> iEqns;
3711 output BackendDAE.Variables oVars;
3712 output BackendDAE.Variables outGlobalKnownVars;
3713 output BackendDAE.Variables oExtVars;
3714 output BackendDAE.Variables oAVars;
3715 output BackendVarTransform.VariableReplacements oRepl;
3716 output list<BackendDAE.Equation> oEqns;
3717 algorithm
3718 (oVars, outGlobalKnownVars, oExtVars, oAVars, oRepl, oEqns) := match (iexplst1, iexplst2)
3719 local
3720 BackendDAE.Variables vars, globalKnownVars, extvars, avars;
3721 BackendVarTransform.VariableReplacements repl;
3722 list<BackendDAE.Equation> eqns;
3723 DAE.Exp e1, e2;
3724 list<DAE.Exp> explst1, explst2;
3725 case ({}, {})
3726 then
3727 (iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3728 case (e1::explst1, e2::explst2)
3729 algorithm
3730 // perform replacements
3731 ✗ (e1, _) := BackendVarTransform.replaceExp(e1, iRepl, NONE());
3732 ✗ (e2, _) := BackendVarTransform.replaceExp(e2, iRepl, NONE());
3733 // select alias
3734 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAlias(e1, e2, source, iVars, inGlobalKnownVars, iExtVars, iAVars, iRepl, iEqns);
3735 // next
3736 ✗ (vars, globalKnownVars, extvars, avars, repl, eqns) := selectAliasLst(explst1, explst2, source, vars, globalKnownVars, extvars, avars, repl, eqns);
3737 then
3738 (vars, globalKnownVars, extvars, avars, repl, eqns);
3739 end match;
3740 end selectAliasLst;
3741
3742 protected function selectAliasVar
3743 input BackendDAE.Var v1;
3744 input Integer index1;
3745 input Integer arrayIndx1;
3746 input DAE.Exp e1;
3747 input BackendDAE.Var v2;
3748 input Integer index2;
3749 input Integer arrayIndx2;
3750 input DAE.Exp e2;
3751 input DAE.ElementSource source;
3752 input BackendDAE.Variables iVars;
3753 input BackendDAE.Variables inGlobalKnownVars;
3754 input BackendDAE.Variables iExtVars;
3755 input BackendDAE.Variables iAVars;
3756 input BackendVarTransform.VariableReplacements iRepl;
3757 output BackendDAE.Variables oVars;
3758 output BackendDAE.Variables outGlobalKnownVars;
3759 output BackendDAE.Variables oExtVars;
3760 output BackendDAE.Variables oAVars;
3761 output BackendVarTransform.VariableReplacements oRepl;
3762 algorithm
3763 (oVars, outGlobalKnownVars, oExtVars, oAVars, oRepl) :=
3764 match (v1, arrayIndx1, v2, arrayIndx2)
3765 local
3766 BackendDAE.Variables vars, globalKnownVars, extvars, avars;
3767 BackendVarTransform.VariableReplacements repl;
3768 list<DAE.SymbolicOperation> ops;
3769 BackendDAE.Var var, avar;
3770 DAE.ComponentRef cr1, cr2, acr;
3771 Integer w1, w2, aindx;
3772 Boolean b, b1, b2;
3773 DAE.Exp e;
3774 // state variable
3775 case (BackendDAE.VAR(varKind=BackendDAE.STATE()), 1, BackendDAE.VAR(varName=cr2), 1)
3776 algorithm
3777 // check if replacable
3778 ✗ false := BackendVariable.isStateVar(v2);
3779 ✗ replaceableAlias(v2);
3780 // merge fixed, start, nominal
3781 ✗ var := BackendVariable.mergeAliasVars(v1, v2, false, inGlobalKnownVars);
3782 // setAliasType
3783 ✗ ops := ElementSource.getSymbolicTransformations(source);
3784 ✗ avar := BackendVariable.mergeVariableOperations(v2, DAE.SOLVED(cr2, e1)::ops);
3785 ✗ avar := BackendVariable.setBindExp(avar, SOME(e1));
3786 // remove from vars
3787 ✗ (vars, _) := BackendVariable.removeVar(index2, iVars);
3788 // add to alias
3789 ✗ avars := BackendVariable.addVar(avar, iAVars);
3790 // add to vars
3791 ✗ vars := BackendVariable.addVar(var, vars);
3792 // add replacement
3793 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr2, e1, NONE());
3794 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3795 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr2, " = ", e1, " found (4).\n");
3796 end if;
3797 then
3798 (vars, inGlobalKnownVars, iExtVars, avars, repl);
3799 // state variable
3800 case (BackendDAE.VAR(varName=cr1), 1, BackendDAE.VAR(varKind=BackendDAE.STATE()), 1)
3801 algorithm
3802 // check if replacable
3803 ✗ false := BackendVariable.isStateVar(v1);
3804 ✗ replaceableAlias(v1);
3805 // merge fixed, start, nominal
3806 ✗ var := BackendVariable.mergeAliasVars(v2, v1, false, inGlobalKnownVars);
3807 // setAliasType
3808 ✗ ops := ElementSource.getSymbolicTransformations(source);
3809 ✗ avar := BackendVariable.mergeVariableOperations(v1, DAE.SOLVED(cr1, e2)::ops);
3810 ✗ avar := BackendVariable.setBindExp(avar, SOME(e2));
3811 // remove from vars
3812 ✗ (vars, _) := BackendVariable.removeVar(index1, iVars);
3813 // add to alias
3814 ✗ avars := BackendVariable.addVar(avar, iAVars);
3815 // add to vars
3816 ✗ vars := BackendVariable.addVar(var, vars);
3817 // add replacement
3818 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr1, e2, NONE());
3819 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3820 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr1, " = ", e2, " found (4).\n");
3821 end if;
3822 then
3823 (vars, inGlobalKnownVars, iExtVars, avars, repl);
3824 // var var / state state
3825 case (BackendDAE.VAR(varName=cr1), 1, BackendDAE.VAR(varName=cr2), 1)
3826 algorithm
3827 // check if replacable
3828 ✗ b1 := BackendVariable.isStateVar(v1);
3829 ✗ b2 := BackendVariable.isStateVar(v2);
3830 ✗ true := boolEq(b1, b2);
3831 ✗ replaceableAlias(v1);
3832 ✗ replaceableAlias(v2);
3833 // calc wights
3834 ✗ w1 := BackendVariable.calcAliasKey(v1);
3835 ✗ w2 := BackendVariable.calcAliasKey(v2);
3836 b := intGt(w2, w1);
3837 // select alias
3838 ✗ (acr, avar, aindx, _, _, var, e) := if b then (cr2, v2, index2, e2, cr1, v1, e1) else (cr1, v1, index1, e1, cr2, v2, e2);
3839 // merge fixed, start, nominal
3840 ✗ var := BackendVariable.mergeAliasVars(var, avar, false, inGlobalKnownVars);
3841 // setAliasType
3842 ✗ ops := ElementSource.getSymbolicTransformations(source);
3843 ✗ avar := BackendVariable.mergeVariableOperations(avar, DAE.SOLVED(acr, e)::ops);
3844 ✗ avar := BackendVariable.setBindExp(avar, SOME(e));
3845 ✗ avar := if b1 then BackendVariable.setVarKind(avar, BackendDAE.DUMMY_STATE()) else avar;
3846 // remove from vars
3847 ✗ (vars, _) := BackendVariable.removeVar(aindx, iVars);
3848 // add to alias
3849 ✗ avars := BackendVariable.addVar(avar, iAVars);
3850 // add to vars
3851 ✗ vars := BackendVariable.addVar(var, vars);
3852 // add replacement
3853 ✗ repl := BackendVarTransform.addReplacement(iRepl, acr, e, NONE());
3854 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3855 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", acr, " = ", e, " found (4).\n");
3856 end if;
3857 then
3858 (vars, inGlobalKnownVars, iExtVars, avars, repl);
3859 // var/state parameter
3860 case (BackendDAE.VAR(varName=cr1), 1, BackendDAE.VAR(), 2)
3861 algorithm
3862 // check if replacable
3863 ✗ replaceableAlias(v1);
3864 // merge fixed, start, nominal
3865 ✗ var := BackendVariable.mergeAliasVars(v2, v1, false, inGlobalKnownVars);
3866 // setAliasType
3867 ✗ ops := ElementSource.getSymbolicTransformations(source);
3868 ✗ avar := BackendVariable.mergeVariableOperations(v1, DAE.SOLVED(cr1, e2)::ops);
3869 ✗ avar := BackendVariable.setBindExp(avar, SOME(e2));
3870 ✗ avar := if BackendVariable.isStateVar(v1) then BackendVariable.setVarKind(avar, BackendDAE.DUMMY_STATE()) else avar;
3871 // remove from vars
3872 ✗ (vars, _) := BackendVariable.removeVar(index1, iVars);
3873 // add to alias
3874 ✗ avars := BackendVariable.addVar(avar, iAVars);
3875 // add to globalKnownVars
3876 ✗ globalKnownVars := BackendVariable.addVar(var, inGlobalKnownVars);
3877 // add replacement
3878 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr1, e2, NONE());
3879 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3880 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr1, " = ", e2, " found (4).\n");
3881 end if;
3882 then
3883 (vars, globalKnownVars, iExtVars, avars, repl);
3884 // parameter var/state
3885 case (BackendDAE.VAR(), 2, BackendDAE.VAR(varName=cr2), 1)
3886 algorithm
3887 // check if replacable
3888 ✗ replaceableAlias(v2);
3889 // merge fixed, start, nominal
3890 ✗ var := BackendVariable.mergeAliasVars(v1, v2, false, inGlobalKnownVars);
3891 // setAliasType
3892 ✗ ops := ElementSource.getSymbolicTransformations(source);
3893 ✗ avar := BackendVariable.mergeVariableOperations(v2, DAE.SOLVED(cr2, e1)::ops);
3894 ✗ avar := BackendVariable.setBindExp(avar, SOME(e1));
3895 ✗ avar := if BackendVariable.isStateVar(v2) then BackendVariable.setVarKind(avar, BackendDAE.DUMMY_STATE()) else avar;
3896 // remove from vars
3897 ✗ (vars, _) := BackendVariable.removeVar(index2, iVars);
3898 // add to alias
3899 ✗ avars := BackendVariable.addVar(avar, iAVars);
3900 // add to globalKnownVars
3901 ✗ globalKnownVars := BackendVariable.addVar(var, inGlobalKnownVars);
3902 // add replacement
3903 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr2, e1, NONE());
3904 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3905 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr2, " = ", e1, " found (4).\n");
3906 end if;
3907 then
3908 (vars, globalKnownVars, iExtVars, avars, repl);
3909 // var/state extvar
3910 case (BackendDAE.VAR(varName=cr1), 1, BackendDAE.VAR(), 3)
3911 algorithm
3912 // check if replacable
3913 ✗ replaceableAlias(v1);
3914 // merge fixed, start, nominal
3915 ✗ var := BackendVariable.mergeAliasVars(v2, v1, false, inGlobalKnownVars);
3916 // setAliasType
3917 ✗ ops := ElementSource.getSymbolicTransformations(source);
3918 ✗ avar := BackendVariable.mergeVariableOperations(v1, DAE.SOLVED(cr1, e2)::ops);
3919 ✗ avar := BackendVariable.setBindExp(avar, SOME(e2));
3920 ✗ avar := if BackendVariable.isStateVar(v1) then BackendVariable.setVarKind(avar, BackendDAE.DUMMY_STATE()) else avar;
3921 // remove from vars
3922 ✗ (vars, _) := BackendVariable.removeVar(index1, iVars);
3923 // add to alias
3924 ✗ avars := BackendVariable.addVar(avar, iAVars);
3925 // add to extvars
3926 ✗ extvars := BackendVariable.addVar(var, iExtVars);
3927 // add replacement
3928 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr1, e2, NONE());
3929 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3930 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr1, " = ", e2, " found (4).\n");
3931 end if;
3932 then
3933 (vars, inGlobalKnownVars, extvars, avars, repl);
3934 // extvar var/state
3935 case (BackendDAE.VAR(), 3, BackendDAE.VAR(varName=cr2), 1)
3936 algorithm
3937 // check if replacable
3938 ✗ replaceableAlias(v2);
3939 // merge fixed, start, nominal
3940 ✗ var := BackendVariable.mergeAliasVars(v1, v2, false, inGlobalKnownVars);
3941 // setAliasType
3942 ✗ ops := ElementSource.getSymbolicTransformations(source);
3943 ✗ avar := BackendVariable.mergeVariableOperations(v2, DAE.SOLVED(cr2, e1)::ops);
3944 ✗ avar := BackendVariable.setBindExp(avar, SOME(e1));
3945 ✗ avar := if BackendVariable.isStateVar(v2) then BackendVariable.setVarKind(avar, BackendDAE.DUMMY_STATE()) else avar;
3946 // remove from vars
3947 ✗ (vars, _) := BackendVariable.removeVar(index2, iVars);
3948 // add to alias
3949 ✗ avars := BackendVariable.addVar(avar, iAVars);
3950 // add to globalKnownVars
3951 ✗ extvars := BackendVariable.addVar(var, iExtVars);
3952 // add replacement
3953 ✗ repl := BackendVarTransform.addReplacement(iRepl, cr2, e1, NONE());
3954 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
3955 ✗ BackendDump.debugStrCrefStrExpStr("Alias Equation ", cr2, " = ", e1, " found (4).\n");
3956 end if;
3957 then
3958 (vars, inGlobalKnownVars, extvars, avars, repl);
3959 end match;
3960 end selectAliasVar;
3961
3962 protected function replaceableAlias
3963 "author Frenkel TUD 2011-08
3964 check if the variable is a replaceable alias."
3965 input BackendDAE.Var var;
3966 algorithm
3967 () := match var
3968 case _
3969 algorithm
3970 ✗ false := BackendVariable.isVarOnTopLevelAndOutput(var);
3971 ✗ false := BackendVariable.isVarOnTopLevelAndInput(var);
3972 ✗ false := BackendVariable.varHasUncertainValueRefine(var) and BackendDAEUtil.isDataReconciliationEnabled();
3973 then
3974 ();
3975 end match;
3976 end replaceableAlias;
3977
3978 /*
3979 * other helping functions
3980 */
3981
3982 protected function detectImplicitDiscrete
3983 "This function updates the variable kind to discrete
3984 for variables set in when equations."
3985 input BackendDAE.Variables inVariables;
3986 input BackendDAE.Variables inGlobalKnownVars;
3987 input list<BackendDAE.Equation> inEquationLst;
3988 output BackendDAE.Variables outVariables;
3989 algorithm
3990 1095 outVariables := List.fold1(inEquationLst, detectImplicitDiscreteFold, inGlobalKnownVars, inVariables);
3991 end detectImplicitDiscrete;
3992
3993 protected function detectImplicitDiscreteFold
3994 "This function updates the variable kind to discrete
3995 for variables set in when equations."
3996 input BackendDAE.Equation inEquation;
3997 input BackendDAE.Variables inGlobalKnownVars;
3998 input BackendDAE.Variables inVariables;
3999 output BackendDAE.Variables outVariables;
4000 algorithm
4001 outVariables := matchcontinue inEquation
4002 local
4003 DAE.ComponentRef cr;
4004 list<DAE.ComponentRef> crefs;
4005 DAE.Exp e;
4006 list<BackendDAE.Var> vars;
4007 list<DAE.Statement> statementLst;
4008 case BackendDAE.WHEN_EQUATION(whenEquation = BackendDAE.WHEN_STMTS(whenStmtLst = {BackendDAE.ASSIGN(left=DAE.CREF(componentRef=cr))}))
4009 algorithm
4010 419 (vars, _) := BackendVariable.getVar(cr, inVariables);
4011 419 vars := List.map1(vars, BackendVariable.setVarKind, BackendDAE.DISCRETE());
4012 419 then BackendVariable.addVars(vars, inVariables);
4013 case BackendDAE.WHEN_EQUATION(whenEquation = BackendDAE.WHEN_STMTS(whenStmtLst = {BackendDAE.ASSIGN(left=e)}))
4014 algorithm
4015 6 crefs := Expression.getAllCrefs(e);
4016 6 crefs := List.flatten(List.map1(crefs,ComponentReference.expandCref,true));
4017 6 (vars, _) := BackendVariable.getVarLst(crefs, inVariables);
4018 6 vars := List.map1(vars, BackendVariable.setVarKind, BackendDAE.DISCRETE());
4019 6 then BackendVariable.addVars(vars, inVariables);
4020 case BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(statementLst = statementLst))
4021 218 then detectImplicitDiscreteAlgsStatemens(inVariables, inGlobalKnownVars, statementLst, false);
4022 else inVariables;
4023 end matchcontinue;
4024 end detectImplicitDiscreteFold;
4025
4026 protected function getVarsFromExp
4027 "This function collects all variables from an expression-list."
4028 input list<DAE.Exp> inExpLst;
4029 input BackendDAE.Variables inVariables;
4030 output list<BackendDAE.Var> outVarLst;
4031 algorithm
4032 outVarLst := matchcontinue(inExpLst, inVariables)
4033 local
4034 DAE.ComponentRef cref;
4035 list<DAE.Exp> expLst;
4036 BackendDAE.Variables variables;
4037 list<BackendDAE.Var> vars, varLst;
4038 case({}, _) then {};
4039 case(DAE.CREF(componentRef=cref)::expLst, variables) algorithm
4040 34 (vars, _) := BackendVariable.getVar(cref, variables);
4041 34 varLst := getVarsFromExp(expLst, variables);
4042 34 then listAppend(vars,varLst);
4043 case(_::expLst, variables) algorithm
4044 ✗ varLst := getVarsFromExp(expLst, variables);
4045 then varLst;
4046 end matchcontinue;
4047 end getVarsFromExp;
4048
4049 protected function detectImplicitDiscreteAlgsStatemens
4050 "This function updates the variable kind to discrete
4051 for variables set in when equations."
4052 input BackendDAE.Variables inVariables;
4053 input BackendDAE.Variables inGlobalKnownVars;
4054 input list<DAE.Statement> inStatementLst;
4055 input Boolean insideWhen "true if its called from a when statement";
4056 output BackendDAE.Variables outVariables;
4057 algorithm
4058 outVariables := matchcontinue (inVariables, inGlobalKnownVars, inStatementLst, insideWhen)
4059 local
4060 BackendDAE.Variables v, v_1, v_2, v_3, globalKnownVars;
4061 DAE.ComponentRef cr;
4062 list<DAE.Statement> xs, statementLst;
4063 list<BackendDAE.Var> vars;
4064 DAE.Statement statement;
4065 Boolean b;
4066 DAE.Type tp;
4067 DAE.Ident iteratorName;
4068 DAE.Exp e, iteratorExp;
4069 list<DAE.Exp> iteratorexps, expExpLst;
4070 list<DAE.Subscript> subs;
4071
4072 case (v, _, {}, _) then v;
4073 case (v, globalKnownVars, ((DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr)))::xs), true)
4074 algorithm
4075 312 (vars, _) := BackendVariable.getVar(cr, v);
4076 312 vars := List.map(vars, function BackendVariable.setVarKind(inVarKind=BackendDAE.DISCRETE()));
4077 312 v_1 := BackendVariable.addVars(vars, v);
4078 312 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4079 then
4080 v_2;
4081
4082 case (v, globalKnownVars, ((DAE.STMT_ASSIGN(exp1 = DAE.ASUB(exp = DAE.CREF(componentRef = cr), sub=subs)))::xs), true)
4083 algorithm
4084 ✗ cr := ComponentReference.subscriptCref(cr, subs);
4085 ✗ (vars, _) := BackendVariable.getVar(cr, v);
4086 ✗ vars := List.map1(vars, BackendVariable.setVarKind, BackendDAE.DISCRETE());
4087 ✗ v_1 := BackendVariable.addVars(vars, v);
4088 ✗ v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4089 then
4090 v_2;
4091
4092 case(v, globalKnownVars, (DAE.STMT_TUPLE_ASSIGN(expExpLst=expExpLst)::xs), true) algorithm
4093 9 vars := getVarsFromExp(expExpLst, v);
4094 9 vars := List.map1(vars, BackendVariable.setVarKind, BackendDAE.DISCRETE());
4095 9 v_1 := BackendVariable.addVars(vars, v);
4096 9 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4097 then v_2;
4098
4099 case (v, globalKnownVars, (DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef=cr))::xs), true)
4100 algorithm
4101 21 (vars, _) := BackendVariable.getVar(cr, v);
4102 21 vars := List.map1(vars, BackendVariable.setVarKind, BackendDAE.DISCRETE());
4103 21 v_1 := BackendVariable.addVars(vars, v);
4104 21 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4105 then
4106 v_2;
4107 case (v, globalKnownVars, (DAE.STMT_IF(statementLst = statementLst)::xs), true)
4108 algorithm
4109 46 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst, true);
4110 46 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4111 then
4112 v_2;
4113 case (v, globalKnownVars, (DAE.STMT_FOR(type_= tp, iter = iteratorName, range = e, statementLst = statementLst)::xs), true)
4114 algorithm
4115 /* use the range for the componentreferences */
4116 12 cr := ComponentReferenceBasics.makeCrefIdent(iteratorName, tp, {});
4117 12 iteratorExp := Expression.crefExp(cr);
4118 12 iteratorexps := BackendDAEUtil.extendRange(e, globalKnownVars);
4119 12 v_1 := detectImplicitDiscreteAlgsStatemensFor(iteratorExp, iteratorexps, v, globalKnownVars, statementLst, true);
4120 12 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4121 then
4122 v_2;
4123
4124 /*
4125 case (v, globalKnownVars, (DAE.STMT_PARFOR(type_= tp, iter = iteratorName, range = e, statementLst = statementLst, loopPrlVars=loopPrlVars)::xs), true)
4126 algorithm
4127 cr = ComponentReferenceBasics.makeCrefIdent(iteratorName, tp, {});
4128 iteratorExp = Expression.crefExp(cr);
4129 iteratorexps = BackendDAEUtil.extendRange(e, globalKnownVars);
4130 v_1 = detectImplicitDiscreteAlgsStatemensFor(iteratorExp, iteratorexps, v, globalKnownVars, statementLst, true);
4131 v_2 = detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, true);
4132 then
4133 v_2;
4134 */
4135
4136 case (v, globalKnownVars, (DAE.STMT_WHEN(statementLst=statementLst, elseWhen=NONE())::xs), _)
4137 algorithm
4138 124 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst, true);
4139 124 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, xs, false);
4140 then
4141 v_2;
4142 case (v, globalKnownVars, (DAE.STMT_WHEN(statementLst=statementLst, elseWhen=SOME(statement))::xs), _)
4143 algorithm
4144 51 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst, true);
4145 51 v_2 := detectImplicitDiscreteAlgsStatemens(v_1, globalKnownVars, {statement}, true);
4146 51 v_3 := detectImplicitDiscreteAlgsStatemens(v_2, globalKnownVars, xs, false);
4147 then
4148 v_3;
4149 case (v, globalKnownVars, (_::xs), b)
4150 algorithm
4151 417 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, xs, b);
4152 then
4153 v_1;
4154 end matchcontinue;
4155 end detectImplicitDiscreteAlgsStatemens;
4156
4157 protected function detectImplicitDiscreteAlgsStatemensFor
4158 input DAE.Exp inIteratorExp;
4159 input list<DAE.Exp> inExplst;
4160 input BackendDAE.Variables inVariables;
4161 input BackendDAE.Variables inGlobalKnownVars;
4162 input list<DAE.Statement> inStatementLst;
4163 input Boolean insideWhen "true if its called from a when statement";
4164 output BackendDAE.Variables outVariables;
4165 algorithm
4166 outVariables := matchcontinue (inIteratorExp, inExplst, inVariables, inGlobalKnownVars, inStatementLst, insideWhen)
4167 local
4168 BackendDAE.Variables v, v_1, v_2, globalKnownVars;
4169 list<DAE.Statement> statementLst, statementLst1;
4170 Boolean b;
4171 DAE.Exp e, ie;
4172 list<DAE.Exp> rest;
4173
4174 // case if the loop range can't extend, some vaiables
4175 case (_, {}, v, globalKnownVars, _, _)
4176 algorithm
4177 4 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, inStatementLst, true);
4178 then v_1;
4179 case (ie, e::{}, v, globalKnownVars, statementLst, _)
4180 algorithm
4181 8 (statementLst1, _) := DAEUtil.traverseDAEEquationsStmts(statementLst, Expression.replaceExpTpl, ((ie, e)));
4182 8 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst1, true);
4183 then
4184 v_1;
4185 case (ie, e::rest, v, globalKnownVars, statementLst, b)
4186 algorithm
4187 14 (statementLst1, _) := DAEUtil.traverseDAEEquationsStmts(statementLst, Expression.replaceExpTpl, ((ie, e)));
4188 14 v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst1, true);
4189 14 v_2 := detectImplicitDiscreteAlgsStatemensFor(ie, rest, v_1, globalKnownVars, statementLst, b);
4190 then
4191 v_2;
4192 case (ie, e::rest, v, globalKnownVars, statementLst, b)
4193 algorithm
4194 ✗ (statementLst1, _) := DAEUtil.traverseDAEEquationsStmts(statementLst, Expression.replaceExpTpl, ((ie, e)));
4195 ✗ v_1 := detectImplicitDiscreteAlgsStatemens(v, globalKnownVars, statementLst1, true);
4196 ✗ v_2 := detectImplicitDiscreteAlgsStatemensFor(ie, rest, v_1, globalKnownVars, statementLst, b);
4197 then
4198 v_2;
4199 case (_, _, _, _, _, _)
4200 algorithm
4201 ✗ print("BackendDAECreate.detectImplicitDiscreteAlgsStatemensFor failed \n");
4202 ✗ then
4203 fail();
4204 end matchcontinue;
4205 end detectImplicitDiscreteAlgsStatemensFor;
4206
4207 function lowerFunctions
4208 input output AvlTreePathFunction.Tree funcTree;
4209 algorithm
4210 1097 funcTree := AvlTreePathFunction.map(funcTree, deriveFunction);
4211 end lowerFunctions;
4212
4213 function deriveFunction
4214 input AvlTreePathFunction.Key key;
4215 input output AvlTreePathFunction.Value value;
4216 algorithm
4217 value := match value
4218 local
4219 DAE.Function fn;
4220 case SOME(fn as DAE.FUNCTION(functions = (DAE.FUNCTION_PARTIAL_DERIVATIVE()) :: _)) algorithm
4221 // TODO derive function-partial-derivatives
4222 ✗ Error.addSourceMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE,
4223 {"partial derivative of function", "use --newBackend flag."}, fn.source.info);
4224 ✗ then fail();
4225 else value;
4226 end match;
4227 end deriveFunction;
4228
4229 protected function renameFunctionParameter"renames the parameters in function calls. the function path is prepended to the parameter cref.
4230 This is used for the Cpp runtime for initializing parameters in function calls. The names have to be unique in case there are equally named parameters in different functions.
4231 author:Waurich TUD 2014-10"
4232 input AvlTreePathFunction.Tree fTreeIn;
4233 output AvlTreePathFunction.Tree fTreeOut;
4234 algorithm
4235 fTreeOut := matchcontinue fTreeIn
4236 local
4237 list<tuple<AvlTreePathFunction.Key,AvlTreePathFunction.Value>> funcLst;
4238 AvlTreePathFunction.Tree funcs;
4239 case _
4240 algorithm
4241 ✗ true := (stringEq(Flags.getConfigString(Flags.SIMCODE_TARGET),"Cpp"));
4242 ✗ funcLst := AvlTreePathFunction.toList(fTreeIn);
4243 ✗ funcLst := List.map(funcLst,renameFunctionParameter1);
4244 ✗ funcs := AvlTreePathFunction.addList(AvlTreePathFunction.new(), funcLst);
4245 then funcs;
4246 else
4247 then fTreeIn;
4248 end matchcontinue;
4249 end renameFunctionParameter;
4250
4251 protected function renameFunctionParameter1
4252 input tuple<AvlTreePathFunction.Key, AvlTreePathFunction.Value> funcIn;
4253 output tuple<AvlTreePathFunction.Key, AvlTreePathFunction.Value> funcOut;
4254 protected
4255 AvlTreePathFunction.Key key;
4256 AvlTreePathFunction.Value value;
4257 String pathName;
4258 DAE.Function fn;
4259 algorithm
4260 ✗ (key, value) := funcIn;
4261
4262 funcOut := match value
4263 case SOME(fn as DAE.FUNCTION())
4264 algorithm
4265 ✗ pathName := AbsynUtil.pathString(fn.path);
4266 ✗ pathName := Util.stringReplaceChar(pathName, ".", "_") + "_";
4267 ✗ fn.functions := list(renameFunctionParameter2(fn_def, pathName) for fn_def in fn.functions);
4268 ✗ then
4269 (key, SOME(fn));
4270
4271 else funcIn;
4272 end match;
4273 end renameFunctionParameter1;
4274
4275 protected function renameFunctionParameter2"
4276 author:Waurich TUD 2014-10"
4277 input DAE.FunctionDefinition funcIn;
4278 input String pathName;
4279 output DAE.FunctionDefinition funcOut;
4280 algorithm
4281 funcOut := matchcontinue funcIn
4282 local
4283 list<DAE.Element> body, params;
4284 list<DAE.ComponentRef> crefs, crefs_new;
4285 list<DAE.Exp> params_new;
4286 VarTransform.VariableReplacements repl;
4287 case DAE.FUNCTION_DEF(body=body)
4288 algorithm
4289 ✗ params := List.filterOnTrue(body,DAEUtil.isParameter);
4290 ✗ false := listEmpty(params);
4291 ✗ crefs := List.map(params,DAEUtil.varCref);
4292 ✗ crefs_new := List.map1r(crefs,ComponentReference.prependStringCref,pathName);
4293 ✗ params_new := List.map(crefs_new,Expression.crefExp);
4294 ✗ repl := VarTransform.emptyReplacements();
4295 ✗ repl := VarTransform.addReplacementLst(repl,crefs,params_new);
4296 ✗ (body,_) := DAEUtil.traverseDAEElementList(body,replaceParameters,repl);
4297 ✗ then DAE.FUNCTION_DEF(body);
4298 else
4299 then funcIn;
4300 end matchcontinue;
4301 end renameFunctionParameter2;
4302
4303 protected function replaceParameters"
4304 author:Waurich TUD 2014-10"
4305 input DAE.Exp inExp;
4306 input VarTransform.VariableReplacements replIn;
4307 output DAE.Exp outExp;
4308 output VarTransform.VariableReplacements replOut;
4309 algorithm
4310 replOut := replIn;
4311 ✗ (outExp,_) := VarTransform.replaceExp(inExp,replIn,NONE());
4312 end replaceParameters;
4313
4314 annotation(__OpenModelica_Interface="backend");
4315 end BackendDAECreate;
4316