Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 56.7% 750 / 0 / 1322
Functions: -% 0 / 1 / 1
Branches: 51.3% 391 / 0 / 762

OMCompiler/Compiler/BackEnd/RemoveSimpleEquations.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 RemoveSimpleEquations "
37 file: RemoveSimpleEquations.mo
38 package: RemoveSimpleEquations
39 description: RemoveSimpleEquations contains functions to remove simple equations.
40 Simple equations are either alias equations or time independent equations.
41 Alias equations can be simplified to 'a = b', 'a = -b' or 'a = not b'.
42 The package contains three main functions.
43 fastAcausal: to remove with a linear scaling with respect to the
44 number of equations in an acausal system as much as
45 possible simple equations.
46 allAcausal: to remove all simple equations in an acausal system
47 the function may needs a lots of time.
48 causal: to remove with a linear scaling with respect to the
49 number of equations in an causal system all
50 simple equations"
51
52 public import Absyn;
53 public import BackendDAE;
54 public import DAE;
55
56 protected
57 import AvlSetInt;
58 import BackendDAEUtil;
59 import BackendDump;
60 import BackendEquation;
61 import BackendVariable;
62 import BackendVarTransform;
63 import BaseHashTable;
64 import Ceval;
65 import ComponentReference;
66 import ComponentReferenceBasics;
67 import Debug;
68 import ElementSource;
69 import Error;
70 import EvaluateFunctions;
71 import Expression;
72 protected import ExpressionBasics;
73 import ExpressionSimplify;
74 import ExpressionSolve;
75 import Flags;
76 import GCExt;
77 import HashTableCrToCrEqLst;
78 import HashTableCrToExp;
79 import HashTableExpToIndex;
80 import List;
81 import SimCodeUtil;
82 import Types;
83 import UnorderedSet;
84 import Util;
85 import MetaModelica.Dangerous.listReverseInPlace;
86
87
88
89 protected type EquationSourceAndAttributes = tuple<DAE.ElementSource, BackendDAE.EquationAttributes> "eqnAttributes(source,EquationAttributes)";
90
91 protected
92 uniontype SimpleContainer
93 record ALIAS
94 DAE.ComponentRef cr1;
95 Boolean negatedCr1;
96 Integer i1;
97 DAE.ComponentRef cr2;
98 Boolean negatedCr2;
99 Integer i2;
100 EquationSourceAndAttributes eqnAttributes;
101 Integer visited;
102 end ALIAS;
103
104 record PARAMETERALIAS
105 DAE.ComponentRef unknowncr;
106 Boolean negatedCr1;
107 Integer i1;
108 DAE.ComponentRef paramcr;
109 Boolean negatedCr2;
110 Integer i2;
111 EquationSourceAndAttributes eqnAttributes;
112 Integer visited;
113 end PARAMETERALIAS;
114
115 record TIMEALIAS
116 DAE.ComponentRef cr1;
117 Boolean negatedCr1;
118 Integer i1;
119 DAE.ComponentRef cr2;
120 Boolean negatedCr2;
121 Integer i2;
122 EquationSourceAndAttributes eqnAttributes;
123 Integer visited;
124 end TIMEALIAS;
125
126 record TIMEINDEPENTVAR
127 DAE.ComponentRef cr;
128 Integer i;
129 DAE.Exp exp;
130 EquationSourceAndAttributes eqnAttributes;
131 Integer visited;
132 end TIMEINDEPENTVAR;
133 end SimpleContainer;
134
135 protected type AccTuple = tuple<BackendDAE.Variables, BackendDAE.Shared, list<BackendDAE.Equation>, list<SimpleContainer>, Integer, array<list<Integer>>, Boolean>;
136
137 protected type StartValues =
138 tuple<Option<DAE.StartOrigin>, list<tuple<Option<DAE.Exp>, DAE.ComponentRef>>>
139 "strongest origin seen so far, start values with that origin";
140
141 protected type VarSetAttributes =
142 tuple<
143 Boolean,
144 StartValues,
145 list<tuple<DAE.Exp, DAE.ComponentRef>>,
146 tuple<Option<DAE.Exp>,
147 Option<DAE.Exp>>,
148 Boolean
149 > "fixed, startvalues, nominal, (min, max), discrete";
150
151 protected constant VarSetAttributes EMPTYVARSETATTRIBUTES = (false, (NONE(), {}), {}, (NONE(), NONE()), false);
152
153 // =============================================================================
154 // Starting point for preOpt and postOpt removeSimpleEquations module
155 //
156 // =============================================================================
157
158 public function removeSimpleEquations "
159 This is the main function of 'remove simple equations' for both acausal and
160 causal systems."
161 input BackendDAE.BackendDAE inDAE;
162 output BackendDAE.BackendDAE outDAE;
163 protected
164 Boolean rebuilt;
165 algorithm
166
2/2
✓ Branch 1 taken 1060 times.
✓ Branch 2 taken 2841 times.
3901 if BackendDAEUtil.hasDAEMatching(inDAE) then
167 // This case performs "remove simple equations" on a causal system.
168 // Note: It is fine to do some substitutions in order to minimize SCCs, but
169 // alias/known variable vectors may not be touched.
170 outDAE := match Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS)
171 1060 case "default" then causal(inDAE);
172 ✗ case "causal" then causal(inDAE);
173 ✗ case "new" then performAliasEliminationBB(inDAE, findAliases=true);
174 else inDAE;
175 end match;
176
177 1060 (outDAE, rebuilt) := fixAliasVars(outDAE) "workaround for #3323";
178 1060 outDAE := fixAliasAndKnownVarsCausal(inDAE, outDAE, not rebuilt);
179 1060 outDAE := fixAliasVarsVariablity(outDAE) "workaround for #5673";
180 else
181 // This case performs "remove simple equations" on an acausal system.
182 outDAE := match Flags.getConfigString(Flags.REMOVE_SIMPLE_EQUATIONS)
183 2841 case "default" then fastAcausal(inDAE);
184 ✗ case "fastAcausal" then fastAcausal(inDAE);
185 ✗ case "allAcausal" then allAcausal(inDAE);
186 ✗ case "new" then performAliasEliminationBB(inDAE, true);
187 else inDAE;
188 end match;
189
190 2841 outDAE := fixAliasVars(outDAE) "workaround for #3323";
191 2841 outDAE := fixKnownVars(outDAE);
192 2841 outDAE := fixAliasVarsVariablity(outDAE) "workaround for #5673";
193 end if;
194 end removeSimpleEquations;
195
196 public function removeVerySimpleEquations "This is a very simple removeSimpleEquations, finding a few variables and removing them to speed up the rest of the backend"
197 input BackendDAE.BackendDAE inDAE;
198 output BackendDAE.BackendDAE outDAE;
199 algorithm
200 ✗ if BackendDAEUtil.hasDAEMatching(inDAE) then
201 ✗ Error.addInternalError("Cannot run removeVerySimpleEquations on a matched system (continuing anyway)", sourceInfo());
202 outDAE := inDAE;
203 else
204 ✗ outDAE := performAliasEliminationBB(inDAE, findAliases=true);
205 end if;
206 end removeVerySimpleEquations;
207
208 public function fixAliasVarsVariablity
209 " This is a workaround for #5673
210 This module traverses all alias variables and double-checks if the referenced alias variables variablitly
211 is parameter or not and changes variablilty of alias variable to BackendDAE.PARAM()."
212 input BackendDAE.BackendDAE inDAE;
213 output BackendDAE.BackendDAE outDAE;
214 protected
215 BackendDAE.Variables aliasVars, systvars, globalKnownVars;
216 DAE.Exp binding;
217 list<DAE.ComponentRef> crefs;
218 Boolean paramOrConst, const;
219 BackendDAE.Shared shared;
220 list<BackendDAE.Var> referencevar, tempreferencevar, knownVarList={}, aliasVarList={};
221 BackendDAE.Var tempvar;
222 algorithm
223 // only do this for FMUs
224
2/2
✓ Branch 1 taken 3682 times.
✓ Branch 2 taken 219 times.
3901 if not Flags.getConfigBool(Flags.BUILDING_FMU) then
225 outDAE := inDAE;
226 3682 return;
227 end if;
228
229 219 aliasVars := BackendDAEUtil.getAliasVars(inDAE);
230 219 systvars := BackendVariable.listVar(BackendVariable.equationSystemsVarsLst(inDAE.eqs));
231
232 //BackendDump.dumpVariables(aliasVars, "aliasVariable-Actual");
233
2/2
✓ Branch 1 taken 6177 times.
✓ Branch 2 taken 219 times.
6396 for var in BackendVariable.varList(aliasVars) loop
234 6177 binding := BackendVariable.varBindExp(var);
235 6177 crefs := Expression.getAllCrefs(binding);
236
237 // look up for the reference variable variablity
238 // check in shared.globalKnownVars if not found in orderedVars
239 referencevar := {};
240
2/2
✓ Branch 0 taken 6177 times.
✓ Branch 1 taken 6177 times.
12354 for cr in crefs loop
241 6177 tempreferencevar := getVarsHelper(cr, systvars); // first check in EqSystem.OrderedVars
242
2/2
✓ Branch 0 taken 3551 times.
✓ Branch 1 taken 2626 times.
6177 if listEmpty(tempreferencevar) then
243 3551 tempreferencevar := getVarsHelper(cr,inDAE.shared.globalKnownVars);
244 end if;
245 6177 referencevar := listAppend(tempreferencevar, referencevar);
246 end for;
247
248 // check list of referencevariable either PARAM() or CONST()
249
1/2
✓ Branch 0 taken 6177 times.
✗ Branch 1 not taken.
6177 if listEmpty(referencevar) then
250 paramOrConst := false;
251 const := false;
252 else
253 6177 paramOrConst := List.all(referencevar, BackendVariable.isParamOrConstant);
254 6177 const := List.all(referencevar, BackendVariable.isConst);
255 end if;
256
257 // remove the variable from aliasVarList and add it to knownVarList after changing it to PARAM()/CONST() and fixed=true
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6177 times.
6177 if const then
259 ✗ tempvar := BackendVariable.setVarKind(var,BackendDAE.CONST());
260 ✗ knownVarList := BackendVariable.setVarFixed(tempvar, true) :: knownVarList;
261 elseif paramOrConst then
262 598 tempvar := BackendVariable.setVarKind(var,BackendDAE.PARAM());
263 598 knownVarList := BackendVariable.setVarFixed(tempvar, true) :: knownVarList;
264 else
265 aliasVarList := var :: aliasVarList;
266 end if;
267 end for;
268
269 //BackendDump.dumpVarList(aliasVarList, "AfterChangingParameters");
270 // add the parameter dependent alias vars to Global known Vars after removing from aliasVarList
271 219 globalKnownVars := BackendVariable.mergeVariables(inDAE.shared.globalKnownVars, BackendVariable.listVar(knownVarList));
272
273 219 outDAE := BackendDAEUtil.setAliasVars(inDAE, BackendVariable.listVar(aliasVarList));
274 219 outDAE := BackendDAEUtil.setDAEGlobalKnownVars(outDAE, globalKnownVars);
275 end fixAliasVarsVariablity;
276
277 protected function getVarsHelper
278 input DAE.ComponentRef cr;
279 input BackendDAE.Variables vars;
280 output list<BackendDAE.Var> outVars;
281 algorithm
282 try
283 9728 (outVars, _) := BackendVariable.getVar(cr, vars);
284 else
285 // guard against failures
286 outVars := {};
287 end try;
288 end getVarsHelper;
289
290 protected function fixAliasVars "author: lochel
291 This is a workaround for #3323
292 TODO: Remove this once removeSimpleEquations is implemented properly.
293
294 This module traverses all alias variables and double-checks if they are alias or known variables."
295 input BackendDAE.BackendDAE inDAE;
296 output BackendDAE.BackendDAE outDAE;
297 output Boolean rebuilt = false "Whether the sets were rebuilt, which reverses the known variables.";
298 protected
299 BackendDAE.Variables aliasVars;
300 list<BackendDAE.Var> aliasVarList = {};
301 list<BackendDAE.Var> movedVars = {};
302 DAE.Exp binding;
303 algorithm
304 3901 aliasVars := BackendDAEUtil.getAliasVars(inDAE);
305
306
2/2
✓ Branch 1 taken 217845 times.
✓ Branch 2 taken 3901 times.
221746 for var in BackendVariable.varList(aliasVars) loop
307 217845 binding := BackendVariable.varBindExp(var);
308
2/2
✓ Branch 1 taken 1172 times.
✓ Branch 2 taken 216673 times.
217845 if Expression.isConst(binding) then
309 movedVars := var::movedVars;
310 else
311 aliasVarList := var::aliasVarList;
312 end if;
313 end for;
314
315
2/2
✓ Branch 0 taken 3793 times.
✓ Branch 1 taken 108 times.
3901 if listEmpty(movedVars) then
316 outDAE := inDAE;
317 3793 return;
318 end if;
319
320 108 outDAE := BackendDAEUtil.setAliasVars(inDAE, BackendVariable.listVar(aliasVarList));
321 108 outDAE := BackendDAEUtil.setDAEGlobalKnownVars(outDAE, BackendVariable.listVar(
322 listAppend(movedVars, BackendVariable.varList(BackendDAEUtil.getGlobalKnownVarsFromDAE(inDAE)))));
323 rebuilt := true;
324 end fixAliasVars;
325
326 protected function fixKnownVars "author: lochel
327 This is a workaround.
328 TODO: Remove this once removeSimpleEquations is implemented properly.
329
330 This module traverses all known variables and double-checks if they are known or not."
331 input output BackendDAE.BackendDAE dae;
332 protected
333 BackendDAE.EqSystem eqs;
334 BackendDAE.Variables globalKnownVars;
335 DAE.Exp binding;
336 list<BackendDAE.Equation> eqnList = {};
337 list<BackendDAE.Var> varList = {};
338 list<BackendDAE.Var> knownVarList = {};
339 list<DAE.ComponentRef> crlst;
340 algorithm
341 // Without local known variables no binding can depend on one.
342
2/2
✓ Branch 1 taken 2840 times.
✓ Branch 2 taken 1 time.
2841 if BackendVariable.varsSize(dae.shared.localKnownVars) == 0 then
343 2840 return;
344 end if;
345 1 globalKnownVars := dae.shared.globalKnownVars;
346
347
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 for var in BackendVariable.varList(globalKnownVars) loop
348 ✗ if BackendVariable.varHasBindExp(var) then
349 ✗ binding := BackendVariable.varBindExp(var);
350 ✗ (_, crlst) := Expression.traverseExpTopDown(binding, Expression.traversingComponentRefFinderNoPreDer, {});
351 ✗ if BackendDAEUtil.containAnyVar(crlst, dae.shared.localKnownVars) then
352 ✗ varList := BackendVariable.setBindExp(var, NONE())::varList;
353 ✗ eqnList := BackendDAE.EQUATION(BackendVariable.varExp(var), binding, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING)::eqnList;
354 else
355 knownVarList := var::knownVarList;
356 end if;
357 else
358 knownVarList := var::knownVarList;
359 end if;
360 end for;
361
362
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if not listEmpty(varList) then
363 ✗ eqs := BackendDAEUtil.createEqSystem(BackendVariable.listVar(varList), BackendEquation.listEquation(eqnList), {}, BackendDAE.UNSPECIFIED_PARTITION());
364 ✗ dae.eqs := eqs::dae.eqs;
365 end if;
366
367 1 dae := BackendDAEUtil.setDAEGlobalKnownVars(dae, BackendVariable.listVar(knownVarList));
368 end fixKnownVars;
369
370 protected function fixAliasAndKnownVarsCausal "author: lochel
371 TODO: Remove this once removeSimpleEquations is implemented properly.
372
373 This module moves back all newly introduced alias variables to the correct partition."
374 input BackendDAE.BackendDAE inDAE1 "original dae";
375 input BackendDAE.BackendDAE inDAE2 "transformed dae";
376 input Boolean visitReversed "Visit the known variables last to first.";
377 output BackendDAE.BackendDAE outDAE = inDAE2;
378 protected
379 list<BackendDAE.Var> knownVars;
380 BackendDAE.Variables aliasVars1, knownVars1;
381 BackendDAE.Variables aliasVars2, knownVars2;
382 list<BackendDAE.Var> aliasVarList = {};
383 list<BackendDAE.Var> knownVarList = {};
384 DAE.ComponentRef cref;
385 algorithm
386 1060 aliasVars1 := BackendDAEUtil.getAliasVars(inDAE1);
387 1060 aliasVars2 := BackendDAEUtil.getAliasVars(inDAE2);
388
389 1060 knownVars1 := BackendDAEUtil.getGlobalKnownVarsFromDAE(inDAE1);
390 1060 knownVars2 := BackendDAEUtil.getGlobalKnownVarsFromDAE(inDAE2);
391
392
2/2
✓ Branch 1 taken 107062 times.
✓ Branch 2 taken 1060 times.
108122 for var in BackendVariable.varList(aliasVars2) loop
393 107062 cref := BackendVariable.varCref(var);
394
2/2
✓ Branch 1 taken 5399 times.
✓ Branch 2 taken 101663 times.
107062 if not BackendVariable.existsVar(cref, aliasVars1, false) then
395 // put var back to the correct partition
396 5399 outDAE := fixAliasVarsCausal2(var, outDAE);
397 else
398 aliasVarList := var::aliasVarList;
399 end if;
400 end for;
401 1060 outDAE := BackendDAEUtil.setAliasVars(outDAE, BackendVariable.listVar(aliasVarList));
402
403 //BackendDump.dumpVarList(knownVarList, "knownVarList in");
404 // Placing a variable decides where the ones referring to it can go, so the
405 // partitioning depends on the order: visit them as fixAliasVars' rebuild
406 // would have ordered them.
407 1060 knownVars := BackendVariable.varList(knownVars2);
408
4/4
✓ Branch 0 taken 1030 times.
✓ Branch 1 taken 30 times.
✓ Branch 3 taken 183123 times.
✓ Branch 4 taken 1060 times.
185243 for var in (if visitReversed then listReverse(knownVars) else knownVars) loop
409 183123 cref := BackendVariable.varCref(var);
410
4/6
✓ Branch 1 taken 1743 times.
✓ Branch 2 taken 181380 times.
✓ Branch 4 taken 1743 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1743 times.
✗ Branch 8 not taken.
183123 if not BackendVariable.existsVar(cref, knownVars1, false) and
411 not (BackendVariable.isInput(var) or BackendVariable.isAlgebraicOldState(var)) then
412 // put var back to the correct partition
413 1743 outDAE := fixKnownVarsCausal2(var, outDAE);
414 else
415 knownVarList := var::knownVarList;
416 end if;
417 end for;
418 //BackendDump.dumpVarList(knownVarList, "knownVarList out");
419
2/2
✓ Branch 0 taken 1030 times.
✓ Branch 1 taken 30 times.
1060 outDAE := BackendDAEUtil.setDAEGlobalKnownVars(outDAE, BackendVariable.listVar(if visitReversed then listReverse(knownVarList) else knownVarList));
420 end fixAliasAndKnownVarsCausal;
421
422 protected function fixAliasVarsCausal2
423 input BackendDAE.Var inVar;
424 input BackendDAE.BackendDAE inDAE;
425 output BackendDAE.BackendDAE outDAE;
426 protected
427 DAE.Exp binding;
428 list<DAE.ComponentRef> rightCrefs;
429 BackendDAE.EqSystems eqs, eqs1 = {};
430 BackendDAE.Shared shared;
431 Boolean done=false;
432
433 BackendDAE.Var var;
434 BackendDAE.Equation eqn;
435
436 BackendDAE.Variables orderedVars "ordered Variables, only states and alg. vars";
437 BackendDAE.EquationArray orderedEqs "ordered Equations";
438 algorithm
439 try
440 5399 binding := BackendVariable.varBindExp(inVar);
441 5399 rightCrefs := Expression.getAllCrefs(binding);
442 5399 BackendDAE.DAE(eqs, shared) := inDAE;
443 5399 var := BackendVariable.setBindExp(inVar, NONE());
444 5399 var := BackendVariable.setVarFixed(var, false) "??? should we do this ???";
445 5399 eqn := BackendDAE.EQUATION(BackendVariable.varExp(var), binding, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
446
2/2
✓ Branch 0 taken 34663 times.
✓ Branch 1 taken 5399 times.
40062 for eq in eqs loop
447 34663 BackendDAE.EQSYSTEM(orderedVars=orderedVars, orderedEqs=orderedEqs) := eq;
448
2/2
✓ Branch 1 taken 4749 times.
✓ Branch 2 taken 29914 times.
34663 if BackendVariable.existsAnyVar(rightCrefs, orderedVars, false) then
449 4749 orderedVars := BackendVariable.addVar(var, orderedVars);
450 4749 orderedEqs := BackendEquation.add(eqn, orderedEqs);
451 4749 eqs1 := BackendDAEUtil.setEqSystEqs(BackendDAEUtil.setEqSystVars(eq, orderedVars), orderedEqs)::eqs1;
452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4749 times.
4749 false := done;
453 done := true;
454 else
455 eqs1 := eq::eqs1;
456 end if;
457 end for;
458
459 // if no partition was selected, create a new one
460
2/2
✓ Branch 0 taken 650 times.
✓ Branch 1 taken 4749 times.
5399 if not done then
461 650 eqs1 := BackendDAEUtil.createEqSystem( BackendVariable.listVar({var}), BackendEquation.listEquation({eqn}),
462 {}, BackendDAE.UNSPECIFIED_PARTITION() )::eqs1;
463 end if;
464 5399 outDAE := BackendDAE.DAE(listReverse(eqs1), shared);
465 //BackendDump.dumpVarList({inVar}, "fixAliasVarsCausal2 done for ...");
466 else
467 ✗ BackendDump.dumpVarList({inVar}, "fixAliasVarsCausal2 failed for ...");
468 ✗ Error.addCompilerError("fixAliasVarsCausal2 failed");
469 ✗ fail();
470 end try;
471 end fixAliasVarsCausal2;
472
473 protected function fixKnownVarsCausal2
474 input BackendDAE.Var inVar;
475 input BackendDAE.BackendDAE inDAE;
476 output BackendDAE.BackendDAE outDAE;
477 protected
478 DAE.Exp binding;
479 list<DAE.ComponentRef> rightCrefs;
480 BackendDAE.EqSystems eqs1 = {};
481 Boolean done=false;
482
483 BackendDAE.Var var;
484 BackendDAE.Equation eqn;
485
486 BackendDAE.Variables orderedVars "ordered Variables, only states and alg. vars";
487 BackendDAE.EquationArray orderedEqs "ordered Equations";
488 algorithm
489 try
490 1743 binding := BackendVariable.varBindExp(inVar);
491 1743 rightCrefs := Expression.getAllCrefs(binding);
492 1743 var := BackendVariable.setBindExp(inVar, NONE());
493 1743 eqn := BackendDAE.EQUATION(BackendVariable.varExp(var), binding, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
494
2/2
✓ Branch 0 taken 136836 times.
✓ Branch 1 taken 1743 times.
138579 for eq in inDAE.eqs loop
495 136836 BackendDAE.EQSYSTEM(orderedVars=orderedVars, orderedEqs=orderedEqs) := eq;
496
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 136836 times.
136836 if BackendVariable.existsAnyVar(rightCrefs, orderedVars, false) then
497 ✗ orderedVars := BackendVariable.addVar(var, orderedVars);
498 ✗ orderedEqs := BackendEquation.add(eqn, orderedEqs);
499 ✗ eqs1 := BackendDAEUtil.setEqSystEqs(BackendDAEUtil.setEqSystVars(eq, orderedVars), orderedEqs)::eqs1;
500 ✗ false := done;
501 done := true;
502 else
503 eqs1 := eq::eqs1;
504 end if;
505 end for;
506
507 // if no partition was selected, create a new one
508
1/2
✓ Branch 0 taken 1743 times.
✗ Branch 1 not taken.
1743 if not done then
509 1743 eqs1 := BackendDAEUtil.createEqSystem( BackendVariable.listVar({var}), BackendEquation.listEquation({eqn}),
510 {}, BackendDAE.UNSPECIFIED_PARTITION() )::eqs1;
511 end if;
512 1743 outDAE := BackendDAE.DAE(listReverse(eqs1), inDAE.shared);
513 else
514 ✗ BackendDump.dumpVarList({inVar}, "fixKnownVarsCausal2 failed for ...");
515 ✗ Error.addCompilerError("fixKnownVarsCausal2 failed");
516 ✗ fail();
517 end try;
518 end fixKnownVarsCausal2;
519
520 // =============================================================================
521 // section for fastAcausal
522 //
523 // =============================================================================
524
525 public function fastAcausal "author: Frenkel TUD 2012-12
526 This Function remove with a linear scaling with respect to the number of
527 equations in an acausal system as much as possible simple equations."
528 input BackendDAE.BackendDAE inDAE;
529 output BackendDAE.BackendDAE outDAE;
530 protected
531 BackendVarTransform.VariableReplacements repl;
532 Boolean b, warnAliasConflicts;
533 Integer size;
534 UnorderedSet<DAE.ComponentRef> unReplaceable;
535 algorithm
536 // get the size of the system to set up the replacement hashmap
537 2897 size := BackendDAEUtil.daeSize(inDAE);
538 2897 size := intMax(BaseHashTable.defaultBucketSize, realInt(realMul(intReal(size), 0.7)));
539 2897 repl := BackendVarTransform.emptyReplacementsSized(size);
540 // check for unReplaceable crefs
541 2897 unReplaceable := newCrefSet();
542 2897 unReplaceable := BackendDAEUtil.foldEqSystem(inDAE, addUnreplaceable, unReplaceable);
543 2897 (_,unReplaceable) := BackendDAEUtil.traverseBackendDAEExps(inDAE, Expression.traverseSubexpressionsHelper, (traverserExpUnreplaceable, unReplaceable));
544 2897 unReplaceable := addUnreplaceableFromWhens(inDAE, unReplaceable);
545
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2892 times.
2897 if Flags.isSet(Flags.DUMP_REPL) then
546 5 dumpCrefSet(unReplaceable, "Unreplaceable Crefs:");
547 end if;
548 // traverse all systems and remove simple equations
549 2897 (outDAE, (repl, b, _, _, warnAliasConflicts)) := BackendDAEUtil.mapEqSystemAndFold(inDAE, fastAcausal1, (repl, false, unReplaceable, Flags.getConfigInt(Flags.MAXTRAVERSALS), false));
550
4/4
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 2836 times.
✓ Branch 3 taken 58 times.
✓ Branch 4 taken 3 times.
2897 if warnAliasConflicts and BackendDAEUtil.isSimulationDAE(inDAE.shared) then
551 58 Error.addMessage(Error.REDUNDANT_ALIAS_SET, {});
552 end if;
553 // traverse the shared parts
554 2897 outDAE := removeSimpleEquationsShared(b, outDAE, repl);
555 end fastAcausal;
556
557 protected function newCrefSet
558 output UnorderedSet<DAE.ComponentRef> set = UnorderedSet.new(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
559 end newCrefSet;
560
561 protected function addCref
562 input DAE.ComponentRef cr;
563 input output UnorderedSet<DAE.ComponentRef> set;
564 algorithm
565 27189 UnorderedSet.add(cr, set);
566 end addCref;
567
568 protected function dumpCrefSet
569 "Prints the set like BackendDump.dumpHashSet, in bucket order."
570 input UnorderedSet<DAE.ComponentRef> set;
571 input String heading;
572 algorithm
573 6 print("\n" + heading + " (" + intString(UnorderedSet.size(set)) + ")\n" + BackendDump.UNDERLINE + "\n");
574
4/4
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 6 times.
23 print(stringDelimitList(list(ComponentReferenceBasics.printComponentRefStr(cr) for cr in UnorderedSet.toList(set)), "\n"));
575 6 print("\n");
576 end dumpCrefSet;
577
578 protected function addUnreplaceable
579 input BackendDAE.EqSystem syst;
580 input BackendDAE.Shared shared;
581 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
582 output UnorderedSet<DAE.ComponentRef> outUnreplaceable = inUnreplaceable;
583 protected
584 BackendDAE.Variables orderedVars;
585 algorithm
586 21834 BackendDAE.EQSYSTEM(orderedVars=orderedVars) := syst;
587
2/2
✓ Branch 1 taken 304965 times.
✓ Branch 2 taken 21834 times.
326799 for var in BackendVariable.varList(orderedVars) loop
588
2/2
✓ Branch 1 taken 13812 times.
✓ Branch 2 taken 291153 times.
304965 if BackendVariable.varUnreplaceable(var) then
589 13812 outUnreplaceable := addCref(BackendVariable.varCref(var), outUnreplaceable);
590 end if;
591 end for;
592 end addUnreplaceable;
593
594 protected function fastAcausal1 "author: Frenkel TUD 2012-12
595 traverse an Equations system to remove simple equations"
596 input BackendDAE.EqSystem inSystem;
597 input BackendDAE.Shared inShared;
598 input tuple<BackendVarTransform.VariableReplacements, Boolean, UnorderedSet<DAE.ComponentRef>, Integer, Boolean> inTpl;
599 output BackendDAE.EqSystem outSystem = BackendDAEUtil.copyEqSystem(inSystem);
600 output BackendDAE.Shared outShared;
601 output tuple<BackendVarTransform.VariableReplacements, Boolean, UnorderedSet<DAE.ComponentRef>, Integer, Boolean> outTpl;
602 protected
603 BackendVarTransform.VariableReplacements repl;
604 UnorderedSet<DAE.ComponentRef> unReplaceable;
605 list<BackendDAE.Equation> eqnslst;
606 list<SimpleContainer> simpleeqnslst;
607 BackendDAE.Variables vars;
608 BackendDAE.EquationArray eqns;
609 array<list<Integer>> mT; //[varIdx] = simpleContainer
610 Boolean foundSimple, globalFoundSimple, warnAliasConflicts;
611 Integer maxTraversals;
612 algorithm
613 // Don't apply removeSimpleEquations to clocked partitions
614
2/2
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 20235 times.
20296 if BackendDAEUtil.isClockedSyst(inSystem) then
615 outSystem := inSystem;
616 61 outShared := inShared;
617 outTpl := inTpl;
618 61 return;
619 end if;
620
621 try
622 20235 BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := outSystem;
623 20235 (repl, globalFoundSimple, unReplaceable, maxTraversals, warnAliasConflicts) := inTpl;
624 // transform to list, this is later not neccesary because the acausal system should save the equations as list
625 20235 eqnslst := BackendEquation.equationList(eqns);
626 20235 mT := arrayCreate(BackendVariable.varsSize(vars), {});
627 // check equations
628 20235 (_, _, eqnslst, simpleeqnslst, _, _, foundSimple) := List.fold( eqnslst, simpleEquationsFinder,
629 (vars, inShared, {}, {}, 1, mT, false) );
630
631 //print("Found "+intString(listLength(simpleeqnslst))+" SimpleEquationsContainers\n");
632 //print(stringDelimitList(List.map(simpleeqnslst, dumpSimpleContainer),"\n")+"\n");
633
634 20235 (vars, outShared, repl, unReplaceable, eqnslst, globalFoundSimple, warnAliasConflicts) := causalFinder(foundSimple, simpleeqnslst, eqnslst, 1, maxTraversals, vars, inShared, repl, unReplaceable, mT, {}, globalFoundSimple, warnAliasConflicts);
635
636 20235 outSystem := updateSystem(globalFoundSimple, eqnslst, vars, repl, outSystem);
637
4/4
✓ Branch 0 taken 17949 times.
✓ Branch 1 taken 2286 times.
✓ Branch 2 taken 1859 times.
✓ Branch 3 taken 18376 times.
40043 outTpl := ((repl, globalFoundSimple, unReplaceable, maxTraversals, warnAliasConflicts));
638 20235 GCExt.free(mT);
639 else
640 //Error.addCompilerWarning("The module removeSimpleEquations failed for a subsystem. The relevant subsystem get skipped and the transformation is proceeded.");
641 outSystem := inSystem;
642 ✗ outShared := inShared;
643 outTpl := inTpl;
644 end try;
645 end fastAcausal1;
646
647 protected function causalFinder "author: Frenkel TUD 2012-12"
648 input Boolean foundSimple;
649 input list<SimpleContainer> simpleContainerIn;
650 input list<BackendDAE.Equation> iEqnslst;
651 input Integer traversalIdx;
652 input Integer maxTraversals;
653 input BackendDAE.Variables iVars;
654 input BackendDAE.Shared ishared;
655 input BackendVarTransform.VariableReplacements iRepl;
656 input UnorderedSet<DAE.ComponentRef> iUnreplaceable;
657 input array<list<Integer>> iMT;
658 input list<BackendDAE.Equation> iGlobalEqnslst;
659 input Boolean inGlobalFoundSimple;
660 output BackendDAE.Variables outVars = iVars;
661 output BackendDAE.Shared outShared = ishared;
662 output BackendVarTransform.VariableReplacements outRepl = iRepl;
663 output UnorderedSet<DAE.ComponentRef> outUnReplaceable = iUnreplaceable;
664 output list<BackendDAE.Equation> outEqnslst;
665 output Boolean outGlobalFoundSimple = inGlobalFoundSimple;
666 input output Boolean warnAliasConflicts;
667 protected
668 BackendDAE.Variables vars;
669 BackendVarTransform.VariableReplacements repl;
670 Boolean b, b1;
671 array<SimpleContainer> simpleContainer;
672 list<BackendDAE.Equation> eqnslst;
673 BackendDAE.Shared shared;
674 algorithm
675
2/2
✓ Branch 0 taken 19573 times.
✓ Branch 1 taken 2813 times.
22386 if foundSimple then
676 // transform simpleeqns to array
677 19573 simpleContainer := List.listArrayReverse(simpleContainerIn);
678 // collect and handle sets
679 19573 (vars, eqnslst, shared, repl, b) := handleSets(arrayLength(simpleContainer), 1, simpleContainer, iMT, iUnreplaceable, iVars, iEqnslst, ishared, iRepl);
680
4/4
✓ Branch 0 taken 17210 times.
✓ Branch 1 taken 2363 times.
✓ Branch 2 taken 17149 times.
✓ Branch 3 taken 61 times.
36722 warnAliasConflicts := warnAliasConflicts or b;
681
682 // perform replacements and try again
683 19573 (eqnslst, b1) := BackendVarTransform.replaceEquations(eqnslst, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
684 19573 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst, warnAliasConflicts) := causalFinder1(intGt(traversalIdx, maxTraversals), b1, eqnslst, traversalIdx+1, maxTraversals, vars, shared, repl, iUnreplaceable, iMT, iGlobalEqnslst, inGlobalFoundSimple, warnAliasConflicts);
685 outGlobalFoundSimple := true;
686 else
687 2813 outEqnslst := listAppend(iEqnslst, iGlobalEqnslst);
688 end if;
689 end causalFinder;
690
691 protected function causalFinder1 "author: Frenkel TUD 2012-12"
692 input Boolean finished "index > traversal";
693 input Boolean b;
694 input list<BackendDAE.Equation> iEqnslst;
695 input Integer index;
696 input Integer maxTraversals;
697 input BackendDAE.Variables iVars;
698 input BackendDAE.Shared ishared;
699 input BackendVarTransform.VariableReplacements iRepl;
700 input UnorderedSet<DAE.ComponentRef> iUnreplaceable;
701 input array<list<Integer>> iMT;
702 input list<BackendDAE.Equation> iGlobalEqnslst;
703 input Boolean inGlobalFoundSimple;
704 output BackendDAE.Variables outVars = iVars;
705 output BackendDAE.Shared outShared = ishared;
706 output BackendVarTransform.VariableReplacements outRepl = iRepl;
707 output UnorderedSet<DAE.ComponentRef> outUnReplaceable = iUnreplaceable;
708 output list<BackendDAE.Equation> outEqnslst = listAppend(iEqnslst, iGlobalEqnslst);
709 input output Boolean warnAliasConflicts;
710 algorithm
711 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst) :=
712 match (finished, b, iEqnslst)
713 local
714 Boolean b1;
715 list<BackendDAE.Equation> eqnslst;
716 list<SimpleContainer> simpleeqnslst;
717 BackendDAE.Variables vars;
718 BackendDAE.Shared shared;
719 163 case(true, _, _) then (iVars, ishared, iRepl, iUnreplaceable, listAppend(iEqnslst, iGlobalEqnslst));
720 case(_, false, {}) then (iVars, ishared, iRepl, iUnreplaceable, iGlobalEqnslst);
721 396 case(_, false, _) then (iVars, ishared, iRepl, iUnreplaceable, listAppend(iEqnslst, iGlobalEqnslst));
722 case(_, true, _)
723 algorithm
724 2151 (vars, shared, eqnslst, simpleeqnslst, _, _, b1) := List.fold(iEqnslst, simpleEquationsFinder, (iVars, ishared, {}, {}, 1, iMT, false));
725 2151 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst, _, warnAliasConflicts) := causalFinder(b1, simpleeqnslst, eqnslst, index, maxTraversals, vars, shared, iRepl, iUnreplaceable, iMT, iGlobalEqnslst, inGlobalFoundSimple, warnAliasConflicts);
726 2151 then
727 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst);
728 end match;
729 end causalFinder1;
730
731
732 // =============================================================================
733 // section for allAcausal
734 //
735 // =============================================================================
736
737 public function allAcausal "author: Frenkel TUD 2012-12"
738 input BackendDAE.BackendDAE inDAE;
739 output BackendDAE.BackendDAE outDAE;
740 protected
741 BackendVarTransform.VariableReplacements repl;
742 Boolean b, warnAliasConflicts;
743 Integer size;
744 UnorderedSet<DAE.ComponentRef> unReplaceable;
745 algorithm
746 // get the size of the system to set up the replacement hashmap
747 ✗ size := BackendDAEUtil.daeSize(inDAE);
748 ✗ size := intMax(BaseHashTable.defaultBucketSize, realInt(realMul(intReal(size), 0.7)));
749 ✗ repl := BackendVarTransform.emptyReplacementsSized(size);
750 // check for unReplaceable crefs
751 ✗ unReplaceable := newCrefSet();
752 ✗ unReplaceable := BackendDAEUtil.foldEqSystem(inDAE, addUnreplaceable, unReplaceable);
753 ✗ (_,unReplaceable) := BackendDAEUtil.traverseBackendDAEExps(inDAE, Expression.traverseSubexpressionsHelper, (traverserExpUnreplaceable, unReplaceable));
754 ✗ unReplaceable := addUnreplaceableFromWhens(inDAE, unReplaceable);
755 ✗ if Flags.isSet(Flags.DUMP_REPL) then
756 ✗ dumpCrefSet(unReplaceable, "Unreplaceable Crefs:");
757 end if;
758 ✗ (outDAE, (repl, _, b, warnAliasConflicts)) := BackendDAEUtil.mapEqSystemAndFold(inDAE, allAcausal1, (repl, unReplaceable, false, false));
759 ✗ if warnAliasConflicts and BackendDAEUtil.isSimulationDAE(inDAE.shared) then
760 ✗ Error.addMessage(Error.REDUNDANT_ALIAS_SET, {});
761 end if;
762 ✗ outDAE := removeSimpleEquationsShared(b, outDAE, repl);
763 // until remove simple equations does not update assignments and comps remove them
764 end allAcausal;
765
766 protected function allAcausal1 "author: Frenkel TUD 2012-12
767 This function moves simple equations on the form a=b and a=const and
768 a=f(not time) in BackendDAE.BackendDAE to get speed up"
769 input BackendDAE.EqSystem inSystem;
770 input BackendDAE.Shared inShared;
771 input tuple<BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, Boolean, Boolean> inTpl;
772 output BackendDAE.EqSystem outSystem;
773 output BackendDAE.Shared outShared;
774 output tuple<BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, Boolean, Boolean> outTpl;
775 protected
776 BackendDAE.Variables vars;
777 BackendDAE.EquationArray eqns;
778 BackendVarTransform.VariableReplacements repl;
779 UnorderedSet<DAE.ComponentRef> unReplaceable;
780 Boolean b, b1, warnAliasConflicts;
781 array<list<Integer>> mT;
782 list<BackendDAE.Equation> eqnslst;
783 algorithm
784 // Don't apply removeSimpleEquations to clocked partitions
785 ✗ if BackendDAEUtil.isClockedSyst(inSystem) then
786 outSystem := inSystem;
787 outShared := inShared;
788 outTpl := inTpl;
789 ✗ return;
790 end if;
791
792 ✗ BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns) := inSystem;
793 ✗ (repl, unReplaceable, b1, warnAliasConflicts) := inTpl;
794
795 // transform to list, this is later not neccesary because the acausal system should save the equations as list
796 ✗ eqnslst := BackendEquation.equationList(eqns);
797 ✗ mT := arrayCreate(BackendVariable.varsSize(vars), {});
798
799 // check equations
800 ✗ (vars, outShared, repl, unReplaceable, _, eqnslst, b, warnAliasConflicts) := allCausalFinder(eqnslst, (vars, inShared, repl, unReplaceable, mT, {}, false, warnAliasConflicts));
801
802 ✗ outSystem := updateSystem(b, eqnslst, vars, repl, inSystem);
803 ✗ outTpl := ((repl, unReplaceable, b or b1, warnAliasConflicts));
804 end allAcausal1;
805
806
807 // =============================================================================
808 // section for causal
809 //
810 // =============================================================================
811
812 public function causal "author: Frenkel TUD 2012-12"
813 input BackendDAE.BackendDAE inDAE;
814 output BackendDAE.BackendDAE outDAE;
815 protected
816 BackendVarTransform.VariableReplacements repl;
817 Boolean b, warnAliasConflicts;
818 Integer size;
819 UnorderedSet<DAE.ComponentRef> unReplaceable;
820 algorithm
821 // get the size of the system to set up the replacement hashmap
822 1060 size := BackendDAEUtil.daeSize(inDAE);
823 1060 size := intMax(BaseHashTable.defaultBucketSize, realInt(realMul(intReal(size), 0.7)));
824 1060 repl := BackendVarTransform.emptyReplacementsSized(size);
825 // check for unReplaceable crefs
826 1060 unReplaceable := newCrefSet();
827 1060 unReplaceable := BackendDAEUtil.foldEqSystem(inDAE, addUnreplaceable, unReplaceable);
828 1060 (_,unReplaceable) := BackendDAEUtil.traverseBackendDAEExps(inDAE, Expression.traverseSubexpressionsHelper, (traverserExpUnreplaceable, unReplaceable));
829 1060 unReplaceable := addUnreplaceableFromWhens(inDAE, unReplaceable);
830 // do not replace state sets
831 1060 unReplaceable := addUnreplaceableFromStateSets(inDAE, unReplaceable);
832
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1059 times.
1060 if Flags.isSet(Flags.DUMP_REPL) then
833 1 dumpCrefSet(unReplaceable, "Unreplaceable Crefs:");
834 end if;
835 1060 (outDAE, (repl, _, b, warnAliasConflicts)) := BackendDAEUtil.mapEqSystemAndFold(inDAE, causal1, (repl, unReplaceable, false, false));
836
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1056 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
1060 if warnAliasConflicts and BackendDAEUtil.isSimulationDAE(inDAE.shared) then
837 4 Error.addMessage(Error.REDUNDANT_ALIAS_SET, {});
838 end if;
839 1060 outDAE := removeSimpleEquationsShared(b, outDAE, repl);
840 // until remove simple equations does not update assignments and comps remove them
841 end causal;
842
843 protected function causal1 "author: Frenkel TUD 2012-12
844 This function moves simple equations on the form a=b and a=const and
845 a=f(not time) in BackendDAE.BackendDAE to get speed up"
846 input BackendDAE.EqSystem inSystem;
847 input BackendDAE.Shared inShared;
848 input tuple<BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, Boolean, Boolean> inTpl;
849 output BackendDAE.EqSystem outSystem;
850 output BackendDAE.Shared outShared;
851 output tuple<BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, Boolean, Boolean> outTpl;
852 protected
853 BackendDAE.Variables vars;
854 BackendDAE.EquationArray eqns;
855 BackendDAE.StrongComponents comps;
856 BackendVarTransform.VariableReplacements repl;
857 UnorderedSet<DAE.ComponentRef> unReplaceable;
858 Boolean b, b1, warnAliasConflicts;
859 array<list<Integer>> mT;
860 list<BackendDAE.Equation> eqnslst;
861 algorithm
862 // Don't apply removeSimpleEquations to clocked partitions
863
2/2
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 1477 times.
1538 if BackendDAEUtil.isClockedSyst(inSystem) then
864 outSystem := inSystem;
865 outShared := inShared;
866 outTpl := inTpl;
867 61 return;
868 end if;
869
870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1477 times.
1477 BackendDAE.EQSYSTEM(orderedVars=vars, orderedEqs=eqns, matching=BackendDAE.MATCHING(comps=comps)) := inSystem;
871 1477 (repl, unReplaceable, b1, warnAliasConflicts) := inTpl;
872
873 1477 mT := arrayCreate(BackendVariable.varsSize(vars), {});
874
875 // check equations
876
1/2
✓ Branch 0 taken 1477 times.
✗ Branch 1 not taken.
2954 (vars, outShared, repl, unReplaceable, _, eqnslst, b, warnAliasConflicts) := traverseComponents(comps, eqns, allCausalFinder, (vars, inShared, repl, unReplaceable, mT, {}, false, warnAliasConflicts));
877
878 1477 outSystem := updateSystem(b, eqnslst, vars, repl, inSystem);
879
4/4
✓ Branch 0 taken 1473 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 961 times.
✓ Branch 3 taken 516 times.
3911 outTpl := ((repl, unReplaceable, b or b1, warnAliasConflicts));
880 end causal1;
881
882 protected function traverseComponents "author: Frenkel TUD 2010-12"
883 replaceable type Type_a subtypeof Any;
884 input BackendDAE.StrongComponents inComps;
885 input BackendDAE.EquationArray iEqns;
886 input FuncType inFunc;
887 input Type_a inTypeA;
888 output Type_a outTypeA;
889 partial function FuncType
890 input list<BackendDAE.Equation> iEqns;
891 input Type_a inTypeA;
892 output Type_a outTypeA;
893 end FuncType;
894 algorithm
895 outTypeA :=
896 match inComps
897 local
898 Integer e;
899 list<Integer> elst;
900 BackendDAE.StrongComponents rest;
901 BackendDAE.Equation eqn;
902 list<BackendDAE.Equation> eqnlst, eqnlst1;
903 BackendDAE.InnerEquations innerEquations;
904 Type_a arg;
905 case {} then inTypeA;
906 case BackendDAE.SINGLEEQUATION(eqn=e)::rest
907 algorithm
908 37928 eqn := BackendEquation.get(iEqns, e);
909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37928 times.
37928 arg := inFunc({eqn}, inTypeA);
910 37928 then
911 traverseComponents(rest, iEqns, inFunc, arg);
912 case BackendDAE.EQUATIONSYSTEM(eqns=elst)::rest
913 algorithm
914 1034 eqnlst := BackendEquation.getList(elst, iEqns);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
1034 arg := inFunc(eqnlst, inTypeA);
916 1034 then
917 traverseComponents(rest, iEqns, inFunc, arg);
918 case BackendDAE.SINGLEARRAY(eqn=e)::rest
919 algorithm
920 217 eqn := BackendEquation.get(iEqns, e);
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217 times.
217 arg := inFunc({eqn}, inTypeA);
922 217 then
923 traverseComponents(rest, iEqns, inFunc, arg);
924 case BackendDAE.SINGLEIFEQUATION(eqn=e)::rest
925 algorithm
926 ✗ eqn := BackendEquation.get(iEqns, e);
927 ✗ arg := inFunc({eqn}, inTypeA);
928 ✗ then
929 traverseComponents(rest, iEqns, inFunc, arg);
930 case BackendDAE.SINGLEALGORITHM(eqn=e)::rest
931 algorithm
932 199 eqn := BackendEquation.get(iEqns, e);
933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 199 times.
199 arg := inFunc({eqn}, inTypeA);
934 199 then
935 traverseComponents(rest, iEqns, inFunc, arg);
936 case BackendDAE.SINGLECOMPLEXEQUATION(eqn=e)::rest
937 algorithm
938 522 eqn := BackendEquation.get(iEqns, e);
939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
522 arg := inFunc({eqn}, inTypeA);
940 522 then
941 traverseComponents(rest, iEqns, inFunc, arg);
942 case BackendDAE.SINGLEWHENEQUATION(eqn=e)::rest
943 algorithm
944 421 eqn := BackendEquation.get(iEqns, e);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 421 times.
421 arg := inFunc({eqn}, inTypeA);
946 421 then
947 traverseComponents(rest, iEqns, inFunc, arg);
948 case BackendDAE.TORNSYSTEM(BackendDAE.TEARINGSET(residualequations=elst, innerEquations=innerEquations))::rest
949 algorithm
950 // collect all equations
951 ✗ eqnlst := BackendEquation.getList(elst, iEqns);
952 ✗ (elst,_,_) := List.map_3(innerEquations, BackendDAEUtil.getEqnAndVarsFromInnerEquation);
953 ✗ eqnlst1 := BackendEquation.getList(elst, iEqns);
954 ✗ arg := inFunc(listAppend(eqnlst, eqnlst1), inTypeA);
955 ✗ then
956 traverseComponents(rest, iEqns, inFunc, arg);
957 end match;
958 end traverseComponents;
959
960 protected function allCausalFinder "author: Frenkel TUD 2012-12"
961 input list<BackendDAE.Equation> eqns;
962 input tuple<BackendDAE.Variables, BackendDAE.Shared, BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, array<list<Integer>>, list<BackendDAE.Equation>, Boolean, Boolean> inTpl;
963 output tuple<BackendDAE.Variables, BackendDAE.Shared, BackendVarTransform.VariableReplacements, UnorderedSet<DAE.ComponentRef>, array<list<Integer>>, list<BackendDAE.Equation>, Boolean, Boolean> outTpl;
964 protected
965 BackendDAE.Variables vars;
966 BackendDAE.Shared shared;
967 BackendVarTransform.VariableReplacements repl;
968 UnorderedSet<DAE.ComponentRef> unReplaceable;
969 array<list<Integer>> mt;
970 Boolean b, b1, b2, b3, globalFoundSimple, warnAliasConflicts;
971 list<BackendDAE.Equation> globaleqnslst, eqnslst;
972 list<SimpleContainer> simpleeqnslst;
973 algorithm
974 40321 (vars, shared, repl, unReplaceable, mt, globaleqnslst, b, warnAliasConflicts) := inTpl;
975 40321 (eqnslst, b2) := BackendVarTransform.replaceEquations(eqns, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
976 40321 (_, _, eqnslst, simpleeqnslst, _, _, b1) := List.fold(eqnslst, simpleEquationsFinder, (vars, shared, {}, {}, 1, mt, false));
977 40321 (vars, shared, repl, unReplaceable, eqnslst, globalFoundSimple, b3) := allCausalFinder1(b1, b2, simpleeqnslst, eqnslst, vars, shared, repl, unReplaceable, mt, globaleqnslst, b, warnAliasConflicts);
978
4/4
✓ Branch 0 taken 39615 times.
✓ Branch 1 taken 706 times.
✓ Branch 2 taken 39611 times.
✓ Branch 3 taken 4 times.
40321 warnAliasConflicts := warnAliasConflicts or b3;
979
2/2
✓ Branch 0 taken 12182 times.
✓ Branch 1 taken 28139 times.
52503 outTpl := (vars, shared, repl, unReplaceable, mt, eqnslst, globalFoundSimple, warnAliasConflicts);
980 end allCausalFinder;
981
982 protected function allCausalFinder1 "author: Frenkel TUD 2012-12"
983 input Boolean foundSimple;
984 input Boolean didReplacement;
985 input list<SimpleContainer> iSimpleeqnslst;
986 input list<BackendDAE.Equation> iEqnslst;
987 input BackendDAE.Variables iVars;
988 input BackendDAE.Shared ishared;
989 input BackendVarTransform.VariableReplacements iRepl;
990 input UnorderedSet<DAE.ComponentRef> iUnreplaceable;
991 input array<list<Integer>> iMT;
992 input list<BackendDAE.Equation> iGlobalEqnslst;
993 input Boolean globalFoundSimple;
994 output BackendDAE.Variables outVars;
995 output BackendDAE.Shared outShared;
996 output BackendVarTransform.VariableReplacements outRepl;
997 output UnorderedSet<DAE.ComponentRef> outUnReplaceable;
998 output list<BackendDAE.Equation> outEqnslst;
999 output Boolean outGlobalFoundSimple;
1000 input output Boolean warnAliasConflicts;
1001 algorithm
1002 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst, outGlobalFoundSimple, warnAliasConflicts) :=
1003 match (foundSimple, iEqnslst)
1004 local
1005 BackendDAE.Variables vars;
1006 BackendVarTransform.VariableReplacements repl;
1007 Boolean b, b1;
1008 array<SimpleContainer> simpleeqns;
1009 list<BackendDAE.Equation> eqnslst;
1010 BackendDAE.Shared shared;
1011 case (false, {})
1012 ✗ then (iVars, ishared, iRepl, iUnreplaceable, iGlobalEqnslst, didReplacement or globalFoundSimple, warnAliasConflicts);
1013 case (false, _)
1014 33480 then (iVars, ishared, iRepl, iUnreplaceable, listAppend(iEqnslst, iGlobalEqnslst), didReplacement or globalFoundSimple, warnAliasConflicts);
1015 case (true, _)
1016 algorithm
1017 // transform simpleeqns to array
1018 6951 simpleeqns := List.listArrayReverse(iSimpleeqnslst);
1019 // collect and handle sets
1020 6951 (vars, eqnslst, shared, repl, b) := handleSets(arrayLength(simpleeqns), 1, simpleeqns, iMT, iUnreplaceable, iVars, iEqnslst, ishared, iRepl);
1021
4/4
✓ Branch 0 taken 6928 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 6924 times.
✓ Branch 3 taken 4 times.
6951 warnAliasConflicts := warnAliasConflicts or b;
1022
1023 // perform replacements and try again
1024 6951 (eqnslst, b1) := BackendVarTransform.replaceEquations(eqnslst, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
1025 6951 then
1026 allCausalFinder2(b1, eqnslst, vars, shared, repl, iUnreplaceable, iMT, iGlobalEqnslst, true, warnAliasConflicts);
1027 end match;
1028 end allCausalFinder1;
1029
1030 protected function allCausalFinder2 "author: Frenkel TUD 2012-12"
1031 input Boolean b;
1032 input list<BackendDAE.Equation> iEqnslst;
1033 input BackendDAE.Variables iVars;
1034 input BackendDAE.Shared ishared;
1035 input BackendVarTransform.VariableReplacements iRepl;
1036 input UnorderedSet<DAE.ComponentRef> iUnreplaceable;
1037 input array<list<Integer>> iMT;
1038 input list<BackendDAE.Equation> iGlobalEqnslst;
1039 input Boolean globalFoundSimple;
1040 output BackendDAE.Variables outVars;
1041 output BackendDAE.Shared outShared;
1042 output BackendVarTransform.VariableReplacements outRepl;
1043 output UnorderedSet<DAE.ComponentRef> outUnReplaceable;
1044 output list<BackendDAE.Equation> outEqnslst;
1045 output Boolean outGlobalFoundSimple;
1046 input output Boolean warnAliasConflicts;
1047 algorithm
1048 (outVars, outShared, outRepl, outUnReplaceable, outEqnslst, outGlobalFoundSimple, warnAliasConflicts) :=
1049 match (b, iEqnslst)
1050 local
1051 Boolean b1;
1052 list<BackendDAE.Equation> eqnslst;
1053 list<SimpleContainer> simpleeqnslst;
1054 BackendDAE.Variables vars;
1055 BackendDAE.Shared shared;
1056 6582 case(false, {}) then (iVars, ishared, iRepl, iUnreplaceable, iGlobalEqnslst, globalFoundSimple, warnAliasConflicts);
1057 259 case(false, _) then (iVars, ishared, iRepl, iUnreplaceable, listAppend(iEqnslst, iGlobalEqnslst), globalFoundSimple, warnAliasConflicts);
1058 case(true, _)
1059 algorithm
1060 110 (vars, shared, eqnslst, simpleeqnslst, _, _, b1) := List.fold(iEqnslst, simpleEquationsFinder, (iVars, ishared, {}, {}, 1, iMT, false));
1061 110 then
1062 allCausalFinder1(b1, false, simpleeqnslst, eqnslst, vars, shared, iRepl, iUnreplaceable, iMT, iGlobalEqnslst, globalFoundSimple, warnAliasConflicts);
1063 end match;
1064 end allCausalFinder2;
1065
1066
1067 // =============================================================================
1068 // functions to find simple equations
1069 //
1070 // =============================================================================
1071
1072 protected function simpleEquationsFinder "author: Frenkel TUD 2012-12
1073 map from equation to lhs and rhs"
1074 input BackendDAE.Equation eqn;
1075 input AccTuple inTpl;
1076 output AccTuple outTpl;
1077 algorithm
1078 outTpl:=
1079 matchcontinue (eqn, inTpl)
1080 local
1081 DAE.ComponentRef cr;
1082 DAE.Exp e1, e2;
1083 DAE.ElementSource source;
1084 BackendDAE.Variables v;
1085 BackendDAE.Shared s;
1086 list<BackendDAE.Equation> eqns;
1087 list<SimpleContainer> seqns;
1088 Integer index;
1089 array<list<Integer>> mT;
1090 Boolean b;
1091 BackendDAE.EquationAttributes eqAttr;
1092
1093 case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr), _)
1094 algorithm
1095
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 405818 times.
405818 if Flags.isSet(Flags.DEBUG_ALIAS) then
1096 ✗ BackendDump.debugStrExpStrExpStr("Found Equation ", e1, " = ", e2, " to handle.\n");
1097 end if;
1098 405818 then
1099 simpleEquationAcausal(e1, e2, (source, eqAttr), false, inTpl);
1100
1101 case (BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source, attr=eqAttr), _)
1102 algorithm
1103
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2175 times.
2175 if Flags.isSet(Flags.DEBUG_ALIAS) then
1104 ✗ BackendDump.debugStrExpStrExpStr("Found Array Equation ", e1, " = ", e2, " to handle.\n");
1105 end if;
1106 2175 then
1107 simpleArrayEquationAcausal(e1, e2, Expression.typeof(e1), (source, eqAttr), inTpl);
1108
1109 case (BackendDAE.SOLVED_EQUATION(componentRef=cr, exp=e2, source=source, attr=eqAttr), _)
1110 algorithm
1111 375 e1 := Expression.crefExp(cr);
1112
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 375 times.
375 if Flags.isSet(Flags.DEBUG_ALIAS) then
1113 ✗ BackendDump.debugStrExpStrExpStr("Found Solved Equation ", e1, " = ", e2, " to handle.\n");
1114 end if;
1115 375 then
1116 simpleEquationAcausal(e1, e2, (source, eqAttr), false, inTpl);
1117
1118 case (BackendDAE.RESIDUAL_EQUATION(exp=e1, source=source, attr=eqAttr), _)
1119 algorithm
1120 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
1121 ✗ BackendDump.debugStrExpStr("Found Residual Equation ", e1, " to handle.\n");
1122 end if;
1123 ✗ then
1124 simpleExpressionAcausal(e1, (source, eqAttr), false, inTpl);
1125
1126 case (BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=eqAttr), _)
1127 algorithm
1128
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2883 times.
2883 if Flags.isSet(Flags.DEBUG_ALIAS) then
1129 ✗ BackendDump.debugStrExpStrExpStr("Found Complex Equation ", e1, " = ", e2, " to handle.\n");
1130 end if;
1131 2883 then
1132 simpleEquationAcausal(e1, e2, (source, eqAttr), false, inTpl);
1133
1134 case (_, (v, s, eqns, seqns, index, mT, b))
1135
2/2
✓ Branch 0 taken 92306 times.
✓ Branch 1 taken 155925 times.
340537 then ((v, s, eqn::eqns, seqns, index, mT, b));
1136
1137 end matchcontinue;
1138 end simpleEquationsFinder;
1139
1140 protected function simpleEquationAcausal "author Frenkel TUD 2012-12
1141 helper for simpleEquationsFinder"
1142 input DAE.Exp lhs;
1143 input DAE.Exp rhs;
1144 input EquationSourceAndAttributes eqnAttributes;
1145 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1146 input AccTuple inTpl;
1147 output AccTuple outTpl;
1148 algorithm
1149 outTpl := match (lhs, rhs)
1150 local
1151 DAE.ComponentRef cr1, cr2;
1152 DAE.Exp e1, e2;
1153 DAE.Type ty;
1154 list<DAE.Exp> elst1, elst2;
1155 list<list<DAE.Exp>> elstlst1, elstlst2;
1156 DAE.Operator op;
1157
1158 // a = b;
1159 case (DAE.CREF(componentRef = cr1), DAE.CREF(componentRef = cr2))
1160 99485 then addSimpleEquationAcausal(cr1, lhs, false, cr2, rhs, false, eqnAttributes, selfCalled, inTpl);
1161
1162 // a = -b;
1163 case (DAE.CREF(componentRef = cr1), DAE.UNARY(op as DAE.UMINUS(_), DAE.CREF(componentRef = cr2)))
1164 2477 then addSimpleEquationAcausal(cr1, DAE.UNARY(op, lhs), false, cr2, rhs, true, eqnAttributes, selfCalled, inTpl);
1165
1166 case (DAE.CREF(componentRef = cr1), DAE.UNARY(op as DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr2)))
1167 ✗ then addSimpleEquationAcausal(cr1, DAE.UNARY(op, lhs), false, cr2, rhs, true, eqnAttributes, selfCalled, inTpl);
1168
1169 // -a = b;
1170 case (DAE.UNARY(op as DAE.UMINUS(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
1171 126 then addSimpleEquationAcausal(cr1, lhs, true, cr2, DAE.UNARY(op, rhs), false, eqnAttributes, selfCalled, inTpl);
1172
1173 case (DAE.UNARY(op as DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
1174 ✗ then addSimpleEquationAcausal(cr1, lhs, true, cr2, DAE.UNARY(op, rhs), false, eqnAttributes, selfCalled, inTpl);
1175
1176 // -a = -b;
1177 case (DAE.UNARY(DAE.UMINUS(_), e1 as DAE.CREF(componentRef = cr1)), DAE.UNARY(DAE.UMINUS(_), e2 as DAE.CREF(componentRef = cr2)))
1178 24 then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1179
1180 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF(componentRef = cr2)))
1181 ✗ then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1182
1183 // a = not b;
1184 case (DAE.CREF(componentRef = cr1), DAE.LUNARY(op as DAE.NOT(_), DAE.CREF(componentRef = cr2)))
1185 121 then addSimpleEquationAcausal(cr1, DAE.LUNARY(op, lhs), false, cr2, rhs, true, eqnAttributes, selfCalled, inTpl);
1186
1187 // not a = b;
1188 case (DAE.LUNARY(op as DAE.NOT(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
1189 ✗ then addSimpleEquationAcausal(cr1, lhs, true, cr2, DAE.LUNARY(op, lhs), false, eqnAttributes, selfCalled, inTpl);
1190
1191 // not a = not b;
1192 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF(componentRef = cr1)), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF(componentRef = cr2)))
1193 ✗ then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1194
1195 // {a1, a2, a3, ..} = {b1, b2, b3, ..};
1196 case (DAE.ARRAY(array = elst1), DAE.ARRAY(array = elst2))
1197 ✗ then List.threadFold2(elst1, elst2, simpleEquationAcausal, eqnAttributes, true, inTpl);
1198
1199 case (DAE.MATRIX(matrix = elstlst1), DAE.MATRIX(matrix = elstlst2))
1200 ✗ then List.threadFold2(elstlst1, elstlst2, simpleEquationAcausalLst, eqnAttributes, true, inTpl);
1201
1202 // a = {b1, b2, b3, ..}
1203 case (DAE.CREF(), DAE.ARRAY(ty=ty))
1204 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1205
1206 case (DAE.CREF(), DAE.MATRIX(ty=ty))
1207 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1208
1209 // -a = {b1, b2, b3, ..}
1210 case (DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()), DAE.ARRAY(ty=ty))
1211 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1212
1213 case (DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()), DAE.MATRIX(ty=ty))
1214 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1215
1216 // a = -{b1, b2, b3, ..}
1217 case (DAE.CREF(), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.ARRAY(ty=ty)))
1218 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1219
1220 case (DAE.CREF(), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.MATRIX(ty=ty)))
1221 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1222
1223 // -a = -{b1, b2, b3, ..}
1224 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF()), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.ARRAY(ty=ty)))
1225 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1226
1227 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF()), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.MATRIX(ty=ty)))
1228 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1229
1230 // {a1, a2, a3, ..} = b
1231 case (DAE.ARRAY(ty=ty), DAE.CREF())
1232 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1233
1234 case (DAE.MATRIX(ty=ty), DAE.CREF())
1235 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1236
1237 // -{a1, a2, a3, ..} = b
1238 case (DAE.UNARY(DAE.UMINUS_ARR(_), DAE.ARRAY(ty=ty)), DAE.CREF())
1239 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1240
1241 case (DAE.UNARY(DAE.UMINUS_ARR(_), DAE.MATRIX(ty=ty)), DAE.CREF())
1242 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1243
1244 // {a1, a2, a3, ..} = -b
1245 case (DAE.ARRAY(ty=ty), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()))
1246 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1247
1248 case (DAE.MATRIX(ty=ty), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()))
1249 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1250
1251 // -{a1, a2, a3, ..} = -b
1252 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.ARRAY(ty=ty)), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF()))
1253 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1254
1255 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.MATRIX(ty=ty)), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF()))
1256 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1257
1258 // not a = {b1, b2, b3, ..}
1259 case (DAE.LUNARY(DAE.NOT(_), DAE.CREF()), DAE.ARRAY(ty=ty))
1260 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1261
1262 case (DAE.LUNARY(DAE.NOT(_), DAE.CREF()), DAE.MATRIX(ty=ty))
1263 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1264
1265 // a = not {b1, b2, b3, ..}
1266 case (DAE.CREF(), DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(ty=ty)))
1267 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1268
1269 case (DAE.CREF(), DAE.LUNARY(DAE.NOT(_), DAE.MATRIX(ty=ty)))
1270 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1271
1272 // not a = not {b1, b2, b3, ..}
1273 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF()), DAE.LUNARY(DAE.NOT(_), e2 as DAE.ARRAY(ty=ty)))
1274 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1275
1276 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF()), DAE.LUNARY(DAE.NOT(_), e2 as DAE.MATRIX(ty=ty)))
1277 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1278
1279 // {a1, a2, a3, ..} = not b
1280 case (DAE.ARRAY(ty=ty), DAE.LUNARY(DAE.NOT(_), DAE.CREF()))
1281 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1282
1283 case (DAE.MATRIX(ty=ty), DAE.LUNARY(DAE.NOT(_), DAE.CREF()))
1284 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1285
1286 // not {a1, a2, a3, ..} = b
1287 case (DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(ty=ty)), DAE.CREF())
1288 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1289
1290 case (DAE.LUNARY(DAE.NOT(_), DAE.MATRIX(ty=ty)), DAE.CREF())
1291 ✗ then simpleArrayEquationAcausal(lhs, rhs, ty, eqnAttributes, inTpl);
1292
1293 // not {a1, a2, a3, ..} = not b
1294 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.ARRAY(ty=ty)), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF()))
1295 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1296
1297 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.MATRIX(ty=ty)), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF()))
1298 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1299
1300 // time independent equations
1301 else
1302 310775 then simpleEquationAcausal1(lhs, rhs, eqnAttributes, selfCalled, inTpl);
1303
1304 end match;
1305 end simpleEquationAcausal;
1306
1307
1308 protected function simpleArrayEquationAcausal "author Frenkel TUD 2012-12
1309 helper for simpleEquationAcausal"
1310 input DAE.Exp lhs;
1311 input DAE.Exp rhs;
1312 input DAE.Type ty;
1313 input EquationSourceAndAttributes eqnAttributes;
1314 input AccTuple inTpl;
1315 output AccTuple outTpl;
1316 protected
1317 DAE.Dimensions dims;
1318 list<Integer> ds;
1319 list<list<DAE.Subscript>> subslst;
1320 list<DAE.Exp> elst1, elst2;
1321 Boolean hasInlineAfterIndexReduction, expandLhs, expandRhs;
1322 DAE.ElementSource source;
1323 BackendDAE.EquationAttributes attr;
1324 BackendDAE.Equation eq;
1325 algorithm
1326 2175 dims := Expression.arrayDimension(ty);
1327 2175 ds := Expression.dimensionsSizes(dims);
1328 2175 subslst := List.map(ds, Expression.dimensionSizeSubscripts);
1329 2175 subslst := Expression.rangesToSubscripts(subslst);
1330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2175 times.
2175 if listEmpty(subslst) then
1331 (source,attr) := eqnAttributes;
1332 outTpl := inTpl;
1333 ✗ return;
1334 /* TODO: Shouldn't we generate some sort of assertion for the lhs/rhs actually being of zero dimension or not throwing errors at run-time? */
1335 for e in {lhs,rhs} loop
1336 if Expression.isEvaluatedConst(e) then
1337 continue;
1338 end if;
1339 eq := BackendDAE.WHEN_EQUATION(0, BackendDAE.WHEN_STMTS(
1340 DAE.BCONST(false),
1341 {BackendDAE.ASSERT(DAE.BCONST(false), DAE.SCONST("Failed assertion exp is 0"), DAE.ASSERTIONLEVEL_ERROR, source)},
1342 NONE()
1343 ), source, attr);
1344 outTpl := simpleEquationsFinder(eq, outTpl);
1345 end for;
1346 return;
1347 /* End TODO. Note: The above code does not execute */
1348 end if;
1349 2175 (,hasInlineAfterIndexReduction) := Expression.traverseExpTopDown(lhs, Expression.findCallIsInlineAfterIndexReduction, false);
1350
1/2
✓ Branch 0 taken 2175 times.
✗ Branch 1 not taken.
4350 (,hasInlineAfterIndexReduction) := Expression.traverseExpTopDown(rhs, Expression.findCallIsInlineAfterIndexReduction, hasInlineAfterIndexReduction);
1351 2175 (elst1,expandLhs) := List.mapFold(subslst, function Expression.applyExpSubscriptsFoldCheckSimplify(exp=lhs), false);
1352 2175 (elst2,expandRhs) := List.mapFold(subslst, function Expression.applyExpSubscriptsFoldCheckSimplify(exp=rhs), false);
1353
2/2
✓ Branch 0 taken 873 times.
✓ Branch 1 taken 1302 times.
2175 if not hasInlineAfterIndexReduction then
1354 // If inlining after index reduction or i, we need to expand equations to pass sorting+matching
1355 // Note: We *should* be looking for the derivative annotation here, but it's not available directly
1356 // and better would be if sorting+matching could expand/split equations when necessary
1357 if false and not (expandLhs and expandRhs) then
1358 print(getInstanceName() + " not expanding " + ExpressionBasics.printExpStr(lhs) + " = " + ExpressionBasics.printExpStr(rhs) + "\n");
1359 end if;
1360
2/2
✓ Branch 0 taken 868 times.
✓ Branch 1 taken 5 times.
873 true := expandLhs and expandRhs "Do not expand equation if it doesn't help with anything... Like x=f(...); => x[1]=f()[1], ..., x[n]=f()[n]";
1361 else
1362 end if;
1363 1307 outTpl := List.threadFold2(elst1, elst2, simpleEquationAcausal, eqnAttributes, true, inTpl);
1364 end simpleArrayEquationAcausal;
1365
1366 protected function simpleEquationAcausalLst "author: Frenkel TUD 2012-12
1367 helper for simpleEquationAcausal"
1368 input list<DAE.Exp> elst1;
1369 input list<DAE.Exp> elst2;
1370 input EquationSourceAndAttributes eqnAttributes;
1371 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1372 input AccTuple inTpl;
1373 output AccTuple outTpl;
1374 algorithm
1375 ✗ outTpl := List.threadFold2(elst1, elst2, simpleEquationAcausal, eqnAttributes, selfCalled, inTpl);
1376 end simpleEquationAcausalLst;
1377
1378 protected function simpleEquationAcausal1 "author: Frenkel TUD 2012-12
1379 helper for simpleEquationAcausal"
1380 input DAE.Exp lhs;
1381 input DAE.Exp rhs;
1382 input EquationSourceAndAttributes eqnAttributes;
1383 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1384 input AccTuple inTpl;
1385 output AccTuple outTpl;
1386 algorithm
1387 outTpl := matchcontinue (lhs, rhs)
1388 local
1389 list<DAE.Exp> elst1, elst2;
1390 // Record
1391 case (_, _)
1392 algorithm
1393 310775 elst1 := Expression.splitRecord(lhs, Expression.typeof(lhs));
1394 1622 elst2 := Expression.splitRecord(rhs, Expression.typeof(rhs));
1395 3 then List.threadFold2(elst1, elst2, simpleEquationAcausal, eqnAttributes, true, inTpl);
1396 // {a1+b1, a2+b2, a3+b3, ..} = 0;
1397 case (DAE.ARRAY(array = elst1), _)
1398 guard
1399 Expression.isZero(rhs)
1400 ✗ then List.fold2(elst1, simpleExpressionAcausal, eqnAttributes, true, inTpl);
1401 // 0 = {a1+b1, a2+b2, a3+b3, ..};
1402 case (_, DAE.ARRAY(array = elst2))
1403 guard
1404 Expression.isZero(lhs)
1405 ✗ then List.fold2(elst2, simpleExpressionAcausal, eqnAttributes, true, inTpl);
1406 // lhs = 0
1407 case (_, _)
1408 guard
1409 Expression.isZero(rhs)
1410 60624 then simpleExpressionAcausal(lhs, eqnAttributes, selfCalled, inTpl);
1411 // 0 = rhs
1412 case (_, _)
1413 guard
1414 Expression.isZero(lhs)
1415 19385 then simpleExpressionAcausal(rhs, eqnAttributes, selfCalled, inTpl);
1416 // time independent equations
1417 else
1418 263464 then timeIndependentEquationAcausal(lhs, rhs, eqnAttributes, selfCalled, inTpl);
1419 end matchcontinue;
1420 end simpleEquationAcausal1;
1421
1422 protected function generateEquation "author: Frenkel TUD 2012-12
1423 helper to generate an equation from lhs and rhs.
1424 This function is called if an equation is found which is not simple"
1425 input DAE.Exp lhs;
1426 input DAE.Exp rhs;
1427 input DAE.Type ty;
1428 input EquationSourceAndAttributes eqnAttributes;
1429 input AccTuple inTpl;
1430 output AccTuple outTpl;
1431 algorithm
1432 outTpl := matchcontinue (eqnAttributes, inTpl)
1433 local
1434 Integer size;
1435 DAE.Dimensions dims;
1436 DAE.Type tp;
1437 list<Integer> ds;
1438 BackendDAE.Variables v;
1439 BackendDAE.Shared s;
1440 list<BackendDAE.Equation> eqns;
1441 list<SimpleContainer> seqns;
1442 Integer index;
1443 Option<Integer> recordSize;
1444 array<list<Integer>> mT;
1445 Boolean b, b1, b2;
1446 DAE.ElementSource source;
1447 BackendDAE.EquationAttributes eqAttr;
1448
1449 // complex types to complex equations
1450 case ((source, eqAttr), (v, s, eqns, seqns, index, mT, b))
1451 guard
1452 DAEUtil.expTypeComplex(ty)
1453 algorithm
1454 ✗ size := Expression.sizeOf(ty);
1455 // print("Add Equation:\n" + BackendDump.equationStr(BackendDAE.COMPLEX_EQUATION(size, lhs, rhs, source)) + "\n");
1456 ✗ then
1457 ((v, s, BackendDAE.COMPLEX_EQUATION(size, lhs, rhs, source, eqAttr)::eqns, seqns, index, mT, b));
1458 // array types to array equations
1459 case ((source, eqAttr), (v, s, eqns, seqns, index, mT, b))
1460 guard
1461 DAEUtil.expTypeArray(ty)
1462 algorithm
1463 ✗ dims := Expression.arrayDimension(ty);
1464 ✗ ds := Expression.dimensionsSizes(dims);
1465 ✗ tp := DAEUtil.expTypeElementType(ty);
1466 ✗ if DAEUtil.expTypeComplex(tp) then
1467 ✗ recordSize := SOME(Expression.sizeOf(tp));
1468 else
1469 recordSize := NONE();
1470 end if;
1471 // print("Add Equation:\n" + BackendDump.equationStr(BackendDAE.ARRAY_EQUATION(ds, lhs, rhs, source)) + "\n");
1472 ✗ then
1473 ((v, s, BackendDAE.ARRAY_EQUATION(ds, lhs, rhs, source, eqAttr, recordSize)::eqns, seqns, index, mT, b));
1474 // other types
1475 case ((source, eqAttr), (v, s, eqns, seqns, index, mT, b))
1476 algorithm
1477 5869 b1 := DAEUtil.expTypeComplex(ty);
1478 5869 b2 := DAEUtil.expTypeArray(ty);
1479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5869 times.
5869 false := b1 or b2;
1480 // print("Add Equation:\n" + BackendDump.equationStr(BackendDAE.EQUATION(lhs, rhs, source)) + "\n");
1481 //Error.assertionOrAddSourceMessage(not b1, Error.INTERNAL_ERROR, {str}, Absyn.dummyInfo);
1482
2/2
✓ Branch 1 taken 1960 times.
✓ Branch 2 taken 3909 times.
13698 then
1483 ((v, s, BackendDAE.EQUATION(lhs, rhs, source, eqAttr)::eqns, seqns, index, mT, b));
1484 else
1485 algorithm
1486 // show only on failtrace!
1487 ✗ true := Flags.isSet(Flags.FAILTRACE);
1488 ✗ Debug.traceln("- BackendDAEOptimize.generateEquation failed on: " + ExpressionBasics.printExpStr(lhs) + " = " + ExpressionBasics.printExpStr(rhs) + "\n");
1489 ✗ then
1490 fail();
1491 end matchcontinue;
1492 end generateEquation;
1493
1494 protected function simpleExpressionAcausal "author: Frenkel TUD 2012-12
1495 helper for simpleEquationsAcausal"
1496 input DAE.Exp exp;
1497 input EquationSourceAndAttributes eqnAttributes;
1498 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1499 input AccTuple inTpl;
1500 output AccTuple outTpl;
1501 algorithm
1502 outTpl := match exp
1503 local
1504 DAE.ComponentRef cr1, cr2;
1505 DAE.Exp e1, e2;
1506 DAE.Type ty, tp;
1507
1508 // a + b = 0 => a = -b
1509 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.ADD(ty=ty), e2 as DAE.CREF(componentRef = cr2))
1510 9340 then addSimpleEquationAcausal(cr1, DAE.UNARY(DAE.UMINUS(ty), e1), false, cr2, e2, true, eqnAttributes, selfCalled, inTpl);
1511 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.ADD_ARR(ty=ty), e2 as DAE.CREF(componentRef = cr2))
1512 ✗ then addSimpleEquationAcausal(cr1, DAE.UNARY(DAE.UMINUS_ARR(ty), e1), false, cr2, e2, true, eqnAttributes, selfCalled, inTpl);
1513
1514 // a - b = 0 => a = b
1515 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.SUB(), e2 as DAE.CREF(componentRef = cr2))
1516 6687 then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1517 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.SUB_ARR(), e2 as DAE.CREF(componentRef = cr2))
1518 ✗ then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1519
1520 // -a + b = 0 => a = b
1521 case DAE.BINARY(DAE.UNARY(DAE.UMINUS(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ADD(), e2 as DAE.CREF(componentRef = cr2))
1522 ✗ then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1523 case DAE.BINARY(DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ADD_ARR(), e2 as DAE.CREF(componentRef = cr2))
1524 ✗ then addSimpleEquationAcausal(cr1, e1, false, cr2, e2, false, eqnAttributes, selfCalled, inTpl);
1525
1526 // -a - b = 0 => -a = b
1527 case DAE.BINARY(e1 as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = cr1)), DAE.SUB(ty=ty), e2 as DAE.CREF(componentRef = cr2))
1528 445 then addSimpleEquationAcausal(cr1, e1, true, cr2, DAE.UNARY(DAE.UMINUS(ty), e2), false, eqnAttributes, selfCalled, inTpl);
1529 case DAE.BINARY(e1 as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr1)), DAE.SUB_ARR(ty=ty), e2 as DAE.CREF(componentRef = cr2))
1530 ✗ then addSimpleEquationAcausal(cr1, e1, true, cr2, DAE.UNARY(DAE.UMINUS_ARR(ty), e2), false, eqnAttributes, selfCalled, inTpl);
1531
1532 // a + {b1, b2, b3} = 0 => a = -{b1, b2, b3}
1533 case DAE.BINARY(e1 as DAE.CREF(), DAE.ADD_ARR(tp), e2 as DAE.ARRAY(ty=ty))
1534 ✗ then simpleArrayEquationAcausal(e1, DAE.UNARY(DAE.UMINUS_ARR(tp), e2), ty, eqnAttributes, inTpl);
1535 case DAE.BINARY(e1 as DAE.CREF(), DAE.ADD_ARR(tp), e2 as DAE.MATRIX(ty=ty))
1536 ✗ then simpleArrayEquationAcausal(e1, DAE.UNARY(DAE.UMINUS_ARR(tp), e2), ty, eqnAttributes, inTpl);
1537
1538 // a - {b1, b2, b3} = 0 => a = {b1, b2, b3}
1539 case DAE.BINARY(e1 as DAE.CREF(), DAE.SUB_ARR(_), e2 as DAE.ARRAY(ty=ty))
1540 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1541 case DAE.BINARY(e1 as DAE.CREF(), DAE.SUB_ARR(_), e2 as DAE.MATRIX(ty=ty))
1542 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1543
1544 // -a + {b1, b2, b3} = 0 => a = {b1, b2, b3}
1545 case DAE.BINARY(DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF()), DAE.ADD_ARR(_), e2 as DAE.ARRAY(ty=ty))
1546 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1547 case DAE.BINARY(DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF()), DAE.ADD_ARR(_), e2 as DAE.MATRIX(ty=ty))
1548 ✗ then simpleArrayEquationAcausal(e1, e2, ty, eqnAttributes, inTpl);
1549
1550 // -a - {b1, b2, b3} = 0 => -a = {b1, b2, b3}
1551 case DAE.BINARY(e1 as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()), DAE.SUB_ARR(_), e2 as DAE.ARRAY(ty=ty))
1552 ✗ then simpleArrayEquationAcausal(e1, DAE.UNARY(DAE.UMINUS_ARR(ty), e2), ty, eqnAttributes, inTpl);
1553 case DAE.BINARY(e1 as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF()), DAE.SUB_ARR(_), e2 as DAE.MATRIX(ty=ty))
1554 ✗ then simpleArrayEquationAcausal(e1, DAE.UNARY(DAE.UMINUS_ARR(ty), e2), ty, eqnAttributes, inTpl);
1555
1556 // time independent equations
1557 else
1558 63537 then timeIndependentExpressionAcausal(exp, eqnAttributes, selfCalled, inTpl);
1559
1560 end match;
1561
1562 end simpleExpressionAcausal;
1563
1564 protected function addSimpleEquationAcausal "author: Frenkel TUD 2012-12
1565 add a simple equation to the list of simple equations"
1566 input DAE.ComponentRef cr1;
1567 input DAE.Exp inE1;
1568 input Boolean negatedCr1;
1569 input DAE.ComponentRef cr2;
1570 input DAE.Exp inE2;
1571 input Boolean negatedCr2;
1572 input EquationSourceAndAttributes eqnAttributes;
1573 input Boolean genEqn "true if not possible to get the Alias generate an equation";
1574 input AccTuple inTpl;
1575 output AccTuple outTpl;
1576 algorithm
1577 outTpl := matchcontinue(genEqn, inTpl)
1578 local
1579 BackendDAE.Variables vars;
1580 BackendDAE.Shared shared;
1581 list<BackendDAE.Equation> eqns;
1582 list<SimpleContainer> seqns;
1583 Integer index;
1584 array<list<Integer>> mT;
1585 list<BackendDAE.Var> vars1, vars2;
1586 list<Integer> ilst1, ilst2;
1587 Boolean varskn1, varskn2, time1, time2;
1588 DAE.Exp e1, e2;
1589 DAE.Type ty;
1590
1591 case(_, (vars, shared, eqns, seqns, index, mT, _))
1592 algorithm
1593
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 118705 times.
118705 if Flags.isSet(Flags.DEBUG_ALIAS) then
1594 ✗ BackendDump.debugStrCrefStrCrefStr("Alias Equation ", cr1, " = ", cr2, " found. Negated lhs[" + boolString(negatedCr1) + "] = rhs[" + boolString(negatedCr2) + "].\n");
1595 end if;
1596 // get Variables
1597 118705 (vars1, ilst1, varskn1, time1) := getVars(cr1, vars, shared);
1598 118705 (vars2, ilst2, varskn2, time2) := getVars(cr2, vars, shared);
1599 // add to Simple Equations List
1600
2/2
✓ Branch 2 taken 158 times.
✓ Branch 3 taken 118545 times.
118703 true := intEq(listLength(vars1),listLength(vars2));
1601 118545 (seqns, index, mT) := generateSimpleContainters(vars1, negatedCr1, ilst1, varskn1, time1, vars2, negatedCr2, ilst2, varskn2, time2, eqnAttributes, seqns, index, mT);
1602 118545 then
1603 ((vars, shared, eqns, seqns, index, mT, true));
1604
1605 case(true, _)
1606 algorithm
1607 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
1608 ✗ BackendDump.debugStrExpStrExpStr("Non Alias Equation ", inE1, " = ", inE2, " to generate.\n");
1609 end if;
1610 ✗ e1 := Expression.crefExp(cr1);
1611 ✗ ty := Expression.typeof(e1);
1612 e2 := inE2;
1613 ✗ then
1614 generateEquation(e1, e2, ty, eqnAttributes, inTpl);
1615
1616 end matchcontinue;
1617 end addSimpleEquationAcausal;
1618
1619 protected function getVars "author: Frenkel TUD 2012-11"
1620 input DAE.ComponentRef cr;
1621 input BackendDAE.Variables vars;
1622 input BackendDAE.Shared shared;
1623 output list<BackendDAE.Var> oVars;
1624 output list<Integer> oIndexs;
1625 output Boolean varskn;
1626 output Boolean time_;
1627 algorithm
1628 (oVars, oIndexs, varskn, time_) := matchcontinue cr
1629 case DAE.CREF_IDENT(ident = "time", subscriptLst = {})
1630 then
1631 ({}, {}, true, true);
1632 case _
1633 algorithm
1634
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 228664 times.
237253 (oVars as _::_, oIndexs) := BackendVariable.getVar(cr, vars);
1635 then
1636 (oVars, oIndexs, false, false);
1637 case _
1638 algorithm
1639
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8587 times.
8589 (oVars as _::_, oIndexs) := BackendVariable.getVarShared(cr, shared);
1640
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8587 times.
8587 if ComponentReference.crefIsScalarWithVariableSubs(cr) then
1641 //waurich: We don't support this case properly at the moment. Don't assign an alias.
1642 oVars := {};
1643 oIndexs := {};
1644 end if;
1645 then
1646 (oVars, oIndexs, true, false);
1647 end matchcontinue;
1648 end getVars;
1649
1650 protected function generateSimpleContainters "author: Frenkel TUD 2012-12
1651 add a simple equation to the list of simple equations"
1652 input list<BackendDAE.Var> vars1;
1653 input Boolean negatedCr1;
1654 input list<Integer> ilst1;
1655 input Boolean varskn1;
1656 input Boolean time1;
1657 input list<BackendDAE.Var> vars2;
1658 input Boolean negatedCr2;
1659 input list<Integer> ilst2;
1660 input Boolean varskn2;
1661 input Boolean time2;
1662 input EquationSourceAndAttributes eqnAttributes;
1663 input list<SimpleContainer> iSeqns;
1664 input Integer iIndex;
1665 input array<list<Integer>> iMT;
1666 output list<SimpleContainer> oSeqns;
1667 output Integer oIndex;
1668 output array<list<Integer>> oMT;
1669 algorithm
1670 (oSeqns, oIndex, oMT) := match(vars1, ilst1, varskn1, time1, vars2, ilst2, varskn2, time2)
1671 local
1672 BackendDAE.Var v1, v2;
1673 Integer i1, i2;
1674 list<BackendDAE.Var> vlst1, vlst2;
1675 list<Integer> irest1, irest2, colum;
1676 list<SimpleContainer> seqns;
1677 Integer index;
1678 array<list<Integer>> mT;
1679 DAE.ComponentRef cr1, cr2;
1680
1681 case ({BackendDAE.VAR(varName=cr1)}, {i1}, true, true, {BackendDAE.VAR(varName=cr2)}, {i2}, false, false)
1682 algorithm
1683 ✗ colum := iMT[i2];
1684 ✗ arrayUpdate(iMT, i2, iIndex::colum);
1685 ✗ then
1686 (TIMEALIAS(cr2, negatedCr2, i2, cr1, negatedCr1, i1, eqnAttributes, -1)::iSeqns, iIndex+1, iMT);
1687
1688 case ({BackendDAE.VAR(varName=cr1)}, {i1}, false, false, {BackendDAE.VAR(varName=cr2)}, {i2}, true, true)
1689 algorithm
1690 ✗ colum := iMT[i1];
1691 ✗ arrayUpdate(iMT, i1, iIndex::colum);
1692 ✗ then
1693 (TIMEALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, -1)::iSeqns, iIndex+1, iMT);
1694
1695 case({}, _, _, _, {}, _, _, _) then (iSeqns, iIndex, iMT);
1696
1697 case(v1::vlst1, i1::irest1, _, false, v2::vlst2, i2::irest2, _, false)
1698 algorithm
1699 118561 (seqns, index, mT) := generateSimpleContainter(v1, negatedCr1, i1, varskn1, v2, negatedCr2, i2, varskn2, eqnAttributes, iSeqns, iIndex, iMT);
1700 118561 (seqns, index, mT) := generateSimpleContainters(vlst1, negatedCr1, irest1, varskn1, time1, vlst2, negatedCr2, irest2, varskn2, time2, eqnAttributes, seqns, index, mT);
1701 then
1702 (seqns, index, mT);
1703
1704 end match;
1705 end generateSimpleContainters;
1706
1707 protected function generateSimpleContainter "author: Frenkel TUD 2012-12
1708 add a simple equation to the list of simple equations"
1709 input BackendDAE.Var v1;
1710 input Boolean negatedCr1;
1711 input Integer i1;
1712 input Boolean varskn1;
1713 input BackendDAE.Var v2;
1714 input Boolean negatedCr2;
1715 input Integer i2;
1716 input Boolean varskn2;
1717 input EquationSourceAndAttributes eqnAttributes;
1718 input list<SimpleContainer> iSeqns;
1719 input Integer iIndex;
1720 input array<list<Integer>> iMT;
1721 output list<SimpleContainer> oSeqns;
1722 output Integer oIndex;
1723 output array<list<Integer>> oMT;
1724 algorithm
1725 (oSeqns, oIndex, oMT) := match(v1, varskn1, v2, varskn2, eqnAttributes)
1726 local
1727 DAE.ComponentRef cr1, cr2;
1728 list<Integer> colum;
1729 DAE.Exp crexp1, crexp2;
1730 String lhs, rhs;
1731 DAE.ElementSource source;
1732
1733 case (BackendDAE.VAR(varName=cr1), false, BackendDAE.VAR(varName=cr2), false, _)
1734 algorithm
1735 109958 checkEqualAlias(intEq(i1, i2), v1, negatedCr1, v2, negatedCr2, eqnAttributes);
1736 109958 colum := iMT[i1];
1737 109958 arrayUpdate(iMT, i1, iIndex::colum);
1738 109958 colum := iMT[i2];
1739 109958 arrayUpdate(iMT, i2, iIndex::colum);
1740
4/4
✓ Branch 0 taken 98305 times.
✓ Branch 1 taken 11653 times.
✓ Branch 2 taken 109421 times.
✓ Branch 3 taken 537 times.
427642 then
1741 (ALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, -1)::iSeqns, iIndex+1, iMT);
1742
1743 case (BackendDAE.VAR(varName=cr1), true, BackendDAE.VAR(varName=cr2), false, _)
1744 algorithm
1745 309 colum := iMT[i2];
1746 309 arrayUpdate(iMT, i2, iIndex::colum);
1747
4/4
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 288 times.
✓ Branch 3 taken 21 times.
1195 then
1748 (PARAMETERALIAS(cr2, negatedCr2, i2, cr1, negatedCr1, i1, eqnAttributes, -1)::iSeqns, iIndex+1, iMT);
1749
1750 case (BackendDAE.VAR(varName=cr1), false, BackendDAE.VAR(varName=cr2), true, _)
1751 algorithm
1752 8294 colum := iMT[i1];
1753 8294 arrayUpdate(iMT, i1, iIndex::colum);
1754
4/4
✓ Branch 0 taken 8030 times.
✓ Branch 1 taken 264 times.
✓ Branch 2 taken 8280 times.
✓ Branch 3 taken 14 times.
32898 then
1755 (PARAMETERALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, -1)::iSeqns, iIndex+1, iMT);
1756 case (BackendDAE.VAR(varName=cr1), true, BackendDAE.VAR(varName=cr2), true, (source, _))
1757 algorithm
1758 ✗ crexp1 := Expression.crefExp(cr1);
1759 ✗ crexp2 := Expression.crefExp(cr2);
1760 ✗ crexp1 := negateExpression(negatedCr1, crexp1, crexp1, " generateSimpleContainter ");
1761 ✗ crexp2 := negateExpression(negatedCr2, crexp2, crexp2, " generateSimpleContainter ");
1762 ✗ lhs := ExpressionBasics.printExpStr(crexp1);
1763 ✗ rhs := ExpressionBasics.printExpStr(crexp2);
1764 ✗ Error.addSourceMessage(Error.EQ_WITHOUT_TIME_DEP_VARS, {lhs, rhs}, ElementSource.getElementSourceFileInfo(source));
1765 ✗ then
1766 fail();
1767
1768 end match;
1769 end generateSimpleContainter;
1770
1771 protected function checkEqualAlias "author: Frenkel TUD 2012-12
1772 report a warning if we found an equation a=a"
1773 input Boolean equal;
1774 input BackendDAE.Var v1;
1775 input Boolean negatedCr1;
1776 input BackendDAE.Var v2;
1777 input Boolean negatedCr2;
1778 input EquationSourceAndAttributes eqnAttributes;
1779 algorithm
1780 () := match(equal, v1, v2, eqnAttributes)
1781 local
1782 DAE.ComponentRef cr1, cr2;
1783 DAE.Exp crexp1, crexp2;
1784 String eqn_str, var_str;
1785 SourceInfo info;
1786 DAE.ElementSource source;
1787
1788 case(false, _, _, _) then ();
1789
1790 case(true, BackendDAE.VAR(varName=cr1), BackendDAE.VAR(varName=cr2), (source, _))
1791 algorithm
1792 ✗ var_str := BackendDump.varString(v1);
1793 ✗ crexp1 := Expression.crefExp(cr1);
1794 ✗ crexp2 := Expression.crefExp(cr2);
1795 ✗ crexp1 := negateExpression(negatedCr1, crexp1, crexp1, " checkEqualAlias ");
1796 ✗ crexp2 := negateExpression(negatedCr2, crexp2, crexp2, " checkEqualAlias ");
1797 ✗ eqn_str := ExpressionBasics.printExpStr(crexp1) + " = " + ExpressionBasics.printExpStr(crexp2) + "\n";
1798 ✗ info := ElementSource.getElementSourceFileInfo(source);
1799 ✗ Error.addSourceMessage(Error.STRUCT_SINGULAR_SYSTEM, {eqn_str, var_str}, info);
1800 ✗ then
1801 fail();
1802
1803 end match;
1804 end checkEqualAlias;
1805
1806 protected function timeIndependentEquationAcausal "author: Frenkel TUD 2012-12
1807 helper for simpleEquationsAcausal"
1808 input DAE.Exp lhs;
1809 input DAE.Exp rhs;
1810 input EquationSourceAndAttributes eqnAttributes;
1811 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1812 input AccTuple inTpl;
1813 output AccTuple outTpl;
1814 algorithm
1815 outTpl := matchcontinue (selfCalled, inTpl)
1816 local
1817 DAE.Type ty;
1818 BackendDAE.Variables vars, globalKnownVars;
1819 list<Integer> ilst;
1820 list<BackendDAE.Var> vlst;
1821 AvlSetInt.Tree tree;
1822
1823 case (_, (vars, BackendDAE.SHARED(globalKnownVars=globalKnownVars), _, _, _, _, _))
1824 algorithm
1825 // collect vars and check if variable time not there
1826
2/2
✓ Branch 3 taken 1713 times.
✓ Branch 4 taken 261751 times.
283898 (_, (false, ilst)) := Expression.traverseExpTopDown(lhs, function traversingTimeVarsFinder(vars = vars, globalKnownVars = globalKnownVars), (false, {}));
1827
2/2
✓ Branch 4 taken 20434 times.
✓ Branch 5 taken 241317 times.
261751 (_, (false, ilst)) := Expression.traverseExpTopDown(rhs, function traversingTimeVarsFinder(vars = vars, globalKnownVars = globalKnownVars), (false, ilst));
1828 241317 tree := AvlSetInt.new();
1829 241317 tree := AvlSetInt.addList(tree, ilst);
1830 241317 ilst := AvlSetInt.listKeys(tree);
1831 241317 vlst := List.map1r(ilst, BackendVariable.getVarAt, vars);
1832 241317 then
1833 solveTimeIndependentAcausal(vlst, ilst, lhs, rhs, eqnAttributes, inTpl);
1834 // in all other case keep the equation
1835 case (true, _)
1836 algorithm
1837 3639 ty := Expression.typeof(lhs);
1838 3639 then
1839 generateEquation(lhs, rhs, ty, eqnAttributes, inTpl);
1840 end matchcontinue;
1841 end timeIndependentEquationAcausal;
1842
1843 protected function timeIndependentExpressionAcausal "author: Frenkel TUD 2012-12
1844 helper for simpleEquationsAcausal"
1845 input DAE.Exp exp;
1846 input EquationSourceAndAttributes eqnAttributes;
1847 input Boolean selfCalled "this is a flag to know if we are selfcalled to save memory in case of non simple equation";
1848 input AccTuple inTpl;
1849 output AccTuple outTpl;
1850 algorithm
1851 outTpl := matchcontinue (selfCalled, inTpl)
1852 local
1853 DAE.Exp e2;
1854 DAE.Type ty;
1855 BackendDAE.Variables vars, globalKnownVars;
1856 list<Integer> ilst;
1857 list<BackendDAE.Var> vlst;
1858 AvlSetInt.Tree tree;
1859
1860 case (_, (vars, BackendDAE.SHARED(globalKnownVars=globalKnownVars), _, _, _, _, _))
1861 algorithm
1862 // collect vars and check if variable time not there
1863
2/2
✓ Branch 3 taken 982 times.
✓ Branch 4 taken 62555 times.
63537 (_, (false, ilst)) := Expression.traverseExpTopDown(exp, function traversingTimeVarsFinder(vars = vars, globalKnownVars = globalKnownVars), (false, {}));
1864 62555 tree := AvlSetInt.new();
1865 62555 tree := AvlSetInt.addList(tree, ilst);
1866 62555 ilst := AvlSetInt.listKeys(tree);
1867 62555 vlst := List.map1r(ilst, BackendVariable.getVarAt, vars);
1868 62555 ty := Expression.typeof(exp);
1869 62555 e2 := Expression.makeConstZero(ty);
1870 62555 then
1871 // shoulde be ok since solve checks only for iszero
1872 solveTimeIndependentAcausal(vlst, ilst, exp, e2, eqnAttributes, inTpl);
1873 // in all other case keep the equation
1874 case (true, _)
1875 algorithm
1876 270 ty := Expression.typeof(exp);
1877 270 e2 := Expression.makeConstZero(ty);
1878 270 then
1879 generateEquation(exp, e2, ty, eqnAttributes, inTpl);
1880 end matchcontinue;
1881 end timeIndependentExpressionAcausal;
1882
1883 protected function toplevelInputOrUnfixed "author: Frenkel TUD 2012-12
1884 return true is var on topliven and input or is unfixed parameter or unreplaceable"
1885 input BackendDAE.Var inVar;
1886 output Boolean b;
1887 algorithm
1888
8/8
✓ Branch 1 taken 167211 times.
✓ Branch 2 taken 16277 times.
✓ Branch 4 taken 166747 times.
✓ Branch 5 taken 464 times.
✓ Branch 7 taken 148342 times.
✓ Branch 8 taken 18405 times.
✓ Branch 10 taken 2459 times.
✓ Branch 11 taken 145883 times.
183488 b := BackendVariable.isVarOnTopLevelAndInput(inVar) or BackendVariable.varUnreplaceable(inVar) or
1889 BackendVariable.isParam(inVar) and not BackendVariable.varFixed(inVar);
1890 end toplevelInputOrUnfixed;
1891
1892 protected function traversingTimeVarsFinder "author: Frenkel 2012-12
1893 Collects the variable indices of an expression, in no particular order; the
1894 flag is set when it depends on time. Bind vars and globalKnownVars by
1895 partial application."
1896 input DAE.Exp inExp;
1897 input tuple<Boolean, list<Integer>> inTuple;
1898 input BackendDAE.Variables vars;
1899 input BackendDAE.Variables globalKnownVars;
1900 output DAE.Exp outExp;
1901 output Boolean cont;
1902 output tuple<Boolean, list<Integer>> outTuple;
1903 algorithm
1904 (outExp,cont,outTuple) := match (inExp,inTuple)
1905 local
1906 Boolean b, c, topLevelInput;
1907 DAE.ComponentRef cr;
1908 list<Integer> ilst, vlst;
1909 list<BackendDAE.Var> varlst;
1910 tuple<Boolean, list<Integer>> tpl;
1911
1912 case (DAE.CREF(DAE.CREF_IDENT(ident="time", subscriptLst={}), _), (b, ilst))
1913
2/2
✓ Branch 0 taken 3913 times.
✓ Branch 1 taken 12 times.
3925 then (inExp, false, if b then inTuple else (true, ilst));
1914
1915 case (DAE.CREF(cr, _), (b, ilst)) algorithm
1916 try
1917
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 178162 times.
1417434 (varlst, _::_):= BackendVariable.getVar(cr, globalKnownVars) "input variables stored in known variables are input on top level";
1918 178162 topLevelInput := not List.none(varlst, toplevelInputOrUnfixed);
1919 else
1920 topLevelInput := false;
1921 end try;
1922
2/2
✓ Branch 0 taken 19200 times.
✓ Branch 1 taken 1398234 times.
1417434 if topLevelInput then
1923
2/2
✓ Branch 0 taken 17563 times.
✓ Branch 1 taken 1637 times.
19200 (c, tpl) := (false, if b then inTuple else (true, ilst));
1924 else
1925 // var
1926 try
1927
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1225447 times.
1398234 (_::_, vlst):= BackendVariable.getVar(cr, vars);
1928
2/2
✓ Branch 1 taken 1221335 times.
✓ Branch 2 taken 4112 times.
2446782 (c, tpl) := (true, (b, listAppend(vlst, ilst)));
1929 else
1930
2/2
✓ Branch 0 taken 4655 times.
✓ Branch 1 taken 168132 times.
177442 (c, tpl) := (not b, inTuple);
1931 end try;
1932 end if;
1933 then (inExp, c, tpl);
1934
1935
2/2
✓ Branch 0 taken 1653 times.
✓ Branch 1 taken 82 times.
1735 case (DAE.CALL(path = Absyn.IDENT(name="pre")), (b, ilst)) then (inExp, false, if b then inTuple else (true, ilst));
1936 ✗ case (DAE.CALL(path = Absyn.IDENT(name="previous")), (b, ilst)) then (inExp, false, if b then inTuple else (true, ilst));
1937 ✗ case (DAE.CALL(path = Absyn.IDENT(name="change")), (b, ilst)) then (inExp, false, if b then inTuple else (true, ilst));
1938 ✗ case (DAE.CALL(path = Absyn.IDENT(name="edge")), (b, ilst)) then (inExp, false, if b then inTuple else (true, ilst));
1939
1940 case (_, (b, _))
1941 2904194 then (inExp, not b, inTuple);
1942 end match;
1943 end traversingTimeVarsFinder;
1944
1945 protected function solveTimeIndependentAcausal "author: Frenkel TUD 2012-12
1946 helper for simpleEquationsAcausal"
1947 input list<BackendDAE.Var> vlst;
1948 input list<Integer> ilst;
1949 input DAE.Exp lhs;
1950 input DAE.Exp rhs;
1951 input EquationSourceAndAttributes eqnAttributes;
1952 input AccTuple inTpl;
1953 output AccTuple outTpl;
1954 algorithm
1955 outTpl := match (vlst, ilst, eqnAttributes, inTpl)
1956 local
1957 DAE.ComponentRef cr;
1958 DAE.Exp cre, es;
1959 BackendDAE.Var v;
1960 Integer i, size;
1961 DAE.ElementSource source;
1962 BackendDAE.EquationAttributes eqAttr;
1963
1964 case ({v as BackendDAE.VAR(varName=cr)}, {i}, _, _)
1965 algorithm
1966 // try to solve the equation
1967 46690 cre := Expression.crefExp(cr);
1968
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 46011 times.
46690 (es, {}) := ExpressionSolve.solve(lhs, rhs, cre);
1969 // constant or alias
1970 46011 then
1971 constOrAliasAcausal(v, i, cr, es, eqnAttributes, inTpl);
1972 case (_, _, (source, eqAttr), (_, BackendDAE.SHARED(), _, _, _, _, _))
1973 algorithm
1974 // size of equation have to be equal with number of vars
1975 257182 size := Expression.sizeOf(Expression.typeof(lhs));
1976
2/2
✓ Branch 1 taken 257149 times.
✓ Branch 2 taken 33 times.
257182 true := intEq(size, listLength(vlst));
1977 33 then
1978 solveTimeIndependentAcausal1(vlst, ilst, lhs, rhs, (source, eqAttr), inTpl);
1979 end match;
1980 end solveTimeIndependentAcausal;
1981
1982 protected function solveTimeIndependentAcausal1 "author: Frenkel TUD 2012-12
1983 helper for simpleEquations"
1984 input list<BackendDAE.Var> vlst;
1985 input list<Integer> ilst;
1986 input DAE.Exp lhs;
1987 input DAE.Exp rhs;
1988 input EquationSourceAndAttributes eqnAttributes;
1989 input AccTuple inTpl;
1990 output AccTuple outTpl;
1991 algorithm
1992 outTpl := match inTpl
1993 local
1994 DAE.ComponentRef cr;
1995 DAE.Exp cre, es;
1996 list<DAE.ComponentRef> crlst;
1997 // a = ...
1998 case _
1999 algorithm
2000
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
66 cr::crlst := List.map(vlst, BackendVariable.varCref);
2001 33 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
2002
1/2
✓ Branch 3 taken 33 times.
✗ Branch 4 not taken.
33 true := List.all(crlst, function ComponentReferenceBasics.crefPrefixOf(prefixCref = cr));
2003 // try to solve the equation
2004 ✗ cre := Expression.crefExp(cr);
2005 ✗ (es, {}) := ExpressionSolve.solve(lhs, rhs, cre);
2006 // constant or alias
2007 ✗ then
2008 constOrAliasArrayAcausal(vlst, ilst, es, eqnAttributes, inTpl);
2009 // {a1, a2, a3, ..} = ...
2010
2011 end match;
2012 end solveTimeIndependentAcausal1;
2013
2014 protected function constOrAliasArrayAcausal "author: Frenkel TUD 2012-12"
2015 input list<BackendDAE.Var> vars;
2016 input list<Integer> indxs;
2017 input DAE.Exp exp;
2018 input EquationSourceAndAttributes eqnAttributes;
2019 input AccTuple inTpl;
2020 output AccTuple outTpl;
2021 algorithm
2022 outTpl := match (vars, indxs)
2023 local
2024 BackendDAE.Var v;
2025 list<BackendDAE.Var> vlst;
2026 Integer i;
2027 list<Integer> ilst;
2028 DAE.ComponentRef cr;
2029 DAE.Exp e;
2030 list<DAE.Subscript> subs;
2031 AccTuple tpl;
2032 case ({}, _) then inTpl;
2033 case ((v as BackendDAE.VAR(varName=cr))::vlst, i::ilst)
2034 algorithm
2035 ✗ subs := ComponentReference.crefLastSubs(cr);
2036 ✗ e := Expression.applyExpSubscripts(exp, subs);
2037 ✗ tpl := constOrAliasAcausal(v, i, cr, e, eqnAttributes, inTpl);
2038 ✗ then
2039 constOrAliasArrayAcausal(vlst, ilst, exp, eqnAttributes, tpl);
2040 end match;
2041 end constOrAliasArrayAcausal;
2042
2043 protected function constOrAliasAcausal "author: Frenkel TUD 2012-12"
2044 input BackendDAE.Var var;
2045 input Integer i;
2046 input DAE.ComponentRef cr;
2047 input DAE.Exp exp;
2048 input EquationSourceAndAttributes eqnAttributes;
2049 input AccTuple inTpl;
2050 output AccTuple outTpl;
2051 algorithm
2052 outTpl := matchcontinue inTpl
2053 local
2054 BackendDAE.Variables vars, globalKnownVars;
2055 BackendDAE.Shared shared;
2056 list<BackendDAE.Equation> eqns;
2057 list<SimpleContainer> seqns;
2058 Integer index;
2059 array<list<Integer>> mT;
2060 DAE.ComponentRef cra;
2061 list<BackendDAE.Var> vars2;
2062 list<Integer> ilst2;
2063 Boolean negated;
2064 list<Integer> colum;
2065 AvlTreePathFunction.Tree functions;
2066 DAE.Exp exp2;
2067 // alias a
2068 case (vars, shared, eqns, seqns, index, mT, _)
2069 algorithm
2070 // alias
2071 46011 (negated, cra) := aliasExp(exp);
2072 // get Variables
2073 16 globalKnownVars := BackendVariable.daeGlobalKnownVars(shared);
2074 16 (vars2, ilst2) := BackendVariable.getVar(cra, globalKnownVars);
2075 // add to Simple Equations List
2076 16 (seqns, index, mT) := generateSimpleContainters({var}, false, {i}, false, false, vars2, negated, ilst2, true, false, eqnAttributes, seqns, index, mT);
2077 16 then
2078 ((vars, shared, eqns, seqns, index, mT, true));
2079 // const
2080 case (vars, shared, eqns, seqns, index, mT, _)
2081 guard
2082 Expression.isConstValue(exp)
2083 algorithm
2084
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41864 times.
41864 if Flags.isSet(Flags.DEBUG_ALIAS) then
2085 ✗ BackendDump.debugStrCrefStrExpStr("Const Equation ", cr, " = ", exp, " found.\n");
2086 end if;
2087 41864 colum := mT[i];
2088 41864 arrayUpdate(mT, i, index::colum);
2089 83728 then
2090 ((vars, shared, eqns, TIMEINDEPENTVAR(cr, i, exp, eqnAttributes, -1)::seqns, index+1, mT, true));
2091
2092 case (vars, shared as BackendDAE.SHARED(functionTree=functions), eqns, seqns, index, mT, _)
2093 guard
2094 not Expression.isImpure(exp) and not Expression.containsRecordType(exp) // lochel: this is at least needed for impure functions
2095 algorithm
2096 //exp2 = Ceval.cevalSimpleWithFunctionTreeReturnExp(exp, functions);
2097 3321 exp2 := EvaluateFunctions.evaluateConstantFunctionCallExp(exp, functions, false, Flags.getConfigInt(Flags.EVAL_RECURSION_LIMIT));
2098
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3321 times.
3321 if Flags.isSet(Flags.DEBUG_ALIAS) then
2099 ✗ BackendDump.debugStrCrefStrExpStr("Const Equation (through Ceval, case 1) ", cr, " = ", exp, " found.\n");
2100 end if;
2101 3321 colum := mT[i];
2102 3321 arrayUpdate(mT, i, index::colum);
2103 6642 then
2104 ((vars, shared, eqns, TIMEINDEPENTVAR(cr, i, exp2, eqnAttributes, -1)::seqns, index+1, mT, true));
2105
2106 // TODO: Remove or fix this case. We do not want to add function calls here as they are inlined in a very bad way sometimes.
2107 case (vars, shared, eqns, seqns, index, mT, _)
2108 guard
2109 not Expression.isImpure(exp) and not Expression.containsRecordType(exp) // lochel: this is at least needed for impure functions
2110 algorithm
2111 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
2112 ✗ BackendDump.debugStrCrefStrExpStr("Const Equation (through Ceval, case 2) ", cr, " = ", exp, " found.\n");
2113 end if;
2114 ✗ colum := mT[i];
2115 ✗ arrayUpdate(mT, i, index::colum);
2116 ✗ then ((vars, shared, eqns, TIMEINDEPENTVAR(cr, i, exp, eqnAttributes, -1)::seqns, index+1, mT, true));
2117
2118 end matchcontinue;
2119 end constOrAliasAcausal;
2120
2121 protected function aliasExp "author: Frenkel TUD 2011-04"
2122 input DAE.Exp exp;
2123 output Boolean negate;
2124 output DAE.ComponentRef outCr;
2125 algorithm
2126 (negate, outCr) := match exp
2127 local DAE.ComponentRef cr;
2128 // alias a
2129 case DAE.CREF(componentRef = cr) then (false, cr);
2130 // alias -a
2131 case DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = cr)) then (true, cr);
2132 // alias -a
2133 case DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr)) then (true, cr);
2134 // alias not a
2135 case DAE.LUNARY(DAE.NOT(_), DAE.CREF(componentRef = cr)) then (true, cr);
2136 end match;
2137 end aliasExp;
2138
2139 protected function handleSets "author: Frenkel TUD 2012-12
2140 convert the found simple equtions to replacements and remove the simple
2141 variabes from the variables"
2142 input Integer containerIdx "downwards";
2143 input Integer inMark;
2144 input array<SimpleContainer> containerArr;
2145 input array<list<Integer>> iMT;
2146 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2147 input output BackendDAE.Variables vars;
2148 input output list<BackendDAE.Equation> eqnslst;
2149 input output BackendDAE.Shared shared;
2150 input output BackendVarTransform.VariableReplacements repl;
2151 output Boolean warnAliasConflicts = false;
2152 protected
2153 Option<tuple<Integer, Integer>> rmax, smax;
2154 Option<Integer> unremovable, const;
2155 Integer mark = inMark;
2156 Boolean b;
2157 algorithm
2158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26524 times.
190270 for idx in containerIdx:-1:1 loop
2159
2/2
✓ Branch 2 taken 83944 times.
✓ Branch 3 taken 79802 times.
163746 if not intGt(getVisited(containerArr[idx]), 0) then
2160 // convert the found simple equtions to replacements and remove the simple
2161 // variabes from the variables
2162
2163 // collect set
2164 //print("Check Simple Container "+dumpSimpleContainer(containerArr[idx])+"\n");
2165 83944 (rmax, smax, unremovable, const, _) := getAlias({idx}, NONE(), mark, containerArr, iMT, vars, unReplaceable, false, {}, NONE(), NONE(), NONE(), NONE());
2166 // traverse set and add replacements, move vars, ...
2167 83944 (vars, eqnslst, shared, repl, b) := handleSet(rmax, smax, unremovable, const, mark+1, containerArr, iMT, unReplaceable, vars, eqnslst, shared, repl);
2168 83944 mark := mark+2;
2169
4/4
✓ Branch 0 taken 78846 times.
✓ Branch 1 taken 5098 times.
✓ Branch 2 taken 78766 times.
✓ Branch 3 taken 80 times.
83944 warnAliasConflicts := warnAliasConflicts or b;
2170 end if;
2171 end for;
2172 end handleSets;
2173
2174 protected uniontype AliasWork "work item of the alias graph traversal in getAlias"
2175 record ALIAS_ROWS "containers still to visit on one level"
2176 list<Integer> rows;
2177 Option<Integer> prevVar;
2178 Boolean negate;
2179 list<Integer> stack;
2180 end ALIAS_ROWS;
2181
2182 record ALIAS_SECOND "the second variable of an alias equation, once the first one is done"
2183 Integer var;
2184 Integer container;
2185 Boolean negate;
2186 list<Integer> stack;
2187 end ALIAS_SECOND;
2188 end AliasWork;
2189
2190 protected function getAlias "author: Frenkel TUD 2012-12
2191 traverse the simple tree to find the variable we keep"
2192 input list<Integer> rows; //{containerIdx}
2193 input Option<Integer> prevVar; //previous variable
2194 input Integer mark; //how to mark a visited container
2195 input array<SimpleContainer> containerArr;
2196 input array<list<Integer>> iMT;//[varIdx] = simpleContainer
2197 input BackendDAE.Variables vars;
2198 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2199 input Boolean negate;
2200 input list<Integer> stack;
2201 input Option<tuple<Integer, Integer>> iRmax;
2202 input Option<tuple<Integer, Integer>> iSmax;
2203 input Option<Integer> iUnremovable;
2204 input Option<Integer> iConst;
2205 output Option<tuple<Integer, Integer>> oRmax = iRmax;
2206 output Option<tuple<Integer, Integer>> oSmax = iSmax;
2207 output Option<Integer> oUnremovable = iUnremovable;
2208 output Option<Integer> oConst = iConst;
2209 output Boolean oContinue = true;
2210 protected
2211 list<AliasWork> work = {ALIAS_ROWS(rows, prevVar, negate, stack)};
2212 AliasWork item;
2213 SimpleContainer container;
2214 list<Integer> rest, adjEqs, currStack;
2215 Integer r, i, i1, i2, prevVarIdx;
2216 Boolean neg, negatedCr1, negatedCr2;
2217 algorithm
2218
2/2
✓ Branch 0 taken 412271 times.
✓ Branch 1 taken 83944 times.
496215 while not listEmpty(work) loop
2219 412271 item :: work := work;
2220
2221 () := match item
2222 // scored even when the walk stopped, followed only if not
2223 case ALIAS_SECOND()
2224 algorithm
2225 36461 (oRmax, oSmax, oUnremovable) := getAliasScore(item.var, item.container, vars, unReplaceable, oRmax, oSmax, oUnremovable);
2226
2/2
✓ Branch 0 taken 35672 times.
✓ Branch 1 taken 789 times.
36461 if oContinue then
2227 35672 adjEqs := List.removeOnTrue(item.container, intEq, iMT[item.var]);
2228 35672 work := ALIAS_ROWS(adjEqs, SOME(item.var), item.negate, item.stack)::work;
2229 end if;
2230 then ();
2231
2232 case ALIAS_ROWS() guard oContinue and not listEmpty(item.rows)
2233 algorithm
2234 154991 r :: rest := item.rows;
2235 154991 container := containerArr[r];
2236
2237
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 154991 times.
154991 if isVisited(mark, container) then
2238 ✗ oConst := getAliasCircular(container, r, item.negate, item.stack, containerArr, oUnremovable);
2239 oRmax := NONE();
2240 ✗ oSmax := NONE();
2241 ✗ oUnremovable := NONE();
2242 oContinue := false;
2243 else
2244 // set visited
2245 154991 arrayUpdate(containerArr, r, setVisited(mark, container));
2246 154991 work := ALIAS_ROWS(rest, item.prevVar, item.negate, item.stack)::work;
2247 154991 currStack := r::item.stack;
2248
2249 () := match (container, item.prevVar)
2250 case (ALIAS(i1=i1, negatedCr1=negatedCr1, i2=i2, negatedCr2=negatedCr2), NONE())
2251 algorithm
2252 36461 neg := boolOr(negatedCr1, negatedCr2);
2253
2/2
✓ Branch 0 taken 4472 times.
✓ Branch 1 taken 31989 times.
36461 neg := if neg then not item.negate else item.negate;
2254 36461 (oRmax, oSmax, oUnremovable) := getAliasScore(i1, r, vars, unReplaceable, oRmax, oSmax, oUnremovable);
2255 36461 adjEqs := List.removeOnTrue(r, intEq, iMT[i1]);
2256 // pushed first, so it runs after this subtree
2257
2/2
✓ Branch 0 taken 31989 times.
✓ Branch 1 taken 4472 times.
68450 work := ALIAS_SECOND(i2, r, neg, currStack)::work;
2258 36461 work := ALIAS_ROWS(adjEqs, SOME(i1), neg, currStack)::work;
2259 then ();
2260
2261 case (ALIAS(i1=i1, negatedCr1=negatedCr1, i2=i2, negatedCr2=negatedCr2), SOME(prevVarIdx))
2262 algorithm
2263
2/2
✓ Branch 0 taken 37726 times.
✓ Branch 1 taken 27016 times.
64742 i := if intEq(prevVarIdx, i1) then i2 else i1;
2264 64742 neg := boolOr(negatedCr1, negatedCr2);
2265
2/2
✓ Branch 0 taken 7105 times.
✓ Branch 1 taken 57637 times.
64742 neg := if neg then not item.negate else item.negate;
2266 64742 (oRmax, oSmax, oUnremovable) := getAliasScore(i, r, vars, unReplaceable, oRmax, oSmax, oUnremovable);
2267 64742 adjEqs := List.removeOnTrue(r, intEq, iMT[i]);
2268 // go deeper
2269
2/2
✓ Branch 0 taken 56861 times.
✓ Branch 1 taken 7881 times.
129484 work := ALIAS_ROWS(adjEqs, SOME(i), neg, currStack)::work;
2270 then ();
2271
2272 // PARAMETERALIAS, TIMEALIAS and TIMEINDEPENTVAR end the traversal
2273 else
2274 algorithm
2275 oRmax := NONE();
2276 53788 oSmax := NONE();
2277 53788 oUnremovable := NONE();
2278 oConst := SOME(r);
2279 oContinue := false;
2280 then ();
2281 end match;
2282 end if;
2283 then ();
2284
2285 else ();
2286 end match;
2287 end while;
2288 end getAlias;
2289
2290 protected function getAliasScore "author: Frenkel TUD 2012-12
2291 scores the variable of an alias equation, see getAlias3"
2292 input Integer varIdx;
2293 input Integer containerIdx;
2294 input BackendDAE.Variables vars;
2295 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2296 input Option<tuple<Integer, Integer>> iRmax;
2297 input Option<tuple<Integer, Integer>> iSmax;
2298 input Option<Integer> iUnremovable;
2299 output Option<tuple<Integer, Integer>> oRmax;
2300 output Option<tuple<Integer, Integer>> oSmax;
2301 output Option<Integer> oUnremovable;
2302 protected
2303 BackendDAE.Var v;
2304 Boolean state, replaceable_, replaceble1;
2305 algorithm
2306 137664 v := BackendVariable.getVarAt(vars, varIdx);
2307 137664 (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2308
3/4
✓ Branch 1 taken 131190 times.
✓ Branch 2 taken 6474 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 131190 times.
137664 state := BackendVariable.isStateVar(v) or BackendVariable.isClockedStateVar(v);
2309
4/4
✓ Branch 0 taken 137037 times.
✓ Branch 1 taken 627 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 133380 times.
141948 (oRmax, oSmax, oUnremovable) := getAlias3(v, varIdx, state, replaceable_ and replaceble1, containerIdx, iRmax, iSmax, iUnremovable);
2310 end getAliasScore;
2311
2312 protected function getAliasCircular "author: Frenkel TUD 2012-12
2313 the container was visited before: either a valid circular equality or an error"
2314 input SimpleContainer container;
2315 input Integer currIdx;
2316 input Boolean negate;
2317 input list<Integer> stack;
2318 input array<SimpleContainer> containerArr;
2319 input Option<Integer> iUnremovable;
2320 output Option<Integer> oConst;
2321 protected
2322 DAE.ComponentRef cr;
2323 String msg;
2324 algorithm
2325 oConst := matchcontinue (negate, iUnremovable)
2326 // valid circular equality
2327 case (true, SOME(_))
2328 algorithm
2329 // is only valid for real or int
2330 ✗ ALIAS(cr1=cr) := container;
2331 ✗ true := Types.isIntegerOrRealOrSubTypeOfEither(ComponentReference.crefLastType(cr));
2332 then iUnremovable;
2333
2334 case (true, _)
2335 algorithm
2336 ✗ ALIAS(cr1=cr) := container;
2337 ✗ true := Types.isIntegerOrRealOrSubTypeOfEither(ComponentReference.crefLastType(cr));
2338 then SOME(currIdx);
2339
2340 else
2341 algorithm
2342 msg := "Circular Equalities Detected for Variables:\n";
2343 ✗ msg := circularEqualityMsg(stack, currIdx, containerArr, msg);
2344 // report error
2345 ✗ Error.addMessage(Error.INTERNAL_ERROR, {msg});
2346 ✗ then fail();
2347 end matchcontinue;
2348 end getAliasCircular;
2349
2350 protected function circularEqualityMsg "author: Frenkel TUD 2013-05, adrpo"
2351 input list<Integer> stack;
2352 input Integer iR;
2353 input array<SimpleContainer> simpleeqnsarr;
2354 input String iMsg;
2355 output String oMsg;
2356 protected
2357 list<String> lst;
2358 String msg;
2359 algorithm
2360 ✗ lst := circularEqualityMsg_dispatch(stack, iR, simpleeqnsarr);
2361 ✗ msg := stringDelimitList(lst, "\n");
2362 ✗ msg := stringAppendList({iMsg, msg, "\n"});
2363 oMsg := msg;
2364 end circularEqualityMsg;
2365
2366 protected function circularEqualityMsg_dispatch "author: Frenkel TUD 2013-05, adrpo"
2367 input list<Integer> stack;
2368 input Integer iR;
2369 input array<SimpleContainer> simpleeqnsarr;
2370 output list<String> oMsg = {};
2371 protected
2372 algorithm
2373 ✗ for r in stack loop
2374 ✗ if r == iR then
2375 break;
2376 end if;
2377
2378 ✗ for n in getVarsNames(simpleeqnsarr[r]) loop
2379 ✗ oMsg := ComponentReferenceBasics.printComponentRefStr(n) :: oMsg;
2380 end for;
2381 oMsg := "----------------------------------" :: oMsg;
2382 end for;
2383
2384 ✗ listReverseInPlace(oMsg);
2385 end circularEqualityMsg_dispatch;
2386
2387 protected function getVarsNames "author: Frenkel TUD 2013-05"
2388 input SimpleContainer iS;
2389 output list<DAE.ComponentRef> names;
2390 algorithm
2391 names := match iS
2392 local
2393 DAE.ComponentRef cr1, cr2;
2394 case ALIAS(cr1=cr1, cr2=cr2) then {cr1, cr2};
2395 case PARAMETERALIAS(unknowncr=cr1, paramcr=cr2) then {cr1, cr2};
2396 case TIMEALIAS(cr1=cr1,cr2=cr2) algorithm then {cr1, cr2};
2397 case TIMEINDEPENTVAR(cr=cr1) then {cr1};
2398 end match;
2399 end getVarsNames;
2400
2401 protected function getAlias3 "
2402 apply some heuristics which variable should be kept in the system. quantify some properties, distributes some points.
2403 handle states differently
2404 author: Frenkel TUD 2012-12"
2405 input BackendDAE.Var var;
2406 input Integer i;
2407 input Boolean state;
2408 input Boolean replaceable_;
2409 input Integer r;
2410 input Option<tuple<Integer, Integer>> iRmax;
2411 input Option<tuple<Integer, Integer>> iSmax;
2412 input Option<Integer> iUnremovable;
2413 output Option<tuple<Integer, Integer>> oRmax; //(idx,points)
2414 output Option<tuple<Integer, Integer>> oSmax;
2415 output Option<Integer> oUnremovable;
2416 algorithm
2417 (oRmax, oSmax, oUnremovable) := match(state, replaceable_, iRmax, iSmax, iUnremovable)
2418 local
2419 Integer w1, w2;
2420 Option<tuple<Integer, Integer>> tpl;
2421 case(false, false, _, _, NONE())
2422 algorithm
2423 3029 w1 := BackendVariable.calcAliasKey(var);
2424 3029 then
2425 (SOME((i, w1)), iSmax, SOME(i));
2426 case(true, false, _, _, NONE())
2427 algorithm
2428 748 w1 := BackendVariable.varStateSelectPrioAlias(var);
2429 748 then
2430 (iRmax, SOME((i, w1)), SOME(i));
2431 case(true, _, _, NONE(), _)
2432 algorithm
2433 3895 w1 := BackendVariable.varStateSelectPrioAlias(var);
2434 3895 then
2435 (iRmax, SOME((i, w1)), iUnremovable);
2436 case(true, _, _, SOME((_, w2)), _)
2437 algorithm
2438 1831 w1 := BackendVariable.varStateSelectPrioAlias(var);
2439
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 1622 times.
1831 tpl := if intGt(w1, w2) then SOME((i, w1)) else iSmax;
2440 then
2441 (iRmax, tpl, iUnremovable);
2442 case(false, _, NONE(), _, _)
2443 algorithm
2444 35475 w1 := BackendVariable.calcAliasKey(var);
2445 35475 then
2446 (SOME((i, w1)), iSmax, iUnremovable);
2447 case(false, _, SOME((_, w2)), _, _)
2448 algorithm
2449 92686 w1 := BackendVariable.calcAliasKey(var);
2450
2/2
✓ Branch 0 taken 14377 times.
✓ Branch 1 taken 78309 times.
92686 tpl := if intLt(w1, w2) then SOME((i, w1)) else iRmax;
2451 then
2452 (tpl, iSmax, iUnremovable);
2453 end match;
2454 end getAlias3;
2455
2456 protected function isVisited "author: Frenkel TUD 2012-12"
2457 input Integer mark; //how to mark a visited container
2458 input SimpleContainer iS;
2459 output Boolean visited;
2460 algorithm
2461 154991 visited := intEq(mark, getVisited(iS));
2462 end isVisited;
2463
2464 protected function getVisited "author: Frenkel TUD 2012-12"
2465 input SimpleContainer iS;
2466 output Integer visited;
2467 algorithm
2468 visited := match iS
2469 case ALIAS(visited=visited) then visited;
2470 case PARAMETERALIAS(visited=visited) then visited;
2471 case TIMEALIAS(visited=visited) then visited;
2472 case TIMEINDEPENTVAR(visited=visited) then visited;
2473 end match;
2474 end getVisited;
2475
2476 protected function setVisited "author: Frenkel TUD 2012-12"
2477 input Integer visited;
2478 input SimpleContainer iS;
2479 output SimpleContainer oS;
2480 algorithm
2481 oS := match iS
2482 local
2483 DAE.ComponentRef cr1, cr2;
2484 Integer i1, i2;
2485 EquationSourceAndAttributes eqnAttributes;
2486 Boolean negatedCr1, negatedCr2;
2487 DAE.Exp exp;
2488
2489 case ALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, _)
2490
4/4
✓ Branch 0 taken 188426 times.
✓ Branch 1 taken 22735 times.
✓ Branch 2 taken 210129 times.
✓ Branch 3 taken 1032 times.
609716 then ALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, visited);
2491
2492 case PARAMETERALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, _)
2493
4/4
✓ Branch 0 taken 16638 times.
✓ Branch 1 taken 568 times.
✓ Branch 2 taken 17136 times.
✓ Branch 3 taken 70 times.
50980 then PARAMETERALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, visited);
2494
2495 case TIMEALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, _)
2496 ✗ then TIMEALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, i2, eqnAttributes, visited);
2497
2498 case TIMEINDEPENTVAR(cr1, i1, exp, eqnAttributes, _)
2499 90370 then TIMEINDEPENTVAR(cr1, i1, exp, eqnAttributes, visited);
2500
2501 end match;
2502 end setVisited;
2503
2504 protected function replaceableAlias "author Frenkel TUD 2012-11
2505 check if the variable is a replaceable_ alias."
2506 input BackendDAE.Var var;
2507 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2508 output Boolean res;
2509 output Boolean res1 "true if not in unReplaceable Map";
2510 algorithm
2511 (res, res1) := matchcontinue var
2512 local
2513 BackendDAE.VarKind kind;
2514 DAE.ComponentRef cr;
2515 Boolean b;
2516
2517 case BackendDAE.VAR(varName=cr, varKind=kind) algorithm
2518 301410 BackendVariable.isVarKindVariable(kind) "cr1 not constant";
2519
2/2
✓ Branch 1 taken 902 times.
✓ Branch 2 taken 300155 times.
301057 false := BackendVariable.isVarOnTopLevelAndOutput(var);
2520
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 300155 times.
300155 false := BackendVariable.isVarOnTopLevelAndInput(var);
2521
4/4
✓ Branch 1 taken 78 times.
✓ Branch 2 taken 300077 times.
✓ Branch 4 taken 76 times.
✓ Branch 5 taken 2 times.
300155 false := BackendVariable.varHasUncertainValueRefine(var) and BackendDAEUtil.isDataReconciliationEnabled();
2522 300079 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
2523 300079 b := not UnorderedSet.contains(cr, unReplaceable);
2524 then (true, b);
2525
2526 else
2527 then (false, false);
2528 end matchcontinue;
2529 end replaceableAlias;
2530
2531 protected function handleSet "author: Frenkel TUD 2012-12
2532 traverse an equations system to remove simple equations"
2533 input Option<tuple<Integer, Integer>> iRmax;
2534 input Option<tuple<Integer, Integer>> iSmax;
2535 input Option<Integer> iUnremovable;
2536 input Option<Integer> iConst;
2537 input Integer mark; //how to mark a visited container
2538 input array<SimpleContainer> simpleeqnsarr;
2539 input array<list<Integer>> iMT;
2540 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2541 input BackendDAE.Variables iVars;
2542 input list<BackendDAE.Equation> iEqnslst;
2543 input BackendDAE.Shared ishared;
2544 input BackendVarTransform.VariableReplacements iRepl;
2545 output BackendDAE.Variables oVars;
2546 output list<BackendDAE.Equation> oEqnslst;
2547 output BackendDAE.Shared oshared;
2548 output BackendVarTransform.VariableReplacements oRepl;
2549 output Boolean warnAliasConflicts = false;
2550 algorithm
2551 (oVars, oEqnslst, oshared, oRepl):=
2552 matchcontinue (iRmax, iSmax, iUnremovable, iConst)
2553 local
2554 SimpleContainer s;
2555 Integer r, i1, i2, i;
2556 BackendDAE.Var v,pv;
2557 DAE.ComponentRef cr1, cr2, cr;
2558 EquationSourceAndAttributes eqnAttributes;
2559 Boolean negated, replaceable_, replaceble1, constExp, isState, negatedCr1, negatedCr2;
2560 DAE.Exp exp1, exp2, expcr, dexp, exp;
2561 BackendDAE.Variables vars;
2562 list<BackendDAE.Equation> eqnslst;
2563 BackendDAE.Shared shared;
2564 BackendVarTransform.VariableReplacements repl;
2565 VarSetAttributes vsattr;
2566 list<Integer> rows;
2567 Option<DAE.Exp> oexp;
2568
2569 // constant alias set
2570 case (_, _, _, SOME(r))
2571 algorithm
2572 53788 s := simpleeqnsarr[r];
2573 // for parameter alias the second component reference is *ALWAYS* the parameter!
2574
2/2
✓ Branch 0 taken 45185 times.
✓ Branch 1 taken 8603 times.
53788 PARAMETERALIAS(unknowncr=cr1, negatedCr1=negatedCr1, i1=i1, negatedCr2=negatedCr2, i2=i2, paramcr=cr2, eqnAttributes=eqnAttributes) := s;
2575 8603 arrayUpdate(simpleeqnsarr, r, setVisited(mark, s));
2576 8603 negated := boolOr(negatedCr1, negatedCr2);
2577 // generate exp from cref an negate if necessary
2578 8603 exp := Expression.crefExp(cr2);
2579 8603 exp2 := negateExpression(negated, exp, exp, " PARAMETERALIAS ");
2580 8603 v := BackendVariable.getVarAt(iVars, i1);
2581 8603 (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2582
4/4
✓ Branch 0 taken 8433 times.
✓ Branch 1 taken 170 times.
✓ Branch 2 taken 345 times.
✓ Branch 3 taken 8088 times.
9118 (vars, eqnslst, shared, repl) := handleSetVar(replaceable_ and replaceble1, SOME(DAE.RCONST(0.0)), v, i1, eqnAttributes, exp2, iMT, iVars, iEqnslst, ishared, iRepl);
2583 8603 expcr := Expression.crefExp(cr1);
2584 8603 pv := BackendVariable.getVarSharedAt(i2, ishared);
2585 8603 vsattr := addVarSetAttributes(pv, negated, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2586
4/4
✓ Branch 0 taken 8433 times.
✓ Branch 1 taken 170 times.
✓ Branch 2 taken 8088 times.
✓ Branch 3 taken 345 times.
8603 vsattr := if replaceable_ and replaceble1 then addVarSetAttributes(v, negated, mark, simpleeqnsarr, vsattr) else vsattr;
2587 8603 rows := List.removeOnTrue(r, intEq, iMT[i1]);
2588 8603 arrayUpdate(iMT, i1, {});
2589 8603 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rows, i1, exp, SOME(expcr), negated, SOME(DAE.RCONST(0.0)), mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2590 8603 then
2591 (vars, eqnslst, shared, repl);
2592
2593 // time set
2594 case (_, _, _, SOME(r))
2595 algorithm
2596 45185 s := simpleeqnsarr[r];
2597 // for time alias the time variable is *ALWAYS* the second
2598
1/2
✓ Branch 0 taken 45185 times.
✗ Branch 1 not taken.
45185 TIMEALIAS(cr1=cr1, i1=i1, negatedCr1=negatedCr1, negatedCr2=negatedCr2, eqnAttributes=eqnAttributes) := s;
2599 ✗ arrayUpdate(simpleeqnsarr, r, setVisited(mark, s));
2600 ✗ negated := boolOr(negatedCr1,negatedCr2);
2601 // generate exp from cref an negate if necessary
2602 ✗ exp := Expression.crefExp(DAE.crefTime);
2603 ✗ exp1 := negateExpression(negated, exp, exp, " timealias ");
2604 ✗ v := BackendVariable.getVarAt(iVars, i1);
2605 ✗ (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2606 ✗ dexp := negateExpression(negated, exp, DAE.RCONST(1.0), " timealias der ");
2607 ✗ (vars, eqnslst, shared, repl) := handleSetVar(replaceable_ and replaceble1, SOME(dexp), v, i1, eqnAttributes, exp1, iMT, iVars, iEqnslst, ishared, iRepl);
2608 ✗ expcr := Expression.crefExp(cr1);
2609 ✗ vsattr := addVarSetAttributes(v, negated, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2610 ✗ rows := List.removeOnTrue(r, intEq, iMT[i1]);
2611 ✗ arrayUpdate(iMT, i1, {});
2612 ✗ (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rows, i1, exp, SOME(expcr), negated, SOME(dexp), mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2613 ✗ then
2614 (vars, eqnslst, shared, repl);
2615
2616 // constant set
2617 case (_, _, _, SOME(r))
2618 algorithm
2619 45185 s := simpleeqnsarr[r];
2620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45185 times.
45185 TIMEINDEPENTVAR(cr=cr, i=i, exp=exp, eqnAttributes=eqnAttributes) := s;
2621 45185 arrayUpdate(simpleeqnsarr, r, setVisited(mark, s));
2622 45185 v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2623 45185 (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2624 45185 (vars, shared, isState, eqnslst) := optMoveVarShared(replaceable_, v, i, eqnAttributes, exp, BackendVariable.addGlobalKnownVarDAE, iMT, iVars, ishared, iEqnslst);
2625 45185 constExp := Expression.isConstValue(exp);
2626 // add to replacements if constant
2627
4/4
✓ Branch 0 taken 41794 times.
✓ Branch 1 taken 3391 times.
✓ Branch 2 taken 41536 times.
✓ Branch 3 taken 258 times.
86721 repl := if replaceable_ and constExp and replaceble1 then BackendVarTransform.addReplacement(iRepl, cr, exp, SOME(BackendVarTransform.skipPreChangeEdgeOperator)) else iRepl;
2628 // if state der(var) has to replaced to 0
2629
2/2
✓ Branch 0 taken 351 times.
✓ Branch 1 taken 44834 times.
45185 repl := if isState then BackendVarTransform.addDerConstRepl(cr, DAE.RCONST(0.0), repl) else repl;
2630 45185 exp := Expression.crefExp(cr);
2631 45185 vsattr := addVarSetAttributes(v, false, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2632 45185 rows := List.removeOnTrue(r, intEq, iMT[i]);
2633 45185 arrayUpdate(iMT, i, {});
2634 45185 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rows, i, exp, NONE(), false, SOME(DAE.RCONST(0.0)), mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2635 45185 then
2636 (vars, eqnslst, shared, repl);
2637
2638 // valid circular equality
2639 case (_, _, _, SOME(r))
2640 algorithm
2641 ✗ s := simpleeqnsarr[r];
2642 ✗ ALIAS(i1=i, i2=i2, eqnAttributes=eqnAttributes) := s;
2643 ✗ arrayUpdate(simpleeqnsarr, r, setVisited(mark, s));
2644 ✗ v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2645 ✗ exp := if Types.isRealOrSubTypeReal(ComponentReference.crefLastType(cr)) then DAE.RCONST(0.0) else DAE.ICONST(0);
2646 ✗ (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2647 ✗ (vars, shared, isState, eqnslst) := optMoveVarShared(replaceable_, v, i, eqnAttributes, exp, BackendVariable.addGlobalKnownVarDAE, iMT, iVars, ishared, iEqnslst);
2648 ✗ constExp := Expression.isConstValue(exp);
2649 // add to replacements if constant
2650 ✗ repl := if replaceable_ and constExp and replaceble1 then BackendVarTransform.addReplacement(iRepl, cr, exp, SOME(BackendVarTransform.skipPreChangeEdgeOperator)) else iRepl;
2651 // if state der(var) has to replaced to 0
2652 ✗ repl := if isState then BackendVarTransform.addDerConstRepl(cr, DAE.RCONST(0.0), repl) else repl;
2653 ✗ exp := Expression.crefExp(cr);
2654 ✗ vsattr := addVarSetAttributes(v, false, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2655 ✗ rows := List.removeOnTrue(r, intEq, iMT[i2]);
2656 ✗ arrayUpdate(iMT, i2, rows);
2657 ✗ rows := List.removeOnTrue(r, intEq, iMT[i]);
2658 ✗ arrayUpdate(iMT, i, {});
2659 ✗ (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rows, i, exp, NONE(), false, SOME(DAE.RCONST(0.0)), mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2660 ✗ then
2661 (vars, eqnslst, shared, repl);
2662
2663 // variable set state
2664 case (_, SOME((i, _)), _, NONE())
2665 algorithm
2666 4472 v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2667 4472 exp := Expression.crefExp(cr);
2668 4472 vsattr := addVarSetAttributes(v, false, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2669 4472 oexp := varStateDerivative(v);
2670 4472 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(iMT[i], i, exp, NONE(), false, oexp, mark, simpleeqnsarr, iMT, unReplaceable, iVars, iEqnslst, ishared, iRepl, vsattr);
2671 4472 arrayUpdate(iMT, i, {});
2672 4472 (vars, warnAliasConflicts) := handleVarSetAttributes(vsattr, v, vars, shared);
2673 4472 then
2674 (vars, eqnslst, shared, repl);
2675
2676 // variable set unReplaceable
2677 case (_, NONE(), SOME(i), NONE())
2678 algorithm
2679 2502 v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2680 2502 exp := Expression.crefExp(cr);
2681 2502 vsattr := addVarSetAttributes(v, false, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2682 2502 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(iMT[i], i, exp, NONE(), false, NONE(), mark, simpleeqnsarr, iMT, unReplaceable, iVars, iEqnslst, ishared, iRepl, vsattr);
2683 2502 arrayUpdate(iMT, i, {});
2684 2502 (vars, warnAliasConflicts) := handleVarSetAttributes(vsattr, v, vars, shared);
2685 2502 then
2686 (vars, eqnslst, shared, repl);
2687
2688 // variable set
2689 case (SOME((i, _)), NONE(), _, NONE())
2690 algorithm
2691 23182 v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2692 23182 exp := Expression.crefExp(cr);
2693 23182 vsattr := addVarSetAttributes(v, false, mark, simpleeqnsarr, EMPTYVARSETATTRIBUTES);
2694 23182 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(iMT[i], i, exp, NONE(), false, NONE(), mark, simpleeqnsarr, iMT, unReplaceable, iVars, iEqnslst, ishared, iRepl, vsattr);
2695 23182 arrayUpdate(iMT, i, {});
2696 23182 (vars, warnAliasConflicts) := handleVarSetAttributes(vsattr, v, vars, shared);
2697 23182 then
2698 (vars, eqnslst, shared, repl);
2699
2700 end matchcontinue;
2701 end handleSet;
2702
2703 protected function varStateDerivative "author: Frenkel TUD 2013-01"
2704 input BackendDAE.Var inVar;
2705 output Option<DAE.Exp> outExp;
2706 algorithm
2707 outExp := match inVar
2708 local
2709 DAE.ComponentRef dcr;
2710 DAE.Exp e;
2711 case BackendDAE.VAR(varKind=BackendDAE.STATE(derName=SOME(dcr)))
2712 algorithm
2713 2576 e := Expression.crefExp(dcr);
2714 then SOME(e);
2715 else NONE();
2716 end match;
2717 end varStateDerivative;
2718
2719 protected function handleSetVar "author: Frenkel TUD 2012-12
2720 traverse an Equations system to remove simple equations"
2721 input Boolean replaceable_;
2722 input Option<DAE.Exp> derReplaceState;
2723 input BackendDAE.Var v;
2724 input Integer i;
2725 input EquationSourceAndAttributes eqnAttributes;
2726 input DAE.Exp exp;
2727 input array<list<Integer>> iMT;
2728 input BackendDAE.Variables iVars;
2729 input list<BackendDAE.Equation> iEqnslst;
2730 input BackendDAE.Shared ishared;
2731 input BackendVarTransform.VariableReplacements iRepl;
2732 output BackendDAE.Variables oVars;
2733 output list<BackendDAE.Equation> oEqnslst;
2734 output BackendDAE.Shared oshared;
2735 output BackendVarTransform.VariableReplacements oRepl;
2736 algorithm
2737 (oVars, oEqnslst, oshared, oRepl):=
2738 match (replaceable_, v, eqnAttributes)
2739 local
2740 DAE.ComponentRef cr;
2741 DAE.Exp crexp;
2742 BackendDAE.Variables vars;
2743 Boolean bs;
2744 list<BackendDAE.Equation> eqnslst;
2745 BackendDAE.Shared shared;
2746 BackendVarTransform.VariableReplacements repl;
2747 DAE.ElementSource source;
2748
2749 case (true, BackendDAE.VAR(varName=cr), (source, _))
2750 algorithm
2751 116860 (vars, shared, bs) := moveVarShared(v, i, source, exp, BackendVariable.addAliasVarDAE, iVars, ishared);
2752 // add to replacements
2753 116860 repl := BackendVarTransform.addReplacement(iRepl, cr, exp, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
2754 // if state der(var) has to replaced
2755 116860 repl := addDerConstRepl(bs, derReplaceState, cr, repl);
2756 116860 then
2757 (vars, iEqnslst, shared, repl);
2758
2759 case (false, BackendDAE.VAR(varName=cr), _)
2760 algorithm
2761 1701 crexp := Expression.crefExp(cr);
2762 1701 (vars, shared, eqnslst, _, _, _, _) := generateEquation(crexp, exp, Expression.typeof(exp), eqnAttributes, (iVars, ishared, iEqnslst, {}, -1, iMT, false));
2763 then
2764 (vars, eqnslst, shared, iRepl);
2765
2766 end match;
2767 end handleSetVar;
2768
2769 protected function addDerConstRepl "author: Frenkel TUD 2013-01"
2770 input Boolean state;
2771 input Option<DAE.Exp> derConstRepl;
2772 input DAE.ComponentRef cr;
2773 input BackendVarTransform.VariableReplacements iRepl;
2774 output BackendVarTransform.VariableReplacements oRepl;
2775 algorithm
2776 oRepl := match(state, derConstRepl)
2777 local DAE.Exp e;
2778 1707 case(true, SOME(e)) then BackendVarTransform.addDerConstRepl(cr, e, iRepl);
2779 else iRepl;
2780 end match;
2781 end addDerConstRepl;
2782
2783 protected function optMoveVarShared "author: Frenkel TUD 2012-12"
2784 input Boolean replaceable_;
2785 input BackendDAE.Var v;
2786 input Integer i;
2787 input EquationSourceAndAttributes eqnAttributes;
2788 input DAE.Exp exp;
2789 input FuncMoveVarShared func;
2790 input array<list<Integer>> iMT;
2791 input BackendDAE.Variables iVars;
2792 input BackendDAE.Shared ishared;
2793 input list<BackendDAE.Equation> iEqnslst;
2794 output BackendDAE.Variables oVars;
2795 output BackendDAE.Shared oshared;
2796 output Boolean bs;
2797 output list<BackendDAE.Equation> oEqnslst;
2798 partial function FuncMoveVarShared
2799 input BackendDAE.Var v;
2800 input BackendDAE.Shared ishared;
2801 output BackendDAE.Shared oshared;
2802 end FuncMoveVarShared;
2803 algorithm
2804 (oVars, oshared, bs, oEqnslst) := match(replaceable_, v, eqnAttributes)
2805 local
2806 DAE.ComponentRef cr;
2807 DAE.Exp crexp;
2808 DAE.ElementSource source;
2809
2810 case(true, _, (source, _))
2811 algorithm
2812 44926 (oVars, oshared, bs) := moveVarShared(v, i, source, exp, func, iVars, ishared);
2813 44926 then
2814 (oVars, oshared, bs, iEqnslst);
2815
2816 case(false, BackendDAE.VAR(varName=cr), _)
2817 algorithm
2818 259 crexp := Expression.crefExp(cr);
2819 259 (oVars, oshared, oEqnslst, _, _, _, _) := generateEquation(crexp, exp, Expression.typeof(exp), eqnAttributes, (iVars, ishared, iEqnslst, {}, -1, iMT, false));
2820 then
2821 (oVars, oshared, false, oEqnslst);
2822
2823 end match;
2824 end optMoveVarShared;
2825
2826 protected function moveVarShared "author: Frenkel TUD 2012-12"
2827 input BackendDAE.Var v;
2828 input Integer i;
2829 input DAE.ElementSource source;
2830 input DAE.Exp exp;
2831 input FuncMoveVarShared func;
2832 input BackendDAE.Variables iVars;
2833 input BackendDAE.Shared ishared;
2834 output BackendDAE.Variables oVars;
2835 output BackendDAE.Shared oshared;
2836 output Boolean bs;
2837 partial function FuncMoveVarShared
2838 input BackendDAE.Var v;
2839 input BackendDAE.Shared ishared;
2840 output BackendDAE.Shared oshared;
2841 end FuncMoveVarShared;
2842 protected
2843 DAE.ComponentRef cr;
2844 list<DAE.SymbolicOperation> ops;
2845 BackendDAE.Var v1;
2846 algorithm
2847 161786 BackendDAE.VAR(varName=cr) := v;
2848 // add bindExp
2849 161786 v1 := BackendVariable.setBindExp(v, SOME(exp));
2850 161786 ops := ElementSource.getSymbolicTransformations(source);
2851 323572 v1 := BackendVariable.mergeVariableOperations(v1, DAE.SOLVED(cr, exp)::ops);
2852 // State?
2853 161786 bs := BackendVariable.isStateVar(v);
2854
2/2
✓ Branch 0 taken 2491 times.
✓ Branch 1 taken 159295 times.
161786 v1 := if bs then BackendVariable.setVarKind(v1, BackendDAE.DUMMY_STATE()) else v1;
2855 // remove from vars
2856 161786 (oVars, _) := BackendVariable.removeVar(i, iVars);
2857 // store changed var
2858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 161786 times.
161786 oshared := func(v1, ishared);
2859 end moveVarShared;
2860
2861 protected function traverseAliasTree "author: Frenkel TUD 2012-12
2862 traverse an equations system to remove simple equations"
2863 input list<Integer> rows;
2864 input Integer ilast;
2865 input DAE.Exp exp;
2866 input Option<DAE.Exp> optExp;
2867 input Boolean globalnegate;
2868 input Option<DAE.Exp> derReplaceState;
2869 input Integer mark; //how to mark a visited container
2870 input array<SimpleContainer> simpleeqnsarr;
2871 input array<list<Integer>> iMT;
2872 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2873 input BackendDAE.Variables iVars;
2874 input list<BackendDAE.Equation> iEqnslst;
2875 input BackendDAE.Shared ishared;
2876 input BackendVarTransform.VariableReplacements iRepl;
2877 input VarSetAttributes iAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
2878 output BackendDAE.Variables oVars;
2879 output list<BackendDAE.Equation> oEqnslst;
2880 output BackendDAE.Shared oshared;
2881 output BackendVarTransform.VariableReplacements oRepl;
2882 output VarSetAttributes oAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
2883 algorithm
2884 (oVars, oEqnslst, oshared, oRepl, oAttributes):=
2885 match rows
2886 local
2887 Integer r;
2888 list<Integer> rest;
2889 BackendDAE.Variables vars;
2890 list<BackendDAE.Equation> eqnslst;
2891 BackendDAE.Shared shared;
2892 BackendVarTransform.VariableReplacements repl;
2893 SimpleContainer s;
2894 VarSetAttributes vsattr;
2895
2896 case {} then (iVars, iEqnslst, ishared, iRepl, iAttributes);
2897 case r::rest
2898 algorithm
2899 109958 s := simpleeqnsarr[r];
2900 109958 arrayUpdate(simpleeqnsarr, r, setVisited(mark, s));
2901 109958 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree1(s, r, ilast, exp, optExp, globalnegate, derReplaceState, mark, simpleeqnsarr, iMT, unReplaceable, iVars, iEqnslst, ishared, iRepl, iAttributes);
2902 109958 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rest, ilast, exp, optExp, globalnegate, derReplaceState, mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2903 then
2904 (vars, eqnslst, shared, repl, vsattr);
2905
2906 end match;
2907 end traverseAliasTree;
2908
2909 protected function traverseAliasTree1 "author: Frenkel TUD 2012-12
2910 traverse an equations system to remove simple equations"
2911 input SimpleContainer sc;
2912 input Integer r;
2913 input Integer ilast;
2914 input DAE.Exp exp;
2915 input Option<DAE.Exp> optExp;
2916 input Boolean globalnegated;
2917 input Option<DAE.Exp> derReplaceState;
2918 input Integer mark; //how to mark a visited container
2919 input array<SimpleContainer> simpleeqnsarr;
2920 input array<list<Integer>> iMT;
2921 input UnorderedSet<DAE.ComponentRef> unReplaceable;
2922 input BackendDAE.Variables iVars;
2923 input list<BackendDAE.Equation> iEqnslst;
2924 input BackendDAE.Shared ishared;
2925 input BackendVarTransform.VariableReplacements iRepl;
2926 input VarSetAttributes iAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
2927 output BackendDAE.Variables oVars;
2928 output list<BackendDAE.Equation> oEqnslst;
2929 output BackendDAE.Shared oshared;
2930 output BackendVarTransform.VariableReplacements oRepl;
2931 output VarSetAttributes oAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
2932 algorithm
2933 (oVars, oEqnslst, oshared, oRepl, oAttributes):=
2934 match sc
2935 local
2936 Integer i1, i2, i;
2937 list<Integer> rows;
2938 BackendDAE.Var v;
2939 BackendDAE.Variables vars;
2940 list<BackendDAE.Equation> eqnslst;
2941 BackendDAE.Shared shared;
2942 BackendVarTransform.VariableReplacements repl;
2943 DAE.ComponentRef cr, cr1, cr2;
2944 Boolean replaceable_, globalnegated1, replaceble1, negatedCr1, negatedCr2, negated;
2945 DAE.ElementSource source;
2946 DAE.Exp crexp, exp1;
2947 Option<DAE.Exp> derReplacement;
2948 String lhs,rhs;
2949 VarSetAttributes vsattr;
2950 BackendDAE.EquationAttributes eqAttr;
2951
2952 case ALIAS(_, negatedCr1, i1, _, negatedCr2, i2, (source, eqAttr), _)
2953 algorithm
2954
2/2
✓ Branch 0 taken 58339 times.
✓ Branch 1 taken 51619 times.
109958 i := if intEq(i1, ilast) then i2 else i1;
2955 109958 negated := boolOr(negatedCr2, negatedCr1);
2956 109958 v as BackendDAE.VAR(varName=cr) := BackendVariable.getVarAt(iVars, i);
2957 109958 (replaceable_, replaceble1) := replaceableAlias(v, unReplaceable); // (isreplaceable, isNotInUnreplaceblaHashMap)
2958 109958 crexp := Expression.crefExp(cr);
2959 // negate if necessary
2960
2/2
✓ Branch 0 taken 12190 times.
✓ Branch 1 taken 97768 times.
109958 globalnegated1 := if negated then not globalnegated else globalnegated;
2961 109958 exp1 := negateExpression(globalnegated1, exp, exp, " ALIAS_1 ");
2962
2/2
✓ Branch 0 taken 12185 times.
✓ Branch 1 taken 97773 times.
109958 derReplacement := if globalnegated1 then negateOptExp(derReplaceState) else derReplaceState;
2963 // replace alias with selected variable if replaceable_
2964
2/2
✓ Branch 0 taken 109683 times.
✓ Branch 1 taken 275 times.
109958 source := if replaceable_ then addSubstitutionOption(optExp, crexp, source) else source;
2965
4/4
✓ Branch 1 taken 109683 times.
✓ Branch 2 taken 275 times.
✓ Branch 3 taken 911 times.
✓ Branch 4 taken 108772 times.
111144 (vars, eqnslst, shared, repl) := handleSetVar(replaceable_ and replaceble1, derReplacement, v, i, (source, eqAttr), exp1, iMT, iVars, iEqnslst, ishared, iRepl);
2966
4/4
✓ Branch 0 taken 109683 times.
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 108772 times.
✓ Branch 3 taken 911 times.
109958 vsattr := if replaceable_ and replaceble1 then addVarSetAttributes(v, globalnegated1, mark, simpleeqnsarr, iAttributes) else iAttributes;
2967 // negate if necessary
2968 109958 crexp := negateExpression(negated, crexp, crexp, " ALIAS_2 ");
2969 109958 rows := List.removeOnTrue(r, intEq, iMT[i]);
2970 109958 arrayUpdate(iMT, i, {});
2971 109958 (vars, eqnslst, shared, repl, vsattr) := traverseAliasTree(rows, i, exp, SOME(crexp), globalnegated1, derReplaceState, mark, simpleeqnsarr, iMT, unReplaceable, vars, eqnslst, shared, repl, vsattr);
2972 then
2973 (vars, eqnslst, shared, repl, vsattr);
2974
2975 case PARAMETERALIAS(cr1, negatedCr1, i1, cr2, negatedCr2, _, (source, _), _)
2976 algorithm
2977 // report error
2978 ✗ cr := if intEq(i1, ilast) then cr2 else cr1;
2979 ✗ negated := boolOr(negatedCr1, negatedCr2);
2980 ✗ crexp := Expression.crefExp(cr);
2981 ✗ crexp := negateExpression(negated, crexp, crexp, " PARAMETERLAIAS ");
2982 ✗ lhs := ExpressionBasics.printExpStr(exp);
2983 ✗ rhs := ExpressionBasics.printExpStr(crexp);
2984 ✗ Error.addSourceMessage(Error.EQ_WITHOUT_TIME_DEP_VARS, {lhs, rhs}, ElementSource.getElementSourceFileInfo(source));
2985 ✗ then
2986 fail();
2987
2988 case TIMEALIAS(eqnAttributes=(source,_))
2989 algorithm
2990 // report error
2991 ✗ rhs := ExpressionBasics.printExpStr(exp);
2992 ✗ Error.addSourceMessage(Error.EQ_WITHOUT_TIME_DEP_VARS, {"time", rhs}, ElementSource.getElementSourceFileInfo(source));
2993 ✗ then
2994 fail();
2995
2996 case TIMEINDEPENTVAR(exp=exp1, eqnAttributes=(source,_))
2997 algorithm
2998 // report error
2999 ✗ lhs := ExpressionBasics.printExpStr(exp);
3000 ✗ rhs := ExpressionBasics.printExpStr(exp1);
3001 ✗ Error.addSourceMessage(Error.EQ_WITHOUT_TIME_DEP_VARS, {lhs, rhs}, ElementSource.getElementSourceFileInfo(source));
3002 ✗ then
3003 fail();
3004
3005 end match;
3006 end traverseAliasTree1;
3007
3008 protected function negateOptExp "author: Frenkel TUD 2012-12"
3009 input Option<DAE.Exp> iExp;
3010 output Option<DAE.Exp> oExp;
3011 algorithm
3012 oExp := match iExp
3013 local DAE.Exp e;
3014 case SOME(e)
3015 algorithm
3016 935 e := negateExpression(true, e, e, " in negateOptExp ");
3017 then SOME(e);
3018 else iExp;
3019 end match;
3020 end negateOptExp;
3021
3022 protected function addSubstitutionOption "author: Frenkel TUD 2012-12"
3023 input Option<DAE.Exp> optExp;
3024 input DAE.Exp exp;
3025 input output DAE.ElementSource source;
3026 protected
3027 DAE.Exp e;
3028 algorithm
3029
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 109683 times.
✓ Branch 2 taken 61162 times.
✓ Branch 3 taken 48521 times.
109683 if isSome(optExp) then
3030 61162 SOME(e) := optExp;
3031 61162 source := ElementSource.addSymbolicTransformationSubstitution(true, source, exp, e);
3032 end if;
3033 end addSubstitutionOption;
3034
3035 protected function addVarSetAttributes "author: Frenkel TUD 2012-12"
3036 input BackendDAE.Var inVar;
3037 input Boolean negate;
3038 input Integer mark; //how to mark a visited container
3039 input array<SimpleContainer> simpleeqnsarr;
3040 input VarSetAttributes iAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
3041 output VarSetAttributes oAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
3042 protected
3043 Boolean fixed, fixedset, discreteset;
3044 Option<DAE.Exp> start;
3045 Option<DAE.StartOrigin> origin;
3046 list<tuple<DAE.Exp, DAE.ComponentRef>> nominalset;
3047 tuple<Option<DAE.Exp>, Option<DAE.Exp>> minmaxset;
3048 StartValues startvalues;
3049 algorithm
3050 200804 (fixedset, startvalues, nominalset, minmaxset, discreteset) := iAttributes;
3051 // get attributes
3052 // fixed
3053 200804 fixed := BackendVariable.varFixed(inVar);
3054 // start, add only if fixed == fixedset or fixed
3055 200804 start := BackendVariable.varStartValueOption(inVar);
3056 200804 origin := BackendVariable.varStartOrigin(inVar);
3057 200804 (fixedset, startvalues) := addStartValue(fixed, fixedset, BackendVariable.varCref(inVar), start, origin, negate, mark, simpleeqnsarr, startvalues);
3058 // nominal
3059 200804 nominalset := addNominalValue(inVar, nominalset);
3060 // minmax
3061 200804 minmaxset := addMinMaxAttribute(inVar, negate, mark, simpleeqnsarr, minmaxset);
3062
4/4
✓ Branch 0 taken 183234 times.
✓ Branch 1 taken 17570 times.
✓ Branch 3 taken 12919 times.
✓ Branch 4 taken 170315 times.
200804 discreteset := discreteset or BackendVariable.isVarDiscrete(inVar);
3063
2/2
✓ Branch 0 taken 176632 times.
✓ Branch 1 taken 24172 times.
377436 oAttributes := (fixedset, startvalues, nominalset, minmaxset, discreteset);
3064 end addVarSetAttributes;
3065
3066 protected function addStartValue "author: Frenkel TUD 2012-12"
3067 input Boolean fixed;
3068 input Boolean fixedset;
3069 input DAE.ComponentRef cr;
3070 input Option<DAE.Exp> start;
3071 input Option<DAE.StartOrigin> origin;
3072 input Boolean negate;
3073 input Integer mark; //how to mark a visited container
3074 input array<SimpleContainer> simpleeqnsarr;
3075 input StartValues iStartvalues;
3076 output Boolean oFixed;
3077 output StartValues oStartvalues;
3078 algorithm
3079 (oFixed, oStartvalues) := matchcontinue(fixed, fixedset, start, iStartvalues)
3080 local
3081 DAE.Exp startexp;
3082 Integer cmp;
3083 Option<DAE.StartOrigin> setorigin;
3084 list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> startvalues;
3085 case (false, true, _, _) then (fixedset, iStartvalues);
3086 case (true, false, NONE(), _)
3087 13656 then (true, (origin, {(start, cr)}));
3088 case (true, false, SOME(startexp), _)
3089 algorithm
3090 2465 startexp := negateExpression(negate, startexp, startexp, " start_1 ");
3091 4930 then
3092 (true, (origin, {(SOME(startexp), cr)}));
3093 case (_, _, NONE(), (setorigin, startvalues))
3094 algorithm
3095 152710 cmp := BackendVariable.startOriginCompare(origin, setorigin);
3096
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 152665 times.
152710 if cmp < 0 then
3097 setorigin := origin;
3098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 startvalues := if fixed then {(start, cr)} else {};
3099 elseif cmp == 0 and fixed then
3100 ✗ startvalues := (start, cr) :: startvalues;
3101 end if;
3102 152710 then
3103 (fixedset, (setorigin, startvalues));
3104 case (_, _, SOME(startexp), (setorigin, startvalues))
3105 algorithm
3106 23924 startexp := negateExpression(negate, startexp, startexp, " start_2 ");
3107 23924 cmp := BackendVariable.startOriginCompare(origin, setorigin);
3108
2/2
✓ Branch 0 taken 13906 times.
✓ Branch 1 taken 10018 times.
23924 if cmp < 0 then
3109 setorigin := origin;
3110 13906 startvalues := {(SOME(startexp), cr)};
3111 elseif cmp == 0 then
3112 5092 startvalues := (SOME(startexp), cr) :: startvalues;
3113 end if;
3114 23924 then
3115 (fixedset, (setorigin, startvalues));
3116 else
3117 algorithm
3118 ✗ print("RemoveSimpleEquations.addStartValue failed!\n");
3119 ✗ then
3120 fail();
3121 end matchcontinue;
3122 end addStartValue;
3123
3124 protected function mergeStartFixedAttributes "author: Frenkel TUD 2012-12"
3125 input BackendDAE.Var inVar;
3126 input Boolean fixed;
3127 input StartValues startvalues;
3128 input BackendDAE.Shared ishared;
3129 output BackendDAE.Var outVar;
3130 output Boolean warnAliasConflicts = false;
3131 algorithm
3132 outVar := matchcontinue(fixed, startvalues, ishared)
3133 local
3134 DAE.ComponentRef cr;
3135 Option<DAE.Exp> start, start1;
3136 Option<DAE.StartOrigin> origin;
3137 DAE.Exp startExp;
3138 list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> values;
3139 list<tuple<DAE.Exp, DAE.ComponentRef>> zerofreevalues;
3140 BackendDAE.Var v;
3141 BackendDAE.Variables globalKnownVars;
3142 String str;
3143
3144 // default value
3145 case (_, (_, {}), _) then inVar;
3146
3147 // fixed true only one start value -> nothing changed
3148 case (true, (origin, {(start, _)}), _) algorithm
3149 966 v := BackendVariable.setVarFixed(inVar, true);
3150 966 v := BackendVariable.setVarStartValueOption(v, start);
3151 966 then BackendVariable.setVarStartOrigin(v, origin);
3152
3153 // fixed true several start values, this need some investigation
3154 case (true, (origin, (start, cr)::values), BackendDAE.SHARED(globalKnownVars=globalKnownVars)) algorithm
3155 1 v := BackendVariable.setVarFixed(inVar, true);
3156 1 start1 := optExpReplaceCrefWithBindExp(start, globalKnownVars);
3157 1 (_, start, _) := equalNonFreeStartValues(values, globalKnownVars, (start1, start, cr));
3158 1 warnAliasConflicts := not Flags.isSet(Flags.ALIAS_CONFLICTS);
3159 1 v := BackendVariable.setVarStartValueOption(v, start);
3160 1 then BackendVariable.setVarStartOrigin(v, origin);
3161
3162 case (true, (_, values), BackendDAE.SHARED()) algorithm
3163 ✗ if not Flags.isSet(Flags.ALIAS_CONFLICTS) then
3164 ✗ Error.addMessage(Error.CONFLICTING_ALIAS_SET, {});
3165 else
3166 // get all nonzero values
3167 ✗ zerofreevalues := List.fold(values, getZeroFreeValues, {});
3168 str := "Conflicting start values for fixed states:\n";
3169 ✗ for value in zerofreevalues loop
3170 ✗ (startExp, cr) := value;
3171 ✗ str := str + " * Candidate: " + ComponentReferenceBasics.printComponentRefStr(cr) + "(start = " + ExpressionBasics.printExpStr(startExp) + ")\n";
3172 end for;
3173 ✗ Error.addCompilerError(str);
3174 end if;
3175 ✗ then
3176 fail();
3177
3178 // fixed false only one start value -> nothing changed
3179 case (false, (origin, {(start, _)}), _) algorithm
3180 5365 v := BackendVariable.setVarStartValueOption(inVar, start);
3181 5365 then BackendVariable.setVarStartOrigin(v, origin);
3182
3183 // fixed false several start value, this need some investigation
3184 case (false, (origin, (start, cr)::values), BackendDAE.SHARED(globalKnownVars=globalKnownVars)) algorithm
3185 2984 start1 := optExpReplaceCrefWithBindExp(start, globalKnownVars);
3186 2984 (_, start, _) := equalFreeStartValues(values, globalKnownVars, (start1, start, cr));
3187 2806 v := BackendVariable.setVarStartValueOption(inVar, start);
3188 2806 then BackendVariable.setVarStartOrigin(v, origin);
3189
3190 case (false, (origin, values), BackendDAE.SHARED(globalKnownVars=globalKnownVars)) algorithm
3191 // get all nonzero values
3192 178 zerofreevalues := List.fold(values, getZeroFreeValues, {});
3193 178 (v, warnAliasConflicts) := selectFreeValue(zerofreevalues, inVar, globalKnownVars);
3194
1/2
✓ Branch 0 taken 178 times.
✗ Branch 1 not taken.
178 if not listEmpty(zerofreevalues) then
3195 178 v := BackendVariable.setVarStartOrigin(v, origin);
3196 end if;
3197 then v;
3198 end matchcontinue;
3199 end mergeStartFixedAttributes;
3200
3201 protected function addNominalValue
3202 input BackendDAE.Var inVar;
3203 input list<tuple<DAE.Exp, DAE.ComponentRef>> iNominal;
3204 output list<tuple<DAE.Exp, DAE.ComponentRef>> oNominal;
3205 protected
3206 DAE.Exp nominal;
3207 DAE.ComponentRef cr;
3208 algorithm
3209 try
3210 200804 nominal := BackendVariable.varNominalValue(inVar);
3211 15020 cr := BackendVariable.varCref(inVar);
3212 15020 oNominal := (nominal, cr)::iNominal;
3213 else
3214 oNominal := iNominal;
3215 end try;
3216 end addNominalValue;
3217
3218 protected function mergeNominalAttribute
3219 input list<tuple<DAE.Exp, DAE.ComponentRef>> nominalList;
3220 input BackendDAE.Var inVar;
3221 input BackendDAE.Variables globalKnownVars;
3222 output BackendDAE.Var outVar;
3223 output Boolean warnAliasConflicts = false;
3224 algorithm
3225 outVar := matchcontinue nominalList
3226 local
3227 DAE.Exp e;
3228 list<DAE.Exp> allExp;
3229
3230 case {} then inVar;
3231
3232 //check if all expressions are equal take just one
3233 case _
3234 algorithm
3235 3101 allExp := List.map(nominalList, Util.tuple21);
3236
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3101 times.
✓ Branch 3 taken 523 times.
✓ Branch 4 taken 2578 times.
3101 {e} := List.uniqueOnTrue(allExp, ExpressionBasics.expEqual);
3237 2578 then BackendVariable.setVarNominalValue(inVar, e);
3238
3239 else
3240 algorithm
3241 523 warnAliasConflicts := not Flags.isSet(Flags.ALIAS_CONFLICTS);
3242 523 then selectFreeValue1(nominalList, "Alias set with conflicting nominal values\n", "nominal", BackendVariable.setVarNominalValue, inVar, globalKnownVars);
3243 end matchcontinue;
3244 end mergeNominalAttribute;
3245
3246 protected function addMinMaxAttribute "author: Frenkel TUD 2012-12"
3247 input BackendDAE.Var inVar;
3248 input Boolean negate;
3249 input Integer mark; //how to mark a visited container
3250 input array<SimpleContainer> simpleeqnsarr;
3251 input tuple<Option<DAE.Exp>, Option<DAE.Exp>> iMinMax;
3252 output tuple<Option<DAE.Exp>, Option<DAE.Exp>> oMinMax;
3253 protected
3254 Option<DAE.VariableAttributes> attr;
3255 list<Option<DAE.Exp>> ominmax;
3256 algorithm
3257 200804 BackendDAE.VAR(values = attr) := inVar;
3258 200804 ominmax := DAEUtil.getMinMax(attr);
3259 200804 oMinMax := mergeMinMax(negate, ominmax, iMinMax, mark, simpleeqnsarr);
3260 end addMinMaxAttribute;
3261
3262 protected function mergeMinMax "author: Frenkel TUD 2012-12"
3263 input Boolean negate;
3264 input list<Option<DAE.Exp>> ominmax;
3265 input tuple<Option<DAE.Exp>, Option<DAE.Exp>> ominmax1;
3266 input Integer mark; //how to mark a visited container
3267 input array<SimpleContainer> simpleeqnsarr;
3268 output tuple<Option<DAE.Exp>, Option<DAE.Exp>> outMinMax;
3269 algorithm
3270 outMinMax :=
3271 match (negate, ominmax)
3272 local
3273 DAE.Exp min, max, min1, max1;
3274 Option<DAE.Exp> omin, omax;
3275 tuple<Option<DAE.Exp>, Option<DAE.Exp>> minMax;
3276 case (_, {})
3277 then
3278 ominmax1;
3279 case (false, {omin, omax})
3280 algorithm
3281 186604 minMax := mergeMinMax1((omin, omax), ominmax1);
3282 186604 checkMinMax(minMax, mark, simpleeqnsarr);
3283 then
3284 minMax;
3285 // in case of a=-b, min and max have to be changed and negated
3286 case (true, {NONE(), NONE()})
3287 then
3288 ominmax1;
3289 case (true, {SOME(min), SOME(max)})
3290 algorithm
3291 169 min1 := negateExpression(true, min, min, " min_1 ");
3292 169 max1 := negateExpression(true, max, max, " max_1 ");
3293 169 minMax := mergeMinMax1((SOME(max1), SOME(min1)), ominmax1);
3294 169 checkMinMax(minMax, mark, simpleeqnsarr);
3295 then
3296 minMax;
3297 case (true, {NONE(), SOME(max)})
3298 algorithm
3299 3 max1 := negateExpression(true, max, max, " max_2 ");
3300 3 minMax := mergeMinMax1((SOME(max1), NONE()), ominmax1);
3301 3 checkMinMax(minMax, mark, simpleeqnsarr);
3302 then
3303 minMax;
3304 case (true, {SOME(min), NONE()})
3305 algorithm
3306 6 min1 := negateExpression(true, min, min, " min_2 ");
3307 6 minMax := mergeMinMax1((NONE(), SOME(min1)), ominmax1);
3308 6 checkMinMax(minMax, mark, simpleeqnsarr);
3309 then
3310 minMax;
3311 else
3312 algorithm
3313 ✗ print("RemoveSimpleEquations.mergeMinMax failed!\n");
3314 ✗ then
3315 fail();
3316 end match;
3317 end mergeMinMax;
3318
3319 protected function mergeMinMax1 "author: Frenkel TUD 2012-12"
3320 input tuple<Option<DAE.Exp>, Option<DAE.Exp>> ominmax;
3321 input tuple<Option<DAE.Exp>, Option<DAE.Exp>> ominmax1;
3322 output tuple<Option<DAE.Exp>, Option<DAE.Exp>> minMax;
3323 protected
3324 Option<DAE.Exp> omin, omin1, omin2;
3325 Option<DAE.Exp> omax, omax1, omax2;
3326 algorithm
3327 186782 (omin, omax) := ominmax;
3328 186782 (omin1, omax1) := ominmax1;
3329
3330 186782 omin2 := Expression.expOptMaxScalar(omin, omin1);
3331 186782 omax2 := Expression.expOptMinScalar(omax, omax1);
3332
2/2
✓ Branch 0 taken 17864 times.
✓ Branch 1 taken 168918 times.
186782 if referenceEq(omin2,omin) and referenceEq(omax2, omax) then
3333 minMax := ominmax;
3334 elseif referenceEq(omin2,omin1) and referenceEq(omax2, omax1) then
3335 minMax := ominmax1;
3336 else
3337 16297 minMax := (omin2, omax2);
3338 end if;
3339 end mergeMinMax1;
3340
3341 protected function checkMinMax "author: Frenkel TUD 2012-12"
3342 input tuple<Option<DAE.Exp>, Option<DAE.Exp>> minmax;
3343 input Integer mark; //how to mark a visited container
3344 input array<SimpleContainer> simpleeqnsarr;
3345 algorithm
3346 () :=
3347 matchcontinue minmax
3348 local
3349 DAE.Exp min, max;
3350 String s, s4, s5;
3351 Real rmin, rmax;
3352 case (SOME(min), SOME(max))
3353 algorithm
3354 18329 rmin := Expression.toReal(min);
3355 8136 rmax := Expression.toReal(max);
3356
1/2
✓ Branch 0 taken 8134 times.
✗ Branch 1 not taken.
8134 true := realGt(rmin, rmax);
3357 ✗ s4 := ExpressionBasics.printExpStr(min);
3358 ✗ s5 := ExpressionBasics.printExpStr(max);
3359 ✗ s := stringAppendList({"Alias variables with invalid limits min ", s4, " > max ", s5});
3360 ✗ Error.addMessage(Error.COMPILER_WARNING, {s});
3361 then ();
3362 // no error
3363 else
3364 ();
3365 end matchcontinue;
3366 end checkMinMax;
3367
3368 protected function handleVarSetAttributes "author: Frenkel TUD 2012-12"
3369 input VarSetAttributes inAttributes "fixed, list<startvalue, origin, cr>, nominal, min, max, discrete";
3370 input BackendDAE.Var inVar;
3371 input BackendDAE.Variables inVars;
3372 input BackendDAE.Shared inShared;
3373 output BackendDAE.Variables outVars;
3374 output Boolean warnAliasConflicts = false;
3375 algorithm
3376 outVars := matchcontinue(inAttributes, inShared)
3377 local
3378 Boolean fixedset, discreteset, isdiscrete, b1=false, b2=false;
3379 list<tuple<DAE.Exp, DAE.ComponentRef>> nominalset;
3380 tuple<Option<DAE.Exp>, Option<DAE.Exp>> minmaxset;
3381 StartValues startvalues;
3382 BackendDAE.Var v = inVar;
3383 BackendDAE.Variables vars, globalKnownVars;
3384 Option<DAE.Exp> min, max;
3385
3386 case((fixedset, startvalues, nominalset, minmaxset, discreteset), BackendDAE.SHARED(globalKnownVars=globalKnownVars)) algorithm
3387 30156 isdiscrete := BackendVariable.isVarDiscrete(inVar);
3388
3389 // start and fixed
3390
2/2
✓ Branch 0 taken 29100 times.
✓ Branch 1 taken 1056 times.
30156 if not isdiscrete then
3391 29100 (v, b1) := mergeStartFixedAttributes(inVar, fixedset, startvalues, inShared);
3392 end if;
3393 // nominal
3394 30156 (v, b2) := mergeNominalAttribute(nominalset, v, globalKnownVars);
3395 // min max
3396 30156 (min, max) := minmaxset;
3397
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30156 times.
✓ Branch 2 taken 3840 times.
✓ Branch 3 taken 26316 times.
30156 if isSome(min) then
3398 3840 min := SOME(ExpressionSimplify.simplify(Util.getOption(min)));
3399 end if;
3400
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30156 times.
✓ Branch 2 taken 3519 times.
✓ Branch 3 taken 26637 times.
30156 if isSome(max) then
3401 3519 max := SOME(ExpressionSimplify.simplify(Util.getOption(max)));
3402 end if;
3403 30156 v := BackendVariable.setVarMinMax(v, min, max);
3404
3405 // Keep the variability of eliminated discrete variables, so algorithms use pre(v).
3406 v := match v.varKind
3407 case BackendDAE.VARIABLE() guard discreteset
3408 5 then BackendVariable.setVarKind(v, BackendDAE.DISCRETE());
3409 else v;
3410 end match;
3411
3412 // update vars
3413 30156 vars := BackendVariable.addVar(v, inVars);
3414
4/4
✓ Branch 0 taken 29979 times.
✓ Branch 1 taken 177 times.
✓ Branch 2 taken 29515 times.
✓ Branch 3 taken 464 times.
30156 warnAliasConflicts := b1 or b2;
3415 then vars;
3416
3417 else algorithm
3418 ✗ print("RemoveSimpleEquations.handleVarSetAttributes failed!\n");
3419 ✗ then fail();
3420 end matchcontinue;
3421 end handleVarSetAttributes;
3422
3423 protected function optExpReplaceCrefWithBindExp "author: Frenkel TUD 2012-12"
3424 input Option<DAE.Exp> iOExp;
3425 input BackendDAE.Variables globalKnownVars;
3426 output Option<DAE.Exp> oOExp;
3427 algorithm
3428 oOExp := match iOExp
3429 local
3430 DAE.Exp e;
3431 Boolean b;
3432 case SOME(e)
3433 algorithm
3434 2985 (e, b) := replaceCrefWithBindExp(e, globalKnownVars);
3435 2985 (e, _) := ExpressionSimplify.condsimplify(b, e);
3436 then
3437 SOME(e);
3438 else iOExp;
3439 end match;
3440 end optExpReplaceCrefWithBindExp;
3441
3442 protected function equalNonFreeStartValues "author: Frenkel TUD 2012-12"
3443 input list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> iValues;
3444 input BackendDAE.Variables globalKnownVars;
3445 input tuple<Option<DAE.Exp>, Option<DAE.Exp>, DAE.ComponentRef> iValue;
3446 output tuple<Option<DAE.Exp>, Option<DAE.Exp>, DAE.ComponentRef> oValue;
3447 algorithm
3448 oValue := match(iValues, iValue)
3449 local
3450 list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> values;
3451 DAE.Exp e, e1, e2;
3452 Boolean b;
3453 DAE.ComponentRef cr;
3454 case ({}, _) then iValue;
3455 case (((NONE(), _))::values, _)
3456 ✗ then
3457 equalNonFreeStartValues(values, globalKnownVars, iValue);
3458 case (((NONE(), _))::values, (NONE(), _, _))
3459 ✗ then
3460 equalNonFreeStartValues(values, globalKnownVars, iValue);
3461 case (((NONE(), cr))::values, (SOME(e2), _, _))
3462 guard
3463 Expression.isZero(e2)
3464 ✗ then
3465 equalNonFreeStartValues(values, globalKnownVars, (NONE(), NONE(), cr));
3466 case (((SOME(e), _))::values, (SOME(e2), _, _))
3467 algorithm
3468 1 (e1, b) := replaceCrefWithBindExp(e, globalKnownVars);
3469 1 (e1, _) := ExpressionSimplify.condsimplify(b, e1);
3470
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 true := ExpressionBasics.expEqual(e1, e2);
3471 1 then
3472 equalNonFreeStartValues(values, globalKnownVars, iValue);
3473 end match;
3474 end equalNonFreeStartValues;
3475
3476 protected function equalFreeStartValues "author: Frenkel TUD 2012-12"
3477 input list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> iValues;
3478 input BackendDAE.Variables globalKnownVars;
3479 input tuple<Option<DAE.Exp>, Option<DAE.Exp>, DAE.ComponentRef> iValue;
3480 output tuple<Option<DAE.Exp>, Option<DAE.Exp>, DAE.ComponentRef> oValue;
3481 algorithm
3482 oValue := match(iValues, iValue)
3483 local
3484 list<tuple<Option<DAE.Exp>, DAE.ComponentRef>> values;
3485 DAE.Exp e, e1, e2;
3486 Boolean b;
3487 DAE.ComponentRef cr;
3488 case ({}, _) then iValue;
3489 // ignore default values
3490 case (((NONE(), _))::values, _)
3491 ✗ then
3492 equalFreeStartValues(values, globalKnownVars, iValue);
3493 case (((SOME(e), cr))::values, (NONE(), _, _))
3494 algorithm
3495 ✗ (e1, b) := replaceCrefWithBindExp(e, globalKnownVars);
3496 ✗ (e1, _) := ExpressionSimplify.condsimplify(b, e1);
3497 ✗ then
3498 equalFreeStartValues(values, globalKnownVars, (SOME(e1), SOME(e), cr));
3499 // compare
3500 case (((SOME(e), _))::values, (SOME(e2), _, _))
3501 algorithm
3502 4153 (e1, b) := replaceCrefWithBindExp(e, globalKnownVars);
3503 4153 (e1, _) := ExpressionSimplify.condsimplify(b, e1);
3504
2/2
✓ Branch 1 taken 178 times.
✓ Branch 2 taken 3975 times.
4153 true := ExpressionBasics.expEqual(e1, e2);
3505 3975 then
3506 equalFreeStartValues(values, globalKnownVars, iValue);
3507 end match;
3508 end equalFreeStartValues;
3509
3510 protected function replaceCrefWithBindExp
3511 input DAE.Exp exp;
3512 input BackendDAE.Variables vars;
3513 output DAE.Exp outExp;
3514 output Boolean replaced;
3515 protected
3516 UnorderedSet<DAE.ComponentRef> replaced_crefs =
3517 UnorderedSet.new(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
3518 algorithm
3519
1/2
✓ Branch 3 taken 7145 times.
✗ Branch 4 not taken.
7145 (outExp, replaced) := Expression.traverseExpBottomUp(exp,
3520 function replaceCrefWithBindExp_traverser(vars = vars, replacedCrefs = replaced_crefs), false);
3521 end replaceCrefWithBindExp;
3522
3523 protected function replaceCrefWithBindExp_traverser
3524 input DAE.Exp exp;
3525 input Boolean replaced;
3526 input BackendDAE.Variables vars;
3527 input UnorderedSet<DAE.ComponentRef> replacedCrefs;
3528 output DAE.Exp outExp;
3529 output Boolean outReplaced;
3530 protected
3531 DAE.ComponentRef cr;
3532 DAE.Exp e;
3533 algorithm
3534 (outExp, outReplaced) := matchcontinue exp
3535 // true if crefs replaced in expression
3536 case DAE.CREF(componentRef = cr)
3537 // check for cyclic bindings in start value
3538 guard not UnorderedSet.contains(cr, replacedCrefs)
3539 algorithm
3540
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 9992 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 9992 times.
10040 (BackendDAE.VAR(bindExp = SOME(e)), _) := BackendVariable.getVarSingle(cr, vars);
3541 9992 UnorderedSet.add(cr, replacedCrefs);
3542 9992 e := Expression.traverseExpBottomUp(e,
3543 function replaceCrefWithBindExp_traverser(vars = vars, replacedCrefs = replacedCrefs), false);
3544 then
3545 (e, true);
3546
3547 case DAE.CREF()
3548 then (exp, true);
3549
3550 else (exp, replaced);
3551 end matchcontinue;
3552 end replaceCrefWithBindExp_traverser;
3553
3554 protected function getZeroFreeValues "author: Frenkel TUD 2012-12"
3555 input tuple<Option<DAE.Exp>, DAE.ComponentRef> inTpl;
3556 input list<tuple<DAE.Exp, DAE.ComponentRef>> iAcc;
3557 output list<tuple<DAE.Exp, DAE.ComponentRef>> oAcc;
3558 algorithm
3559 oAcc := match inTpl
3560 local
3561 DAE.Exp e;
3562 DAE.ComponentRef cr;
3563 735 case (SOME(e), cr) then (e, cr)::iAcc;
3564 else iAcc;
3565 end match;
3566 end getZeroFreeValues;
3567
3568 protected function selectFreeValue "author: Frenkel TUD 2012-12"
3569 input list<tuple<DAE.Exp, DAE.ComponentRef>> iZeroFreeValues;
3570 input BackendDAE.Var inVar;
3571 input BackendDAE.Variables globalKnownVars;
3572 output BackendDAE.Var outVar;
3573 output Boolean warnAliasConflicts = false;
3574 algorithm
3575 outVar := match iZeroFreeValues
3576 case {} then inVar;
3577 case _
3578 algorithm
3579 178 warnAliasConflicts := not Flags.isSet(Flags.ALIAS_CONFLICTS);
3580 178 then selectFreeValue1(iZeroFreeValues, "Alias set with conflicting start values\n", "start", BackendVariable.setVarStartValue, inVar, globalKnownVars);
3581 end match;
3582 end selectFreeValue;
3583
3584 protected function selectNonZeroExpression
3585 "adrpo: select the first non-zero candidate, or the last one if all are zero"
3586 input list<tuple<DAE.Exp, DAE.ComponentRef>> iCandidates;
3587 output DAE.Exp outExp;
3588 output DAE.ComponentRef outCr;
3589 algorithm
3590 (outExp, outCr) := match iCandidates
3591 local
3592 DAE.Exp e;
3593 DAE.ComponentRef cr;
3594 list<tuple<DAE.Exp, DAE.ComponentRef>> rest;
3595
3596 case {(e, cr)} then (e, cr);
3597
3598 case (e, cr)::_ guard not Expression.isZero(e) then (e, cr);
3599
3600 15 case _::rest then selectNonZeroExpression(rest);
3601 end match;
3602 end selectNonZeroExpression;
3603
3604 protected function selectFreeValue1 "author: Frenkel TUD 2012-12
3605 All candidates have the same MLS 8.6.2 priority here, so the choice is
3606 arbitrary: prefer the kept variable's own value, then any non-zero value."
3607 input list<tuple<DAE.Exp, DAE.ComponentRef>> iZeroFreeValues;
3608 input String iStr;
3609 input String iAttributeName;
3610 input FuncSetAttribute inFunc;
3611 input BackendDAE.Var inVar;
3612 input BackendDAE.Variables globalKnownVars;
3613 output BackendDAE.Var outVar;
3614 partial function FuncSetAttribute
3615 input BackendDAE.Var iVar;
3616 input DAE.Exp iExp;
3617 output BackendDAE.Var oVar;
3618 end FuncSetAttribute;
3619 protected
3620 DAE.Exp e, e1;
3621 DAE.ComponentRef cr, cr1, crVar;
3622 list<tuple<DAE.Exp, DAE.ComponentRef>> candidates;
3623 Boolean b;
3624 String s, s2;
3625 algorithm
3626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 701 times.
701 if listEmpty(iZeroFreeValues) then
3627 outVar := inVar;
3628 ✗ return;
3629 end if;
3630
3631 701 crVar := BackendVariable.varCref(inVar);
3632 701 candidates := listReverse(iZeroFreeValues);
3633
12/12
✓ Branch 2 taken 2430 times.
✓ Branch 3 taken 655 times.
✓ Branch 4 taken 3085 times.
✓ Branch 5 taken 701 times.
✓ Branch 6 taken 655 times.
✓ Branch 7 taken 701 times.
✓ Branch 10 taken 655 times.
✓ Branch 11 taken 2430 times.
✓ Branch 12 taken 3085 times.
✓ Branch 13 taken 701 times.
✓ Branch 14 taken 2430 times.
✓ Branch 15 taken 701 times.
6871 candidates := listAppend(
3634 list(c for c guard ComponentReferenceBasics.crefEqual(crVar, Util.tuple22(c)) in candidates),
3635 list(c for c guard not ComponentReferenceBasics.crefEqual(crVar, Util.tuple22(c)) in candidates));
3636 701 (e, cr) := selectNonZeroExpression(candidates);
3637
3638
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 698 times.
701 if Flags.isSet(Flags.ALIAS_CONFLICTS) then
3639 s := iStr;
3640
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for c in iZeroFreeValues loop
3641 6 (e1, cr1) := c;
3642 6 (e1, b) := replaceCrefWithBindExp(e1, globalKnownVars);
3643 6 (e1, _) := ExpressionSimplify.condsimplify(b, e1);
3644
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 5 times.
6 s2 := if b then " = " + ExpressionBasics.printExpStr(e1) else "";
3645 6 s := s + " * Candidate: " + ComponentReferenceBasics.printComponentRefStr(cr1) + "(" + iAttributeName + " = " + ExpressionBasics.printExpStr(Util.tuple21(c)) + s2 + ")\n";
3646 end for;
3647 3 s := s + "=> Select value from " + ComponentReferenceBasics.printComponentRefStr(cr) + "(" + iAttributeName + " = " + ExpressionBasics.printExpStr(e) + ") for variable: " + ComponentReferenceBasics.printComponentRefStr(crVar) + "\n";
3648 3 Error.addMessage(Error.COMPILER_WARNING, {s});
3649 end if;
3650
3651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 701 times.
701 outVar := inFunc(inVar, e);
3652 end selectFreeValue1;
3653
3654
3655 // =============================================================================
3656 // functions to update equation system and shared
3657 //
3658 // =============================================================================
3659
3660 protected function updateSystem "author: Frenkel TUD 2012-12
3661 replace the simplified variables and equations in the system"
3662 input Boolean foundSimple;
3663 input list<BackendDAE.Equation> iEqnslst;
3664 input BackendDAE.Variables iVars;
3665 input BackendVarTransform.VariableReplacements repl;
3666 input BackendDAE.EqSystem isyst;
3667 output BackendDAE.EqSystem osyst;
3668 algorithm
3669 osyst:=
3670 match (foundSimple, isyst)
3671 local
3672
3673 BackendDAE.Variables vars;
3674 BackendDAE.EquationArray eqns;
3675 BackendDAE.EqSystem syst;
3676 case (false, _) then isyst;
3677 case (true, syst as BackendDAE.EQSYSTEM())
3678 algorithm
3679 // remove empty entries from vars and update stateorder
3680 18772 (vars, _) := BackendVariable.traverseBackendDAEVars(iVars, updateVar, (BackendVariable.emptyVars(), repl));
3681 // replace unoptimized equations with optimized
3682 18772 eqns := BackendEquation.listEquation(listReverse(iEqnslst));
3683 37544 syst.orderedEqs := eqns; syst.orderedVars := vars;
3684 18772 then
3685 BackendDAEUtil.clearEqSyst(syst);
3686 end match;
3687 end updateSystem;
3688
3689 protected function updateVar "author: Frenkel TUD 2012-12
3690 update the derivatives of states and add the vars to varrarr"
3691 input BackendDAE.Var inVar;
3692 input tuple<BackendDAE.Variables, BackendVarTransform.VariableReplacements> inTpl;
3693 output BackendDAE.Var outVar;
3694 output tuple<BackendDAE.Variables, BackendVarTransform.VariableReplacements> oTpl;
3695 algorithm
3696 (outVar,oTpl) := matchcontinue (inVar,inTpl)
3697 local
3698 DAE.ComponentRef cr;
3699 DAE.Exp e;
3700 BackendDAE.Var v;
3701 BackendDAE.Variables vars;
3702 BackendVarTransform.VariableReplacements repl;
3703 case (v as BackendDAE.VAR(varKind=BackendDAE.STATE(derName=SOME(cr))), (vars, repl))
3704 algorithm
3705 4522 e := BackendVarTransform.getReplacement(repl, cr);
3706 776 v := updateStateOrder(e, v);
3707 776 vars := BackendVariable.addVar(v, vars);
3708 776 then (v, (vars, repl));
3709 case (v, (vars, repl))
3710 algorithm
3711 117210 vars := BackendVariable.addVar(v, vars);
3712 117210 then (v, (vars, repl));
3713 end matchcontinue;
3714 end updateVar;
3715
3716 protected function updateStateOrder "author: Frenkel TUD 2012-12
3717 update the derivatives of states"
3718 input DAE.Exp inExp;
3719 input BackendDAE.Var inVar;
3720 output BackendDAE.Var outVar;
3721 algorithm
3722 outVar := match inExp
3723 local
3724 DAE.ComponentRef cr;
3725 766 case DAE.CREF(componentRef=cr) then BackendVariable.setStateDerivative(inVar, SOME(cr));
3726 10 else BackendVariable.setStateDerivative(inVar, NONE());
3727 end match;
3728 end updateStateOrder;
3729
3730 protected function removeSimpleEquationsShared
3731 input Boolean b;
3732 input BackendDAE.BackendDAE inDAE;
3733 input BackendVarTransform.VariableReplacements repl;
3734 output BackendDAE.BackendDAE outDAE;
3735 algorithm
3736 outDAE:=
3737 match (b, inDAE)
3738 local
3739 BackendDAE.Variables globalKnownVars, externalObjects;
3740 BackendDAE.Variables aliasVars;
3741 list<DAE.Constraint> constraintsLst;
3742 list<DAE.ClassAttributes> clsAttrsLst;
3743
3744 BackendDAE.EqSystems systs, systs1;
3745 list<BackendDAE.Equation> eqnslst;
3746 list<BackendDAE.Var> varlst;
3747 Boolean b1;
3748 BackendDAE.Shared shared;
3749
3750 case (false, _) then inDAE;
3751 case (true, BackendDAE.DAE(systs, shared as BackendDAE.SHARED(globalKnownVars=globalKnownVars, externalObjects=externalObjects, aliasVars=aliasVars,
3752 constraints=constraintsLst, classAttrs=clsAttrsLst)))
3753 algorithm
3754
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1564 times.
1566 if Flags.isSet(Flags.DUMP_REPL) then
3755 2 BackendVarTransform.dumpReplacements(repl);
3756 2 BackendVarTransform.dumpExtendReplacements(repl);
3757 2 BackendVarTransform.dumpDerConstReplacements(repl);
3758 end if;
3759 // replace moved vars in globalKnownVars, remeqns
3760 1566 (_, (_, varlst)) := BackendVariable.traverseBackendDAEVarsWithUpdate(aliasVars, replaceAliasVarTraverser, (repl, {}));
3761 1566 aliasVars := List.fold(varlst, fixAliasConstBindings, aliasVars);
3762 1566 shared.aliasVars := aliasVars;
3763
3764 1566 BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars, replaceVarTraverser, repl);
3765 1566 BackendVariable.traverseBackendDAEVarsWithUpdate(externalObjects, replaceVarTraverser, repl);
3766
3767 1566 (_, eqnslst, b1) := BackendEquation.traverseEquationArray(shared.initialEqs, replaceEquationTraverser, (repl, {}, false));
3768
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1562 times.
1566 shared.initialEqs := if b1 then BackendEquation.listEquation(eqnslst) else shared.initialEqs;
3769
3770 1566 (_, eqnslst, _) := BackendEquation.traverseEquationArray(shared.removedEqs, replaceEquationTraverser, (repl, {}, false));
3771 1566 eqnslst := List.select(eqnslst, BackendEquation.assertWithCondTrue);
3772 1566 shared.removedEqs := BackendEquation.listEquation(eqnslst);
3773
3774 1566 (constraintsLst, clsAttrsLst) := replaceOptimicaExps(constraintsLst, clsAttrsLst, repl);
3775 1566 shared.constraints := constraintsLst;
3776 1566 shared.classAttrs := clsAttrsLst;
3777
3778 1566 systs1 := removeSimpleEquationsShared1(systs, {}, repl, NONE(), aliasVars);
3779
3780 1566 then
3781 BackendDAE.DAE(systs1, shared);
3782 end match;
3783 end removeSimpleEquationsShared;
3784
3785 protected function fixAliasConstBindings "author: Frenkel TUD 2012-12
3786 traverse the alias vars and perfom the alias (not the constant) replacements"
3787 input BackendDAE.Var iAVar;
3788 input BackendDAE.Variables iAVars;
3789 output BackendDAE.Variables oAVars;
3790 protected
3791 DAE.ComponentRef cr;
3792 DAE.Exp e;
3793 BackendDAE.Var avar;
3794 algorithm
3795 26119 cr := BackendVariable.varCref(iAVar);
3796 26119 e := BackendVariable.varBindExp(iAVar);
3797 26119 e := fixAliasConstBindings1(cr, e, iAVars);
3798 26119 avar := BackendVariable.setBindExp(iAVar, SOME(e));
3799 26119 oAVars := BackendVariable.addVar(avar, iAVars);
3800 end fixAliasConstBindings;
3801
3802 protected function fixAliasConstBindings1 "author: Frenkel TUD 2012-12"
3803 input DAE.ComponentRef iCr;
3804 input DAE.Exp iExp;
3805 input BackendDAE.Variables iAVars;
3806 output DAE.Exp oExp;
3807 algorithm
3808 oExp := matchcontinue iAVars
3809 local
3810 DAE.ComponentRef cr;
3811 DAE.Exp e;
3812 case _
3813 algorithm
3814
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26357 times.
26357 cr::_ := Expression.extractCrefsFromExp(iExp);
3815
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 238 times.
26357 (BackendDAE.VAR(bindExp=SOME(e)), _) := BackendVariable.getVarSingle(cr, iAVars);
3816 238 then
3817 fixAliasConstBindings1(cr, e, iAVars);
3818 else
3819 then
3820 iExp;
3821 end matchcontinue;
3822 end fixAliasConstBindings1;
3823
3824 protected function replaceAliasVarTraverser "author: Frenkel TUD 2011-12"
3825 input BackendDAE.Var inVar;
3826 input tuple<BackendVarTransform.VariableReplacements, list<BackendDAE.Var>> inTpl;
3827 output BackendDAE.Var outVar;
3828 output tuple<BackendVarTransform.VariableReplacements, list<BackendDAE.Var>> outTpl;
3829 algorithm
3830 (outVar,outTpl) := matchcontinue (inVar,inTpl)
3831 local
3832 BackendDAE.Var v, v1;
3833 BackendVarTransform.VariableReplacements repl;
3834 DAE.Exp e, e1;
3835 list<BackendDAE.Var> varlst;
3836 Boolean b;
3837 case (v as BackendDAE.VAR(bindExp=SOME(e)), (repl, varlst))
3838 algorithm
3839
2/2
✓ Branch 1 taken 229836 times.
✓ Branch 2 taken 37841 times.
267677 (e1, true) := BackendVarTransform.replaceExp(e, repl, NONE());
3840 37841 b := Expression.isConstValue(e1);
3841
2/2
✓ Branch 0 taken 11722 times.
✓ Branch 1 taken 26119 times.
49563 v1 := if not b then BackendVariable.setBindExp(v, SOME(e1)) else v;
3842 37841 varlst := List.consOnTrue(b, v1, varlst);
3843 37841 then (v1, (repl, varlst));
3844 else (inVar,inTpl);
3845 end matchcontinue;
3846 end replaceAliasVarTraverser;
3847
3848 protected function replaceVarTraverser "author: Frenkel TUD 2011-03"
3849 input BackendDAE.Var inVar;
3850 input BackendVarTransform.VariableReplacements inRepl;
3851 output BackendDAE.Var outVar;
3852 output BackendVarTransform.VariableReplacements repl;
3853 algorithm
3854 (outVar,repl) := matchcontinue (inVar,inRepl)
3855 local
3856 BackendDAE.Var v, v1;
3857 DAE.Exp e, e1;
3858 case (v as BackendDAE.VAR(bindExp=SOME(e)), repl)
3859 algorithm
3860
1/2
✓ Branch 1 taken 463136 times.
✗ Branch 2 not taken.
463136 (e1, true) := BackendVarTransform.replaceExp(e, repl, NONE());
3861 ✗ v1 := BackendVariable.setBindExp(v, SOME(e1));
3862 then (v1, repl);
3863 else (inVar,inRepl);
3864 end matchcontinue;
3865 end replaceVarTraverser;
3866
3867 protected function removeSimpleEquationsShared1 "author: Frenkel TUD 2012-12"
3868 input BackendDAE.EqSystems inSysts;
3869 input BackendDAE.EqSystems inSysts1;
3870 input BackendVarTransform.VariableReplacements repl;
3871 input Option<BackendVarTransform.VariableReplacements> statesetrepl;
3872 input BackendDAE.Variables aliasVars;
3873 output BackendDAE.EqSystems outSysts;
3874 algorithm
3875 outSysts := match inSysts
3876 local
3877 BackendDAE.EqSystems rest;
3878 BackendDAE.EquationArray eqns;
3879 list<BackendDAE.Equation> eqnslst;
3880 Boolean b, b1;
3881 BackendDAE.EqSystem syst;
3882 BackendDAE.StateSets stateSets;
3883 Option<BackendVarTransform.VariableReplacements> statesetrepl1;
3884
3885 case {} then inSysts1;
3886 case syst::rest
3887 algorithm
3888 2251 (_, eqnslst, b) := BackendEquation.traverseEquationArray(syst.orderedEqs, replaceEquationTraverser, (repl, {}, false));
3889 2251 (stateSets, b1, statesetrepl1) := removeAliasVarsStateSets(syst.stateSets, statesetrepl, syst.orderedVars, aliasVars, {}, false);
3890
4/4
✓ Branch 0 taken 2104 times.
✓ Branch 1 taken 147 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 2103 times.
2251 if b or b1 then
3891 148 eqns := BackendEquation.listEquation(listReverse(eqnslst));
3892 148 syst.stateSets := stateSets;
3893 148 syst.orderedEqs := eqns;
3894 148 syst := BackendDAEUtil.clearEqSyst(syst);
3895 end if;
3896
3897 2251 (_, eqnslst, _) := BackendEquation.traverseEquationArray(syst.removedEqs, replaceEquationTraverser, (repl, {}, false));
3898 // remove asserts with condition=true from removed equations
3899 2251 eqnslst := List.select(eqnslst, BackendEquation.assertWithCondTrue);
3900 2251 syst.removedEqs := BackendEquation.listEquation(eqnslst);
3901 2251 then
3902 removeSimpleEquationsShared1(rest, syst::inSysts1, repl, statesetrepl1, aliasVars);
3903 end match;
3904 end removeSimpleEquationsShared1;
3905
3906 protected function removeAliasVarsStateSets "author: Frenkel TUD 2012-12"
3907 input BackendDAE.StateSets iStateSets;
3908 input Option<BackendVarTransform.VariableReplacements> iStatesetrepl;
3909 input BackendDAE.Variables vars;
3910 input BackendDAE.Variables aliasVars;
3911 input BackendDAE.StateSets iAcc;
3912 input Boolean inB;
3913 output BackendDAE.StateSets oStateSets;
3914 output Boolean outB;
3915 output Option<BackendVarTransform.VariableReplacements> oStatesetrepl;
3916 algorithm
3917 (oStateSets, outB, oStatesetrepl) := match iStateSets
3918 local
3919 BackendDAE.StateSets stateSets;
3920 Integer index, rang;
3921 list< DAE.ComponentRef> states;
3922 DAE.ComponentRef crA, crJ;
3923 list< BackendDAE.Var> varA, statescandidates, ovars, varJ;
3924 list< BackendDAE.Equation> eqns, oeqns;
3925 BackendVarTransform.VariableReplacements repl;
3926 UnorderedSet<DAE.ComponentRef> hs;
3927 Boolean b, b1;
3928 BackendDAE.Jacobian jac;
3929 2251 case {} then (listReverse(iAcc), inB, iStatesetrepl);
3930 case BackendDAE.STATESET(index, rang, states, crA, varA, statescandidates, ovars, eqns, oeqns, crJ, varJ, jac)::stateSets
3931 algorithm
3932 19 repl := getAliasReplacements(iStatesetrepl, aliasVars);
3933 // do not replace the set variables
3934 19 hs := newCrefSet();
3935 19 hs := List.applyAndFold(statescandidates, addCref, BackendVariable.varCref, hs);
3936 19 ovars := replaceOtherStateSetVars(ovars, vars, aliasVars, hs, {});
3937 19 (eqns, b) := BackendVarTransform.replaceEquations(eqns, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
3938 19 (oeqns, b1) := BackendVarTransform.replaceEquations(oeqns, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
3939 19 oeqns := List.fold(oeqns, removeEqualLshRshEqns, {});
3940 19 oeqns := listReverse(oeqns);
3941
4/4
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 15 times.
✓ Branch 4 taken 2 times.
53 (stateSets, b, oStatesetrepl) := removeAliasVarsStateSets(stateSets, SOME(repl), vars, aliasVars, BackendDAE.STATESET(index, rang, states, crA, varA, statescandidates, ovars, eqns, oeqns, crJ, varJ, jac)::iAcc, b or b1);
3942 then
3943 (stateSets, b, oStatesetrepl);
3944 end match;
3945 end removeAliasVarsStateSets;
3946
3947 protected function removeEqualLshRshEqns "author: Frenkel TUD 2012-12"
3948 input BackendDAE.Equation iEqn;
3949 input list<BackendDAE.Equation> iEqns;
3950 output list<BackendDAE.Equation> oEqns;
3951 algorithm
3952 oEqns := matchcontinue iEqn
3953 local
3954 DAE.Exp rhs, lhs;
3955 Boolean b;
3956 case BackendDAE.EQUATION(exp=lhs, scalar=rhs)
3957 algorithm
3958 81 b := ExpressionBasics.expEqual(lhs, rhs);
3959 81 then
3960 List.consOnTrue(not b, iEqn, iEqns);
3961 case BackendDAE.ARRAY_EQUATION(left=lhs, right=rhs)
3962 algorithm
3963 ✗ b := ExpressionBasics.expEqual(lhs, rhs);
3964 ✗ then
3965 List.consOnTrue(not b, iEqn, iEqns);
3966 case BackendDAE.COMPLEX_EQUATION(left=lhs, right=rhs)
3967 algorithm
3968 ✗ b := ExpressionBasics.expEqual(lhs, rhs);
3969 ✗ then
3970 List.consOnTrue(not b, iEqn, iEqns);
3971 else iEqn::iEqns;
3972 end matchcontinue;
3973 end removeEqualLshRshEqns;
3974
3975 protected function replaceOtherStateSetVars "author: Frenkel TUD 2012-12"
3976 input list< BackendDAE.Var> iVarLst;
3977 input BackendDAE.Variables vars;
3978 input BackendDAE.Variables aliasVars;
3979 input UnorderedSet<DAE.ComponentRef> hs;
3980 input list< BackendDAE.Var> iAcc;
3981 output list< BackendDAE.Var> oVarLst;
3982 algorithm
3983 oVarLst := matchcontinue iVarLst
3984 local
3985 BackendDAE.Var var;
3986 list< BackendDAE.Var> varlst;
3987 DAE.ComponentRef cr;
3988 DAE.Exp exp;
3989 Boolean b;
3990 case {} then iAcc;
3991 case var::varlst
3992 algorithm
3993 66 cr := BackendVariable.varCref(var);
3994
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 66 times.
66 false := UnorderedSet.contains(cr, hs);
3995 66 (var, _) := BackendVariable.getVarSingle(cr, aliasVars);
3996 3 exp := BackendVariable.varBindExp(var);
3997
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 cr::{} := Expression.extractCrefsFromExp(exp);
3998 3 b := UnorderedSet.contains(cr, hs);
3999 3 (var, _) := BackendVariable.getVarSingle(cr, vars);
4000 3 varlst := List.consOnTrue(not b, var, iAcc);
4001 3 then
4002 replaceOtherStateSetVars(varlst, vars, aliasVars, hs, varlst);
4003 case var::varlst
4004 algorithm
4005 63 cr := BackendVariable.varCref(var);
4006
1/2
✓ Branch 1 taken 63 times.
✗ Branch 2 not taken.
63 true := UnorderedSet.contains(cr, hs);
4007 ✗ then
4008 replaceOtherStateSetVars(varlst, vars, aliasVars, hs, iAcc);
4009 case var::varlst
4010 63 then
4011 replaceOtherStateSetVars(varlst, vars, aliasVars, hs, var::iAcc);
4012 end matchcontinue;
4013 end replaceOtherStateSetVars;
4014
4015 protected function replaceOptimicaExps
4016 " Helper function to removeSimpleEquationsShared.
4017 Replaces variables in constraints and classAttributes
4018 Expressions."
4019 input list<DAE.Constraint> icontraints;
4020 input list<DAE.ClassAttributes> iclassAttributes;
4021 input BackendVarTransform.VariableReplacements irepl;
4022 output list<DAE.Constraint> ocontraints;
4023 output list<DAE.ClassAttributes> oclassAttributes;
4024 algorithm
4025 (ocontraints, oclassAttributes) := match(icontraints, iclassAttributes)
4026 local
4027 Option<DAE.Exp> objetiveE, objectiveIntegrandE, startTimeE, finalTimeE;
4028 list<DAE.Constraint> constraintLst, rest;
4029 list<DAE.Exp> constraintLstExps;
4030 list<DAE.ClassAttributes> classAttributes, restClassAtr;
4031 case ({}, {}) then ({}, {});
4032 case ({}, DAE.OPTIMIZATION_ATTRS(objetiveE, objectiveIntegrandE, startTimeE, finalTimeE)::restClassAtr)
4033 algorithm
4034
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
32 (_, (_, {objetiveE}, _)) := replaceOptExprTraverser((objetiveE, (irepl, {}, false)));
4035
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
32 (_, (_, {objectiveIntegrandE}, _)) := replaceOptExprTraverser((objectiveIntegrandE, (irepl, {}, false)));
4036
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
32 (_, (_, {startTimeE}, _)) := replaceOptExprTraverser((startTimeE, (irepl, {}, false)));
4037
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
32 (_, (_, {finalTimeE}, _)) := replaceOptExprTraverser((finalTimeE, (irepl, {}, false)));
4038 32 (_, classAttributes) := replaceOptimicaExps({}, restClassAtr, irepl);
4039 32 classAttributes := DAE.OPTIMIZATION_ATTRS(objetiveE, objectiveIntegrandE, startTimeE, finalTimeE)::classAttributes;
4040 then ({}, classAttributes);
4041 case (DAE.CONSTRAINT_EXPS(constraintLstExps)::rest, _)
4042 algorithm
4043 3 constraintLstExps := replaceOptimicaContraints(constraintLstExps, irepl);
4044 3 (constraintLst, _) := replaceOptimicaExps(rest, iclassAttributes, irepl);
4045 3 constraintLst := DAE.CONSTRAINT_EXPS(constraintLstExps)::constraintLst;
4046 then (constraintLst, iclassAttributes);
4047 end match;
4048 end replaceOptimicaExps;
4049
4050 protected function replaceOptimicaContraints
4051 input list<DAE.Exp> icontraints;
4052 input BackendVarTransform.VariableReplacements irepl;
4053 output list<DAE.Exp> ocontraints;
4054 algorithm
4055 ocontraints := match icontraints
4056 local
4057 list<DAE.Exp> constraintLst, rest;
4058 DAE.Exp e;
4059 case {} then ({});
4060 case e::rest
4061 algorithm
4062
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
8 (_, (_, {e}, _)) := replaceExprTraverser((e, (irepl, {}, false)));
4063 8 constraintLst := replaceOptimicaContraints(rest, irepl);
4064 constraintLst := e::constraintLst;
4065 then (constraintLst);
4066 end match;
4067 end replaceOptimicaContraints;
4068
4069 protected function getAliasReplacements "author: Frenkel TUD 2012-12"
4070 input Option<BackendVarTransform.VariableReplacements> iStatesetrepl;
4071 input BackendDAE.Variables aliasVars;
4072 output BackendVarTransform.VariableReplacements oStatesetrepl;
4073 algorithm
4074 oStatesetrepl := match iStatesetrepl
4075 local
4076 BackendVarTransform.VariableReplacements repl;
4077 case SOME(repl) then repl;
4078 else
4079 algorithm
4080 11 repl := BackendVarTransform.emptyReplacementsSized(BackendVariable.varsSize(aliasVars));
4081 11 repl := BackendVariable.traverseBackendDAEVars(aliasVars, getAliasVarReplacements, repl);
4082 then
4083 repl;
4084 end match;
4085 end getAliasReplacements;
4086
4087 protected function getAliasVarReplacements
4088 input BackendDAE.Var inVar;
4089 input BackendVarTransform.VariableReplacements inRepl;
4090 output BackendDAE.Var v;
4091 output BackendVarTransform.VariableReplacements repl;
4092 protected
4093 DAE.Exp exp;
4094 DAE.ComponentRef cr;
4095 algorithm
4096 v := inVar;
4097
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3463 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3463 times.
3463 BackendDAE.VAR(varName=cr, bindExp=SOME(exp)) := v;
4098 3463 repl := BackendVarTransform.addReplacement(inRepl, cr, exp, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
4099 end getAliasVarReplacements;
4100
4101 protected function replaceEquationTraverser "
4102 Helper function to e.g. removeSimpleEquations"
4103 input BackendDAE.Equation inEq;
4104 input tuple<BackendVarTransform.VariableReplacements, list<BackendDAE.Equation>, Boolean> inTpl;
4105 output BackendDAE.Equation outEq;
4106 output tuple<BackendVarTransform.VariableReplacements, list<BackendDAE.Equation>, Boolean> outTpl;
4107 algorithm
4108 (outEq,outTpl) := match (inEq,inTpl)
4109 local
4110 BackendDAE.Equation e, eqn;
4111 DAE.Exp lhs, rhs, res;
4112 BackendVarTransform.VariableReplacements repl;
4113 list<BackendDAE.Equation> eqns, eqns1;
4114 Boolean b, b1;
4115 case (e, (repl, eqns, b))
4116 algorithm
4117 112090 (eqns1, b1) := BackendVarTransform.replaceEquations({e}, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
4118
4/4
✓ Branch 1 taken 1900 times.
✓ Branch 2 taken 110190 times.
✓ Branch 4 taken 1804 times.
✓ Branch 5 taken 96 times.
112090 if BackendEquation.isInitialEquation(e) and BackendEquation.isEquation(e) then
4119 1804 eqn := listHead(eqns1);
4120
4121 1804 lhs := BackendEquation.getEquationLHS(eqn);
4122 1804 rhs := BackendEquation.getEquationRHS(eqn);
4123 1804 res := Expression.createResidualExp(lhs, rhs);
4124
4125
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1799 times.
1804 if Expression.isConst(res) then
4126
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 time.
5 if Expression.isZero(res) then
4127
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2 times.
4 Error.addCompilerNotification("The following initial equation is redundant and consistent due to simplifications in RemoveSimpleEquations and therefore removed from the initialization problem: " + BackendDump.equationString(e) + (if b1 then " -> " + BackendDump.equationString(eqn) else ""));
4128 eqns1 := {};
4129 4 b1 := true;
4130 else
4131
1/2
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 Error.addCompilerWarning("The following initial equation is inconsistent due to simplifications in RemoveSimpleEquations and therefore removed from the initialization problem: " + BackendDump.equationString(e) + (if b1 then " -> " + BackendDump.equationString(eqn) else ""));
4132 eqns1 := {};
4133 1 b1 := true;
4134 end if;
4135 end if;
4136 end if;
4137 112090 eqns := listAppend(eqns1, eqns);
4138
4/4
✓ Branch 0 taken 86292 times.
✓ Branch 1 taken 25798 times.
✓ Branch 2 taken 85964 times.
✓ Branch 3 taken 328 times.
198054 then (e, (repl, eqns, b or b1));
4139 end match;
4140 end replaceEquationTraverser;
4141
4142 protected function replaceExprTraverser "
4143 Helper function to e.g. removeSimpleEquations"
4144 input tuple<DAE.Exp, tuple<BackendVarTransform.VariableReplacements, list<DAE.Exp>, Boolean>> inTpl;
4145 output tuple<DAE.Exp, tuple<BackendVarTransform.VariableReplacements, list<DAE.Exp>, Boolean>> outTpl;
4146 algorithm
4147 outTpl:=
4148 match inTpl
4149 local
4150 DAE.Exp exp, exp1;
4151 BackendVarTransform.VariableReplacements repl;
4152 list<DAE.Exp> exps;
4153 Boolean b, b1;
4154 case (exp, (repl, exps, b))
4155 algorithm
4156 8 (exp1, b1) := BackendVarTransform.replaceExp(exp, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
4157 exps := exp1::exps;
4158
3/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
12 then ((exp, (repl, exps, b or b1)));
4159 end match;
4160 end replaceExprTraverser;
4161
4162 protected function replaceOptExprTraverser "
4163 Helper function to e.g. removeSimpleEquations"
4164 input tuple<Option<DAE.Exp>, tuple<BackendVarTransform.VariableReplacements, list<Option<DAE.Exp>>, Boolean>> inTpl;
4165 output tuple<Option<DAE.Exp>, tuple<BackendVarTransform.VariableReplacements, list<Option<DAE.Exp>>, Boolean>> outTpl;
4166 algorithm
4167 outTpl:=
4168 match inTpl
4169 local
4170 DAE.Exp exp, exp1;
4171 BackendVarTransform.VariableReplacements repl;
4172 Option<DAE.Exp> expOpt;
4173 list<Option<DAE.Exp>> exps;
4174 Boolean b, b1;
4175 case (NONE(), (repl, exps, b))
4176 algorithm
4177 exps := NONE()::exps;
4178
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
172 then ((NONE(), (repl, exps, b)));
4179 case (expOpt as SOME(exp), (repl, exps, b))
4180 algorithm
4181 42 (exp1, b1) := BackendVarTransform.replaceExp(exp, repl, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
4182
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 8 times.
42 if referenceEq(exp1, exp) then
4183 exps := expOpt::exps;
4184 else
4185 exps := SOME(exp1)::exps;
4186 end if;
4187
3/4
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 34 times.
50 then ((expOpt, (repl, exps, b or b1)));
4188 end match;
4189 end replaceOptExprTraverser;
4190
4191
4192 // =============================================================================
4193 // functions to find unReplaceable variables
4194 //
4195 // unReplaceable:
4196 // - variables with variable subscribts
4197 // - variables set in when-clauses
4198 // - variables used in pre
4199 // - statescandidates of statesets
4200 // - lhs of array assign statement, because there is a cref used and this is not replaceable_ with array of crefs
4201 // =============================================================================
4202
4203 protected function addUnreplaceableFromStateSets "author: Frenkel TUD 2012-12"
4204 input BackendDAE.BackendDAE inDAE;
4205 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
4206 output UnorderedSet<DAE.ComponentRef> outUnreplaceable;
4207 protected
4208 BackendDAE.EqSystems systs;
4209 algorithm
4210 1060 BackendDAE.DAE(eqs=systs) := inDAE;
4211 1060 outUnreplaceable := List.fold(systs, addUnreplaceableFromStateSetSystem, inUnreplaceable);
4212 end addUnreplaceableFromStateSets;
4213
4214 protected function addUnreplaceableFromStateSetSystem "author: Frenkel TUD 2012-12
4215 traverse an equation system to handle states sets"
4216 input BackendDAE.EqSystem isyst;
4217 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
4218 output UnorderedSet<DAE.ComponentRef> outUnreplaceable;
4219 algorithm
4220 outUnreplaceable:= match isyst
4221 local
4222 BackendDAE.StateSets stateSets;
4223 UnorderedSet<DAE.ComponentRef> unReplaceable;
4224 // no stateSet
4225 case BackendDAE.EQSYSTEM(stateSets={}) then inUnreplaceable;
4226 // sets
4227 case BackendDAE.EQSYSTEM(stateSets=stateSets)
4228 algorithm
4229 13 unReplaceable := List.fold(stateSets, addUnreplaceableFromStateSet, inUnreplaceable);
4230 then
4231 unReplaceable;
4232 end match;
4233 end addUnreplaceableFromStateSetSystem;
4234
4235 protected function addUnreplaceableFromStateSet "author: Frenkel TUD 2012-12"
4236 input BackendDAE.StateSet iStateSet;
4237 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
4238 output UnorderedSet<DAE.ComponentRef> outUnreplaceable;
4239 protected
4240 list<BackendDAE.Var> statevars;
4241 list<DAE.ComponentRef> crlst;
4242 algorithm
4243 21 BackendDAE.STATESET(statescandidates=statevars) := iStateSet;
4244 21 crlst := List.map(statevars, BackendVariable.varCref);
4245 21 crlst := List.map(crlst, ComponentReferenceBasics.crefStripLastSubs);
4246 21 outUnreplaceable := List.fold(crlst, addCref, inUnreplaceable);
4247 end addUnreplaceableFromStateSet;
4248
4249 protected function addUnreplaceableFromWhens "collect all lhs of whens and array assign statement because these are not
4250 replaceable_ or if they are replaced the initial system get in trouble"
4251 input BackendDAE.BackendDAE inDAE;
4252 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
4253 output UnorderedSet<DAE.ComponentRef> outUnreplaceable;
4254 protected
4255 BackendDAE.EqSystems systs;
4256 BackendDAE.EquationArray eqns;
4257 algorithm
4258 3957 BackendDAE.DAE(eqs=systs, shared=BackendDAE.SHARED(initialEqs=eqns)) := inDAE;
4259 3957 outUnreplaceable := List.fold(systs, addUnreplaceableFromWhensSystem, inUnreplaceable);
4260 3957 (_,outUnreplaceable) := BackendDAEUtil.traverseBackendDAEExpsEqns(eqns, Expression.traverseSubexpressionsHelper, (addUnreplaceableFromEqnsExp, outUnreplaceable));
4261 end addUnreplaceableFromWhens;
4262
4263 protected function addUnreplaceableFromEqnsExp
4264 input DAE.Exp e;
4265 input UnorderedSet<DAE.ComponentRef> hs;
4266 output DAE.Exp outExp;
4267 output UnorderedSet<DAE.ComponentRef> ohs;
4268 algorithm
4269 (outExp,ohs) := match e
4270 local
4271 DAE.ComponentRef cr;
4272 case DAE.CREF(componentRef=DAE.WILD())
4273 then (e,hs);
4274
4275 case DAE.CREF(componentRef=cr)
4276 algorithm
4277 4992 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
4278 ohs := addCref(cr, hs);
4279 then (e,ohs);
4280 // let WILD pass
4281 else (e,hs);
4282 end match;
4283 end addUnreplaceableFromEqnsExp;
4284
4285 protected function addUnreplaceableFromWhensSystem "traverse the Whens of an equation system to add all variables set in when"
4286 input BackendDAE.EqSystem isyst;
4287 input UnorderedSet<DAE.ComponentRef> inUnreplaceable;
4288 output UnorderedSet<DAE.ComponentRef> outUnreplaceable;
4289 protected
4290 BackendDAE.EquationArray eqns;
4291 algorithm
4292 21834 eqns := BackendEquation.getEqnsFromEqSystem(isyst);
4293 21834 outUnreplaceable := BackendEquation.traverseEquationArray(eqns, addUnreplaceableFromWhenEqn, inUnreplaceable);
4294 end addUnreplaceableFromWhensSystem;
4295
4296 protected function addUnreplaceableFromWhenEqn
4297 input BackendDAE.Equation inEq;
4298 input UnorderedSet<DAE.ComponentRef> inHs;
4299 output BackendDAE.Equation eqn;
4300 output UnorderedSet<DAE.ComponentRef> hs;
4301 algorithm
4302 (eqn,hs) := match (inEq,inHs)
4303 local
4304 BackendDAE.WhenEquation weqn;
4305 list< DAE.Statement> stmts;
4306 // when eqn
4307 case (eqn as BackendDAE.WHEN_EQUATION(whenEquation=weqn), hs)
4308 algorithm
4309 916 hs := addUnreplaceableFromWhen(weqn, hs);
4310 then (eqn,hs);
4311 // algorithm
4312 case (eqn as BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(statementLst=stmts)), hs)
4313 algorithm
4314 440 hs := List.fold(stmts, addUnreplaceableFromWhenStmt, hs);
4315 then (eqn, hs);
4316 else (inEq,inHs);
4317 end match;
4318 end addUnreplaceableFromWhenEqn;
4319
4320 protected function addUnreplaceableFromWhenStmt
4321 input DAE.Statement inStmt;
4322 input UnorderedSet<DAE.ComponentRef> inHS;
4323 output UnorderedSet<DAE.ComponentRef> outHS;
4324 algorithm
4325 outHS := matchcontinue inStmt
4326 local
4327 DAE.Statement stmt;
4328 list<DAE.Statement> stmts;
4329 UnorderedSet<DAE.ComponentRef> hs;
4330 DAE.ComponentRef cr;
4331
4332 case DAE.STMT_WHEN(statementLst=stmts, elseWhen=NONE()) algorithm
4333 228 hs := List.fold(stmts, addUnreplaceableFromStmt, inHS);
4334 then hs;
4335
4336 case DAE.STMT_WHEN(statementLst=stmts, elseWhen=SOME(stmt)) algorithm
4337 84 hs := List.fold(stmts, addUnreplaceableFromStmt, inHS);
4338 84 hs := addUnreplaceableFromWhenStmt(stmt, hs);
4339 then hs;
4340
4341 // add also lhs of array assign stmts because these are not replaceable with array(...)
4342 case DAE.STMT_ASSIGN_ARR(lhs=DAE.CREF(componentRef=cr)) algorithm
4343 84 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
4344 hs := addCref(cr, inHS);
4345 then hs;
4346
4347 // lochel: do not replace arrays that appear on lhs [#2271]
4348 // TODO: improve this case, it blocks too much simplifications
4349 case DAE.STMT_ASSIGN(exp1=DAE.CREF(componentRef=cr)) algorithm
4350 // DAE.T_ARRAY(ty=_) = ComponentReference.crefLastType(cr);
4351 // failure({} = ComponentReference.crefLastSubs(cr));
4352 // true = ComponentReference.isArrayElement(cr);
4353 1820 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
4354 hs := addCref(cr, inHS);
4355 then hs;
4356
4357 else
4358 then inHS;
4359 end matchcontinue;
4360 end addUnreplaceableFromWhenStmt;
4361
4362 protected function addUnreplaceableFromStmt
4363 input DAE.Statement inStmt;
4364 input UnorderedSet<DAE.ComponentRef> inHS;
4365 output UnorderedSet<DAE.ComponentRef> outHS;
4366 algorithm
4367 outHS := match inStmt
4368 local
4369 DAE.ComponentRef cr;
4370 UnorderedSet<DAE.ComponentRef> hs;
4371 list<DAE.Exp> expExpLst;
4372 list<DAE.ComponentRef> crlst;
4373
4374 case DAE.STMT_ASSIGN(exp1=DAE.CREF(componentRef=cr)) algorithm
4375 493 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
4376 hs := addCref(cr, inHS);
4377 then hs;
4378
4379 case DAE.STMT_TUPLE_ASSIGN(expExpLst=expExpLst) algorithm
4380 15 crlst := List.flatten(List.map(expExpLst, Expression.extractCrefsFromExp));
4381 15 crlst := List.map(crlst, ComponentReferenceBasics.crefStripLastSubs);
4382 15 hs := List.fold(crlst, addCref, inHS);
4383 then hs;
4384
4385 case DAE.STMT_ASSIGN_ARR(lhs=DAE.CREF(componentRef=cr)) algorithm
4386 10 cr := ComponentReferenceBasics.crefStripLastSubs(cr);
4387 hs := addCref(cr, inHS);
4388 then hs;
4389
4390 else
4391 then inHS;
4392 end match;
4393 end addUnreplaceableFromStmt;
4394
4395 protected function addUnreplaceableFromWhen "This is a helper function for addUnreplaceableFromWhenEqn."
4396 input BackendDAE.WhenEquation inWEqn;
4397 input UnorderedSet<DAE.ComponentRef> iHs;
4398 output UnorderedSet<DAE.ComponentRef> oHs;
4399 algorithm
4400 oHs := match inWEqn
4401 local
4402 BackendDAE.WhenEquation weqn;
4403 UnorderedSet<DAE.ComponentRef> hs;
4404 list<BackendDAE.WhenOperator> whenStmtLst;
4405 Option<BackendDAE.WhenEquation> oweqn;
4406
4407 case BackendDAE.WHEN_STMTS(whenStmtLst=whenStmtLst,elsewhenPart=oweqn)
4408 algorithm
4409 933 hs := addUnreplaceableFromWhenOps(whenStmtLst, iHs);
4410
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 933 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 916 times.
933 if isSome(oweqn) then
4411 17 SOME(weqn) := oweqn;
4412 hs := addUnreplaceableFromWhen(weqn, hs);
4413 end if;
4414 then hs;
4415 end match;
4416 end addUnreplaceableFromWhen;
4417
4418 protected function addUnreplaceableFromWhenOps
4419 "This is a helper function for addUnreplaceableFromWhenEqn."
4420 input list<BackendDAE.WhenOperator> inWhenOps;
4421 input UnorderedSet<DAE.ComponentRef> iHs;
4422 output UnorderedSet<DAE.ComponentRef> oHs;
4423 algorithm
4424 oHs := match inWhenOps
4425 local
4426 DAE.ComponentRef left;
4427 list<DAE.ComponentRef> crefLst;
4428 DAE.Exp e;
4429 list<BackendDAE.WhenOperator> rest;
4430 UnorderedSet<DAE.ComponentRef> hs;
4431
4432 case BackendDAE.ASSIGN(left = DAE.CREF(componentRef = left))::rest
4433 algorithm
4434 921 left := ComponentReferenceBasics.crefStripLastSubs(left);
4435 hs := addCref(left, iHs);
4436 921 then addUnreplaceableFromWhenOps(rest, hs);
4437 case BackendDAE.ASSIGN(left = e)::rest
4438 algorithm
4439 12 crefLst := Expression.getAllCrefs(e);
4440 hs := iHs;
4441
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 12 times.
36 for left in crefLst loop
4442 24 left := ComponentReferenceBasics.crefStripLastSubs(left);
4443 hs := addCref(left, hs);
4444 end for;
4445 12 then addUnreplaceableFromWhenOps(rest, hs);
4446 else
4447 then iHs;
4448 end match;
4449 end addUnreplaceableFromWhenOps;
4450
4451 protected function traverserExpUnreplaceable
4452 input DAE.Exp e;
4453 input UnorderedSet<DAE.ComponentRef> unReplaceable;
4454 output DAE.Exp outExp;
4455 output UnorderedSet<DAE.ComponentRef> outHt;
4456 algorithm
4457 (outExp,outHt) := match e
4458 local
4459 DAE.ComponentRef cr;
4460 list<DAE.Exp> explst;
4461 list<DAE.ComponentRef> crlst;
4462 case DAE.CREF(componentRef = cr)
4463 algorithm
4464 try
4465 1131101 outHt := traverseCrefUnreplaceable(cr, NONE(), unReplaceable);
4466 else
4467 outHt := unReplaceable;
4468 end try;
4469 then (e, outHt);
4470 case DAE.CALL(path=Absyn.IDENT(name = "pre"), expLst=explst)
4471 algorithm
4472 try
4473 3725 crlst := List.flatten(List.map(explst, Expression.extractCrefsFromExp));
4474 3725 crlst := List.map(crlst, ComponentReferenceBasics.crefStripLastSubs);
4475 3725 outHt := List.fold(crlst, addCref, unReplaceable);
4476 else
4477 outHt := unReplaceable;
4478 end try;
4479 then (e, outHt);
4480 else (e,unReplaceable);
4481 end match;
4482 end traverserExpUnreplaceable;
4483
4484 protected function traverseCrefUnreplaceable
4485 input DAE.ComponentRef inCref;
4486 input Option<DAE.ComponentRef> preCref;
4487 input UnorderedSet<DAE.ComponentRef> iUnreplaceable;
4488 output UnorderedSet<DAE.ComponentRef> oUnreplaceable;
4489 algorithm
4490 oUnreplaceable := match(inCref, preCref)
4491 local
4492 DAE.Ident name;
4493 DAE.ComponentRef cr, pcr;
4494 DAE.Type ty;
4495 list<DAE.Subscript> subs;
4496 UnorderedSet<DAE.ComponentRef> unReplaceable;
4497 Boolean b;
4498
4499 case (DAE.CREF_QUAL(ident=name, identType=ty, subscriptLst=subs, componentRef=cr), SOME(pcr)) algorithm
4500 1654108 (_, b) := Expression.traverseExpTopDownSubs(subs, Expression.traversingComponentRefPresent, false);
4501
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1654107 times.
1654108 pcr := if b then ComponentReference.crefPrependIdent(pcr, name, {}, ty) else pcr;
4502
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1654107 times.
1654108 unReplaceable := if b then addCref(pcr, iUnreplaceable) else iUnreplaceable;
4503 1654108 pcr := ComponentReference.crefPrependIdent(pcr, name, subs, ty);
4504 1654108 then traverseCrefUnreplaceable(cr, SOME(pcr), unReplaceable);
4505
4506 case (DAE.CREF_QUAL(ident=name, identType=ty, subscriptLst=subs, componentRef=cr), NONE()) algorithm
4507 1019782 (_, b) := Expression.traverseExpTopDownSubs(subs, Expression.traversingComponentRefPresent, false);
4508
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1019780 times.
1019782 unReplaceable := if b then addCref(DAE.CREF_IDENT(name, ty, {}), iUnreplaceable) else iUnreplaceable;
4509 2039564 then traverseCrefUnreplaceable(cr, SOME(DAE.CREF_IDENT(name, ty, subs)), unReplaceable);
4510
4511 case (DAE.CREF_IDENT(ident=name, identType=ty, subscriptLst=subs), SOME(pcr)) algorithm
4512 1019782 (_, b) := Expression.traverseExpTopDownSubs(subs, Expression.traversingComponentRefPresent, false);
4513
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 1018830 times.
1019782 unReplaceable := if b then addCref(ComponentReference.crefPrependIdent(pcr, name, {}, ty), iUnreplaceable) else iUnreplaceable;
4514 then unReplaceable;
4515
4516 case (DAE.CREF_IDENT(ident=name, identType=ty), NONE()) algorithm
4517 111282 (_, b) := Expression.traverseExpTopDownCrefHelper(inCref, Expression.traversingComponentRefPresent, false);
4518
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 111065 times.
111282 unReplaceable := if b then addCref(DAE.CREF_IDENT(name, ty, {}), iUnreplaceable) else iUnreplaceable;
4519 then unReplaceable;
4520
4521 case (DAE.OPTIMICA_ATTR_INST_CREF(), _) then iUnreplaceable;
4522 case (DAE.WILD(), _) then iUnreplaceable;
4523 end match;
4524 end traverseCrefUnreplaceable;
4525
4526 protected function negateExpression "negate an expression with a debug message"
4527 input Boolean negationFlag;
4528 input DAE.Exp inExp "the expression we should negate if flag is true";
4529 input DAE.Exp inAlternative "the expression we should return if flag is false";
4530 input String message;
4531 output DAE.Exp outExpression;
4532 algorithm
4533 outExpression := match negationFlag
4534 local DAE.Exp negatedExp, negate;
4535 // we should negate
4536 case true
4537 algorithm
4538 26735 negatedExp := Expression.negate(inExp);
4539
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26735 times.
26735 if Flags.isSet(Flags.DEBUG_ALIAS) then
4540 ✗ BackendDump.debugStrExpStr("Negating: ", inExp, " " + message + ".\n");
4541 end if;
4542 then
4543 negatedExp;
4544 // we should not negate
4545 case false
4546 algorithm
4547
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 229455 times.
229455 if Flags.isSet(Flags.DEBUG_ALIAS) then
4548 ✗ BackendDump.debugStrExpStrExpStr("Not negating: ", inExp, " returning: ", inAlternative, " " + message + ".\n");
4549 end if;
4550 then
4551 inAlternative;
4552 end match;
4553 end negateExpression;
4554
4555 protected function performAliasEliminationBB "BB,
4556 This module changes the DAE by finding simple equations, doing appropriate substitutions, e.g. known and alias vars!
4557 NOTE: This is currently an experimental prototype."
4558 input BackendDAE.BackendDAE inDAE;
4559 input Boolean findAliases;
4560 output BackendDAE.BackendDAE outDAE;
4561 algorithm
4562 ✗ outDAE := BackendDAEUtil.mapEqSystem(inDAE, function eliminateTrivialEquations(findAliases=findAliases));
4563 ✗ outDAE := BackendDAEUtil.mapEqSystem(outDAE, getAliasAttributes);
4564 end performAliasEliminationBB;
4565
4566 protected function eliminateTrivialEquations "BB,
4567 main module for eliminating trivial equations
4568 "
4569 input BackendDAE.EqSystem inSystem;
4570 input BackendDAE.Shared inShared;
4571 input Boolean findAliases;
4572 output BackendDAE.EqSystem outSystem;
4573 output BackendDAE.Shared outShared;
4574 algorithm
4575 (outSystem,outShared) := matchcontinue(inSystem,inShared)
4576 local
4577 BackendDAE.Variables orderedVars;
4578 BackendDAE.Variables globalKnownVars;
4579 BackendDAE.EquationArray orderedEqs;
4580 BackendDAE.EquationArray inieqns;
4581
4582 list<BackendDAE.Var> varList;
4583 list<BackendDAE.Equation> eqList;
4584 list<BackendDAE.Equation> initEqList, remEqList;
4585 list<BackendDAE.Equation> simpleEqList;
4586
4587 HashTableCrToExp.HashTable HTCrToExp;
4588 HashTableCrToCrEqLst.HashTable HTCrToCrEqLst;
4589 list<tuple<DAE.ComponentRef,DAE.Exp>> tplExp;
4590 list<tuple<DAE.ComponentRef,list<tuple<DAE.ComponentRef,BackendDAE.Equation>>>> tplCrEqLst;
4591
4592 Integer countAliasEquations, countSimpleEquations, size;
4593 BackendDAE.EqSystem syst;
4594 BackendDAE.Shared shared;
4595 BackendDAE.EventInfo eventInfo;
4596 BackendDAE.Variables globalKnownVars;
4597 BackendDAE.Variables aliasVars;
4598 BackendDAE.EquationArray inieqns;
4599 list<BackendDAE.Var> varlst;
4600 BackendVarTransform.VariableReplacements repl;
4601
4602 case ( syst as BackendDAE.EQSYSTEM(orderedVars=orderedVars, orderedEqs=orderedEqs),
4603 shared as BackendDAE.SHARED( globalKnownVars=globalKnownVars, aliasVars=aliasVars, initialEqs=inieqns,
4604 eventInfo=eventInfo) )
4605 algorithm
4606
4607 // sizes of Hash tables are system dependent!!!!
4608 ✗ size := BackendVariable.varsSize(orderedVars);
4609 ✗ size := intMax(BaseHashTable.defaultBucketSize, realInt(realMul(intReal(size), 0.7)));
4610 ✗ HTCrToExp := HashTableCrToExp.emptyHashTableSized(size);
4611 ✗ HTCrToCrEqLst := HashTableCrToCrEqLst.emptyHashTableSized(size);
4612 ✗ repl := BackendVarTransform.emptyReplacementsSized(size);
4613
4614 //SimCodeUtil.execStat("START :");
4615 // Find known variables and all simple equations and add known variables to shared object!!!
4616 ✗ (_, HTCrToExp, HTCrToCrEqLst, eqList, simpleEqList) := BackendEquation.traverseEquationArray(orderedEqs, function findSimpleEquations(findAliases=findAliases),
4617 (orderedVars, HTCrToExp, HTCrToCrEqLst, {}, {}));
4618 ✗ tplExp := BaseHashTable.hashTableList(HTCrToExp);
4619 // (globalKnownVars, orderedVars) = moveVars(tplExp, globalKnownVars, orderedVars);
4620 //SimCodeUtil.execStat("FINDSIMPLE1: ");
4621
4622
4623 //Find Alias variables and move variables to shared object!!!
4624 ✗ tplCrEqLst := BaseHashTable.hashTableList(HTCrToCrEqLst);
4625 ✗ HTCrToExp := addRestCrefs(tplCrEqLst, HTCrToExp, HTCrToCrEqLst);
4626 ✗ tplExp := BaseHashTable.hashTableList(HTCrToExp);
4627 ✗ (aliasVars, orderedVars) := moveVars(tplExp, aliasVars, orderedVars);
4628
4629 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4630 // Necessary, since no update of variable size is done so far !!!!
4631 ✗ varList := BackendVariable.varList(orderedVars);
4632 // Necessary since no pdate is done for stateDerInfo, this information should be collected afterwards
4633 ✗ varList := removeStateDerInfo(varList);
4634 ✗ orderedVars := BackendVariable.listVar1(varList);
4635 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4636 //SimCodeUtil.execStat("FINDSIMPLE2: ");
4637
4638 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4639 //Insert known simplifications at all relevant places!!!!
4640 //This should be changed to traverseEquationArray_WithUpdate or traverseExpsOfEquationArray
4641 //update kept system equations
4642 ✗ (eqList,_) := BackendEquation.traverseExpsOfEquationList(eqList, traverseExpTopDown, HTCrToExp);
4643 ✗ orderedEqs := BackendEquation.listEquation(eqList);
4644 //Update initial equations
4645 ✗ initEqList := BackendEquation.equationList(inieqns);
4646 ✗ (initEqList,_) := BackendEquation.traverseExpsOfEquationList(initEqList, traverseExpTopDown, HTCrToExp);
4647 ✗ inieqns := BackendEquation.listEquation(initEqList);
4648
4649 // Update removed equations !!!
4650 ✗ remEqList := BackendEquation.equationList(syst.removedEqs);
4651 ✗ (remEqList,_) := BackendEquation.traverseExpsOfEquationList(remEqList, traverseExpTopDown, HTCrToExp);
4652 //remove asserts with condition=true from removed equations
4653 ✗ syst.removedEqs := BackendEquation.listEquation(List.select(remEqList, BackendEquation.assertWithCondTrue));
4654
4655 ✗ remEqList := BackendEquation.equationList(shared.removedEqs);
4656 ✗ (remEqList,_) := BackendEquation.traverseExpsOfEquationList(remEqList, traverseExpTopDown, HTCrToExp);
4657 //remove asserts with condition=true from removed equations
4658 ✗ shared.removedEqs := BackendEquation.listEquation(List.select(remEqList, BackendEquation.assertWithCondTrue));
4659
4660
4661 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4662 ✗ repl := addVarReplacements(tplExp,repl);
4663 // Update Alias variables, some might be moved to known variables!!!
4664 ✗ (aliasVars, (_, varlst)) := BackendVariable.traverseBackendDAEVarsWithUpdate(aliasVars, replaceAliasVarTraverser, (repl, {}));
4665 ✗ aliasVars := List.fold(varlst, fixAliasConstBindings, aliasVars);
4666 ✗ (globalKnownVars, _) := BackendVariable.traverseBackendDAEVarsWithUpdate(globalKnownVars, replaceVarTraverser, repl);
4667
4668 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4669 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4670 // Update optimica expressions !!!
4671 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4672 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4673 // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
4674 //SimCodeUtil.execStat("FINDSIMPLE4: ");
4675
4676 ✗ if Flags.isSet(Flags.DUMP_REPL) then
4677 ✗ tplExp := BaseHashTable.hashTableList(HTCrToExp);
4678 ✗ countAliasEquations := listLength(tplExp);
4679 ✗ countSimpleEquations := listLength(simpleEqList);
4680 ✗ print("Number of Unknowns: " + intString(BackendVariable.varsSize(orderedVars)) + "\n");
4681 ✗ print("Number of \"Complex\" Equations: " + intString(BackendEquation.equationLstSize(eqList)) + "\n");
4682 ✗ print("Number of Alias Equations: " + intString(countAliasEquations) + "\n");
4683 ✗ print("Number of Simple Equations: " + intString(countSimpleEquations) + "\n");
4684 ✗ print("\nAliases:\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
4685 ✗ BaseHashTable.dumpHashTable(HTCrToExp);
4686 end if;
4687 //SimCodeUtil.execStat("FINDSIMPLE6: ");
4688
4689 ✗ syst.orderedVars := orderedVars;
4690 ✗ syst.orderedEqs := orderedEqs;
4691
4692 ✗ shared.eventInfo := eventInfo;
4693 ✗ shared.globalKnownVars := globalKnownVars;
4694 ✗ shared.aliasVars := aliasVars;
4695 ✗ shared.initialEqs := inieqns;
4696
4697 ✗ then (BackendDAEUtil.clearEqSyst(syst), shared);
4698 else (inSystem, inShared);
4699 end matchcontinue;
4700 end eliminateTrivialEquations;
4701
4702 protected function moveVars "BB,
4703 move found variables to the alias variables
4704 "
4705 input list<tuple<DAE.ComponentRef, DAE.Exp>> cr_exp_lst;
4706 input BackendDAE.Variables inAliasVars;
4707 input BackendDAE.Variables inVars;
4708 output BackendDAE.Variables outAliasVars = inAliasVars;
4709 output BackendDAE.Variables outVars = inVars;
4710 protected
4711 DAE.ComponentRef cr;
4712 DAE.Exp e;
4713 BackendDAE.Var v;
4714 Integer i;
4715 list<DAE.SymbolicOperation> ops;
4716 Boolean bs;
4717 algorithm
4718 ✗ for cr_exp in cr_exp_lst loop
4719 ✗ (cr,e) := cr_exp;
4720 try
4721 ✗ (v,i) := BackendVariable.getVarSingle(cr,outVars);
4722 // add bindExp
4723 ✗ v := BackendVariable.setBindExp(v, SOME(e));
4724 // Update this to given source information!!!!
4725 ✗ ops := ElementSource.getSymbolicTransformations(DAE.emptyElementSource);
4726 ✗ v := BackendVariable.mergeVariableOperations(v, DAE.SOLVED(cr, e)::ops);
4727 ✗ bs := BackendVariable.isStateVar(v);
4728 ✗ v := if bs then BackendVariable.setVarKind(v, BackendDAE.DUMMY_STATE()) else v;
4729 // remove and add from corresponding var set
4730 ✗ (outVars, _) := BackendVariable.removeVar(i, outVars);
4731 ✗ outAliasVars := BackendVariable.addVar(v, outAliasVars);
4732 else
4733 ✗ outAliasVars := outAliasVars;
4734 ✗ outVars := outVars;
4735 end try;
4736 end for;
4737 end moveVars;
4738
4739 protected function addVarReplacements "BB,
4740 use VarReplacements only for whileLst
4741 "
4742 input list<tuple<DAE.ComponentRef, DAE.Exp>> cr_exp_lst;
4743 input BackendVarTransform.VariableReplacements inRepl;
4744 output BackendVarTransform.VariableReplacements outRepl=inRepl;
4745 protected
4746 DAE.ComponentRef cr;
4747 DAE.Exp e;
4748 algorithm
4749 ✗ for cr_exp in cr_exp_lst loop
4750 ✗ (cr,e) := cr_exp;
4751 // add to replacements
4752 ✗ outRepl := BackendVarTransform.addReplacement(outRepl, cr, e, SOME(BackendVarTransform.skipPreChangeEdgeOperator));
4753 end for;
4754 end addVarReplacements;
4755
4756 protected function traverseExpTopDown "BB,
4757 traverse top down, when inserting
4758 "
4759 input DAE.Exp inExp;
4760 input HashTableCrToExp.HashTable inHTCrToExp;
4761 output DAE.Exp outExp;
4762 output HashTableCrToExp.HashTable outHTCrToExp = inHTCrToExp;
4763 algorithm
4764 ✗ (outExp, _) := Expression.traverseExpTopDown(inExp, insertReplacementsInEquations, inHTCrToExp);
4765 ✗ (outExp,_) := ExpressionSimplify.simplify(outExp);
4766 end traverseExpTopDown;
4767
4768 protected function insertReplacementsInEquations "BB,
4769 inserts replacements stored in the hash table into equations
4770 "
4771 input DAE.Exp inE1;
4772 input HashTableCrToExp.HashTable inHTCrToExp;
4773 output DAE.Exp outE1;
4774 output Boolean cont;
4775 output HashTableCrToExp.HashTable outHTCrToExp;
4776 algorithm
4777 (outE1, cont, outHTCrToExp) := matchcontinue inE1
4778 local
4779 DAE.ComponentRef cr;
4780 DAE.Exp value;
4781 case DAE.CREF(componentRef=cr) algorithm
4782 ✗ if BaseHashTable.hasKey(cr, inHTCrToExp) then
4783 ✗ value := BaseHashTable.get(cr, inHTCrToExp);
4784 else
4785 value := inE1;
4786 end if;
4787 then (value, true, inHTCrToExp);
4788 else (inE1, true, inHTCrToExp);
4789 end matchcontinue;
4790 end insertReplacementsInEquations;
4791
4792 protected function removeStateDerInfo "BB,
4793 remove stateDerInfo! This information should be collected after removeSimpleEquations
4794 "
4795 input list<BackendDAE.Var> inVarList;
4796 output list<BackendDAE.Var> vars;
4797 algorithm
4798 ✗ vars := list(if BackendVariable.isStateVar(var) then BackendVariable.setStateDerivative(var, NONE()) else var for var in inVarList);
4799 end removeStateDerInfo;
4800
4801 protected function findSimpleEquations "BB,
4802 main function for detecting simple equations
4803 "
4804 input BackendDAE.Equation inEq;
4805 input tuple <BackendDAE.Variables, HashTableCrToExp.HashTable, HashTableCrToCrEqLst.HashTable, list<BackendDAE.Equation>, list<BackendDAE.Equation>> inTuple;
4806 input Boolean findAliases;
4807 output BackendDAE.Equation outEq;
4808 output tuple <BackendDAE.Variables, HashTableCrToExp.HashTable, HashTableCrToCrEqLst.HashTable, list<BackendDAE.Equation>, list<BackendDAE.Equation>> outTuple;
4809 algorithm
4810 (outEq, outTuple) := matchcontinue(inEq, inTuple)
4811 local
4812 BackendDAE.Equation eq, eqSolved;
4813 HashTableCrToExp.HashTable HTCrToExp;
4814 HashTableCrToCrEqLst.HashTable HTCrToCrEqLst;
4815 list<DAE.ComponentRef> cr_lst;
4816 list<BackendDAE.Equation> eqList;
4817 list<BackendDAE.Equation> simpleEqList;
4818 Integer count, paramCount;
4819 DAE.ComponentRef cr, cr1, cr2;
4820 DAE.Exp res, value, exp1, exp2;
4821 BackendDAE.Variables vars;
4822 Boolean keepEquation;
4823 DAE.ElementSource source;
4824 BackendDAE.EquationAttributes eqAttr;
4825
4826 case (eq ,(vars, HTCrToExp, HTCrToCrEqLst, eqList, simpleEqList)) algorithm
4827 ✗ res := BackendEquation.getEquationRHS(eq);
4828 ✗ (_, (cr_lst,_,count,paramCount,true)) := Expression.traverseExpTopDown(res, findCrefs, ({},vars,0,0,true));
4829 ✗ res := BackendEquation.getEquationLHS(eq);
4830 ✗ (_, (cr_lst,_,count,_,true)) := Expression.traverseExpTopDown(res, findCrefs, (cr_lst,vars,count,paramCount,true));
4831 keepEquation := true;
4832 ✗ if (count == 1) then
4833 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
4834 ✗ print("Found Equation knw0: " + BackendDump.equationString(eq) + "\n");
4835 end if;
4836 ✗ {cr} := cr_lst;
4837 ✗ false := BackendVariable.isState(cr,vars);
4838 ✗ false := BackendVariable.isClockedState(cr,vars);
4839 ✗ false := BackendVariable.isOutput(cr,vars);
4840 ✗ false := BackendVariable.isDiscrete(cr,vars);
4841 ✗ exp1 := Expression.crefExp(cr);
4842 ✗ true := Types.isSimpleType(Expression.typeof(exp1));
4843 ✗ eqSolved as BackendDAE.EQUATION(scalar=res) := BackendEquation.solveEquation(eq,exp1,NONE());
4844 ✗ true := isSimple(res);
4845 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
4846 ✗ print("Found Equation knw1: " + BackendDump.equationString(eq) + "\n");
4847 end if;
4848 ✗ HTCrToExp := addToCrToExp(cr, eqSolved, HTCrToExp, HTCrToCrEqLst);
4849 keepEquation := false;
4850 elseif (count == 2) and findAliases then
4851 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
4852 ✗ print("Found Equation al0: " + BackendDump.equationString(eq) + "\n");
4853 end if;
4854 ✗ {cr2, cr1} := cr_lst;
4855 // Be careful, when replacing states!!!
4856 // if BackendVariable.isState(cr1,vars) then
4857 // true = BackendVariable.isState(cr2,vars);
4858 // end if;
4859 ✗ false := BackendVariable.isState(cr1,vars) or BackendVariable.isState(cr2,vars);
4860 ✗ false := BackendVariable.isClockedState(cr1,vars) or BackendVariable.isClockedState(cr2,vars);
4861 ✗ false := BackendVariable.isOutput(cr1,vars) or BackendVariable.isOutput(cr2,vars);
4862 ✗ false := BackendVariable.isDiscrete(cr1,vars) or BackendVariable.isDiscrete(cr2,vars);
4863 ✗ exp1 := Expression.crefExp(cr1);
4864 ✗ true := Types.isSimpleType(Expression.typeof(exp1));
4865 ✗ exp2 := Expression.crefExp(cr2);
4866
4867 ✗ BackendDAE.EQUATION(scalar=res) := BackendEquation.solveEquation(eq,exp2,NONE());
4868 ✗ true := isSimple(res);
4869 ✗ BackendDAE.EQUATION(scalar=res) := BackendEquation.solveEquation(eq,exp1,NONE());
4870 ✗ true := isSimple(res);
4871 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
4872 ✗ print("Found Equation al1: " + BackendDump.equationString(eq) + "\n");
4873 end if;
4874
4875 ✗ HTCrToCrEqLst := addToCrAndEqLists(cr2, cr1, inEq, HTCrToCrEqLst);
4876 ✗ HTCrToCrEqLst := addToCrAndEqLists(cr1, cr2, inEq, HTCrToCrEqLst);
4877
4878 ✗ if (BaseHashTable.hasKey(cr2, HTCrToExp)) then
4879 ✗ value := BaseHashTable.get(cr2, HTCrToExp);
4880 ✗ BackendDAE.EQUATION(scalar=res, source=source, attr=eqAttr) := BackendEquation.solveEquation(eq, Expression.crefExp(cr1),NONE());
4881 ✗ (res,_) := Expression.replaceExp(res,Expression.crefExp(cr2),value);
4882 ✗ (res,_) := ExpressionSimplify.simplify(res);
4883 ✗ HTCrToExp := addToCrToExp(cr1, BackendDAE.EQUATION(Expression.crefExp(cr1), res, source, eqAttr), HTCrToExp, HTCrToCrEqLst);
4884 else
4885 ✗ if (BaseHashTable.hasKey(cr1, HTCrToExp)) then
4886 ✗ value := BaseHashTable.get(cr1, HTCrToExp);
4887 ✗ BackendDAE.EQUATION(scalar=res, source=source, attr=eqAttr) := BackendEquation.solveEquation(eq, Expression.crefExp(cr2),NONE());
4888 ✗ (res,_) := Expression.replaceExp(res,Expression.crefExp(cr1),value);
4889 ✗ (res,_) := ExpressionSimplify.simplify(res);
4890 ✗ HTCrToExp := addToCrToExp(cr2, BackendDAE.EQUATION(Expression.crefExp(cr2), res, source, eqAttr), HTCrToExp, HTCrToCrEqLst);
4891 end if;
4892 end if;
4893 keepEquation := false;
4894 end if;
4895 ✗ if (keepEquation) then
4896 eqList := inEq::eqList;
4897 else
4898 simpleEqList := inEq::simpleEqList;
4899 end if;
4900 ✗ then (inEq, (vars, HTCrToExp, HTCrToCrEqLst, eqList, simpleEqList));
4901 case (_,(vars, HTCrToExp, HTCrToCrEqLst, eqList, simpleEqList))algorithm
4902 eqList := inEq::eqList;
4903 ✗ then (inEq, (vars, HTCrToExp, HTCrToCrEqLst, eqList, simpleEqList));
4904 else algorithm
4905 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.findSimpleEquations ++++++++++\n");
4906 then (inEq, inTuple);
4907 end matchcontinue;
4908 end findSimpleEquations;
4909
4910 protected function findCrefs "BB,
4911 looks for variable crefs in Expressions, if more then 2 are found stop searching
4912 also stop if complex structures appear, e.g. IFEXP
4913 "
4914 input DAE.Exp inE1;
4915 input tuple<list<DAE.ComponentRef>, BackendDAE.Variables, Integer, Integer, Boolean> inTuple;
4916 output DAE.Exp outE1;
4917 output Boolean cont;
4918 output tuple<list<DAE.ComponentRef>, BackendDAE.Variables, Integer, Integer, Boolean> outTuple;
4919 algorithm
4920 (outE1, cont, outTuple) := matchcontinue(inE1,inTuple)
4921 local
4922 DAE.ComponentRef cr;
4923 list<DAE.ComponentRef> cr_lst;
4924 Integer count, paramCount;
4925 BackendDAE.Variables vars;
4926 ✗ case(_,(_,vars,count,_,_)) guard(count<0) then(inE1, false, ({},vars,-1,-1,false));
4927 case (DAE.CREF(componentRef=cr),(cr_lst,vars,count,paramCount,true)) guard(count < 2 and not (ComponentReferenceBasics.crefEqual(cr,DAE.crefTime))) algorithm
4928 ✗ BackendVariable.getVar(cr, vars);
4929 ✗ then (inE1, true, (cr::cr_lst,vars,count+1,paramCount,true));
4930 case (DAE.CREF(componentRef=cr),(cr_lst,vars,count,paramCount,true)) guard(count < 2 and not (ComponentReferenceBasics.crefEqual(cr,DAE.crefTime)))
4931 ✗ then (inE1, true, (cr_lst,vars,count,paramCount+1,true));
4932 case (DAE.CREF(),(_,vars,_,_,true))
4933 ✗ then (inE1, false, ({},vars,-1,-1,false));
4934 case (DAE.RELATION(),(_,vars,_,_,_))
4935 ✗ then (inE1, false, ({},vars,-1,-1,false));
4936 case (DAE.IFEXP(),(_,vars,_,_,_))
4937 ✗ then (inE1, false, ({},vars,-1,-1,false));
4938 case (DAE.CALL(),(_,vars,_,_,_))
4939 ✗ then (inE1, false, ({},vars,-1,-1,false));
4940 case (DAE.RECORD(),(_,vars,_,_,_))
4941 ✗ then (inE1, false, ({},vars,-1,-1,false));
4942 else (inE1, true, inTuple);
4943 end matchcontinue;
4944 end findCrefs;
4945
4946 protected function addToCrAndEqLists "BB,
4947 collect depending varaibles and corresponding equations
4948 in a lookup hash table
4949 "
4950 input DAE.ComponentRef cr1;
4951 input DAE.ComponentRef cr2;
4952 input BackendDAE.Equation eq;
4953 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
4954 output HashTableCrToCrEqLst.HashTable outHTCrToCrEqLst;
4955 protected
4956 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
4957 BackendDAE.Equation eqSolved;
4958 algorithm
4959 outHTCrToCrEqLst := match inHTCrToCrEqLst
4960 local
4961 HashTableCrToCrEqLst.HashTable HTCrToCrEqLst;
4962 case HTCrToCrEqLst algorithm
4963 ✗ eqSolved := BackendEquation.solveEquation(eq, Expression.crefExp(cr2),NONE());
4964 ✗ if (BaseHashTable.hasKey(cr1, HTCrToCrEqLst)) then
4965 ✗ cr_eq_lst := BaseHashTable.get(cr1, HTCrToCrEqLst);
4966 ✗ cr_eq_lst := (cr2,eqSolved)::cr_eq_lst;
4967 else
4968 ✗ cr_eq_lst := {(cr2,eqSolved)};
4969 end if;
4970 ✗ HTCrToCrEqLst := BaseHashTable.add((cr1, cr_eq_lst), HTCrToCrEqLst);
4971 then HTCrToCrEqLst;
4972 else algorithm
4973 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.addToCrAndEqLists ++++++++++\n");
4974 ✗ BackendDump.printEquation(eq);
4975 ✗ print("Solve for:" + ComponentReference.debugPrintComponentRefTypeStr(cr1) + "\n");
4976 ✗ then fail();
4977 end match;
4978 end addToCrAndEqLists;
4979
4980 protected function addToCrToExp "BB,
4981 add one entry and all depending ones to the hash table HTCrToExp
4982 "
4983 input DAE.ComponentRef cr;
4984 input BackendDAE.Equation eq;
4985 input HashTableCrToExp.HashTable inHTCrToExp;
4986 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
4987 output HashTableCrToExp.HashTable outHTCrToExp;
4988 protected
4989 DAE.Exp value;
4990 algorithm
4991 outHTCrToExp := matchcontinue()
4992 case () algorithm
4993 ✗ BackendDAE.EQUATION(scalar=value) := BackendEquation.solveEquation(eq, Expression.crefExp(cr),NONE());
4994 ✗ outHTCrToExp := BaseHashTable.add((cr, value), inHTCrToExp);
4995 // if Flags.isSet(Flags.DEBUG_ALIAS) then
4996 // print("ADD: " + ComponentReference.debugPrintComponentRefTypeStr(cr) + " = " + ExpressionBasics.printExpStr(value) + "\n");
4997 // BaseHashTable.dumpHashTable(outHTCrToExp);
4998 // print("LOOKUP HASH TABLE: \n");
4999 // BaseHashTable.dumpHashTable(inHTCrToCrEqLst);
5000 // end if;
5001 ✗ outHTCrToExp := solveAllCrefs(cr, value, outHTCrToExp, inHTCrToCrEqLst);
5002 then outHTCrToExp;
5003 else algorithm
5004 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.addToCrToExp ++++++++++\n");
5005 ✗ BackendDump.printEquation(eq);
5006 ✗ print(ComponentReference.debugPrintComponentRefTypeStr(cr) + "\n");
5007 ✗ then fail();
5008 end matchcontinue;
5009 end addToCrToExp;
5010
5011 protected function solveAllCrefs "BB,
5012 if an entry with cr = exp is added to HTCrToExp, all depending
5013 variables will be added, too
5014 "
5015 input DAE.ComponentRef cr;
5016 input DAE.Exp value;
5017 input HashTableCrToExp.HashTable inHTCrToExp;
5018 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
5019 output HashTableCrToExp.HashTable outHTCrToExp;
5020 algorithm
5021 outHTCrToExp := matchcontinue inHTCrToExp
5022 local
5023 HashTableCrToExp.HashTable HTCrToExp;
5024 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5025 case HTCrToExp algorithm
5026 ✗ if BaseHashTable.hasKey(cr, inHTCrToCrEqLst) then
5027 ✗ cr_eq_lst := BaseHashTable.get(cr, inHTCrToCrEqLst);
5028 ✗ HTCrToExp := solveAllCrefs1(cr, value, cr_eq_lst, HTCrToExp, inHTCrToCrEqLst);
5029 end if;
5030 then (HTCrToExp);
5031 else algorithm
5032 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.solveAllCrefs ++++++++++\n");
5033 then (inHTCrToExp);
5034 end matchcontinue;
5035 end solveAllCrefs;
5036
5037 protected function solveAllCrefs1 "BB,
5038 helper function for solveAllCrefs
5039 "
5040 input DAE.ComponentRef cr;
5041 input DAE.Exp value;
5042 input list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5043 input HashTableCrToExp.HashTable inHTCrToExp;
5044 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
5045 output HashTableCrToExp.HashTable outHTCrToExp;
5046 algorithm
5047 outHTCrToExp := matchcontinue(cr_eq_lst, inHTCrToExp)
5048 local
5049 DAE.ComponentRef cr1;
5050 DAE.Exp res;
5051 BackendDAE.Equation eq;
5052 HashTableCrToExp.HashTable HTCrToExp;
5053 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_rest;
5054 DAE.ElementSource source;
5055 BackendDAE.EquationAttributes eqAttr;
5056
5057 case ({}, HTCrToExp) then HTCrToExp;
5058 case ((cr1,eq)::cr_eq_rest, HTCrToExp) algorithm
5059 ✗ if (not BaseHashTable.hasKey(cr1, HTCrToExp) and not isCrefInValue(cr1,value)) then
5060 ✗ BackendDAE.EQUATION(scalar=res, source=source, attr=eqAttr) := BackendEquation.solveEquation(eq, Expression.crefExp(cr1),NONE());
5061 ✗ (res,_) := Expression.replaceExp(res,Expression.crefExp(cr),value);
5062 ✗ (res,_) := ExpressionSimplify.simplify(res);
5063 //source = ElementSource.addSymbolicTransformationSubstitution(true, source, Expression.crefExp(cr1), res);
5064 ✗ HTCrToExp := addToCrToExp(cr1, BackendDAE.EQUATION(Expression.crefExp(cr1), res, source, eqAttr), inHTCrToExp, inHTCrToCrEqLst);
5065 end if;
5066 ✗ HTCrToExp := solveAllCrefs1(cr, value, cr_eq_rest, HTCrToExp, inHTCrToCrEqLst);
5067 then (HTCrToExp);
5068 else algorithm
5069 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.solveAllCrefs1 ++++++++++\n");
5070 then (inHTCrToExp);
5071 end matchcontinue;
5072 end solveAllCrefs1;
5073
5074 protected function isCrefInValue "BB,
5075 true, if cr is in expression value
5076 "
5077 input DAE.ComponentRef cr;
5078 input DAE.Exp value;
5079 output Boolean isInValue;
5080 protected
5081 list<DAE.ComponentRef> cr_lst;
5082 algorithm
5083 ✗ cr_lst := Expression.extractCrefsFromExp(value);
5084 ✗ isInValue := listMember(cr, cr_lst);
5085 end isCrefInValue;
5086
5087 protected function addRestCrefs "BB,
5088 add all non-constant alias variables to the hash table HTCrToExp
5089 "
5090 input list<tuple<DAE.ComponentRef,list<tuple<DAE.ComponentRef,BackendDAE.Equation>>>> tplCrEqLst;
5091 input HashTableCrToExp.HashTable inHTCrToExp;
5092 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
5093 output HashTableCrToExp.HashTable HTCrToExp = inHTCrToExp;
5094 protected
5095 DAE.ComponentRef cr1;
5096 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5097 algorithm
5098 try
5099 ✗ for tpl in tplCrEqLst loop
5100 ✗ (cr1,cr_eq_lst) := tpl;
5101 ✗ if not BaseHashTable.hasKey(cr1, HTCrToExp) then
5102 ✗ HTCrToExp := addThisCrefs(cr_eq_lst, HTCrToExp, inHTCrToCrEqLst);
5103 end if;
5104 end for;
5105 else
5106 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.addRestCrefs ++++++++++\n");
5107 ✗ fail();
5108 end try;
5109 end addRestCrefs;
5110
5111 protected function addThisCrefs "BB
5112 add all dependent alias variable (cr1 = expression) to
5113 the hash table HTCrToExp.
5114 "
5115 input list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5116 input HashTableCrToExp.HashTable inHTCrToExp;
5117 input HashTableCrToCrEqLst.HashTable inHTCrToCrEqLst;
5118 output HashTableCrToExp.HashTable outHTCrToExp;
5119 algorithm
5120 outHTCrToExp := matchcontinue(cr_eq_lst, inHTCrToExp)
5121 local
5122 DAE.ComponentRef cr1;
5123 BackendDAE.Equation eq;
5124 HashTableCrToExp.HashTable HTCrToExp;
5125 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_rest;
5126
5127 case ({},HTCrToExp) then HTCrToExp;
5128 case ((cr1,eq)::cr_eq_rest, HTCrToExp) algorithm
5129 ✗ if (not BaseHashTable.hasKey(cr1, HTCrToExp)) then
5130 ✗ HTCrToExp := addToCrToExp(cr1, eq, HTCrToExp, inHTCrToCrEqLst);
5131 end if;
5132 ✗ HTCrToExp := addThisCrefs(cr_eq_rest, HTCrToExp, inHTCrToCrEqLst);
5133 then (HTCrToExp);
5134 else algorithm
5135 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.addThisCrefs ++++++++++\n");
5136 then (inHTCrToExp);
5137 end matchcontinue;
5138 end addThisCrefs;
5139
5140 protected function isSimple "BB
5141 start module for detecting simple equation/expressions
5142 "
5143 input DAE.Exp inExp;
5144 output Boolean outIsSimple;
5145 algorithm
5146 //print("Traverse " + ExpressionBasics.printExpStr(inExp) + "\n");
5147 ✗ (_,outIsSimple) := Expression.traverseExpTopDown(inExp, checkOperator, true);
5148 //print("Simple: " + boolString(outIsSimple) + "\n");
5149 end isSimple;
5150
5151 protected function checkOperator "BB
5152 check, if left and right expression of an equation are simple:
5153 a = b, a = -b, a = not b, a = 2.0, etc.
5154 this module will be extended in the future!
5155 "
5156 input DAE.Exp inExp;
5157 input Boolean inIsSimple;
5158 output DAE.Exp outExp;
5159 output Boolean cont;
5160 output Boolean outIsSimple;
5161 algorithm
5162 (outExp, cont, outIsSimple) := matchcontinue inExp
5163 local
5164 DAE.Exp exp1, exp2;
5165 DAE.Operator op;
5166 case DAE.BINARY(exp1, op, exp2) algorithm
5167 ✗ true := checkOp(op);
5168 ✗ (_, true,_) := checkOperator(exp1,inIsSimple);
5169 ✗ (_, true,_) := checkOperator(exp2,inIsSimple);
5170 ✗ then (inExp, true, true);
5171 case DAE.UNARY(_,exp1)
5172 ✗ then checkOperator(exp1,inIsSimple);
5173 case DAE.LUNARY(_,exp1)
5174 ✗ then checkOperator(exp1,inIsSimple);
5175 case DAE.CREF()
5176 ✗ then (inExp, true, true);
5177 case DAE.ICONST()
5178 ✗ then (inExp, true, true);
5179 case DAE.RCONST()
5180 ✗ then (inExp, true, true);
5181 case DAE.BCONST()
5182 ✗ then (inExp, true, true);
5183 case DAE.SCONST()
5184 ✗ then (inExp, true, true);
5185 ✗ else (inExp, false, false);
5186 end matchcontinue;
5187 end checkOperator;
5188
5189 protected function checkOp "BB,
5190 "
5191 input DAE.Operator inOp;
5192 output Boolean outB;
5193 algorithm
5194 outB := match inOp
5195 case DAE.ADD() then true;
5196 case DAE.SUB() then true;
5197 case DAE.UMINUS() then true;
5198 case DAE.MUL() then false;
5199 case DAE.EQUAL() then false;
5200 case DAE.DIV() then false;
5201 case DAE.POW() then false;
5202 else false;
5203 end match;
5204 end checkOp;
5205
5206 protected function determineAliasLst "BB,
5207 determine all alias variables and store them in a hash table
5208 Problem: aliasVars are in the shared object, and has to be traversed
5209 for every equation system.
5210 "
5211 input BackendDAE.Variables inAliasVars;
5212 input BackendDAE.Variables inVars;
5213 input HashTableCrToCrEqLst.HashTable inHTAliasLst;
5214 output HashTableCrToCrEqLst.HashTable outHTAliasLst = inHTAliasLst;
5215 protected
5216 DAE.ComponentRef cr1, cr2;
5217 list<DAE.ComponentRef> cr_lst;
5218 DAE.Exp e;
5219 BackendDAE.Equation eq;
5220 Option<BackendDAE.Var> w;
5221 BackendDAE.Var v;
5222 Integer count;
5223 array<Option<BackendDAE.Var>> vars;
5224
5225 algorithm
5226 ✗ BackendDAE.VARIABLES(varArr = BackendDAE.VARIABLE_ARRAY(varOptArr = vars)) := inAliasVars;
5227 ✗ for w in vars loop
5228 try
5229 ✗ SOME(v) := w;
5230 ✗ cr1 := BackendVariable.varCref(v);
5231 ✗ e := BackendVariable.varBindExp(v);
5232 ✗ (_, (cr_lst,_,count,_,_)) := Expression.traverseExpTopDown(e, findCrefs, ({},inVars,0,0,true));
5233 // add bindExp
5234 ✗ 1 := count;
5235 ✗ {cr2} := cr_lst;
5236 ✗ eq := BackendDAE.EQUATION(Expression.crefExp(cr1), e, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING);
5237 ✗ outHTAliasLst := addToCrAndEqLists(cr2, cr1, eq, outHTAliasLst);
5238 else
5239 ✗ outHTAliasLst := outHTAliasLst;
5240 end try;
5241 end for;
5242 end determineAliasLst;
5243
5244
5245 protected function getAliasAttributes "BB,
5246 go through all equation systems and set the start and nominal
5247 values of the alias variables.
5248 "
5249 input BackendDAE.EqSystem inSystem;
5250 input BackendDAE.Shared inShared;
5251 output BackendDAE.EqSystem outSystem;
5252 output BackendDAE.Shared outShared = inShared;
5253 protected
5254 BackendDAE.Variables orderedVars;
5255 BackendDAE.Variables aliasVars;
5256
5257 HashTableCrToCrEqLst.HashTable HTAliasLst;
5258 list<tuple<DAE.ComponentRef,list<tuple<DAE.ComponentRef,BackendDAE.Equation>>>> tplAliasLst;
5259 Integer size;
5260 algorithm
5261 ✗ BackendDAE.EQSYSTEM(orderedVars=orderedVars):= inSystem;
5262 ✗ BackendDAE.SHARED(aliasVars=aliasVars) := inShared;
5263
5264 ✗ size := BackendVariable.varsSize(orderedVars);
5265 ✗ size := intMax(BaseHashTable.defaultBucketSize, realInt(realMul(intReal(size), 0.7)));
5266 ✗ HTAliasLst := HashTableCrToCrEqLst.emptyHashTableSized(size);
5267
5268 ✗ HTAliasLst := determineAliasLst(aliasVars, orderedVars, HTAliasLst);
5269 ✗ tplAliasLst := BaseHashTable.hashTableList(HTAliasLst);
5270 ✗ orderedVars := setAttributes(tplAliasLst, orderedVars, aliasVars);
5271
5272 ✗ outSystem := BackendDAEUtil.setEqSystVars(inSystem, orderedVars);
5273 end getAliasAttributes;
5274
5275 protected function setAttributes "BB
5276 determine all start and nominal values for alias variables and
5277 set the corresponding values of the variable which is kept in the system
5278 "
5279 input list<tuple<DAE.ComponentRef,list<tuple<DAE.ComponentRef,BackendDAE.Equation>>>> tplCrEqLst;
5280 input BackendDAE.Variables inVars;
5281 input BackendDAE.Variables inAliasVars;
5282 output BackendDAE.Variables outVars = inVars;
5283 protected
5284 DAE.ComponentRef cr1;
5285 list<DAE.ComponentRef> cr_lst;
5286 DAE.Exp e;
5287 BackendDAE.Var v;
5288 Integer i, j;
5289 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5290 HashTableExpToIndex.HashTable HTStartExpToInt;
5291 HashTableExpToIndex.HashTable HTNominalExpToInt;
5292 list<tuple<DAE.Exp,Integer>> tplExpIndList;
5293 algorithm
5294 ✗ if listEmpty(tplCrEqLst) then
5295 ✗ return;
5296 end if;
5297 try
5298 ✗ HTStartExpToInt := HashTableExpToIndex.emptyHashTableSized(100);
5299 ✗ HTNominalExpToInt := HashTableExpToIndex.emptyHashTableSized(100);
5300 ✗ for tpl in tplCrEqLst loop
5301 ✗ (cr1,cr_eq_lst) := tpl;
5302 ✗ BaseHashTable.clear(HTStartExpToInt);
5303 ✗ BaseHashTable.clear(HTNominalExpToInt);
5304 ✗ (v,i) := BackendVariable.getVarSingle(cr1,outVars);
5305 ✗ if BackendVariable.varHasStartValue(v) then
5306 ✗ e := BackendVariable.varStartValue(v);
5307 ✗ if Expression.isZero(e) then
5308 e := DAE.RCONST(0.0);
5309 end if;
5310 ✗ cr_lst := Expression.extractCrefsFromExp(e);
5311 ✗ j := 2 - listLength(cr_lst);
5312 ✗ j := j*ComponentReference.crefDepth(cr1);
5313 ✗ HTStartExpToInt := BaseHashTable.add((e, j), HTStartExpToInt);
5314 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5315 ✗ print("START: " + ComponentReferenceBasics.printComponentRefStr(cr1) + " = " + ExpressionBasics.printExpStr(e) + "\n");
5316 end if;
5317 end if;
5318 ✗ if BackendVariable.varHasNominalValue(v) then
5319 ✗ e := BackendVariable.varNominalValue(v);
5320 ✗ cr_lst := Expression.extractCrefsFromExp(e);
5321 ✗ j := 2 - listLength(cr_lst);
5322 ✗ j := j*ComponentReference.crefDepth(cr1);
5323 ✗ HTNominalExpToInt := BaseHashTable.add((e, j), HTNominalExpToInt);
5324 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5325 ✗ print("NOMINAL: " + ComponentReferenceBasics.printComponentRefStr(cr1) + " = " + ExpressionBasics.printExpStr(e) + "\n");
5326 end if;
5327 end if;
5328 ✗ (HTStartExpToInt,HTNominalExpToInt) := getThisAttributes(cr1,cr_eq_lst,inAliasVars,HTStartExpToInt,HTNominalExpToInt);
5329 ✗ tplExpIndList := BaseHashTable.hashTableList(HTStartExpToInt);
5330 ✗ if not listEmpty(tplExpIndList) then
5331 ✗ e := getDominantAttributeValue(tplExpIndList);
5332 ✗ v := BackendVariable.setVarStartValue(v,e);
5333 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5334 ✗ print("START: " + ComponentReferenceBasics.printComponentRefStr(cr1) + " = " + ExpressionBasics.printExpStr(e) + "\n");
5335 ✗ BaseHashTable.dumpHashTable(HTStartExpToInt);
5336 end if;
5337 end if;
5338 ✗ tplExpIndList := BaseHashTable.hashTableList(HTNominalExpToInt);
5339 ✗ if not listEmpty(tplExpIndList) then
5340 ✗ e := getDominantAttributeValue(tplExpIndList);
5341 ✗ v := BackendVariable.setVarNominalValue(v,e);
5342 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5343 ✗ print("NOMINAL: " + ComponentReferenceBasics.printComponentRefStr(cr1) + " = " + ExpressionBasics.printExpStr(e) + "\n");
5344 ✗ BaseHashTable.dumpHashTable(HTNominalExpToInt);
5345 end if;
5346 end if;
5347 ✗ outVars := BackendVariable.setVarAt(outVars,i,v);
5348 end for;
5349 else
5350 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.setAttributes ++++++++++\n");
5351 end try;
5352 end setAttributes;
5353
5354 protected function getThisAttributes "BB,
5355 get start and nominal values of alias variables and prioritize
5356 the expressions with respect to the crefDeth.
5357 "
5358 input DAE.ComponentRef cr;
5359 input list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_lst;
5360 input BackendDAE.Variables inAliasVars;
5361 input HashTableExpToIndex.HashTable inHTStartExpToInt;
5362 input HashTableExpToIndex.HashTable inHTNominalExpToInt;
5363 output HashTableExpToIndex.HashTable outHTStartExpToInt=inHTStartExpToInt;
5364 output HashTableExpToIndex.HashTable outHTNominalExpToInt=inHTNominalExpToInt;
5365
5366 algorithm
5367 (outHTStartExpToInt,outHTNominalExpToInt) := matchcontinue cr_eq_lst
5368 local
5369 DAE.ComponentRef cr1;
5370 list<DAE.ComponentRef> cr_lst;
5371 DAE.Exp res, e, e1 = DAE.ICONST(0), e2;
5372 BackendDAE.Var v;
5373 list<tuple<DAE.ComponentRef,BackendDAE.Equation>> cr_eq_rest;
5374 Integer j, j1;
5375
5376 ✗ case {} then (outHTStartExpToInt,outHTNominalExpToInt);
5377 case (cr1,_)::cr_eq_rest algorithm
5378 ✗ (v,_) := BackendVariable.getVarSingle(cr1,inAliasVars);
5379 ✗ e := BackendVariable.varBindExp(v);
5380 ✗ if BackendVariable.varHasStartValue(v) then
5381 ✗ res := BackendVariable.varStartValue(v);
5382 ✗ BackendDAE.EQUATION(scalar=e1) := BackendEquation.solveEquation(BackendDAE.EQUATION(Expression.crefExp(cr1),e,DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING), Expression.crefExp(cr),NONE());
5383 ✗ BackendDAE.EQUATION(scalar=e2) := BackendEquation.solveEquation(BackendDAE.EQUATION(res,e,DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_BINDING), Expression.crefExp(cr),NONE());
5384 ✗ (e2,_) := ExpressionSimplify.simplify(e2);
5385 ✗ if Expression.isZero(e2) then
5386 e2 := DAE.RCONST(0.0);
5387 end if;
5388 ✗ cr_lst := Expression.extractCrefsFromExp(e2);
5389 ✗ j := 2 - listLength(cr_lst);
5390 ✗ j := j*ComponentReference.crefDepth(cr1);
5391 ✗ if BaseHashTable.hasKey(e2, outHTStartExpToInt) then
5392 ✗ j1 := BaseHashTable.get(e2, outHTStartExpToInt);
5393 if (j1<j) then
5394 j := j1;
5395 end if;
5396 end if;
5397 ✗ outHTStartExpToInt := BaseHashTable.add((e2, j), outHTStartExpToInt);
5398 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5399 ✗ print("START: " + ComponentReferenceBasics.printComponentRefStr(cr) + " = " + ExpressionBasics.printExpStr(e1) + " = " + ExpressionBasics.printExpStr(e2) + "\n");
5400 end if;
5401 end if;
5402 ✗ if BackendVariable.varHasNominalValue(v) then
5403 ✗ e2 := BackendVariable.varNominalValue(v);
5404 ✗ cr_lst := Expression.extractCrefsFromExp(e2);
5405 ✗ j := 2 - listLength(cr_lst);
5406 ✗ j := j*ComponentReference.crefDepth(cr1);
5407 ✗ if BaseHashTable.hasKey(e2, outHTNominalExpToInt) then
5408 ✗ j1 := BaseHashTable.get(e2, outHTNominalExpToInt);
5409 if (j1<j) then
5410 j := j1;
5411 end if;
5412 end if;
5413 ✗ outHTNominalExpToInt := BaseHashTable.add((e2, j), outHTNominalExpToInt);
5414 ✗ if Flags.isSet(Flags.DEBUG_ALIAS) then
5415 ✗ print("NOMINAL: " + ComponentReferenceBasics.printComponentRefStr(cr) + " = " + ExpressionBasics.printExpStr(e1) + " = " + ExpressionBasics.printExpStr(e2) + "\n");
5416 end if;
5417 end if;
5418 ✗ (outHTStartExpToInt,outHTNominalExpToInt) := getThisAttributes(cr, cr_eq_rest, inAliasVars, outHTStartExpToInt, outHTNominalExpToInt);
5419 then (outHTStartExpToInt,outHTNominalExpToInt);
5420 else algorithm
5421 ✗ print("\n++++++++++ Error in RemoveSimpleEquations.getThisAttributes ++++++++++\n");
5422 ✗ then (outHTStartExpToInt,outHTNominalExpToInt);
5423 end matchcontinue;
5424 end getThisAttributes;
5425
5426 function getDominantAttributeValue "BB,
5427 pick the expression with lowest integer value, if two
5428 integer values are equal, take the first occurring one.
5429 "
5430 input list<tuple<DAE.Exp,Integer>> tplExpIndList;
5431 output DAE.Exp outE = DAE.ICONST(0);
5432 protected
5433 DAE.Exp e;
5434 tuple<DAE.Exp,Integer> tpl;
5435 Integer i, j = 111111;
5436 algorithm
5437 ✗ for tpl in tplExpIndList loop
5438 ✗ (e,i) := tpl;
5439 ✗ if (i<j) then
5440 outE := e;
5441 j := i;
5442 end if;
5443 end for;
5444 end getDominantAttributeValue;
5445
5446
5447 protected function dumpSimpleContainer
5448 input SimpleContainer container;
5449 output String sOut;
5450 algorithm
5451 sOut := matchcontinue container
5452 local
5453 DAE.ComponentRef cr1,cr2;
5454 DAE.Exp e;
5455 String s1,s2;
5456 Boolean n1,n2;
5457 Integer i1,i2;
5458 case ALIAS(cr1,n1,i1,cr2,n2,i2,_,_)
5459 algorithm
5460 ✗ s1 := if n1 then "(-)" else "" ;
5461 ✗ s2 := if n2 then "(-)" else "" ;
5462 ✗ s1 := s1 +ComponentReferenceBasics.printComponentRefStr(cr1);
5463 ✗ s2:= s2 +ComponentReferenceBasics.printComponentRefStr(cr2);
5464 ✗ then "ALIASE: \t\t"+s1 + " = " +s2+" ("+intString(i1)+", "+intString(i2)+")";
5465 case PARAMETERALIAS(cr1,n1,i1,cr2,n2,i2,_,_)
5466 algorithm
5467 ✗ s1 := if n1 then "(-)" else "" ;
5468 ✗ s2 := if n2 then "(-)" else "" ;
5469 ✗ s1 := s1 +ComponentReferenceBasics.printComponentRefStr(cr1);
5470 ✗ s2:= s2 +ComponentReferenceBasics.printComponentRefStr(cr2);
5471 ✗ then "PARAMETERALIASE: \t"+s1 + " = " +s2+" ("+intString(i1)+", "+intString(i2)+")";
5472 case TIMEALIAS(cr1,n1,i1,cr2,n2,i2,_,_)
5473 algorithm
5474 ✗ s1 := if n1 then "(-)" else "" ;
5475 ✗ s2 := if n2 then "(-)" else "" ;
5476 ✗ s1 := s1 +ComponentReferenceBasics.printComponentRefStr(cr1);
5477 ✗ s2:= s2 +ComponentReferenceBasics.printComponentRefStr(cr2);
5478 ✗ then "TIMEALIASE: \t"+s1 + " = " +s2+" ("+intString(i1)+", "+intString(i2)+")";
5479 case TIMEINDEPENTVAR(cr1,_,e,_,_)
5480 algorithm
5481 ✗ then "TIMEINDEPENT: \t"+ComponentReferenceBasics.printComponentRefStr(cr1) + " = " +ExpressionBasics.printExpStr(e);
5482 else
5483 then "----------";
5484 end matchcontinue;
5485 end dumpSimpleContainer;
5486
5487 annotation(__OpenModelica_Interface="backend");
5488 end RemoveSimpleEquations;
5489