Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 52.1% 337 / 0 / 647
Functions: -% 0 / 1 / 1
Branches: 42.2% 169 / 0 / 400

OMCompiler/Compiler/BackEnd/BackendEquation.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 BackendEquation
37 " file: BackendEquation.mo
38 package: BackendEquation
39 description: BackendEquation contains functions that do something with
40 BackendDAE.Equation data type."
41
42 import Absyn;
43 import AbsynUtil;
44 import BackendDAE;
45 import DAE;
46
47 protected
48 import Algorithm;
49 import Array;
50 import BackendDAEUtil;
51 import BackendDump;
52 import BackendVariable;
53 import BaseHashTable;
54 import AvlSetInt;
55 import ClassInf;
56 import ComponentReference;
57 protected import ComponentReferenceBasics;
58 import DAEUtil;
59 import Debug;
60 import ElementSource;
61 import Error;
62 import ExpandableArray;
63 import Expression;
64 protected import ExpressionBasics;
65 import ExpressionDump;
66 import ExpressionSimplify;
67 import ExpressionSolve;
68 import Flags;
69 import HashTable;
70 import List;
71 import Types;
72
73 public function emptyEqns "author: lochel
74 Returns an empty expandable equation array."
75 output BackendDAE.EquationArray equationArray = emptyEqnsSized(0);
76 end emptyEqns;
77
78 public function emptyEqnsSized "author: lochel
79 Returns an empty expandable equation array with a given size."
80 input Integer size;
81 output BackendDAE.EquationArray outEquationArray = ExpandableArray.new(size, BackendDAE.DUMMY_EQUATION());
82 end emptyEqnsSized;
83
84 public function add "author: lochel
85 Adds an equation to an EquationArray."
86 input BackendDAE.Equation inEquation;
87 input output BackendDAE.EquationArray equationArray;
88 algorithm
89 749752 ExpandableArray.add(inEquation, equationArray);
90 end add;
91
92 public function addList "author: hkiel
93 Adds a list of BackendDAE.Equation to BackendDAE.EquationArray."
94 input list<BackendDAE.Equation> eqnlst;
95 input output BackendDAE.EquationArray equationArray;
96 algorithm
97 190092 ExpandableArray.expandToSize(ExpandableArray.getLastUsedIndex(equationArray) + listLength(eqnlst), equationArray);
98
2/2
✓ Branch 0 taken 166710 times.
✓ Branch 1 taken 190092 times.
356802 for e in eqnlst loop
99 166710 equationArray := add(e, equationArray);
100 end for;
101 end addList;
102
103 public function delete
104 input Integer inPos "one-based indexing";
105 input output BackendDAE.EquationArray equationArray;
106 algorithm
107 261 ExpandableArray.delete(inPos, equationArray);
108 end delete;
109
110 public function deleteList
111 "Deletes all equations from the given list of indices."
112 input output BackendDAE.EquationArray equationArray;
113 input list<Integer> inIndices "one-based indexing";
114 algorithm
115
2/2
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 493 times.
760 for index in inIndices loop
116 267 ExpandableArray.delete(index, equationArray);
117 end for;
118 end deleteList;
119
120 public function merge "author: lochel
121 This function returns an EquationArray containing all the equations from both
122 inputs."
123 input BackendDAE.EquationArray inEqns1;
124 input BackendDAE.EquationArray inEqns2;
125 output BackendDAE.EquationArray outEqns;
126 algorithm
127 2486 outEqns := copyEquationArray(inEqns2);
128 2486 outEqns := addList(equationList(inEqns1), outEqns);
129 end merge;
130
131 public function listEquation "author: PA
132 Transform a list of equations into an expandable BackendDAE.Equation array."
133 input list<BackendDAE.Equation> inEquationList;
134 output BackendDAE.EquationArray outEquationArray;
135 algorithm
136 281406 outEquationArray := ExpandableArray.new(listLength(inEquationList), BackendDAE.DUMMY_EQUATION());
137
2/2
✓ Branch 0 taken 1942528 times.
✓ Branch 1 taken 281406 times.
2223934 for eq in inEquationList loop
138 1942528 ExpandableArray.add(eq, outEquationArray);
139 end for;
140 end listEquation;
141
142 public function equationList "author: lochel
143 Transform the expandable BackendDAE.Equation array to a list of Equations."
144 input BackendDAE.EquationArray equationArray;
145 output list<BackendDAE.Equation> outEquationLst = ExpandableArray.toList(equationArray);
146 end equationList;
147
148 public function copyEquationArray
149 "Performs a deep copy of an expandable equation array."
150 input BackendDAE.EquationArray inEquationArray;
151 output BackendDAE.EquationArray outEquationArray = ExpandableArray.copy(inEquationArray, BackendDAE.DUMMY_EQUATION());
152 end copyEquationArray;
153
154 public function setAtIndex "author: lochel
155 Sets the n-th array element of an EquationArray.
156 Please note: one-based indexing"
157 input output BackendDAE.EquationArray equationArray;
158 input Integer inPos "one-based indexing";
159 input BackendDAE.Equation inEquation;
160 algorithm
161
1/2
✓ Branch 1 taken 206133 times.
✗ Branch 2 not taken.
206133 if ExpandableArray.occupied(inPos, equationArray) then
162 206133 ExpandableArray.update(inPos, inEquation, equationArray);
163 else
164 ✗ ExpandableArray.set(inPos, inEquation, equationArray);
165 end if;
166 end setAtIndex;
167
168 public function setAtIndexFirst "author: waurich
169 Sets the n-th array element of an EquationArray but with index at first argument.
170 Please note: one-based indexing"
171 input Integer inPos "one-based indexing";
172 input BackendDAE.Equation inEquation;
173 input BackendDAE.EquationArray inEquationArray;
174 output BackendDAE.EquationArray outEquationArray = setAtIndex(inEquationArray, inPos, inEquation);
175 end setAtIndexFirst;
176
177 public function get
178 "Return the n-th equation from the expandable equation array
179 indexed from 1..N."
180 input BackendDAE.EquationArray inEquationArray;
181 input Integer inPos "one-based indexing";
182 output BackendDAE.Equation outEquation = ExpandableArray.get(inPos, inEquationArray);
183 end get;
184
185 public function has
186 "Returns if the element at the given index is occupied or not."
187 input BackendDAE.EquationArray inEquationArray;
188 input Integer inPos "one-based indexing";
189 output Boolean b = ExpandableArray.occupied(inPos, inEquationArray);
190 end has;
191
192 public function getList "author: Frenkel TUD 2011-05
193 returns the equations given by the list of indexes"
194 input list<Integer> inIndices "one-based indexing";
195 input BackendDAE.EquationArray inEquationArray;
196 output list<BackendDAE.Equation> outEqns = {};
197 algorithm
198
4/4
✓ Branch 0 taken 212831 times.
✓ Branch 1 taken 27430 times.
✓ Branch 2 taken 212831 times.
✓ Branch 3 taken 27430 times.
240261 outEqns := list(get(inEquationArray, index) for index in inIndices);
199 end getList;
200
201 public function equationArraySize "author: lochel
202 Returns the size of the equations in an BackendDAE.EquationArray, which
203 should correspond to the number of variables."
204 input BackendDAE.EquationArray equationArray;
205 output Integer outSize;
206 protected
207 Boolean nfScalarize = Flags.isSet(Flags.NF_SCALARIZE);
208 algorithm
209 outSize := 0;
210
2/2
✓ Branch 1 taken 8197 times.
✓ Branch 2 taken 473725 times.
5752148 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
211
1/2
✓ Branch 1 taken 5270226 times.
✗ Branch 2 not taken.
5270226 if ExpandableArray.occupied(i, equationArray) then
212
2/2
✓ Branch 0 taken 5269153 times.
✓ Branch 1 taken 1073 times.
5270226 if nfScalarize then
213 5269153 outSize := outSize + equationSize(ExpandableArray.get(i, equationArray));
214 else
215 1073 outSize := outSize + 1;
216 end if;
217 end if;
218 end for;
219 end equationArraySize;
220
221 public function getNumberOfEquations "author: lochel
222 Returns the number of equations in an BackendDAE.EquationArray, which not
223 corresponds to the number of equations in the system."
224 input BackendDAE.EquationArray inEquationArray;
225 output Integer outSize = ExpandableArray.getNumberOfElements(inEquationArray);
226 end getNumberOfEquations;
227
228 public function traverseEquationArray<T> "author: lochel
229 Traverses all equations of a BackendDAE.EquationArray."
230 input BackendDAE.EquationArray equationArray;
231 input Func inFunc;
232 input output T extraArg;
233
234 partial function Func
235 input output BackendDAE.Equation eq;
236 input output T extraArg;
237 end Func;
238 protected
239 BackendDAE.Equation eqn;
240 algorithm
241
2/2
✓ Branch 1 taken 13672 times.
✓ Branch 2 taken 116890 times.
1555694 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
242
1/2
✓ Branch 1 taken 1425136 times.
✗ Branch 2 not taken.
1425136 if ExpandableArray.occupied(i, equationArray) then
243 1425136 eqn := ExpandableArray.get(i, equationArray);
244
2/2
✓ Branch 0 taken 514687 times.
✓ Branch 1 taken 910449 times.
1425136 (_, extraArg) := inFunc(eqn, extraArg);
245 end if;
246 end for;
247 end traverseEquationArray;
248
249 public function traverseEquationArray_WithStop<T> "author: lochel
250 Traverses all equations of a BackendDAE.EquationArray."
251 input BackendDAE.EquationArray equationArray;
252 input FuncWithStop inFuncWithStop;
253 input output T extraArg;
254
255 partial function FuncWithStop
256 input output BackendDAE.Equation eq;
257 input T inExtraArg;
258 output Boolean cont;
259 output T outExtraArg;
260 end FuncWithStop;
261 protected
262 Boolean continue_;
263 BackendDAE.Equation eqn;
264 algorithm
265
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 262 times.
366 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
266
1/2
✓ Branch 1 taken 339 times.
✗ Branch 2 not taken.
339 if ExpandableArray.occupied(i, equationArray) then
267 339 eqn := ExpandableArray.get(i, equationArray);
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 339 times.
339 (_, continue_, extraArg) := inFuncWithStop(eqn, extraArg);
269
270
2/2
✓ Branch 0 taken 235 times.
✓ Branch 1 taken 104 times.
339 if not continue_ then
271 break;
272 end if;
273 end if;
274 end for;
275 end traverseEquationArray_WithStop;
276
277 public function traverseEquationArray_WithUpdate<T>
278 "Traverses all equations of a BackendDAE.EquationArray."
279 input output BackendDAE.EquationArray equationArray;
280 input FuncWithUpdate inFuncWithUpdate;
281 input output T extraArg;
282
283 partial function FuncWithUpdate
284 input output BackendDAE.Equation inoutEq;
285 input output T inoutA;
286 end FuncWithUpdate;
287 protected
288 BackendDAE.Equation e, new_e;
289 algorithm
290
2/2
✓ Branch 1 taken 53340 times.
✓ Branch 2 taken 103661 times.
739418 for i in 1:ExpandableArray.getLastUsedIndex(equationArray) loop
291
2/2
✓ Branch 1 taken 582065 times.
✓ Branch 2 taken 352 times.
582417 if ExpandableArray.occupied(i, equationArray) then
292 582065 e := ExpandableArray.get(i, equationArray);
293
2/2
✓ Branch 0 taken 342877 times.
✓ Branch 1 taken 239188 times.
582065 (new_e, extraArg) := inFuncWithUpdate(e, extraArg);
294
2/2
✓ Branch 0 taken 344151 times.
✓ Branch 1 taken 237914 times.
582065 if not referenceEq(e, new_e) then
295 344151 ExpandableArray.update(i, new_e, equationArray);
296 end if;
297 end if;
298 end for;
299 end traverseEquationArray_WithUpdate;
300
301 public function sortInitialEqns
302 "author:kabdelhak 2021-9
303 Sorts initial equations to be at the start of the array"
304 input output BackendDAE.EquationArray eqns;
305 protected
306 list<BackendDAE.Equation> eqn_lst, init_eqns, sim_eqns;
307 algorithm
308 462 eqn_lst := equationList(eqns);
309 462 (init_eqns, sim_eqns) := List.splitOnTrue(eqn_lst, isInitialEquation);
310 462 eqn_lst := listAppend(init_eqns, sim_eqns);
311 462 eqns := listEquation(eqn_lst);
312 end sortInitialEqns;
313
314 public function getForEquationIterIdent
315 "Get the iterator of a for-equation
316 author: rfranke"
317 input BackendDAE.Equation inEquation;
318 output Option<DAE.Ident> forIter;
319 algorithm
320 forIter := match inEquation
321 local
322 DAE.Ident iter;
323 case BackendDAE.FOR_EQUATION(iter = DAE.CREF(componentRef = DAE.CREF_IDENT(ident = iter)))
324 then SOME(iter);
325 else NONE();
326 end match;
327 end getForEquationIterIdent;
328
329 public function getWhenEquationExpr "Get the left and right hand parts from an equation appearing in a when clause"
330 input BackendDAE.WhenEquation inWhenEquation;
331 output DAE.ComponentRef outComponentRef;
332 output DAE.Exp outExp;
333 algorithm
334 try
335 ✗ BackendDAE.WHEN_STMTS(whenStmtLst={BackendDAE.ASSIGN(left=DAE.CREF(componentRef = outComponentRef), right=outExp)}) := inWhenEquation;
336 else
337 ✗ Error.addInternalError("BackendEquation.getWhenEquationExpr failed\n", sourceInfo());
338 ✗ fail();
339 end try;
340 end getWhenEquationExpr;
341
342 public function setWhenElsePart
343 "Set the else part of an whenEquation"
344 input BackendDAE.WhenEquation inWhenEquation;
345 input BackendDAE.WhenEquation inElseWhenEquation;
346 output BackendDAE.WhenEquation outWhenEquation;
347 algorithm
348 outWhenEquation := match inWhenEquation
349 local
350 DAE.Exp cond;
351 BackendDAE.WhenEquation elsewhenPart;
352 list<BackendDAE.WhenOperator> whenStmtLst;
353
354 case BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst = whenStmtLst, elsewhenPart=NONE())
355 8 then BackendDAE.WHEN_STMTS(cond, whenStmtLst, SOME(inElseWhenEquation));
356
357 case BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst = whenStmtLst, elsewhenPart=SOME(elsewhenPart))
358 ✗ then BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst = whenStmtLst, elsewhenPart=SOME(setWhenElsePart(elsewhenPart, inElseWhenEquation)));
359
360 else fail();
361 end match;
362 end setWhenElsePart;
363
364 public function equationsLstVars "author: Frenkel TUD 2011-05
365 From the equations and a variable array return all
366 occurring variables from the array."
367 input list<BackendDAE.Equation> inEquationLst;
368 input BackendDAE.Variables inVars;
369 output list<BackendDAE.Var> outVars;
370 protected
371 AvlSetInt.Tree indexes;
372 list<Integer> keys;
373 algorithm
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if listEmpty(inEquationLst) then
375 outVars := {};
376 ✗ return;
377 end if;
378 48 (_, indexes) := traverseExpsOfEquationList(inEquationLst, function checkEquationsVarsExpTopDownTraverseHelper(vars=inVars), AvlSetInt.new());
379 48 keys := AvlSetInt.listKeys(indexes);
380 48 outVars := List.map1r(keys, BackendVariable.getVarAt, inVars);
381 end equationsLstVars;
382
383 public function equationsVars "author: Frenkel TUD 2011-05
384 From the equations and a variable array return all
385 occurring variables from the array."
386 input BackendDAE.EquationArray inEquations;
387 input BackendDAE.Variables inVars;
388 output list<BackendDAE.Var> outVars;
389 protected
390 AvlSetInt.Tree indexes;
391 list<Integer> keys;
392 algorithm
393 4147 indexes := BackendDAEUtil.traverseBackendDAEExpsEqns(inEquations, function checkEquationsVarsExpTopDownTraverseHelper(vars=inVars), AvlSetInt.new());
394 4147 keys := AvlSetInt.listKeys(indexes);
395 4147 outVars := List.map1r(keys, BackendVariable.getVarAt, inVars);
396 end equationsVars;
397
398 public function equationVars "author: Frenkel TUD 2012-03
399 From the equation and a variable array return all
400 variables in the equation."
401 input BackendDAE.Equation inEquation;
402 input BackendDAE.Variables inVars;
403 output list<BackendDAE.Var> outVars;
404 protected
405 AvlSetInt.Tree indexes;
406 list<Integer> keys;
407 algorithm
408 395 (_, indexes) := traverseExpsOfEquation(inEquation, function checkEquationsVarsExpTopDownTraverseHelper(vars=inVars), AvlSetInt.new());
409 395 keys := AvlSetInt.listKeys(indexes);
410 395 outVars := List.map1r(keys, BackendVariable.getVarAt, inVars);
411 end equationVars;
412
413 public function expressionVars "author: Frenkel TUD 2012-03
414 From the expression and a variable array return all
415 variables in the expression."
416 input DAE.Exp inExp;
417 input BackendDAE.Variables vars;
418 output list<BackendDAE.Var> outVars;
419 protected
420 AvlSetInt.Tree indexes;
421 list<Integer> keys;
422 algorithm
423 25550 (_, indexes) := Expression.traverseExpTopDown(inExp, function checkEquationsVarsExpTopDown(vars=vars), AvlSetInt.new());
424 25550 keys := AvlSetInt.listKeys(indexes);
425 25550 outVars := List.map1r(keys, BackendVariable.getVarAt, vars);
426 end expressionVars;
427
428 public function expressionVarsIndexes
429 "From the expression and a variable array return all variables in the expression."
430 input DAE.Exp exp;
431 input output AvlSetInt.Tree indexes;
432 input CheckEquationsVarsExpTopDownFunc func;
433
434 partial function CheckEquationsVarsExpTopDownFunc
435 input output DAE.Exp exp;
436 output Boolean cont;
437 input output AvlSetInt.Tree tree;
438 end CheckEquationsVarsExpTopDownFunc;
439 algorithm
440 1713 (_, indexes) := Expression.traverseExpTopDown(exp, func, indexes);
441 end expressionVarsIndexes;
442
443 public function checkEquationsVarsExpTopDownTraverseHelper
444 "This function traverses expssions to-down to collect all
445 variables that are involed into the expression."
446 input output DAE.Exp exp;
447 input output AvlSetInt.Tree tree;
448 input BackendDAE.Variables vars;
449 algorithm
450 109621 (exp, tree) := Expression.traverseExpTopDown(exp,function checkEquationsVarsExpTopDown(vars=vars),tree);
451 end checkEquationsVarsExpTopDownTraverseHelper;
452
453 public function checkEquationsVarsExpTopDown
454 input output DAE.Exp exp;
455 output Boolean cont;
456 input output AvlSetInt.Tree tree;
457 input BackendDAE.Variables vars;
458 algorithm
459 (cont,tree) := match exp
460 local
461 DAE.ComponentRef cr;
462 list<Integer> ilst;
463 String idn;
464
465 // special case for time, it is never part of the equation system
466 case DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time"))
467 then (true, tree);
468
469 // case for function pointers
470 case DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC())
471 then (true, tree);
472
473 // case for pre and previous vars
474 case DAE.CALL(path = Absyn.IDENT(name = idn)) guard idn=="pre" or idn=="previous"
475 then (false, tree);
476
477 // add it
478 case DAE.CREF(componentRef = cr)
479 algorithm
480 try
481 367890 (_, ilst) := BackendVariable.getVar(cr, vars);
482 86395 tree := AvlSetInt.addList(tree, ilst);
483 else
484 end try;
485 then (true, tree);
486
487 else (true, tree);
488 end match;
489 end checkEquationsVarsExpTopDown;
490
491 public function assertWithCondTrue "author: Frenkel TUD 2012-12"
492 input BackendDAE.Equation inEqn;
493 output Boolean b;
494 algorithm
495 b := match inEqn
496 case BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS({DAE.STMT_ASSERT(cond=DAE.BCONST(true))})) then false;
497 else true;
498 end match;
499 end assertWithCondTrue;
500
501 public function equationsParams "author: marcusw
502 From a list of equations return all occurring parameter variables. Duplicates are removed."
503 input list<BackendDAE.Equation> inEquationLst;
504 input BackendDAE.Variables inVars;
505 output list<BackendDAE.Var> outParamVars;
506 output list<Integer> outParamVarsIdc;
507 algorithm
508 ✗ (_, (_,(outParamVars,outParamVarsIdc,_))) := traverseExpsOfEquationList(inEquationLst, Expression.traverseSubexpressionsHelper, (traversingParamRefFinder, ({}, {}, inVars)));
509 end equationsParams;
510
511 protected function traversingParamRefFinder "author: marcusw
512 Checks if the given expression is a parameter variable and adds it to the result list on true. Duplicates are removed."
513 input DAE.Exp inExp;
514 input tuple<list<BackendDAE.Var>, list<Integer>, BackendDAE.Variables> inTpl; //<result list, result idc, all variables>
515 output DAE.Exp outExp;
516 output tuple<list<BackendDAE.Var>, list<Integer>, BackendDAE.Variables> outTpl;
517 algorithm
518 outExp := inExp;
519 outTpl := match(inExp,inTpl)
520 local
521 BackendDAE.Variables allVars;
522 list<BackendDAE.Var> vars, foundVars;
523 list<Integer> varIdc, foundVarsIdc;
524 DAE.ComponentRef cr;
525
526 case (DAE.CREF(componentRef=DAE.CREF_IDENT(ident="time")), _)
527 then inTpl;
528 case ( DAE.CREF(componentRef=cr), (vars, varIdc, allVars)) algorithm
529 //print("traversingParamRefFinder: try to get Variable " + ComponentReference.crefStr(cr) + "\n");
530 ✗ (foundVars, foundVarsIdc) := BackendVariable.getVar(cr, allVars);
531 ✗ (vars, varIdc) := traversingParamRefFinder0(foundVars, foundVarsIdc, vars, varIdc);
532 ✗ then (vars, varIdc, allVars);
533 else inTpl;
534 end match;
535 end traversingParamRefFinder;
536
537 protected function traversingParamRefFinder0
538 input list<BackendDAE.Var> iVars;
539 input list<Integer> iVarIdc;
540 input list<BackendDAE.Var> iParamVarsList;
541 input list<Integer> iParamVarsIdc;
542 output list<BackendDAE.Var> oParamVarsList;
543 output list<Integer> oParamVarIdc;
544 protected
545 BackendDAE.Var var;
546 list<BackendDAE.Var> vars = iParamVarsList;
547 list<Integer> varIdc = iParamVarsIdc;
548 Integer varIdx;
549 list<Integer> rest = iVarIdc;
550 algorithm
551 ✗ for var in iVars loop
552 ✗ varIdx::rest := rest;
553 ✗ if(BackendVariable.isParam(var)) then
554 ✗ vars := List.unionEltOnTrue(var, vars, BackendVariable.varEqual);
555 ✗ varIdc := List.unionEltOnTrue(varIdx, varIdc, intEq);
556 end if;
557 end for;
558 oParamVarsList := vars;
559 oParamVarIdc := varIdc;
560 end traversingParamRefFinder0;
561
562 public function iterationVarsinRelations
563 "From a list of equations return all variables, which used inside
564 a relation, then this equation system is marked as mixed and also
565 the indexes of the relations may be used in future."
566 input list<BackendDAE.Equation> inEquationLst;
567 input BackendDAE.Variables inVars;
568 output Boolean mixedSystem;
569 output list<Integer> indexes;
570 algorithm
571 5388 (_, (_,(indexes, _))) := traverseExpsOfEquationList(inEquationLst, Expression.traverseSubexpressionsHelper, (traversingRelationsforIterationVars, ({}, inVars)));
572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5388 times.
5388 mixedSystem := not listEmpty(indexes);
573 end iterationVarsinRelations;
574
575 protected function traversingRelationsforIterationVars
576 input DAE.Exp inExp;
577 input tuple<list<Integer>, BackendDAE.Variables> inTpl;
578 output DAE.Exp outExp;
579 output tuple<list<Integer>, BackendDAE.Variables> outTpl;
580 algorithm
581 outExp := inExp;
582 outTpl := match (inExp,inTpl)
583 local
584 BackendDAE.Variables vars;
585 list<Integer> indexes;
586 DAE.Exp e1, e2;
587 Integer index;
588 list<BackendDAE.Var> vlst1,vlst2;
589
590 case (DAE.RELATION(exp1=e1, exp2=e2, index=index), (indexes, vars))
591 algorithm
592 12741 vlst1 := expressionVars(e1, vars);
593 12741 vlst2 := expressionVars(e2, vars);
594 //if lists are not empty continue
595
4/4
✓ Branch 0 taken 5287 times.
✓ Branch 1 taken 7454 times.
✓ Branch 2 taken 264 times.
✓ Branch 3 taken 5023 times.
12741 if not(listEmpty(vlst1) and listEmpty(vlst2)) then
596 7718 outTpl := (index::indexes, vars);
597 else
598 outTpl := inTpl;
599 end if;
600 then (outTpl);
601
602 else (inTpl);
603 end match;
604 end traversingRelationsforIterationVars;
605
606 public function equationsCrefs "author: PA
607 From a list of equations return all occurring variables/component references."
608 input list<BackendDAE.Equation> inEquationLst;
609 output list<DAE.ComponentRef> outExpComponentRefLst;
610 algorithm
611 ✗ (_, (_,outExpComponentRefLst)) := traverseExpsOfEquationList(inEquationLst, Expression.traverseSubexpressionsHelper, (Expression.traversingComponentRefFinder, {}));
612 end equationsCrefs;
613
614 public function equationCrefs "author: PA
615 From one equation return all occurring variables/component references."
616 input BackendDAE.Equation inEquation;
617 output list<DAE.ComponentRef> outExpComponentRefLst;
618 algorithm
619 280 (_, (_, outExpComponentRefLst)) := traverseExpsOfEquation(inEquation, Expression.traverseSubexpressionsHelper, (Expression.traversingComponentRefFinder, {}));
620 end equationCrefs;
621
622 public function equationCrefsSolved "author: kabdelhak
623 From one solved equation return all occurring variables/component references from lhs and rhs."
624 input BackendDAE.Equation inEquation;
625 output list<DAE.ComponentRef> lhs_lst;
626 output list<DAE.ComponentRef> rhs_lst;
627 protected
628 DAE.Exp lhs, rhs;
629 algorithm
630 13 lhs := getEquationLHS(inEquation);
631 13 rhs := getEquationRHS(inEquation);
632 13 lhs_lst := Expression.extractCrefsFromExp(lhs);
633 13 rhs_lst := Expression.extractCrefsFromExp(rhs);
634 end equationCrefsSolved;
635
636 public function getAllCrefFromEquations
637 input BackendDAE.EquationArray inEqns;
638 output list<DAE.ComponentRef> cr_lst;
639 algorithm
640 ✗ cr_lst := traverseEquationArray(inEqns, traversingEquationCrefFinder, {});
641 end getAllCrefFromEquations;
642
643 protected function traversingEquationCrefFinder "author: Frenkel TUD 2010-11"
644 input BackendDAE.Equation inEq;
645 input list<DAE.ComponentRef> inCrefs;
646 output BackendDAE.Equation e;
647 output list<DAE.ComponentRef> cr_lst;
648 algorithm
649 e := inEq;
650 cr_lst := inCrefs;
651 ✗ (_, (_,cr_lst)) := traverseExpsOfEquation(e, Expression.traverseSubexpressionsHelper, (Expression.traversingComponentRefFinder, cr_lst));
652 end traversingEquationCrefFinder;
653
654 public function getCrefsFromEquations
655 input BackendDAE.EquationArray inEqns;
656 input BackendDAE.Variables inVars;
657 input BackendDAE.Variables inKnVars;
658 output list<DAE.ComponentRef> cr_lst;
659 protected
660 HashTable.HashTable ht;
661 algorithm
662 1820 ht := HashTable.emptyHashTable();
663 1820 (_, _, ht) := traverseEquationArray(inEqns, findUnknownCrefs, (inVars, inKnVars, ht));
664 1820 cr_lst := BaseHashTable.hashTableKeyList(ht);
665 end getCrefsFromEquations;
666
667 public function findUnknownCrefs
668 input output BackendDAE.Equation inEq;
669 input output tuple<BackendDAE.Variables, BackendDAE.Variables, HashTable.HashTable> extraArgs;
670 algorithm
671
1/2
✓ Branch 2 taken 16451 times.
✗ Branch 3 not taken.
16451 (_, ( _, extraArgs)) := traverseExpsOfEquation(inEq, Expression.traverseSubexpressionsHelper, (checkEquationsUnknownCrefsExp, extraArgs));
672 end findUnknownCrefs;
673
674 public function equationUnknownCrefs "author: Frenkel TUD 2012-05
675 From the equation and a variable array return all
676 variables in the equation an not in the variable array."
677 input list<BackendDAE.Equation> inEquationLst;
678 input BackendDAE.Variables inVars;
679 input BackendDAE.Variables inKnVars;
680 output list<DAE.ComponentRef> cr_lst;
681 protected
682 HashTable.HashTable ht;
683 algorithm
684 ✗ ht := HashTable.emptyHashTable();
685 ✗ (_, (_, (_, _, ht))) := traverseExpsOfEquationList(inEquationLst, Expression.traverseSubexpressionsHelper, (checkEquationsUnknownCrefsExp, (inVars, inKnVars, ht)));
686 ✗ cr_lst := BaseHashTable.hashTableKeyList(ht);
687 end equationUnknownCrefs;
688
689 protected function checkEquationsUnknownCrefsExp
690 input DAE.Exp inExp;
691 input tuple<BackendDAE.Variables, BackendDAE.Variables, HashTable.HashTable> inTuple;
692 output DAE.Exp outExp;
693 output tuple<BackendDAE.Variables, BackendDAE.Variables, HashTable.HashTable> outTuple;
694 algorithm
695 (outExp,outTuple) := matchcontinue (inExp,inTuple)
696 local
697 DAE.Exp e, e1;
698 BackendDAE.Variables vars, knvars;
699 HashTable.HashTable ht;
700 DAE.ComponentRef cr;
701 list<DAE.Exp> expl;
702 list<DAE.Var> varLst;
703
704 // special case for time, it is never part of the equation system
705 case (DAE.CREF(componentRef = DAE.CREF_IDENT(ident="time")), _)
706 then (inExp, inTuple);
707
708 // special case for records
709 case (e as DAE.CREF(componentRef = cr, ty= DAE.T_COMPLEX(varLst=varLst, complexClassType=ClassInf.RECORD(_))), _)
710 algorithm
711 76 expl := List.map1(varLst, Expression.generateCrefsExpFromExpVar, cr);
712 76 (_, outTuple) := Expression.traverseExpList(expl, checkEquationsUnknownCrefsExp, inTuple);
713 76 then (e, outTuple);
714
715 // special case for arrays
716 case (e as DAE.CREF(ty = DAE.T_ARRAY()), _)
717 algorithm
718
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 (e1, true) := Expression.extendArrExp(e, false);
719 2 (_, outTuple) := Expression.traverseExpBottomUp(e1, checkEquationsUnknownCrefsExp, inTuple);
720 2 then (e, outTuple);
721
722 // case for function pointers
723 case (DAE.CREF(ty=DAE.T_FUNCTION_REFERENCE_FUNC()), _)
724 then (inExp, inTuple);
725
726 // already there
727 case (DAE.CREF(componentRef = cr), (_, _, ht)) guard BaseHashTable.hasKey(cr, ht)
728 then (inExp, inTuple);
729
730 // known
731 case (DAE.CREF(componentRef = cr), (vars, _, _))
732 algorithm
733 74683 BackendVariable.getVar(cr, vars);
734 then (inExp, inTuple);
735
736 case (DAE.CREF(componentRef = cr), (_, knvars, _))
737 algorithm
738 39813 BackendVariable.getVar(cr, knvars);
739 then (inExp, inTuple);
740
741 // add it
742 case (DAE.CREF(componentRef = cr), (vars, knvars, ht))
743 algorithm
744 5978 ht := BaseHashTable.add((cr, 0), ht);
745 5978 then (inExp, (vars, knvars, ht));
746
747 else (inExp,inTuple);
748 end matchcontinue;
749 end checkEquationsUnknownCrefsExp;
750
751 public function traverseExpsOfEquationList<ArgT> "author: Frenkel TUD 2010-11
752 Traverse all expressions of a list of Equations. It is possible to change the
753 equations and the multidim equations and the algorithms."
754 input list<BackendDAE.Equation> inEquations;
755 input FuncExpType func;
756 input ArgT inArg;
757 output list<BackendDAE.Equation> outEquations = {};
758 output ArgT outArg = inArg;
759
760 partial function FuncExpType
761 input output DAE.Exp inoutExp;
762 input output ArgT inoutArg;
763 end FuncExpType;
764 algorithm
765
2/2
✓ Branch 0 taken 286664 times.
✓ Branch 1 taken 37805 times.
324469 for eq in inEquations loop
766 286664 (eq, outArg) := traverseExpsOfEquation(eq, func, outArg);
767 outEquations := eq::outEquations;
768 end for;
769
770 37805 outEquations := MetaModelica.Dangerous.listReverseInPlace(outEquations);
771 end traverseExpsOfEquationList;
772
773 public function traverseExpsOfEquationList_WithStop "author: Frenkel TUD 2012-09
774 Traverses all expressions of a list of equations.
775 It is possible to change the equations."
776 replaceable type Type_a subtypeof Any;
777 input list<BackendDAE.Equation> inEquations;
778 input FuncExpType inFunc;
779 input Type_a inTypeA;
780 output Boolean outBoolean = true;
781 output Type_a outTypeA = inTypeA;
782 partial function FuncExpType
783 input DAE.Exp inExp;
784 input Type_a inTypeA;
785 output DAE.Exp outExp;
786 output Boolean cont;
787 output Type_a outA;
788 end FuncExpType;
789 algorithm
790
2/2
✓ Branch 0 taken 5807 times.
✓ Branch 1 taken 1697 times.
7504 for eqn in inEquations loop
791 5807 (outBoolean, outTypeA) := traverseExpsOfEquation_WithStop(eqn, inFunc, outTypeA);
792
2/2
✓ Branch 0 taken 796 times.
✓ Branch 1 taken 4990 times.
5786 if not outBoolean then
793 break;
794 end if;
795 end for;
796 end traverseExpsOfEquationList_WithStop;
797
798 public function traverseExpsOfEquationList_WithoutChange<ArgT> "
799 Traverse all expressions of a list of Equations"
800 input BackendDAE.Equation inEquation;
801 input FuncExpType func;
802 input ArgT inArg;
803 output ArgT outArg = inArg;
804
805 partial function FuncExpType
806 input output DAE.Exp inoutExp;
807 input output ArgT inoutArg;
808 end FuncExpType;
809 algorithm
810 28 (_, outArg) := traverseExpsOfEquation(inEquation, func, outArg);
811 end traverseExpsOfEquationList_WithoutChange;
812
813
814 protected function traverseExpsOfEquationListList_WithStop<T> "author: Frenkel TUD 2012-09
815 Traverses all expressions of a list of equations.
816 It is possible to change the equations."
817 input list<list<BackendDAE.Equation>> inEquations;
818 input FuncExpType func;
819 input T inTypeA;
820 output Boolean outBoolean = true;
821 output T outTypeA = inTypeA;
822
823 partial function FuncExpType
824 input DAE.Exp inExp;
825 input T inTypeA;
826 output DAE.Exp outExp;
827 output Boolean cont;
828 output T outA;
829 end FuncExpType;
830 algorithm
831
832 ✗ for eqn in inEquations loop
833 ✗ (outBoolean, outTypeA) := traverseExpsOfEquationList_WithStop(eqn, func, outTypeA);
834 ✗ if not outBoolean then
835 break;
836 end if;
837 end for;
838
839 end traverseExpsOfEquationListList_WithStop;
840
841 public function traverseExpsOfEquation<T> "author: Frenkel TUD 2010-11
842 Traverses all expressions of an equation.
843 It is possible to change the equation."
844 input BackendDAE.Equation inEquation;
845 input FuncExpType inFunc;
846 input T inTypeA;
847 output BackendDAE.Equation outEquation;
848 output T outTypeA;
849
850 partial function FuncExpType
851 input output DAE.Exp inoutExp;
852 input output T inoutTypeA;
853 end FuncExpType;
854 algorithm
855 (outEquation, outTypeA) := match inEquation
856 local
857 BackendDAE.Equation eqn, eqn1;
858 BackendDAE.WhenEquation whenEquation;
859 DAE.Exp e1;
860 DAE.ComponentRef cr, cr1;
861 T extArg;
862 list<DAE.Statement> stmts;
863 list<DAE.Exp> conditions;
864 list<list<BackendDAE.Equation>> eqnstrue;
865 list<BackendDAE.Equation> eqnsfalse;
866
867
868 case eqn as BackendDAE.EQUATION() algorithm
869
2/2
✓ Branch 0 taken 1409954 times.
✓ Branch 1 taken 2483467 times.
3893421 (e1, extArg) := inFunc(eqn.exp, inTypeA);
870
2/2
✓ Branch 0 taken 1409954 times.
✓ Branch 1 taken 2483467 times.
3893421 eqn.exp := e1;
871
2/2
✓ Branch 0 taken 1409954 times.
✓ Branch 1 taken 2483467 times.
3893421 (e1, extArg) := inFunc(eqn.scalar, extArg);
872 3893421 eqn.scalar := e1;
873 3893421 then (eqn, extArg);
874
875 case eqn as BackendDAE.ARRAY_EQUATION() algorithm
876
2/2
✓ Branch 0 taken 60484 times.
✓ Branch 1 taken 79210 times.
139694 (e1, extArg) := inFunc(eqn.left, inTypeA);
877
2/2
✓ Branch 0 taken 60484 times.
✓ Branch 1 taken 79210 times.
139694 eqn.left := e1;
878
2/2
✓ Branch 0 taken 60484 times.
✓ Branch 1 taken 79210 times.
139694 (e1, extArg) := inFunc(eqn.right, extArg);
879 139694 eqn.right := e1;
880 139694 then (eqn, extArg);
881
882 case eqn as BackendDAE.SOLVED_EQUATION(componentRef = cr) algorithm
883 44732 e1 := Expression.makeCrefExp(cr, Expression.typeof(eqn.exp));
884
3/4
✓ Branch 0 taken 31826 times.
✓ Branch 1 taken 12906 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 44732 times.
44732 (DAE.CREF(cr1, _), extArg) := inFunc(e1, inTypeA);
885
2/2
✓ Branch 0 taken 31826 times.
✓ Branch 1 taken 12906 times.
44732 eqn.componentRef := cr1;
886
2/2
✓ Branch 0 taken 31826 times.
✓ Branch 1 taken 12906 times.
44732 (e1, extArg) := inFunc(eqn.exp, extArg);
887 44732 eqn.exp := e1;
888 44732 then (eqn, extArg);
889
890 case eqn as BackendDAE.RESIDUAL_EQUATION() algorithm
891
1/2
✓ Branch 0 taken 143 times.
✗ Branch 1 not taken.
143 (e1, extArg) := inFunc(eqn.exp, inTypeA);
892 143 eqn.exp := e1;
893 143 then (eqn, extArg);
894
895 case eqn as BackendDAE.WHEN_EQUATION() algorithm
896 12101 (whenEquation, extArg) := traverseExpsOfWhenEquation(eqn.whenEquation, inFunc, inTypeA);
897 12101 eqn.whenEquation := whenEquation;
898 12101 then (eqn, extArg);
899
900 case eqn as BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(statementLst = stmts)) algorithm
901 39596 (stmts, extArg) := DAEUtil.traverseDAEEquationsStmts(stmts, inFunc, inTypeA);
902 79192 eqn.alg := DAE.ALGORITHM_STMTS(stmts);
903 39596 then (eqn, extArg);
904
905 case eqn as BackendDAE.COMPLEX_EQUATION() algorithm
906
2/2
✓ Branch 0 taken 8113 times.
✓ Branch 1 taken 17605 times.
25718 (e1, extArg) := inFunc(eqn.left, inTypeA);
907
2/2
✓ Branch 0 taken 8113 times.
✓ Branch 1 taken 17605 times.
25718 eqn.left := e1;
908
2/2
✓ Branch 0 taken 8113 times.
✓ Branch 1 taken 17605 times.
25718 (e1, extArg) := inFunc(eqn.right, extArg);
909 25718 eqn.right := e1;
910 25718 then (eqn, extArg);
911
912 case eqn as BackendDAE.IF_EQUATION() algorithm
913 504 (conditions, extArg) := traverseExpsOfExpList(eqn.conditions, inFunc, inTypeA);
914 504 eqn.conditions := conditions;
915 504 (eqnstrue, extArg) := List.map1Fold(eqn.eqnstrue, traverseExpsOfEquationList, inFunc, extArg);
916 504 eqn.eqnstrue := eqnstrue;
917 504 (eqnsfalse, extArg) := List.map1Fold(eqn.eqnsfalse, traverseExpsOfEquation, inFunc, extArg);
918 504 eqn.eqnsfalse := eqnsfalse;
919 504 then (eqn, extArg);
920
921 case eqn as BackendDAE.FOR_EQUATION() algorithm
922 346 (eqn1, extArg) := traverseExpsOfEquation(eqn.body, inFunc, inTypeA);
923 346 eqn.body := eqn1;
924 346 then (eqn, extArg);
925 end match;
926 end traverseExpsOfEquation;
927
928
929 public function traverseExpsOfEquation_WithStop<T> "author: Frenkel TUD 2010-11
930 Traverses all expressions of a equation.
931 It is not possible to change the equation."
932 input BackendDAE.Equation inEquation;
933 input FuncExpType func;
934 input T inTypeA;
935 output Boolean outBoolean;
936 output T outTypeA;
937
938 partial function FuncExpType
939 input DAE.Exp inExp;
940 input T inTypeA;
941 output DAE.Exp outExp;
942 output Boolean cont;
943 output T outA;
944 end FuncExpType;
945 algorithm
946 (outBoolean, outTypeA) := match inEquation
947 local
948 DAE.Exp e1, e2;
949 list<DAE.Exp> expl;
950 DAE.Type tp;
951 DAE.ComponentRef cr;
952 BackendDAE.WhenEquation we;
953 T ext_arg;
954 DAE.Algorithm alg;
955 list<BackendDAE.Equation> eqns;
956 list<list<BackendDAE.Equation>> eqnslst;
957 Boolean b;
958
959 case BackendDAE.EQUATION(exp=e1, scalar=e2)
960 algorithm
961
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42421 times.
42421 (_, b, ext_arg) := func(e1, inTypeA);
962
2/2
✓ Branch 0 taken 42411 times.
✓ Branch 1 taken 10 times.
42421 if b then
963
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42411 times.
42411 (_, b, ext_arg) := func(e2, ext_arg);
964 end if;
965 42421 then (b, ext_arg);
966
967 case BackendDAE.ARRAY_EQUATION(left=e1, right=e2)
968 algorithm
969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 (_, b, ext_arg) := func(e1, inTypeA);
970
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if b then
971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 (_, b, ext_arg) := func(e2, ext_arg);
972 end if;
973 2 then (b, ext_arg);
974
975 case BackendDAE.SOLVED_EQUATION(componentRef=cr, exp=e2)
976 algorithm
977 2067 tp := Expression.typeof(e2);
978 2067 e1 := Expression.makeCrefExp(cr, tp);
979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2067 times.
2067 (_, b, ext_arg) := func(e1, inTypeA);
980
1/2
✓ Branch 0 taken 2067 times.
✗ Branch 1 not taken.
2067 if b then
981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2067 times.
2067 (_, b, ext_arg) := func(e2, ext_arg);
982 end if;
983 2067 then (b, ext_arg);
984
985 case BackendDAE.RESIDUAL_EQUATION(exp=e1)
986 algorithm
987 ✗ (_, b, ext_arg) := func(e1, inTypeA);
988 ✗ then (b, ext_arg);
989
990 case BackendDAE.WHEN_EQUATION(whenEquation= we)
991 algorithm
992 7 (b, ext_arg) := traverseExpsOfWhenEquation_WithStop(we, func, inTypeA);
993 then (b, ext_arg);
994
995 case BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS())
996 algorithm
997
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 true := Flags.isSet(Flags.FAILTRACE);
998 ✗ Debug.traceln("not implemented error - BackendDAE.ALGORITHM - BackendEquation.traverseExpsOfEquation_WithStop\n");
999 //(_, ext_arg_1) = DAEUtil.traverseDAEEquationsStmts(statementLst, func, inTypeA);
1000 ✗ then fail();
1001
1002 //(true, inTypeA);
1003 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2)
1004 algorithm
1005
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
163 (_, b, ext_arg) := func(e1, inTypeA);
1006
1/2
✓ Branch 0 taken 163 times.
✗ Branch 1 not taken.
163 if b then
1007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
163 (_, b, ext_arg) := func(e2, ext_arg);
1008 end if;
1009 163 then (b, ext_arg);
1010
1011 case BackendDAE.IF_EQUATION(conditions=expl, eqnstrue=eqnslst, eqnsfalse=eqns)
1012 algorithm
1013 ✗ (b, ext_arg) := traverseExpsOfExpList_WithStop(expl, func, inTypeA);
1014 ✗ if b then
1015 ✗ (b, ext_arg) := traverseExpsOfEquationListList_WithStop(eqnslst, func, ext_arg);
1016 end if;
1017 ✗ if b then
1018 ✗ (b, ext_arg) := traverseExpsOfEquationList_WithStop(eqns, func, ext_arg);
1019 end if;
1020 ✗ then (b, ext_arg);
1021 end match;
1022 end traverseExpsOfEquation_WithStop;
1023
1024 protected function traverseExpsOfWhenEquation<T>
1025 "Traverses all expressions of a when equation.
1026 Helper function of traverseExpsOfEquation."
1027 input BackendDAE.WhenEquation inWhenEquation;
1028 input FuncExpType inFunc;
1029 input T inTypeA;
1030 output BackendDAE.WhenEquation outWhenEquation;
1031 output T outTypeA;
1032
1033 partial function FuncExpType
1034 input output DAE.Exp inoutExp;
1035 input output T inoutTypeA;
1036 end FuncExpType;
1037 algorithm
1038 (outWhenEquation, outTypeA) := match inWhenEquation
1039 local
1040 BackendDAE.WhenEquation elsewe;
1041 Option<BackendDAE.WhenEquation> oelsewe;
1042 DAE.Exp cond;
1043 list<BackendDAE.WhenOperator> whenStmtLst;
1044 T extArg;
1045
1046 case BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst=whenStmtLst, elsewhenPart = oelsewe)
1047 algorithm
1048
2/2
✓ Branch 0 taken 3973 times.
✓ Branch 1 taken 8338 times.
12311 (cond, extArg) := inFunc(cond, inTypeA);
1049 12311 (whenStmtLst, extArg) := traverseExpsOfWhenOps(whenStmtLst, inFunc, extArg, {});
1050
1051
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12311 times.
✓ Branch 2 taken 210 times.
✓ Branch 3 taken 12101 times.
12311 if isSome(oelsewe) then
1052 210 SOME(elsewe) := oelsewe;
1053 210 (elsewe, extArg) := traverseExpsOfWhenEquation(elsewe, inFunc, extArg);
1054 oelsewe := SOME(elsewe);
1055 else
1056 oelsewe := NONE();
1057 end if;
1058
1/2
✓ Branch 1 taken 12311 times.
✗ Branch 2 not taken.
12311 then (BackendDAE.WHEN_STMTS(cond, whenStmtLst, oelsewe), extArg);
1059 end match;
1060 end traverseExpsOfWhenEquation;
1061
1062 protected function traverseExpsOfWhenOps<T>
1063 "Traverses all expressions of a when equation.
1064 Helper function of traverseExpsOfEquation."
1065 input list<BackendDAE.WhenOperator> inWhenOps;
1066 input FuncExpType inFunc;
1067 input T inTypeA;
1068 input list<BackendDAE.WhenOperator> inAccum;
1069 output list<BackendDAE.WhenOperator> outWhenOps;
1070 output T outTypeA;
1071
1072 partial function FuncExpType
1073 input output DAE.Exp inExp;
1074 input output T inTypeA;
1075 end FuncExpType;
1076 algorithm
1077 (outWhenOps, outTypeA) := match inWhenOps
1078 local
1079 DAE.Exp e1, e2, level;
1080 DAE.ComponentRef cr, cr1;
1081 list<BackendDAE.WhenOperator> rest;
1082 T extArg;
1083 DAE.ElementSource source;
1084
1085 12311 case {} then (listReverse(inAccum),inTypeA);
1086 case BackendDAE.ASSIGN(left = e1, right = e2, source = source)::rest
1087 algorithm
1088
2/2
✓ Branch 0 taken 3704 times.
✓ Branch 1 taken 7753 times.
11457 (e1, extArg) := inFunc(e1, inTypeA);
1089
2/2
✓ Branch 0 taken 3704 times.
✓ Branch 1 taken 7753 times.
11457 (e2, extArg) := inFunc(e2, extArg);
1090 23768 (outWhenOps, extArg) := traverseExpsOfWhenOps(rest, inFunc, extArg, BackendDAE.ASSIGN(e1, e2, source)::inAccum);
1091 then (outWhenOps, extArg);
1092 case BackendDAE.REINIT(stateVar = cr, value = e2, source = source)::rest
1093 algorithm
1094 440 e1 := Expression.crefExp(cr);
1095
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 295 times.
440 (e1, extArg) := inFunc(e1, inTypeA);
1096
1/2
✓ Branch 1 taken 440 times.
✗ Branch 2 not taken.
440 if Expression.isCref(e1) then
1097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 440 times.
440 DAE.CREF(cr1, _) := e1;
1098 else
1099 cr1:=cr;
1100 end if;
1101
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 295 times.
440 (e2, extArg) := inFunc(e2, extArg);
1102 880 (outWhenOps, extArg) := traverseExpsOfWhenOps(rest, inFunc, extArg, BackendDAE.REINIT(cr1, e2, source)::inAccum);
1103 then (outWhenOps, extArg);
1104 case BackendDAE.ASSERT(condition = e1, message = e2, level = level, source = source)::rest
1105 algorithm
1106
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 61 times.
89 (e1, extArg) := inFunc(e1, inTypeA);
1107
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 61 times.
89 (e2, extArg) := inFunc(e2, extArg);
1108 178 (outWhenOps, extArg) := traverseExpsOfWhenOps(rest, inFunc, extArg, BackendDAE.ASSERT(e1, e2, level, source)::inAccum);
1109 then (outWhenOps, extArg);
1110 case BackendDAE.TERMINATE(message = e1, source = source)::rest
1111 algorithm
1112
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 68 times.
101 (e1, extArg) := inFunc(e1, inTypeA);
1113 202 (outWhenOps, extArg) := traverseExpsOfWhenOps(rest, inFunc, extArg, BackendDAE.TERMINATE(e1, source)::inAccum);
1114 then (outWhenOps, extArg);
1115 case BackendDAE.NORETCALL(exp = e1, source = source)::rest
1116 algorithm
1117
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 161 times.
224 (e1, extArg) := inFunc(e1, inTypeA);
1118 448 (outWhenOps, extArg) := traverseExpsOfWhenOps(rest, inFunc, extArg, BackendDAE.NORETCALL(e1, source)::inAccum);
1119 then (outWhenOps, extArg);
1120 end match;
1121 end traverseExpsOfWhenOps;
1122
1123 protected function traverseExpsOfWhenEquation_WithStop<T>
1124 "Traverses all expressions of a when equation.
1125 Helper function of traverseExpsOfEquation."
1126 input BackendDAE.WhenEquation inWhenEquation;
1127 input FuncExpType inFunc;
1128 input T inTypeA;
1129 output Boolean outCont;
1130 output T outTypeA;
1131
1132 partial function FuncExpType
1133 input DAE.Exp inExp;
1134 input T inTypeA;
1135 output DAE.Exp outExp;
1136 output Boolean cont;
1137 output T outTypeA;
1138 end FuncExpType;
1139 algorithm
1140 (outCont, outTypeA) := match inWhenEquation
1141 local
1142 BackendDAE.WhenEquation elsewe;
1143 Option<BackendDAE.WhenEquation> oelsewe;
1144 DAE.Exp cond;
1145 list<BackendDAE.WhenOperator> whenStmtLst;
1146 T extArg;
1147 Boolean b;
1148
1149 case BackendDAE.WHEN_STMTS(condition=cond, whenStmtLst=whenStmtLst, elsewhenPart = oelsewe)
1150 algorithm
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 (_, b, extArg) := inFunc(cond, inTypeA);
1152
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if b then
1153 7 (b, extArg) := traverseExpsOfWhenOps_WithStop(whenStmtLst, inFunc, extArg, b);
1154 end if;
1155
1156
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if b then
1157
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if isSome(oelsewe) then
1158 ✗ SOME(elsewe) := oelsewe;
1159 ✗ (b, extArg) := traverseExpsOfWhenEquation_WithStop(elsewe, inFunc, extArg);
1160 end if;
1161 end if;
1162
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 then (b, extArg);
1163 end match;
1164 end traverseExpsOfWhenEquation_WithStop;
1165
1166 public function statementEq
1167 "Creates equation from one statement."
1168 input DAE.Statement iStmts;
1169 output BackendDAE.Equation oEq;
1170 algorithm
1171 oEq := match iStmts
1172 local
1173 DAE.ComponentRef cr;
1174 DAE.Exp exp;
1175 list<DAE.Exp> explst;
1176
1177 case DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr), exp = exp)
1178 108 then generateEquation(Expression.crefExp(cr), exp);
1179
1180 case DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr), exp = exp)
1181 2 then generateEquation(Expression.crefExp(cr), exp);
1182
1183 case DAE.STMT_TUPLE_ASSIGN(expExpLst = explst, exp = exp)
1184 ✗ then generateEquation(Expression.makeTuple(explst), exp);
1185
1186 end match;
1187 end statementEq;
1188
1189 protected function traverseExpsOfWhenOps_WithStop<T>
1190 "Traverses all expressions of a when equation.
1191 Helper function of traverseExpsOfEquation."
1192 input list<BackendDAE.WhenOperator> inWhenOps;
1193 input FuncExpType inFunc;
1194 input T inTypeA;
1195 input Boolean inCont;
1196 output Boolean outCont;
1197 output T extArg = inTypeA;
1198
1199 partial function FuncExpType
1200 input DAE.Exp inExp;
1201 input T inTypeA;
1202 output DAE.Exp outExp;
1203 output Boolean cont;
1204 output T outTypeA;
1205 end FuncExpType;
1206 algorithm
1207 (outCont, extArg) := match inWhenOps
1208 local
1209 DAE.Type tp;
1210 DAE.Exp e1, e2;
1211 DAE.ComponentRef cr;
1212 list<BackendDAE.WhenOperator> rest;
1213 Boolean b = false;
1214
1215 case {} then (inCont,extArg);
1216 case BackendDAE.ASSIGN(left = e1, right = e2)::rest
1217 algorithm
1218
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if inCont then
1219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 (_, b, extArg) := inFunc(e1, extArg);
1220 end if;
1221
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if b then
1222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 (_, b, extArg) := inFunc(e2, extArg);
1223 end if;
1224 7 (b, extArg) := traverseExpsOfWhenOps_WithStop(rest, inFunc, extArg, b);
1225 then (b, extArg);
1226
1227 case BackendDAE.REINIT(stateVar = cr, value = e2)::rest
1228 algorithm
1229 ✗ tp := Expression.typeof(e2);
1230 ✗ e1 := Expression.makeCrefExp(cr, tp);
1231 ✗ if inCont then
1232 ✗ (_, b, extArg) := inFunc(e1, extArg);
1233 end if;
1234 ✗ if b then
1235 ✗ (_, b, extArg) := inFunc(e2, extArg);
1236 end if;
1237 ✗ (b, extArg) := traverseExpsOfWhenOps_WithStop(rest, inFunc, extArg, b);
1238 then (b, extArg);
1239
1240 case BackendDAE.ASSERT(condition = e1, message = e2)::rest
1241 algorithm
1242 ✗ if inCont then
1243 ✗ (_, b, extArg) := inFunc(e1, extArg);
1244 end if;
1245 ✗ if b then
1246 ✗ (_, b, extArg) := inFunc(e2, extArg);
1247 end if;
1248 ✗ (b, extArg) := traverseExpsOfWhenOps_WithStop(rest, inFunc, extArg, b);
1249 then (b, extArg);
1250
1251 case BackendDAE.TERMINATE(message = e1)::rest
1252 algorithm
1253 ✗ if inCont then
1254 ✗ (_, b, extArg) := inFunc(e1, extArg);
1255 end if;
1256 ✗ (b, extArg) := traverseExpsOfWhenOps_WithStop(rest, inFunc, extArg, b);
1257 then (b, extArg);
1258
1259 case BackendDAE.NORETCALL(exp = e1)::rest
1260 algorithm
1261 ✗ if inCont then
1262 ✗ (_, b, extArg) := inFunc(e1, extArg);
1263 end if;
1264 ✗ (b, extArg) := traverseExpsOfWhenOps_WithStop(rest, inFunc, extArg, b);
1265 then (b, extArg);
1266 end match;
1267 end traverseExpsOfWhenOps_WithStop;
1268
1269 protected function traverseExpsOfExpList<T> "author Frenkel TUD:
1270 Calls user function for each element of list."
1271 input list<DAE.Exp> inExpl;
1272 input FuncExpType rel;
1273 input T inExtArg;
1274 output list<DAE.Exp> outExpl = {};
1275 output T outTypeA = inExtArg;
1276
1277 partial function FuncExpType
1278 input output DAE.Exp inoutExp;
1279 input output T inoutTypeA;
1280 end FuncExpType;
1281 algorithm
1282
1283
2/2
✓ Branch 0 taken 1338 times.
✓ Branch 1 taken 504 times.
1842 for e in inExpl loop
1284
2/2
✓ Branch 0 taken 1330 times.
✓ Branch 1 taken 8 times.
1338 (e, outTypeA) := rel(e, outTypeA);
1285 outExpl := e :: outExpl;
1286 end for;
1287
1288 504 outExpl := MetaModelica.Dangerous.listReverseInPlace(outExpl);
1289 end traverseExpsOfExpList;
1290
1291 protected function traverseExpsOfExpList_WithStop<T> "author Frenkel TUD
1292 Calls user function for each element of list."
1293 input list<DAE.Exp> inExpl;
1294 input FuncExpType rel;
1295 input T inExtArg;
1296 output Boolean outBoolean = true;
1297 output T outTypeA = inExtArg;
1298 partial function FuncExpType
1299 input DAE.Exp inExp;
1300 input T inTypeA;
1301 output DAE.Exp outExp;
1302 output Boolean cont;
1303 output T outA;
1304 end FuncExpType;
1305 algorithm
1306 ✗ for e in inExpl loop
1307 ✗ (_, outBoolean, outTypeA) := rel(e, outTypeA);
1308 ✗ if not outBoolean then
1309 break;
1310 end if;
1311 end for;
1312 end traverseExpsOfExpList_WithStop;
1313
1314 public function equationEqual
1315 "Returns true if two equations are equal"
1316 input BackendDAE.Equation e1;
1317 input BackendDAE.Equation e2;
1318 output Boolean res = true;
1319 algorithm
1320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if referenceEq(e1, e2) then return; end if;
1321 res := match (e1, e2)
1322 local
1323 DAE.Exp e11, e12, e21, e22, exp1, exp2;
1324 DAE.ComponentRef cr1, cr2;
1325 DAE.Algorithm alg1, alg2;
1326 list<DAE.Exp> explst1, explst2;
1327
1328 case (BackendDAE.EQUATION(exp=e11, scalar=e12), BackendDAE.EQUATION(exp=e21, scalar=e22)) algorithm
1329 ✗ res := boolAnd(ExpressionBasics.expEqual(e11, e21), ExpressionBasics.expEqual(e12, e22));
1330 then res;
1331
1332 case (BackendDAE.ARRAY_EQUATION(left=e11, right=e12), BackendDAE.ARRAY_EQUATION(left=e21, right=e22)) algorithm
1333 ✗ res := boolAnd(ExpressionBasics.expEqual(e11, e21), ExpressionBasics.expEqual(e12, e22));
1334 then res;
1335
1336 case (BackendDAE.COMPLEX_EQUATION(left=e11, right=e12), BackendDAE.COMPLEX_EQUATION(left=e21, right=e22)) algorithm
1337
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 res := boolAnd(ExpressionBasics.expEqual(e11, e21), ExpressionBasics.expEqual(e12, e22));
1338 then res;
1339
1340 case (BackendDAE.SOLVED_EQUATION(componentRef=cr1, exp=exp1), BackendDAE.SOLVED_EQUATION(componentRef=cr2, exp=exp2)) algorithm
1341 ✗ res := boolAnd(ComponentReferenceBasics.crefEqualNoStringCompare(cr1, cr2), ExpressionBasics.expEqual(exp1, exp2));
1342 then res;
1343
1344 case (BackendDAE.RESIDUAL_EQUATION(exp=exp1), BackendDAE.RESIDUAL_EQUATION(exp=exp2)) algorithm
1345 ✗ res := ExpressionBasics.expEqual(exp1, exp2);
1346 then res;
1347
1348 case (BackendDAE.ALGORITHM(alg=alg1), BackendDAE.ALGORITHM(alg=alg2)) algorithm
1349 ✗ explst1 := Algorithm.getAllExps(alg1);
1350 ✗ explst2 := Algorithm.getAllExps(alg2);
1351 ✗ res := List.isEqualOnTrue(explst1, explst2, ExpressionBasics.expEqual);
1352 then res;
1353
1354 case (BackendDAE.WHEN_EQUATION(whenEquation = BackendDAE.WHEN_STMTS(whenStmtLst={BackendDAE.ASSIGN(left=e11, right=e12)})), BackendDAE.WHEN_EQUATION(whenEquation = BackendDAE.WHEN_STMTS(whenStmtLst={BackendDAE.ASSIGN(left=e21, right=e22)}))) algorithm
1355 ✗ res := boolAnd(ExpressionBasics.expEqual(e11, e21), ExpressionBasics.expEqual(e12, e22));
1356 then res;
1357
1358 else false;
1359 end match;
1360 end equationEqual;
1361
1362 public function equationAddDAE "author: Frenkel TUD 2011-05"
1363 input BackendDAE.Equation inEquation;
1364 input BackendDAE.EqSystem inEqSystem;
1365 output BackendDAE.EqSystem outEqSystem;
1366 algorithm
1367 27 outEqSystem := BackendDAEUtil.setEqSystEqs(inEqSystem, add(inEquation, inEqSystem.orderedEqs));
1368 27 outEqSystem.matching := BackendDAE.NO_MATCHING();
1369 end equationAddDAE;
1370
1371 public function equationsAddDAE "author: Frenkel TUD 2011-05"
1372 input list<BackendDAE.Equation> inEquations;
1373 input BackendDAE.EqSystem inEqSystem;
1374 output BackendDAE.EqSystem outEqSystem = inEqSystem;
1375 algorithm
1376 275 outEqSystem.orderedEqs := addList(inEquations, outEqSystem.orderedEqs);
1377 outEqSystem.matching := BackendDAE.NO_MATCHING();
1378 end equationsAddDAE;
1379
1380 public function requationsAddDAE "author: Frenkel TUD 2012-10
1381 Add a list of equations to removed equations of a BackendDAE.
1382 If the variable already exists, the function updates the variable."
1383 input list<BackendDAE.Equation> inEquations;
1384 input BackendDAE.EqSystem inSyst;
1385 output BackendDAE.EqSystem outSyst;
1386 algorithm
1387
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 57 times.
63 outSyst := if listEmpty(inEquations) then inSyst
1388 else BackendDAEUtil.setEqSystRemovedEqns(inSyst, addList(inEquations, inSyst.removedEqs));
1389 end requationsAddDAE;
1390
1391 public function removeRemovedEqs
1392 "Remove all removedEqs."
1393 input output BackendDAE.EqSystem eqSystem;
1394 algorithm
1395 5 ExpandableArray.clear(eqSystem.removedEqs);
1396 end removeRemovedEqs;
1397
1398 public function equationToScalarResidualForm "author: Frenkel TUD 2012-06
1399 This function transforms an equation to its scalar residual form.
1400 For instance, a=b is transformed to a-b=0, and the instance {a[1], a[2]}=b to a[1]=b[1] and a[2]=b[2]"
1401 input BackendDAE.Equation inEquation;
1402 input AvlTreePathFunction.Tree funcTree;
1403 output list<BackendDAE.Equation> outEquations;
1404 algorithm
1405
1406 outEquations := match inEquation
1407 local
1408 DAE.Exp e, e1, e2, exp, cond;
1409 DAE.ComponentRef cr;
1410 DAE.ElementSource source;
1411 BackendDAE.Equation backendEq;
1412 list<Integer> ds;
1413 Integer i, branches;
1414 list<DAE.Exp> explst, explst2, condExps;
1415 list<BackendDAE.Equation> eqns, eqnsfalse;
1416 list<list<BackendDAE.Equation>> eqnstrue;
1417 list<list<DAE.Subscript>> subslst;
1418 BackendDAE.EquationAttributes attr;
1419 list<DAE.ComponentRef> crlst, crlst2;
1420 array<list<DAE.Exp>> expA;
1421
1422 case BackendDAE.EQUATION(exp=DAE.TUPLE(explst), scalar=e2, source=source, attr=attr) algorithm
1423 ✗ (_, eqns) := List.fold3(explst,equationTupleToScalarResidualForm, e2, source, attr, (1, {}));
1424 then eqns;
1425
1426 case BackendDAE.EQUATION(exp= DAE.RCONST(real= 0.0), scalar=e2, source=source, attr=attr) algorithm
1427 1122 (e, _) := ExpressionSimplify.simplify(e2);
1428 1122 eqns :={BackendDAE.RESIDUAL_EQUATION(e, source, attr)};
1429 then eqns;
1430
1431 case BackendDAE.EQUATION(exp=e1, scalar= DAE.RCONST(real=0.0), source=source, attr=attr) algorithm
1432 765 (e, _) := ExpressionSimplify.simplify(e1);
1433 765 eqns :={BackendDAE.RESIDUAL_EQUATION(e, source, attr)};
1434 then eqns;
1435
1436 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=attr) algorithm
1437 11834 exp := Expression.createResidualExp(e1, e2);
1438 11834 then {BackendDAE.RESIDUAL_EQUATION(exp, source, attr)};
1439
1440 case BackendDAE.SOLVED_EQUATION(componentRef=cr, exp=e2, source=source, attr=attr) algorithm
1441 ✗ e1 := Expression.crefExp(cr);
1442 ✗ exp := Expression.createResidualExp(e1, e2);
1443 ✗ then {BackendDAE.RESIDUAL_EQUATION(exp, source, attr)};
1444
1445 case BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source, attr=attr) algorithm
1446 3 exp := Expression.createResidualExp(e1, e2);
1447 3 subslst := Expression.dimensionSizesSubscripts(ds);
1448 3 subslst := Expression.rangesToSubscripts(subslst);
1449 3 explst := List.map1r(subslst, Expression.applyExpSubscripts, exp);
1450 3 explst := ExpressionSimplify.simplifyList(explst);
1451 3 eqns := List.map2(explst, generateRESIDUAL_EQUATION, source, attr);
1452 then eqns;
1453
1454 case BackendDAE.COMPLEX_EQUATION(left=e1 as DAE.CALL(expLst=explst),
1455 right=e2, source=source, attr=attr)
1456 guard(Expression.isRecordCall(e1, funcTree) and Expression.isCref(e2))
1457 algorithm
1458 ✗ crlst := ComponentReference.expandCref(Expression.expCref(e2),true);
1459 ✗ explst2 := list(Expression.crefExp(c) for c in crlst);
1460 ✗ explst := List.threadMap(explst, explst2, Expression.createResidualExp);
1461 ✗ eqns := List.map2(explst, generateRESIDUAL_EQUATION, source, attr);
1462 then eqns;
1463
1464 case BackendDAE.COMPLEX_EQUATION(right=e1 as DAE.CALL(expLst=explst),
1465 left=e2, source=source, attr=attr)
1466 guard(Expression.isRecordCall(e1, funcTree) and Expression.isCref(e2))
1467 algorithm
1468 ✗ crlst := ComponentReference.expandCref(Expression.expCref(e2),true);
1469 ✗ explst2 := list(Expression.crefExp(c) for c in crlst);
1470 ✗ explst := List.threadMap(explst, explst2, Expression.createResidualExp);
1471 ✗ eqns := List.map2(explst, generateRESIDUAL_EQUATION, source, attr);
1472 then eqns;
1473
1474 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=attr)
1475 guard(Expression.isCref(e1) and Expression.isCref(e2))
1476 algorithm
1477 ✗ crlst := ComponentReference.expandCref(Expression.expCref(e1),true);
1478 ✗ crlst2 := ComponentReference.expandCref(Expression.expCref(e2),true);
1479 ✗ explst := list(Expression.crefExp(c) for c in crlst);
1480 ✗ explst2 := list(Expression.crefExp(c) for c in crlst2);
1481 ✗ explst := List.threadMap(explst, explst2, Expression.createResidualExp);
1482 ✗ eqns := List.map2(explst, generateRESIDUAL_EQUATION, source, attr);
1483 then eqns;
1484
1485 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=attr) algorithm
1486 4 exp := Expression.createResidualExp(e1, e2);
1487 ✗ then {BackendDAE.RESIDUAL_EQUATION(exp, source, attr)};
1488
1489 case BackendDAE.IF_EQUATION(conditions=condExps, eqnstrue=eqnstrue, eqnsfalse=eqnsfalse, source=source, attr=attr)
1490 algorithm
1491 ✗ branches := listLength(condExps);
1492 ✗ expA := arrayCreate(branches, {});
1493 // create array<list<exp>> with true branches
1494 ✗ for eqLst in eqnstrue loop
1495 i := 1;
1496 ✗ for eq in eqLst loop
1497 ✗ {BackendDAE.RESIDUAL_EQUATION(e1, _, _)} := equationToScalarResidualForm(eq, funcTree);
1498 ✗ expA := Array.consToElement(i, e1, expA);
1499 ✗ i := i + 1;
1500 end for;
1501 end for;
1502 // add also else branches
1503 i := 1;
1504 ✗ for eq in eqnsfalse loop
1505 ✗ {BackendDAE.RESIDUAL_EQUATION(e1, _, _)} := equationToScalarResidualForm(eq, funcTree);
1506 ✗ expA := Array.consToElement(i, e1, expA);
1507 ✗ i := i + 1;
1508 end for;
1509
1510 eqns := {};
1511 ✗ for i in 1:branches loop
1512 ✗ explst := arrayGet(expA, i);
1513 //get else branch
1514 ✗ e2::explst := explst;
1515 explst2 := condExps;
1516 ✗ for e1 in explst loop
1517 ✗ cond::explst2 := explst2;
1518 ✗ e2 := DAE.IFEXP(cond, e1, e2);
1519 end for;
1520 ✗ eqns := BackendDAE.RESIDUAL_EQUATION(e2, source, attr)::eqns;
1521 //BackendDump.printEquationList(eqns);
1522 end for;
1523 then eqns;
1524
1525 case backendEq as BackendDAE.RESIDUAL_EQUATION()
1526 then {backendEq};
1527
1528 case backendEq as BackendDAE.ALGORITHM()
1529 then {backendEq};
1530
1531 case backendEq as BackendDAE.WHEN_EQUATION()
1532 then {backendEq};
1533
1534 else
1535 algorithm
1536 ✗ true := Flags.isSet(Flags.FAILTRACE);
1537 ✗ BackendDump.printEquation(inEquation);
1538 ✗ Debug.trace("- BackendDAE.equationToScalarResidualForm failed\n");
1539 ✗ then fail();
1540 end match;
1541 end equationToScalarResidualForm;
1542
1543 protected function equationTupleToScalarResidualForm "
1544 Tuple-expressions (function calls) that need to be converted to residual form
1545 are scalarized in a stupid, straight-forward way."
1546 input DAE.Exp cr;
1547 input DAE.Exp exp;
1548 input DAE.ElementSource inSource;
1549 input BackendDAE.EquationAttributes inEqAttr;
1550 input tuple<Integer, list<BackendDAE.Equation>> inTpl;
1551 output tuple<Integer, list<BackendDAE.Equation>> outTpl;
1552 algorithm
1553 outTpl := match (cr, inTpl)
1554 local
1555 Integer i;
1556 list<BackendDAE.Equation> eqs;
1557 String str;
1558 DAE.Exp e;
1559
1560 // wild-card does not produce a residual
1561 case (DAE.CREF(componentRef=DAE.WILD()), (i, eqs))
1562 ✗ then ((i+1, eqs));
1563
1564 // 0-length arrays do not produce a residual
1565 case (DAE.ARRAY(array={}), (i, eqs))
1566 ✗ then ((i+1, eqs));
1567
1568 // a scalar real
1569 case (DAE.CREF(ty=DAE.T_REAL()), (i, eqs)) algorithm
1570 ✗ eqs := BackendDAE.RESIDUAL_EQUATION(DAE.TSUB(exp, i, DAE.T_REAL_DEFAULT), inSource, inEqAttr)::eqs;
1571 ✗ then ((i+1, eqs));
1572
1573 // create a sum for arrays...
1574 case (DAE.CREF(ty=DAE.T_ARRAY(ty=DAE.T_REAL())), (i, eqs)) algorithm
1575 ✗ e := Expression.makePureBuiltinCall("sum", {DAE.TSUB(exp, i, DAE.T_REAL_DEFAULT)}, DAE.T_REAL_DEFAULT);
1576 ✗ eqs := BackendDAE.RESIDUAL_EQUATION(e, inSource, inEqAttr)::eqs;
1577 ✗ then ((i+1, eqs));
1578
1579 case (_, (i, _)) algorithm
1580 ✗ str := "BackendEquation.equationTupleToScalarResidualForm failed: " + intString(i) + ": " + ExpressionBasics.printExpStr(cr);
1581 ✗ Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, ElementSource.getElementSourceFileInfo(inSource));
1582 ✗ then fail();
1583 end match;
1584 end equationTupleToScalarResidualForm;
1585
1586 public function equationToResidualForm "author: PA
1587 This function transforms an equation to its residual form.
1588 For instance, a=b is transformed to a-b=0"
1589 input BackendDAE.Equation inEquation;
1590 output BackendDAE.Equation outEquation;
1591 algorithm
1592 outEquation := matchcontinue inEquation
1593 local
1594 DAE.Exp e, e1, e2, exp;
1595 DAE.ComponentRef cr;
1596 DAE.ElementSource source;
1597 BackendDAE.Equation backendEq;
1598 BackendDAE.EquationAttributes eqAttr;
1599
1600 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr) algorithm
1601 //ExpressionDump.dumpExpWithTitle("equationToResidualForm 1\n", e2);
1602 6423 exp := Expression.createResidualExp(e1, e2);
1603 6423 (e, _) := ExpressionSimplify.simplify(exp);
1604 6423 then BackendDAE.RESIDUAL_EQUATION(e, source, eqAttr);
1605
1606 case BackendDAE.SOLVED_EQUATION(componentRef=cr, exp=e2, source=source, attr=eqAttr) algorithm
1607 ✗ e1 := Expression.crefExp(cr);
1608 ✗ exp := Expression.createResidualExp(e1, e2);
1609 ✗ (e, _) := ExpressionSimplify.simplify(exp);
1610 ✗ then BackendDAE.RESIDUAL_EQUATION(e, source, eqAttr);
1611
1612 case BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source, attr=eqAttr) algorithm
1613 ✗ exp := Expression.createResidualExp(e1, e2);
1614 ✗ (e, _) := ExpressionSimplify.simplify(exp);
1615 ✗ then BackendDAE.RESIDUAL_EQUATION(e, source, eqAttr);
1616
1617 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=eqAttr) algorithm
1618 ✗ exp := Expression.createResidualExp(e1, e2);
1619 ✗ (e, _) := ExpressionSimplify.simplify(exp);
1620 ✗ then BackendDAE.RESIDUAL_EQUATION(e, source, eqAttr);
1621
1622 case backendEq as BackendDAE.RESIDUAL_EQUATION()
1623 then backendEq;
1624
1625 case backendEq as BackendDAE.ALGORITHM()
1626 then backendEq;
1627
1628 case backendEq as BackendDAE.WHEN_EQUATION()
1629 then backendEq;
1630
1631 else
1632 algorithm
1633 ✗ true := Flags.isSet(Flags.FAILTRACE);
1634 ✗ Debug.trace("- BackendDAE.equationToResidualForm failed\n");
1635 ✗ then fail();
1636 end matchcontinue;
1637 end equationToResidualForm;
1638
1639 public function traverseEquationToScalarResidualForm
1640 "author: Frenkel TUD 2010-11"
1641 input BackendDAE.Equation inEq;
1642 input tuple<AvlTreePathFunction.Tree, list<BackendDAE.Equation>> inEqs;
1643 output BackendDAE.Equation outEq;
1644 output tuple<AvlTreePathFunction.Tree, list<BackendDAE.Equation>> outEqs;
1645 algorithm
1646 (outEq,outEqs) := match(inEq,inEqs)
1647 local
1648 list<BackendDAE.Equation> eqns,reqn;
1649 BackendDAE.Equation eqn;
1650 AvlTreePathFunction.Tree funcs;
1651
1652 case (eqn, (funcs, eqns))
1653 algorithm
1654 7468 reqn := equationToScalarResidualForm(eqn, funcs);
1655 7464 eqns := listAppend(reqn,eqns);
1656 7464 then (eqn, (funcs, eqns));
1657
1658 else
1659 algorithm
1660 ✗ true := Flags.isSet(Flags.FAILTRACE);
1661 ✗ Error.addInternalError(getInstanceName() + " failed", sourceInfo());
1662 ✗ then fail();
1663 end match;
1664 end traverseEquationToScalarResidualForm;
1665
1666 public function convertResidualsIntoSolvedEquations
1667 "This function converts residuals into solved equations of the following form:
1668 e.g.: 0 = a+b -> $res1 = a+b"
1669 input list<BackendDAE.Equation> inResidualList;
1670 input String inName;
1671 input Integer inIndex;
1672 input Boolean isResidual = false "only used for dae mode";
1673 output list<BackendDAE.Equation> outEquationList = {};
1674 output list<BackendDAE.Var> outVariableList = {};
1675 output Integer outVarIndex = inIndex;
1676 algorithm
1677
2/2
✓ Branch 0 taken 11252 times.
✓ Branch 1 taken 6050 times.
17302 for eq in inResidualList loop
1678 () := match eq
1679 local
1680 DAE.Exp exp;
1681 DAE.ElementSource source "origin of equation";
1682 BackendDAE.EquationAttributes eqAttr;
1683 DAE.ComponentRef componentRef;
1684 BackendDAE.Equation currEquation;
1685 BackendDAE.Var currVariable;
1686
1687 case BackendDAE.RESIDUAL_EQUATION(exp=exp,source=source,attr=eqAttr)
1688 algorithm
1689 11242 componentRef := DAE.CREF_IDENT(inName + intString(outVarIndex), Expression.typeof(exp), {});
1690 11242 currEquation := BackendDAE.SOLVED_EQUATION(componentRef, exp, source, eqAttr);
1691 11242 currVariable := BackendVariable.makeVar(componentRef);
1692
2/2
✓ Branch 0 taken 3800 times.
✓ Branch 1 taken 7442 times.
11242 if isResidual then
1693 3800 currVariable := BackendVariable.setVarKind(currVariable, BackendDAE.DAE_RESIDUAL_VAR());
1694 end if;
1695
1696 11242 outVarIndex := outVarIndex + 1;
1697 outEquationList := currEquation::outEquationList;
1698 outVariableList := currVariable::outVariableList;
1699 then ();
1700 else
1701 algorithm
1702
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 true := Flags.isSet(Flags.FAILTRACE);
1703 ✗ Error.addInternalError(getInstanceName() + " failed", sourceInfo());
1704 ✗ then fail();
1705 end match;
1706 end for;
1707 6050 outEquationList := MetaModelica.Dangerous.listReverseInPlace(outEquationList);
1708 6050 outVariableList := MetaModelica.Dangerous.listReverseInPlace(outVariableList);
1709 end convertResidualsIntoSolvedEquations;
1710
1711 public function equationInfo "
1712 Retrieve the line number information from a BackendDAE.BackendDAEequation"
1713 input BackendDAE.Equation eq;
1714 output SourceInfo info;
1715 algorithm
1716 986312 info := ElementSource.getElementSourceFileInfo(equationSource(eq));
1717 end equationInfo;
1718
1719 public function markedEquationSource
1720 input BackendDAE.EqSystem inEqSystem;
1721 input Integer inPos "one-based indexing";
1722 output DAE.ElementSource outSource;
1723 algorithm
1724 ✗ outSource := equationSource(get(inEqSystem.orderedEqs, inPos));
1725 end markedEquationSource;
1726
1727 public function equationSource "
1728 Retrieve the source from a BackendDAE.BackendDAEequation"
1729 input BackendDAE.Equation eq;
1730 output DAE.ElementSource source;
1731 algorithm
1732 source := match eq
1733 case BackendDAE.EQUATION(source=source) then source;
1734 case BackendDAE.ARRAY_EQUATION(source=source) then source;
1735 case BackendDAE.FOR_EQUATION(source=source) then source;
1736 case BackendDAE.SOLVED_EQUATION(source=source) then source;
1737 case BackendDAE.RESIDUAL_EQUATION(source=source) then source;
1738 case BackendDAE.WHEN_EQUATION(source=source) then source;
1739 case BackendDAE.ALGORITHM(source=source) then source;
1740 case BackendDAE.COMPLEX_EQUATION(source=source) then source;
1741 case BackendDAE.IF_EQUATION(source=source) then source;
1742 else algorithm
1743 ✗ Error.addInternalError("BackendEquation.equationSource failed!", sourceInfo());
1744 ✗ then fail();
1745 end match;
1746 end equationSource;
1747
1748 public function equationSizeKeepAlgorithmAsOne
1749 "Same as equationSize but keeps algorithms as one equation"
1750 input BackendDAE.Equation eq;
1751 output Integer osize;
1752 algorithm
1753 osize := match eq
1754 case BackendDAE.ALGORITHM(_)
1755 then 1;
1756 else
1757 6898 then equationSize(eq);
1758 end match;
1759 end equationSizeKeepAlgorithmAsOne;
1760
1761 public function equationSize
1762 "Retrieve the size from a BackendDAE.BackendDAEequation"
1763 input BackendDAE.Equation eq;
1764 output Integer osize;
1765 algorithm
1766 osize := match eq
1767 local
1768 list<Integer> ds;
1769 Integer size, start, stop, recordSize;
1770 list<BackendDAE.Equation> eqnsfalse;
1771
1772 case BackendDAE.EQUATION()
1773 then 1;
1774
1775 case BackendDAE.ARRAY_EQUATION(dimSize=ds,recordSize=SOME(recordSize)) algorithm
1776 4 size := List.fold(ds, intMul, 1) * recordSize;
1777 then size;
1778
1779 case BackendDAE.ARRAY_EQUATION(dimSize=ds,recordSize=NONE()) algorithm
1780 54148 size := List.fold(ds, intMul, 1);
1781 then size;
1782
1783 case BackendDAE.SOLVED_EQUATION()
1784 then 1;
1785
1786 case BackendDAE.RESIDUAL_EQUATION()
1787 then 1;
1788
1789 case BackendDAE.WHEN_EQUATION(size=size)
1790 then size;
1791
1792 case BackendDAE.ALGORITHM(size=size)
1793 then size;
1794
1795 case BackendDAE.COMPLEX_EQUATION(size=size)
1796 then size;
1797
1798 case BackendDAE.IF_EQUATION(eqnsfalse=eqnsfalse) algorithm
1799 161 size := equationLstSize(eqnsfalse);
1800 then size;
1801
1802 case BackendDAE.FOR_EQUATION(start = DAE.ICONST(start), stop = DAE.ICONST(stop)) algorithm
1803 21 size := (stop - start + 1) * equationSize(eq.body);
1804 then size;
1805
1806 else algorithm
1807 ✗ Error.addInternalError("BackendEquation.equationSize failed!", sourceInfo());
1808 ✗ then fail();
1809 end match;
1810 end equationSize;
1811
1812 public function isInitialEquation
1813 input BackendDAE.Equation inEquation;
1814 output Boolean outBool;
1815 protected
1816 BackendDAE.EquationKind eqKind;
1817 algorithm
1818 242787 eqKind := equationKind(inEquation);
1819 242787 outBool := isInitialEqKind(eqKind);
1820 end isInitialEquation;
1821
1822 public function isInitialEqKind
1823 input BackendDAE.EquationKind inEqKind;
1824 output Boolean outBool;
1825 algorithm
1826 outBool := match inEqKind
1827 case BackendDAE.INITIAL_EQUATION() then true;
1828 else false;
1829 end match;
1830 end isInitialEqKind;
1831
1832 public function isDynamicEquation
1833 input BackendDAE.Equation inEquation;
1834 output Boolean outBool;
1835 algorithm
1836 5192 outBool := isDynamicEqKind(equationKind(inEquation));
1837 end isDynamicEquation;
1838
1839 public function isDynamicEqKind
1840 input BackendDAE.EquationKind inEqKind;
1841 output Boolean outBool;
1842 algorithm
1843 outBool := match inEqKind
1844 case BackendDAE.DYNAMIC_EQUATION() then true;
1845 else false;
1846 end match;
1847 end isDynamicEqKind;
1848
1849 public function isBindingEquation
1850 input BackendDAE.Equation inEquation;
1851 output Boolean outBool;
1852 algorithm
1853 5867 outBool := isBindingEqKind(equationKind(inEquation));
1854 end isBindingEquation;
1855
1856 public function isBindingEqKind
1857 input BackendDAE.EquationKind inEqKind;
1858 output Boolean outBool;
1859 algorithm
1860 outBool := match inEqKind
1861 case BackendDAE.BINDING_EQUATION() then true;
1862 else false;
1863 end match;
1864 end isBindingEqKind;
1865
1866 public function isDiscreteEquation
1867 input BackendDAE.Equation inEquation;
1868 output Boolean outBool;
1869 algorithm
1870 ✗ outBool := isDiscreteEqKind(equationKind(inEquation));
1871 end isDiscreteEquation;
1872
1873 public function isDiscreteEqKind
1874 input BackendDAE.EquationKind inEqKind;
1875 output Boolean outBool;
1876 algorithm
1877 outBool := match inEqKind
1878 case BackendDAE.DISCRETE_EQUATION() then true;
1879 else false;
1880 end match;
1881 end isDiscreteEqKind;
1882
1883 public function isAuxEquation
1884 input BackendDAE.Equation inEquation;
1885 output Boolean outBool;
1886 algorithm
1887 5192 outBool := isAuxEqKind(equationKind(inEquation));
1888 end isAuxEquation;
1889
1890 public function isAuxEqKind
1891 input BackendDAE.EquationKind inEqKind;
1892 output Boolean outBool;
1893 algorithm
1894 outBool := match inEqKind
1895 case BackendDAE.AUX_EQUATION() then true;
1896 else false;
1897 end match;
1898 end isAuxEqKind;
1899
1900 public function defaultClockedEqAttr
1901 input Integer clockIndex;
1902 output BackendDAE.EquationAttributes outEqAttr;
1903 algorithm
1904 106 outEqAttr := BackendDAE.EQUATION_ATTRIBUTES(false, BackendDAE.CLOCKED_EQUATION(clockIndex), BackendDAE.defaultEvalStages);
1905 end defaultClockedEqAttr;
1906
1907 public function equationKind "Retrieve the kind from a BackendDAE.BackendDAEequation"
1908 input BackendDAE.Equation inEquation;
1909 output BackendDAE.EquationKind outEqKind;
1910 algorithm
1911 outEqKind := match inEquation
1912 local
1913 BackendDAE.EquationKind kind;
1914
1915 case BackendDAE.EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1916 case BackendDAE.ARRAY_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1917 case BackendDAE.FOR_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1918 case BackendDAE.SOLVED_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1919 case BackendDAE.RESIDUAL_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1920 case BackendDAE.WHEN_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1921 case BackendDAE.ALGORITHM(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1922 case BackendDAE.COMPLEX_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1923 case BackendDAE.IF_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(kind=kind)) then kind;
1924 else algorithm
1925 ✗ Error.addInternalError(getInstanceName() + " failed!", sourceInfo());
1926 ✗ then fail();
1927 end match;
1928 end equationKind;
1929
1930 public function setEquationKind
1931 input output BackendDAE.Equation eq;
1932 input output BackendDAE.EquationKind k;
1933 algorithm
1934 eq := match eq
1935 local
1936 BackendDAE.EquationAttributes a;
1937 272 case BackendDAE.EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1938 6 case BackendDAE.ARRAY_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1939 ✗ case BackendDAE.FOR_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1940 ✗ case BackendDAE.SOLVED_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1941 ✗ case BackendDAE.RESIDUAL_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1942 ✗ case BackendDAE.WHEN_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1943 ✗ case BackendDAE.ALGORITHM(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1944 ✗ case BackendDAE.COMPLEX_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1945 ✗ case BackendDAE.IF_EQUATION(attr=a) algorithm a.kind := k; eq.attr := a; then eq;
1946 else algorithm
1947 ✗ Error.addInternalError(getInstanceName() + " failed!", sourceInfo());
1948 ✗ then fail();
1949 end match;
1950 end setEquationKind;
1951
1952 public function setEvalStageDynamic
1953 input output BackendDAE.EvaluationStages evalStage;
1954 algorithm
1955 4004 evalStage.dynamicEval := true;
1956 end setEvalStageDynamic;
1957
1958 public function setEvalStageAlgebraic
1959 input output BackendDAE.EvaluationStages evalStage;
1960 algorithm
1961 1391 evalStage.algebraicEval := true;
1962 end setEvalStageAlgebraic;
1963
1964 public function setEvalStageZeroCross
1965 input output BackendDAE.EvaluationStages evalStage;
1966 algorithm
1967 32 evalStage.zerocrossEval := true;
1968 end setEvalStageZeroCross;
1969
1970 public function setEvalStageDiscrete
1971 input output BackendDAE.EvaluationStages evalStage;
1972 algorithm
1973 5222 evalStage.discreteEval := true;
1974 end setEvalStageDiscrete;
1975
1976 public function setEvalStageOnlyDiscrete
1977 input output BackendDAE.EvaluationStages evalStage;
1978 algorithm
1979 ✗ evalStage := setEvalStage(evalStage, discreteEval=true);
1980 end setEvalStageOnlyDiscrete;
1981
1982 public function setEvalStageAll
1983 input output BackendDAE.EvaluationStages evalStage;
1984 algorithm
1985 ✗ evalStage := setEvalStage(evalStage, dynamicEval=true, algebraicEval=true, zerocrossEval=true, discreteEval=true);
1986 end setEvalStageAll;
1987
1988 public function setEvalStage
1989 input output BackendDAE.EvaluationStages evalStage;
1990 input Boolean dynamicEval = false;
1991 input Boolean algebraicEval = false;
1992 input Boolean zerocrossEval = false;
1993 input Boolean discreteEval = false;
1994 algorithm
1995 ✗ evalStage.dynamicEval := dynamicEval;
1996 evalStage.algebraicEval := algebraicEval;
1997 evalStage.zerocrossEval := zerocrossEval;
1998 evalStage.discreteEval := discreteEval;
1999 end setEvalStage;
2000
2001 public function setEquationEvalStage
2002 input output BackendDAE.Equation eqn;
2003 input setEvalStage func;
2004 partial function setEvalStage
2005 input output BackendDAE.EvaluationStages evalStage;
2006 end setEvalStage;
2007 protected
2008 BackendDAE.EquationAttributes attr;
2009 algorithm
2010 10649 attr := getEquationAttributes(eqn);
2011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10649 times.
10649 attr.evalStages := func(attr.evalStages);
2012 10649 eqn := setEquationAttributes(eqn, attr);
2013 end setEquationEvalStage;
2014
2015 public function equationLstSize
2016 input list<BackendDAE.Equation> inEqns;
2017 output Integer size = 0;
2018 algorithm
2019
2/2
✓ Branch 0 taken 9871 times.
✓ Branch 1 taken 30061 times.
39932 for eqn in inEqns loop
2020 9871 size := size + equationSize(eqn);
2021 end for;
2022 end equationLstSize;
2023
2024 public function equationLstSizeKeepAlgorithmAsOne "author: vwaurich
2025 Gets the scalar size of the equations. Algorithms are handled as single equations."
2026 input list<BackendDAE.Equation> inEqns;
2027 output Integer size = 0;
2028 algorithm
2029
2/2
✓ Branch 0 taken 6898 times.
✓ Branch 1 taken 219 times.
7117 for eqn in inEqns loop
2030 6898 size := size + equationSizeKeepAlgorithmAsOne(eqn);
2031 end for;
2032 end equationLstSizeKeepAlgorithmAsOne;
2033
2034 public function removeDiscreteTupleElements
2035 "Removes the discrete elements of a tuple equation together with the matching
2036 right-hand side elements."
2037 input BackendDAE.Equation eqn;
2038 output BackendDAE.Equation outEqn = eqn;
2039 protected
2040 list<DAE.Exp> lhsLst, rhsLst, keptLhs = {}, keptRhs = {};
2041 list<Boolean> isDiscrete;
2042 Boolean d;
2043 algorithm
2044 (lhsLst, rhsLst) := match eqn
2045 case BackendDAE.COMPLEX_EQUATION(left = DAE.TUPLE(PR = lhsLst))
2046 ✗ then (lhsLst, tupleElements(eqn.right, lhsLst));
2047 else ({}, {});
2048 end match;
2049
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 7513 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7513 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
7513 isDiscrete := list(isDiscreteTupleElement(e) for e in lhsLst);
2050
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 7513 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
7513 if not (listMember(true, isDiscrete) and listMember(false, isDiscrete)) then
2051 7513 return;
2052 end if;
2053
2054 ✗ for r in rhsLst loop
2055 ✗ d :: isDiscrete := isDiscrete;
2056 ✗ if not d then
2057 ✗ keptLhs := listHead(lhsLst) :: keptLhs;
2058 keptRhs := r :: keptRhs;
2059 end if;
2060 ✗ lhsLst := listRest(lhsLst);
2061 end for;
2062
2063 outEqn := match eqn
2064 case BackendDAE.COMPLEX_EQUATION() guard listLength(keptLhs) == 1
2065 ✗ then generateEquation(listHead(keptLhs), listHead(keptRhs), eqn.source, eqn.attr);
2066 case BackendDAE.COMPLEX_EQUATION()
2067 ✗ then BackendDAE.COMPLEX_EQUATION(sum(Expression.sizeOf(Expression.typeof(l)) for l in keptLhs),
2068 DAE.TUPLE(listReverse(keptLhs)), DAE.TUPLE(listReverse(keptRhs)), eqn.source, eqn.attr);
2069 end match;
2070 end removeDiscreteTupleElements;
2071
2072 public function isDiscreteTupleElement
2073 input DAE.Exp exp;
2074 output Boolean b = Types.isDiscreteType(Types.arrayElementType(Expression.typeof(exp)));
2075 end isDiscreteTupleElement;
2076
2077 public function tupleElements
2078 "The elements of the right-hand side of a tuple equation."
2079 input DAE.Exp rhs;
2080 input list<DAE.Exp> lhs;
2081 output list<DAE.Exp> elements;
2082 algorithm
2083 elements := match rhs
2084 ✗ case DAE.TUPLE() then rhs.PR;
2085 ✗ else list(DAE.TSUB(rhs, i, Expression.typeof(l)) threaded for l in lhs, i in 1:listLength(lhs));
2086 end match;
2087 end tupleElements;
2088
2089 public function generateEquation "author Frenkel TUD 2012-12
2090 helper to generate an equation from lhs and rhs.
2091 the type of this function is determined by the lhs.
2092 This function is called if an equation is found which is not simple"
2093 input DAE.Exp lhs;
2094 input DAE.Exp rhs;
2095 input DAE.ElementSource source = DAE.emptyElementSource;
2096 input BackendDAE.EquationAttributes inEqAttr = BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN;
2097 output BackendDAE.Equation outEqn;
2098 protected
2099 DAE.Type ty,tp;
2100 algorithm
2101 176200 ty := Expression.typeof(lhs);
2102 outEqn := match ()
2103 local
2104 Integer size;
2105 Option<Integer> recordSize;
2106 DAE.Dimensions dims;
2107 list<Integer> ds;
2108
2109 // complex types to complex equations
2110 case () guard
2111 DAEUtil.expTypeComplex(ty) or DAEUtil.expTypeTuple(ty)
2112 algorithm
2113 1862 size := Expression.sizeOf(ty);
2114 1862 then BackendDAE.COMPLEX_EQUATION(size, lhs, rhs, source, inEqAttr);
2115
2116 // array types to array equations
2117 case () guard
2118 DAEUtil.expTypeArray(ty)
2119 algorithm
2120 29 tp := Expression.typeof(lhs);
2121 29 tp := DAEUtil.expTypeElementType(tp);
2122
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
29 if DAEUtil.expTypeComplex(tp) then
2123 ✗ recordSize := SOME(Expression.sizeOf(tp));
2124 else
2125 recordSize := NONE();
2126 end if;
2127 29 dims := Expression.arrayDimension(ty);
2128 29 ds := Expression.dimensionsSizes(dims);
2129 29 then BackendDAE.ARRAY_EQUATION(ds, lhs, rhs, source, inEqAttr, recordSize);
2130
2131 // other types
2132 case () guard
2133 not DAEUtil.expTypeComplex(ty) and
2134 not DAEUtil.expTypeArray(ty)
2135 174309 then BackendDAE.EQUATION(lhs, rhs, source, inEqAttr);
2136
2137 else algorithm
2138 // show only on failtrace!
2139 ✗ true := Flags.isSet(Flags.FAILTRACE);
2140 ✗ Debug.traceln("- BackendEquation.generateEquation failed on: " + ExpressionBasics.printExpStr(lhs) + " = " + ExpressionBasics.printExpStr(rhs) + "\n");
2141 ✗ then fail();
2142 end match;
2143 end generateEquation;
2144
2145 public function getEquationArraySubsetLst
2146 "Returns a subset of an equation array as lst, specified by a list of indices."
2147 input BackendDAE.EquationArray eqnArr;
2148 input list<Integer> iLst;
2149 output list<BackendDAE.Equation> subset = {};
2150 algorithm
2151 ✗ for i in iLst loop
2152 ✗ subset := ExpandableArray.get(i,eqnArr)::subset;
2153 end for;
2154 end getEquationArraySubsetLst;
2155
2156 public function getEquationAttributes
2157 input BackendDAE.Equation inEqn;
2158 output BackendDAE.EquationAttributes outAttr;
2159 algorithm
2160 outAttr := match inEqn
2161 local
2162 BackendDAE.EquationAttributes attr;
2163
2164 case BackendDAE.EQUATION(attr=attr) then attr;
2165 case BackendDAE.ARRAY_EQUATION(attr=attr) then attr;
2166 case BackendDAE.SOLVED_EQUATION(attr=attr) then attr;
2167 case BackendDAE.RESIDUAL_EQUATION(attr=attr) then attr;
2168 case BackendDAE.ALGORITHM(attr=attr) then attr;
2169 case BackendDAE.WHEN_EQUATION(attr=attr) then attr;
2170 case BackendDAE.COMPLEX_EQUATION(attr=attr) then attr;
2171 case BackendDAE.IF_EQUATION(attr=attr) then attr;
2172 case BackendDAE.FOR_EQUATION(attr=attr) then attr;
2173
2174 else algorithm
2175 ✗ Error.addInternalError("function getEquationAttributes failed", sourceInfo());
2176 ✗ then fail();
2177 end match;
2178 end getEquationAttributes;
2179
2180 public function setEquationAttributes
2181 input BackendDAE.Equation inEqn;
2182 input BackendDAE.EquationAttributes inAttr;
2183 output BackendDAE.Equation outEqn;
2184 algorithm
2185 outEqn := match inEqn
2186 local
2187 DAE.ElementSource source;
2188 list<Integer> dimSize;
2189 DAE.Exp lhs;
2190 DAE.Exp rhs;
2191 DAE.ComponentRef componentRef;
2192 Integer size;
2193 Option<Integer> recordSize;
2194 DAE.Algorithm alg;
2195 DAE.Expand expand;
2196 BackendDAE.WhenEquation whenEquation;
2197 list< .DAE.Exp> conditions;
2198 list<list<BackendDAE.Equation>> eqnstrue;
2199 list<BackendDAE.Equation> eqnsfalse;
2200
2201 case BackendDAE.EQUATION(exp=lhs, scalar=rhs, source=source)
2202 870 then BackendDAE.EQUATION(lhs, rhs, source, inAttr);
2203
2204 case BackendDAE.ARRAY_EQUATION(dimSize=dimSize, left=lhs, right=rhs, source=source, recordSize=recordSize)
2205 5 then BackendDAE.ARRAY_EQUATION(dimSize, lhs, rhs, source, inAttr, recordSize);
2206
2207 case BackendDAE.FOR_EQUATION()
2208 7 then BackendDAE.FOR_EQUATION(inEqn.iter, inEqn.start, inEqn.stop, inEqn.body, inEqn.source, inAttr);
2209
2210 case BackendDAE.SOLVED_EQUATION(componentRef=componentRef, exp=rhs, source=source)
2211 15624 then BackendDAE.SOLVED_EQUATION(componentRef, rhs, source, inAttr);
2212
2213 case BackendDAE.RESIDUAL_EQUATION(exp=rhs, source=source)
2214 ✗ then BackendDAE.RESIDUAL_EQUATION(rhs, source, inAttr);
2215
2216 case BackendDAE.ALGORITHM(size=size, alg=alg, source=source, expand=expand)
2217 71 then BackendDAE.ALGORITHM(size, alg, source, expand, inAttr);
2218
2219 case BackendDAE.WHEN_EQUATION(size=size, whenEquation=whenEquation, source=source)
2220 ✗ then BackendDAE.WHEN_EQUATION(size, whenEquation, source, inAttr);
2221
2222 case BackendDAE.COMPLEX_EQUATION(size=size, left=lhs, right=rhs, source=source)
2223 28 then BackendDAE.COMPLEX_EQUATION(size, lhs, rhs, source, inAttr);
2224
2225 case BackendDAE.IF_EQUATION(conditions=conditions, eqnstrue=eqnstrue, eqnsfalse=eqnsfalse, source=source)
2226 ✗ then BackendDAE.IF_EQUATION(conditions, eqnstrue, eqnsfalse, source, inAttr);
2227
2228 else algorithm
2229 ✗ Error.addInternalError("function setEquationAttributes failed", sourceInfo());
2230 ✗ then fail();
2231 end match;
2232 end setEquationAttributes;
2233
2234 public function setEquationLHS
2235 "
2236 sets the left hand side expression of an equation.
2237 "
2238 input BackendDAE.Equation inEqn;
2239 input DAE.Exp lhs;
2240 output BackendDAE.Equation outEqn;
2241 algorithm
2242 outEqn := match inEqn
2243 local
2244 BackendDAE.Equation eqn;
2245
2246 case eqn as BackendDAE.EQUATION() algorithm
2247 59 eqn.exp := lhs;
2248 then eqn;
2249
2250 case eqn as BackendDAE.ARRAY_EQUATION() algorithm
2251 ✗ eqn.left := lhs;
2252 then eqn;
2253
2254 else algorithm
2255 ✗ Error.addInternalError("function setEquationLHS failed", sourceInfo());
2256 ✗ then fail();
2257 end match;
2258 end setEquationLHS;
2259
2260 public function setEquationRHS
2261 "sets the right hand side expression of an equation."
2262 input BackendDAE.Equation inEqn;
2263 input DAE.Exp rhs;
2264 output BackendDAE.Equation outEqn;
2265 algorithm
2266 outEqn := match inEqn
2267 local
2268 BackendDAE.Equation eqn;
2269
2270 case eqn as BackendDAE.EQUATION() algorithm
2271 65 eqn.scalar := rhs;
2272 then eqn;
2273
2274 case eqn as BackendDAE.ARRAY_EQUATION() algorithm
2275 ✗ eqn.right := rhs;
2276 then eqn;
2277
2278 case eqn as BackendDAE.SOLVED_EQUATION() algorithm
2279 ✗ eqn.exp := rhs;
2280 then eqn;
2281
2282 case eqn as BackendDAE.RESIDUAL_EQUATION() algorithm
2283 ✗ eqn.exp := rhs;
2284 then eqn;
2285
2286 else algorithm
2287 ✗ Error.addInternalError("function setEquationRHS failed", sourceInfo());
2288 ✗ then fail();
2289 end match;
2290 end setEquationRHS;
2291
2292 public function generateSolvedEqnsfromOption "author: Frenkel TUD 2010-05"
2293 input DAE.ComponentRef inLhs;
2294 input Option<DAE.Exp> inRhs;
2295 input DAE.ElementSource inSource;
2296 input BackendDAE.EquationAttributes inEqAttr;
2297 output list<BackendDAE.Equation> outEqn;
2298 algorithm
2299 outEqn := match inRhs
2300 local
2301 DAE.Exp rhs;
2302
2303 case SOME(rhs)
2304 43 then {BackendDAE.SOLVED_EQUATION(inLhs, rhs, inSource, inEqAttr)};
2305
2306 else {};
2307 end match;
2308 end generateSolvedEqnsfromOption;
2309
2310 public function generateResidualFromRelation "author: vitalij"
2311 input String conCrefName;
2312 input DAE.Exp iRhs;
2313 input DAE.ElementSource Source;
2314 input BackendDAE.Variables inVars;
2315 input BackendDAE.Variables knvars;
2316 input BackendDAE.VarKind conKind;
2317
2318 output list<BackendDAE.Equation> outEqn;
2319 output BackendDAE.Var vout;
2320 algorithm
2321 (outEqn, vout) := match iRhs
2322 local
2323 DAE.Exp rhs, e1, e2 , expNull, lowBound;
2324 DAE.ComponentRef lhs, cr;
2325 BackendDAE.Var dummyVar, v;
2326 BackendDAE.Equation eqn;
2327
2328 case DAE.RELATION(e1, DAE.LESS(_), e2, _, _) algorithm
2329 ✗ lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2330 ✗ dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2331 ✗ rhs := Expression.expSub(e1,e2);
2332 ✗ (rhs, _) := ExpressionSimplify.simplify1(rhs);
2333 expNull := DAE.RCONST(0.0);
2334 lowBound := DAE.RCONST(-1e21);
2335 ✗ dummyVar := BackendVariable.setVarMinMax(dummyVar, SOME(lowBound), SOME(expNull));
2336 ✗ then ({BackendDAE.SOLVED_EQUATION(lhs, rhs, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, dummyVar);
2337
2338 case DAE.RELATION(e1, DAE.LESSEQ(_), e2, _, _) algorithm
2339 1 lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2340 1 dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2341 1 rhs := Expression.expSub(e1,e2);
2342 1 (rhs, _) := ExpressionSimplify.simplify1(rhs);
2343 expNull := DAE.RCONST(0.0);
2344 lowBound := DAE.RCONST(-1e21);
2345 1 dummyVar := BackendVariable.setVarMinMax(dummyVar, SOME(lowBound), SOME(expNull));
2346 1 then ({BackendDAE.SOLVED_EQUATION(lhs, rhs, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, dummyVar);
2347
2348 case DAE.RELATION(e1, DAE.GREATER(_), e2, _, _) algorithm
2349 ✗ lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2350 ✗ dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2351 ✗ rhs := Expression.expSub(e2,e1);
2352 ✗ (rhs, _) := ExpressionSimplify.simplify1(rhs);
2353 expNull := DAE.RCONST(0.0);
2354 lowBound := DAE.RCONST(-1e21);
2355 ✗ dummyVar := BackendVariable.setVarMinMax(dummyVar, SOME(lowBound), SOME(expNull));
2356 ✗ then ({BackendDAE.SOLVED_EQUATION(lhs, rhs, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, dummyVar);
2357
2358 case DAE.RELATION(e1, DAE.GREATEREQ(_), e2, _, _) algorithm
2359 2 lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2360 2 dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2361 2 rhs := Expression.expSub(e2,e1);
2362 2 (rhs, _) := ExpressionSimplify.simplify(rhs);
2363 expNull := DAE.RCONST(0.0);
2364 lowBound := DAE.RCONST(-1e21);
2365 2 dummyVar := BackendVariable.setVarMinMax(dummyVar, SOME(lowBound), SOME(expNull));
2366 2 then ({BackendDAE.SOLVED_EQUATION(lhs, rhs, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, dummyVar);
2367
2368 case DAE.RELATION(e1, DAE.EQUAL(_), e2, _, _) algorithm
2369 1 lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2370 1 dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2371 1 rhs := Expression.expSub(e2,e1);
2372 1 (rhs, _) := ExpressionSimplify.simplify(rhs);
2373 expNull := DAE.RCONST(0.0);
2374 1 dummyVar := BackendVariable.setVarMinMax(dummyVar, SOME(expNull), SOME(expNull));
2375 1 then ({BackendDAE.SOLVED_EQUATION(lhs, rhs, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN)}, dummyVar);
2376
2377 case e1 as DAE.CREF(componentRef = cr) algorithm
2378 try
2379 40 (v, _) := BackendVariable.getVarSingle(cr, inVars);
2380 else
2381 ✗ (v, _) := BackendVariable.getVarSingle(cr, knvars);
2382 end try;
2383
2384 40 lhs := ComponentReferenceBasics.makeCrefIdent(conCrefName, DAE.T_REAL_DEFAULT, {});
2385 40 dummyVar := BackendDAE.VAR(lhs, conKind, DAE.OUTPUT(), DAE.NON_PARALLEL(), DAE.T_REAL_DEFAULT, NONE(), NONE(), {}, DAE.emptyElementSource, NONE(), NONE(), NONE(), NONE(), DAE.NON_CONNECTOR(), DAE.NOT_INNER_OUTER(), false, false, false);
2386 40 dummyVar := BackendVariable.mergeAliasVars(dummyVar, v, false, knvars);
2387 40 eqn := BackendDAE.SOLVED_EQUATION(lhs, e1, Source, BackendDAE.EQ_ATTR_DEFAULT_UNKNOWN);
2388
2389 then ({eqn}, dummyVar);
2390 else fail();
2391 end match;
2392 end generateResidualFromRelation;
2393
2394 public function makeTmpEqnForExp
2395 "
2396 author: Vitalij Ruge
2397 make and append an eqn and var for expression
2398 "
2399 input DAE.Exp iExp;
2400 input String name "var name";
2401 input Integer offset;
2402 input BackendDAE.EquationArray ieqns;
2403 input BackendDAE.Variables ivars;
2404 input BackendDAE.Shared ishared;
2405 input Boolean noPara = false;
2406 output DAE.Exp oExp;
2407 output BackendDAE.EquationArray oeqns = ieqns;
2408 output BackendDAE.Variables ovars = ivars;
2409 output BackendDAE.Shared oshared = ishared;
2410 //output BackendDAE.StrongComponent
2411 output Boolean update;
2412 output Boolean para = false;
2413 protected
2414 DAE.ComponentRef cr;
2415 BackendDAE.Var tmpvar;
2416 String name_ = "__OMC__" + intString(offset) + "$" + name;
2417 DAE.Exp y;
2418 BackendDAE.Equation eqn;
2419 list<BackendDAE.Var> eqnVars, eqnKnVars, inputsKnVars;
2420 BackendDAE.Variables knowVars;
2421 Boolean b;
2422
2423 algorithm
2424
2425 4259 (y, _) := ExpressionSimplify.simplify(iExp);
2426
2/2
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 3969 times.
4259 if makeTmpEqnForExp_rule(y) then
2427 update := true;
2428
2429 290 cr := ComponentReferenceBasics.makeCrefIdent(name_, DAE.T_REAL_DEFAULT , {});
2430 290 oExp := Expression.crefExp(cr);
2431
2432 290 tmpvar := BackendVariable.makeVar(cr);
2433 290 tmpvar := BackendVariable.setVarTS(tmpvar,SOME(BackendDAE.AVOID()));
2434
2435 290 eqn := BackendDAE.EQUATION(oExp, y, DAE.emptyElementSource, BackendDAE.EQ_ATTR_DEFAULT_DYNAMIC);
2436
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 281 times.
290 if Flags.isSet(Flags.DUMP_SIMPLIFY_LOOPS) then
2437 9 print(BackendDump.equationString(eqn) + " -- new eqn--\n");
2438 end if;
2439 290 eqnVars := equationVars(eqn, ivars);
2440
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 278 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 3 times.
290 b := listEmpty(eqnVars) and not Expression.expHasCref(y, DAE.crefTime);
2441 if b then
2442 9 knowVars := BackendVariable.daeGlobalKnownVars(oshared);
2443 9 eqnKnVars := equationVars(eqn, knowVars);
2444 9 (inputsKnVars,_) := List.splitOnTrue(eqnKnVars, BackendVariable.isInput);
2445 b := listEmpty(inputsKnVars);
2446 end if;
2447
2448 b := false "hack";
2449 if b then
2450 if noPara then
2451 oExp := ExpressionSimplify.simplify(iExp);
2452 update := false;
2453 else
2454 tmpvar := BackendVariable.setBindExp(tmpvar, SOME(y));
2455 tmpvar := BackendVariable.setVarKind(tmpvar, BackendDAE.PARAM());
2456 oshared := BackendVariable.addGlobalKnownVarDAE(tmpvar, oshared);
2457 para := true;
2458 end if;
2459 else
2460 290 oeqns := BackendEquation.add(eqn, oeqns);
2461 290 ovars := BackendVariable.addVar(tmpvar, ovars);
2462 end if;
2463
2464 else
2465 oExp := y;
2466 update := false;
2467 end if;
2468
2469 end makeTmpEqnForExp;
2470
2471 protected function makeTmpEqnForExp_rule
2472 input DAE.Exp inExp;
2473 output Boolean allowed;
2474 algorithm
2475
2476
6/6
✓ Branch 1 taken 4232 times.
✓ Branch 2 taken 27 times.
✓ Branch 4 taken 298 times.
✓ Branch 5 taken 3934 times.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 290 times.
4259 if Expression.isCref(inExp) or Expression.isConst(inExp) or Expression.isUnaryCref(inExp) then
2477 allowed := false;
2478 3969 return;
2479 end if;
2480
2481 allowed := match inExp
2482 local DAE.Exp e1, e2;
2483 case DAE.BINARY(e1,DAE.DIV(),e2)
2484 guard (Expression.isOne(e1) or Expression.isConstMinusOne(e1)) and (Expression.isCref(e2) or Expression.isUnaryCref(e2))
2485 then false;
2486 ✗ case DAE.CAST(exp=e1) then makeTmpEqnForExp_rule(e1);
2487 else true;
2488 end match;
2489
2490 end makeTmpEqnForExp_rule;
2491
2492 public function normalizationVec
2493 "
2494 author: Vitalij Ruge
2495 normalization of vector
2496 "
2497 input array<DAE.Exp> vec;
2498 input String name "var name";
2499 input Integer offset;
2500 input BackendDAE.EquationArray ieqns;
2501 input BackendDAE.Variables ivars;
2502 input BackendDAE.Shared ishared;
2503 output array<DAE.Exp> nvec;
2504 output BackendDAE.EquationArray oeqns;
2505 output BackendDAE.Variables ovars;
2506 output BackendDAE.Shared oshared;
2507 protected
2508 DAE.Exp len = Expression.lenVec(vec);
2509 algorithm
2510 ✗ (len,oeqns,ovars,oshared) := makeTmpEqnForExp(len, name, offset, ieqns, ivars,ishared);
2511 ✗ if Expression.isZero(len) then
2512 ✗ fail();
2513 end if;
2514 ✗ nvec := Array.map1(vec, Expression.makeDiv, len);
2515 end normalizationVec;
2516
2517 public function solveEquation "author: wbraun
2518 Solves an equation w.r.t. a component reference. All equations are transformed
2519 to a EQUATION(cref, exp).
2520 Algorithm, when and if-equation are left as they are."
2521 input BackendDAE.Equation eqn;
2522 input DAE.Exp crefExp;
2523 input Option<AvlTreePathFunction.Tree> functions;
2524 output BackendDAE.Equation outEqn;
2525 algorithm
2526 // kabdelhak: Why does every kind of equation produce a regular equation?
2527 outEqn := matchcontinue eqn
2528 local
2529 DAE.Exp e1, e2;
2530 DAE.Exp res;
2531 DAE.ComponentRef cref, cr;
2532 DAE.ElementSource source;
2533 BackendDAE.EquationAttributes eqAttr;
2534
2535 case BackendDAE.EQUATION(exp=e1, scalar=e2, source=source, attr=eqAttr) algorithm
2536
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
80 (res, _, {}, {}) := ExpressionSolve.solve2(e1, e2, crefExp, functions, NONE());
2537 80 then BackendDAE.EQUATION(crefExp, res, source, eqAttr);
2538
2539 case BackendDAE.ARRAY_EQUATION(left=e1, right=e2, source=source, attr=eqAttr) algorithm
2540 ✗ (res, _, {}, {}) := ExpressionSolve.solve2(e1, e2, crefExp, functions, NONE());
2541 ✗ then (BackendDAE.EQUATION(crefExp, res, source, eqAttr));
2542
2543 case BackendDAE.SOLVED_EQUATION(componentRef=cref, exp=e2, source=source, attr=eqAttr) algorithm
2544 ✗ cr := Expression.expCref(crefExp);
2545 ✗ true := ComponentReferenceBasics.crefEqual(cref, cr);
2546 ✗ then (BackendDAE.EQUATION(crefExp, e2, source, eqAttr));
2547
2548 case BackendDAE.SOLVED_EQUATION(componentRef=cref, exp=e2, source=source, attr=eqAttr) algorithm
2549 // already checked in rule above:
2550 //cr = Expression.expCref(crefExp);
2551 //false = ComponentReferenceBasics.crefEqual(cref, cr);
2552 ✗ e1 := Expression.crefExp(cref);
2553 ✗ (res, _, {}, {}) := ExpressionSolve.solve2(e1, e2, crefExp, functions, NONE());
2554 ✗ then (BackendDAE.EQUATION(crefExp, res, source, eqAttr));
2555
2556 case BackendDAE.RESIDUAL_EQUATION(exp=e2, source=source, attr=eqAttr) algorithm
2557 ✗ e1 := Expression.makeConstZero(Expression.typeof(e2));
2558 ✗ (res, _, {}, {}) := ExpressionSolve.solve2(e2, e1, crefExp, functions, NONE());
2559 ✗ then (BackendDAE.EQUATION(crefExp, res, source, eqAttr));
2560
2561 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=eqAttr) algorithm
2562 ✗ (res, _, {}, {}) := ExpressionSolve.solve2(e1, e2, crefExp, functions, NONE());
2563 ✗ then (BackendDAE.EQUATION(crefExp, res, source, eqAttr));
2564 /* These won't get solved
2565 BackendDAE.ALGORITHM
2566 BackendDAE.WHEN_EQUATION
2567 BackendDAE.IF_EQUATION
2568 */
2569 else algorithm
2570 ✗ BackendDump.dumpBackendDAEEqnList({eqn}, "function BackendEquation.solveEquation failed w.r.t " + ExpressionBasics.printExpStr(crefExp), true);
2571 ✗ Error.addInternalError("function solveEquation failed", sourceInfo());
2572 ✗ then fail();
2573 end matchcontinue;
2574 end solveEquation;
2575
2576 public function generateRESIDUAL_EQUATION "author: Frenkel TUD 2010-05"
2577 input DAE.Exp inExp;
2578 input DAE.ElementSource inSource;
2579 input BackendDAE.EquationAttributes inEqAttr;
2580 output BackendDAE.Equation outEqn;
2581 algorithm
2582 7 outEqn := BackendDAE.RESIDUAL_EQUATION(inExp, inSource, inEqAttr);
2583 end generateRESIDUAL_EQUATION;
2584
2585 public function generateRESIDUAL_EQUATION1
2586 input tuple<DAE.Exp, DAE.Exp> inTpl;
2587 input DAE.ElementSource source;
2588 input BackendDAE.EquationAttributes inEqAttr;
2589 output BackendDAE.Equation outEqn;
2590 protected
2591 DAE.Exp e1, e2, e;
2592 algorithm
2593 ✗ (e1, e2) := inTpl;
2594 ✗ e := Expression.createResidualExp(e1, e2);
2595 ✗ outEqn := BackendDAE.RESIDUAL_EQUATION(e, source, inEqAttr);
2596 end generateRESIDUAL_EQUATION1;
2597
2598 public function equationSystemsEqnsLst
2599 input BackendDAE.EqSystems systs;
2600 output list<BackendDAE.Equation> outEqns = {};
2601 protected
2602 list<BackendDAE.Equation> eqns;
2603 BackendDAE.EquationArray eq;
2604 algorithm
2605 ✗ for es in systs loop
2606 ✗ BackendDAE.EQSYSTEM(orderedEqs=eq) := es;
2607 ✗ eqns := equationList(eq);
2608 ✗ outEqns := List.append_reverse(eqns, outEqns);
2609 end for;
2610 ✗ outEqns := MetaModelica.Dangerous.listReverseInPlace(outEqns);
2611 end equationSystemsEqnsLst;
2612
2613 public function getEqnsFromEqSystems "
2614 Extracts the orderedEqs attribute from an equation system."
2615 input BackendDAE.EqSystems inEqSystems;
2616 output BackendDAE.EquationArray outOrderedEqs;
2617 algorithm
2618 ✗ outOrderedEqs := listEquation(equationSystemsEqnsLst(inEqSystems));
2619 end getEqnsFromEqSystems;
2620
2621 public function getEqnsFromEqSystem "
2622 Extracts the orderedEqs attribute from an equation system."
2623 input BackendDAE.EqSystem inEqSystem;
2624 output BackendDAE.EquationArray outOrderedEqs = inEqSystem.orderedEqs;
2625 end getEqnsFromEqSystem;
2626
2627 public function getInitialEqnsFromShared "
2628 Extracts the initial equations from a shared object."
2629 input BackendDAE.Shared inShared;
2630 output BackendDAE.EquationArray outInitialEqs = inShared.initialEqs;
2631 end getInitialEqnsFromShared;
2632
2633 public function aliasEquation "author Frenkel TUD 2011-04
2634 Returns the two sides of an alias equation as expressions and cref.
2635 If the equation is not simple, this function will fail."
2636 input BackendDAE.Equation inEqn;
2637 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2638 algorithm
2639 outTpls := match inEqn
2640 local
2641 DAE.Exp e, e1, e2;
2642 DAE.ComponentRef cr;
2643
2644 case BackendDAE.EQUATION(exp=e1, scalar=e2)
2645 ✗ then aliasEquation1(e1, e2, {});
2646
2647 case BackendDAE.ARRAY_EQUATION(left=e1, right=e2)
2648 ✗ then aliasEquation1(e1, e2, {});
2649
2650 case BackendDAE.SOLVED_EQUATION(componentRef=cr, exp=e2) algorithm
2651 ✗ e := Expression.crefExp(cr);
2652 ✗ then aliasEquation1(e, e2, {});
2653
2654 case BackendDAE.RESIDUAL_EQUATION(exp=e1)
2655 ✗ then aliasExpression(e1, {});
2656
2657 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2)
2658 ✗ then aliasEquation1(e1, e2, {});
2659 end match;
2660 end aliasEquation;
2661
2662 protected function aliasEquation1 "author Frenkel TUD 2011-04
2663 helper for aliasEquation"
2664 input DAE.Exp lhs;
2665 input DAE.Exp rhs;
2666 input list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> inTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2667 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2668 algorithm
2669 outTpls := match (lhs, rhs)
2670 local
2671 DAE.ComponentRef cr1, cr2;
2672 DAE.Exp e1, e2;
2673 DAE.Operator op;
2674 list<DAE.Exp> elst1, elst2;
2675 list<list<DAE.Exp>> elstlst1, elstlst2;
2676 list<DAE.Var> varLst1, varLst2;
2677 Absyn.Path patha, patha1, pathb, pathb1;
2678
2679 // a = b;
2680 case (DAE.CREF(componentRef = cr1), DAE.CREF(componentRef = cr2))
2681 ✗ then (cr1, cr2, lhs, rhs, false)::inTpls;
2682
2683 // a = -b;
2684 case (DAE.CREF(componentRef = cr1), DAE.UNARY(op as DAE.UMINUS(_), DAE.CREF(componentRef = cr2)))
2685 ✗ then (cr1, cr2, DAE.UNARY(op, lhs), rhs, true)::inTpls;
2686
2687 case (DAE.CREF(componentRef = cr1), DAE.UNARY(op as DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr2)))
2688 ✗ then (cr1, cr2, DAE.UNARY(op, lhs), rhs, true)::inTpls;
2689
2690 // -a = b;
2691 case (DAE.UNARY(op as DAE.UMINUS(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
2692 ✗ then (cr1, cr2, lhs, DAE.UNARY(op, rhs), true)::inTpls;
2693
2694 case (DAE.UNARY(op as DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
2695 ✗ then (cr1, cr2, lhs, DAE.UNARY(op, rhs), true)::inTpls;
2696
2697 // -a = -b;
2698 case (DAE.UNARY(DAE.UMINUS(_), e1 as DAE.CREF(componentRef = cr1)), DAE.UNARY(DAE.UMINUS(_), e2 as DAE.CREF(componentRef = cr2)))
2699 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2700
2701 case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF(componentRef = cr2)))
2702 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2703
2704 // a = not b;
2705 case (DAE.CREF(componentRef = cr1), DAE.LUNARY(op as DAE.NOT(_), DAE.CREF(componentRef = cr2)))
2706 ✗ then (cr1, cr2, DAE.LUNARY(op, lhs), rhs, true)::inTpls;
2707
2708 // not a = b;
2709 case (DAE.LUNARY(op as DAE.NOT(_), DAE.CREF(componentRef = cr1)), DAE.CREF(componentRef = cr2))
2710 ✗ then (cr1, cr2, lhs, DAE.LUNARY(op, rhs), true)::inTpls;
2711
2712 // not a = not b;
2713 case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF(componentRef = cr1)), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF(componentRef = cr2)))
2714 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2715
2716 // {a1, a2, a3, ..} = {b1, b2, b3, ..};
2717 case (DAE.ARRAY(array = elst1), DAE.ARRAY(array = elst2))
2718 ✗ then List.threadFold(elst1, elst2, aliasEquation1, inTpls);
2719
2720 case (DAE.MATRIX(matrix = elstlst1), DAE.MATRIX(matrix = elstlst2))
2721 ✗ then List.threadFold(elstlst1, elstlst2, aliasEquationLst, inTpls);
2722
2723 // a = {b1, b2, b3, ..}
2724 //case (DAE.CREF(componentRef = cr1), DAE.ARRAY(array = elst2, dims=dims), _)
2725 //then // aliasArray(cr1, false, elst2, dims, inTpls);
2726
2727 // -a = {b1, b2, b3, ..}
2728 //case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ARRAY(array = elst2, dims=dims), _)
2729 //then // aliasArray(cr1, true, elst2, dims, inTpls);
2730
2731 // a = -{b1, b2, b3, ..}
2732 //case (DAE.CREF(componentRef = cr1), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.ARRAY(array = elst2, ty=ty)), _)
2733
2734 // -a = -{b1, b2, b3, ..}
2735 //case (DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.UNARY(DAE.UMINUS_ARR(_), DAE.ARRAY(array = elst2, ty=ty)), _)
2736
2737 // {a1, a2, a3, ..} = b
2738 //case (DAE.ARRAY(array = elst1), DAE.CREF(componentRef = cr2), _)
2739
2740 // -{a1, a2, a3, ..} = b
2741 //case (DAE.UNARY(DAE.UMINUS_ARR(_), DAE.ARRAY(array = elst1, ty=ty)), DAE.CREF(componentRef = cr2), _)
2742
2743 // {a1, a2, a3, ..} = -b
2744 //case (DAE.ARRAY(array = elst1), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF(componentRef = cr2)), _)
2745
2746 // -{a1, a2, a3, ..} = -b
2747 //case (DAE.UNARY(DAE.UMINUS_ARR(_)DAE.ARRAY(array = elst1, ty=ty)), DAE.UNARY(DAE.UMINUS_ARR(_), e2 as DAE.CREF(componentRef = cr2)), _)
2748
2749 // not a = {b1, b2, b3, ..}
2750 //case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ARRAY(array = elst2, ty=ty), _)
2751
2752 // a = not {b1, b2, b3, ..}
2753 //case (DAE.CREF(componentRef = cr1), DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(array = elst2, ty=ty)), _)
2754
2755 // not a = not {b1, b2, b3, ..}
2756 //case (DAE.LUNARY(DAE.NOT(_), e1 as DAE.CREF(componentRef = cr1)), DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(array = elst2, ty=ty)), _)
2757
2758 // {a1, a2, a3, ..} = not b
2759 //case (DAE.ARRAY(array = elst1, ty=ty), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF(componentRef = cr2)), _)
2760
2761 // not {a1, a2, a3, ..} = b
2762 //case (DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(array = elst1, ty=ty)), DAE.CREF(componentRef = cr2), _)
2763
2764 // not {a1, a2, a3, ..} = not b
2765 //case (DAE.LUNARY(DAE.NOT(_), DAE.ARRAY(array = elst1, ty=ty)), DAE.LUNARY(DAE.NOT(_), e2 as DAE.CREF(componentRef = cr2)), _)
2766
2767 // a = Record(b1, b2, b3, ..)
2768 case (DAE.CREF(componentRef = cr1), DAE.CALL(path=pathb, expLst=elst2, attr=DAE.CALL_ATTR(ty=DAE.T_COMPLEX(varLst=varLst2, complexClassType=ClassInf.RECORD(pathb1)))))
2769 guard AbsynUtil.pathEqual(pathb, pathb1)
2770 ✗ then aliasRecord(cr1, varLst2, elst2, inTpls);
2771
2772 // Record(a1, a2, a3, ..) = b
2773 case (DAE.CALL(path=patha, expLst=elst1, attr=DAE.CALL_ATTR(ty=DAE.T_COMPLEX(varLst=varLst1, complexClassType=ClassInf.RECORD(patha1)))), DAE.CREF(componentRef = cr2))
2774 guard AbsynUtil.pathEqual(patha, patha1)
2775 ✗ then aliasRecord(cr2, varLst1, elst1, inTpls);
2776
2777 // Record(a1, a2, a3, ..) = Record(b1, b2, b3, ..)
2778 case (DAE.CALL(path=patha, expLst=elst1, attr=DAE.CALL_ATTR(ty=DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(patha1)))), DAE.CALL(path=pathb, expLst=elst2, attr=DAE.CALL_ATTR(ty=DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(pathb1)))))
2779 guard AbsynUtil.pathEqual(patha, patha1) and AbsynUtil.pathEqual(pathb, pathb1)
2780 ✗ then List.threadFold(elst1, elst2, aliasEquation1, inTpls);
2781
2782 // matchcontinue part
2783 ✗ else aliasEquation2(lhs, rhs, inTpls);
2784 end match;
2785 end aliasEquation1;
2786
2787 protected function aliasEquationLst "author Frenkel TUD 2011-04
2788 helper for aliasEquation"
2789 input list<DAE.Exp> elst1;
2790 input list<DAE.Exp> elst2;
2791 input list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> inTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2792 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2793 algorithm
2794 ✗ outTpls := List.threadFold(elst1, elst2, aliasEquation1, inTpls);
2795 end aliasEquationLst;
2796
2797 protected function aliasEquation2 "author Frenkel TUD 2011-04
2798 helper for aliasEquation"
2799 input DAE.Exp lhs;
2800 input DAE.Exp rhs;
2801 input list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> inTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2802 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2803 algorithm
2804 outTpls := match (lhs, rhs)
2805 local
2806 list<DAE.Exp> elst1, elst2;
2807
2808 // {a1+b1, a2+b2, a3+b3, ..} = 0;
2809 case (DAE.ARRAY(array = elst1), _) guard
2810 Expression.isZero(rhs)
2811 ✗ then List.fold(elst1, aliasExpression, inTpls);
2812
2813 // 0 = {a1+b1, a2+b2, a3+b3, ..};
2814 case (_, DAE.ARRAY(array = elst2)) guard
2815 Expression.isZero(lhs)
2816 ✗ then List.fold(elst2, aliasExpression, inTpls);
2817
2818 // lhs = 0
2819 case (_, _) guard
2820 Expression.isZero(rhs)
2821 ✗ then aliasExpression(lhs, inTpls);
2822
2823 // 0 = rhs
2824 case (_, _) guard
2825 Expression.isZero(lhs)
2826 ✗ then aliasExpression(rhs, inTpls);
2827 end match;
2828 end aliasEquation2;
2829
2830 protected function aliasRecord "author Frenkel TUD 2011-04
2831 helper for aliasEquation"
2832 input DAE.ComponentRef cr;
2833 input list<DAE.Var> varLst;
2834 input list<DAE.Exp> explst;
2835 input list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> inTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2836 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2837 algorithm
2838 outTpls := match (varLst, explst)
2839 local
2840 DAE.ComponentRef cr1, cr2;
2841 DAE.Exp e1, e2;
2842 DAE.Type ty;
2843 DAE.Operator op;
2844 list<DAE.Exp> elst;
2845 list<DAE.Var> vlst;
2846 DAE.Ident ident;
2847
2848 case ({}, {})
2849 then inTpls;
2850
2851 // a = b
2852 case (DAE.TYPES_VAR(name=ident, ty=ty)::vlst, (e2 as DAE.CREF(componentRef = cr2))::elst) algorithm
2853 ✗ cr1 := ComponentReference.crefPrependIdent(cr, ident, {}, ty);
2854 ✗ e1 := DAE.CREF(cr1, ty);
2855 ✗ then aliasRecord(cr, vlst, elst, (cr1, cr2, e1, e2, false)::inTpls);
2856
2857 // a = -b
2858 case (DAE.TYPES_VAR(name=ident, ty=ty)::vlst, (e2 as DAE.UNARY(op as DAE.UMINUS(_), DAE.CREF(componentRef = cr2)))::elst) algorithm
2859 ✗ cr1 := ComponentReference.crefPrependIdent(cr, ident, {}, ty);
2860 ✗ e1 := DAE.UNARY(op, DAE.CREF(cr1, ty));
2861 ✗ then aliasRecord(cr, vlst, elst, (cr1, cr2, e1, e2, true)::inTpls);
2862
2863 case (DAE.TYPES_VAR(name=ident, ty=ty)::vlst, (e2 as DAE.UNARY(op as DAE.UMINUS_ARR(_), DAE.CREF(componentRef = cr2)))::elst) algorithm
2864 ✗ cr1 := ComponentReference.crefPrependIdent(cr, ident, {}, ty);
2865 ✗ e1 := DAE.UNARY(op, DAE.CREF(cr1, ty));
2866 ✗ then aliasRecord(cr, vlst, elst, (cr1, cr2, e1, e2, true)::inTpls);
2867
2868 // a = not b
2869 case (DAE.TYPES_VAR(name=ident, ty=ty)::vlst, (e2 as DAE.LUNARY(op as DAE.NOT(_), DAE.CREF(componentRef = cr2)))::elst) algorithm
2870 ✗ cr1 := ComponentReference.crefPrependIdent(cr, ident, {}, ty);
2871 ✗ e1 := DAE.LUNARY(op, DAE.CREF(cr1, ty));
2872 ✗ then aliasRecord(cr, vlst, elst, (cr1, cr2, e1, e2, true)::inTpls);
2873
2874 // a = {b1, b2, b3}
2875 end match;
2876 end aliasRecord;
2877
2878 protected function aliasExpression "author Frenkel TUD 2011-11
2879 Returns the two sides of an alias expression as expressions and cref.
2880 If the expression is not simple, this function will fail."
2881 input DAE.Exp exp;
2882 input list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> inTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2883 output list<tuple<DAE.ComponentRef, DAE.ComponentRef, DAE.Exp, DAE.Exp, Boolean>> outTpls "(cr1, cr2, cr1=e2, cr2=e1, true if negated alias)";
2884 algorithm
2885 outTpls := match exp
2886 local
2887 DAE.ComponentRef cr1, cr2;
2888 DAE.Exp e1, e2;
2889 DAE.Type ty;
2890
2891 // a + b
2892 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.ADD(ty=ty), e2 as DAE.CREF(componentRef = cr2))
2893 ✗ then (cr1, cr2, DAE.UNARY(DAE.UMINUS(ty), e1), DAE.UNARY(DAE.UMINUS(ty), e2), true)::inTpls;
2894
2895 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.ADD_ARR(ty=ty), e2 as DAE.CREF(componentRef = cr2))
2896 ✗ then (cr1, cr2, DAE.UNARY(DAE.UMINUS_ARR(ty), e1), DAE.UNARY(DAE.UMINUS_ARR(ty), e2), true)::inTpls;
2897
2898 // a - b
2899 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.SUB(), e2 as DAE.CREF(componentRef = cr2))
2900 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2901
2902 case DAE.BINARY(e1 as DAE.CREF(componentRef = cr1), DAE.SUB_ARR(), e2 as DAE.CREF(componentRef = cr2))
2903 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2904
2905 // -a + b
2906 case DAE.BINARY(DAE.UNARY(DAE.UMINUS(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ADD(), e2 as DAE.CREF(componentRef = cr2))
2907 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2908
2909 case DAE.BINARY(DAE.UNARY(DAE.UMINUS_ARR(_), e1 as DAE.CREF(componentRef = cr1)), DAE.ADD_ARR(), e2 as DAE.CREF(componentRef = cr2))
2910 ✗ then (cr1, cr2, e1, e2, false)::inTpls;
2911
2912 // -a - b = 0
2913 case DAE.BINARY(e1 as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = cr1)), DAE.SUB(ty=ty), e2 as DAE.CREF(componentRef = cr2))
2914 ✗ then (cr1, cr2, e1, DAE.UNARY(DAE.UMINUS(ty), e2), true)::inTpls;
2915
2916 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))
2917 ✗ then (cr1, cr2, e1, DAE.UNARY(DAE.UMINUS_ARR(ty), e2), true)::inTpls;
2918 end match;
2919 end aliasExpression;
2920
2921 public function derivativeEquation "author Frenkel TUD 2011-04
2922 Returns the two sides of an derivative equation as expressions and cref.
2923 If the equation is not a derivative equation, this function will fail."
2924 input BackendDAE.Equation eqn;
2925 output DAE.ComponentRef cr;
2926 output DAE.ComponentRef dcr "the derivative of cr";
2927 output DAE.Exp e;
2928 output DAE.Exp de "der(cr)";
2929 output Boolean negate;
2930 algorithm
2931 (cr, dcr, e, de, negate) := match eqn
2932 local
2933 DAE.Exp ne, ne2;
2934
2935 // a = der(b);
2936 case BackendDAE.EQUATION(exp=e as DAE.CREF(componentRef = dcr), scalar=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}))
2937 then (cr, dcr, e, de, false);
2938
2939 // der(a) = b;
2940 case BackendDAE.EQUATION(exp=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), scalar=e as DAE.CREF(componentRef = dcr))
2941 then (cr, dcr, e, de, false);
2942
2943 // a = -der(b);
2944 case BackendDAE.EQUATION(exp=e as DAE.CREF(componentRef = dcr), scalar=de as DAE.UNARY(DAE.UMINUS(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}))) algorithm
2945 ✗ ne := Expression.negate(e);
2946 then (cr, dcr, ne, de, true);
2947
2948 case BackendDAE.EQUATION(exp=e as DAE.CREF(componentRef = dcr), scalar=de as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}))) algorithm
2949 ✗ ne := Expression.negate(e);
2950 then (cr, dcr, ne, de, true);
2951
2952 // -der(a) = b;
2953 case BackendDAE.EQUATION(exp=de as DAE.UNARY(DAE.UMINUS(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})), scalar=e as DAE.CREF(componentRef = dcr)) algorithm
2954 ✗ ne := Expression.negate(e);
2955 then (cr, dcr, ne, de, true);
2956
2957 case BackendDAE.EQUATION(exp=de as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})), scalar=e as DAE.CREF(componentRef = dcr)) algorithm
2958 ✗ ne := Expression.negate(e);
2959 then (cr, dcr, ne, de, true);
2960
2961 // -a = der(b);
2962 case BackendDAE.EQUATION(exp=e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = dcr)), scalar=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})) algorithm
2963 13 ne := Expression.negate(de);
2964 then (cr, dcr, e, ne, true);
2965
2966 case BackendDAE.EQUATION(exp=e as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = dcr)), scalar=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})) algorithm
2967 ✗ ne := Expression.negate(de);
2968 then (cr, dcr, e, ne, true);
2969
2970 // der(a) = -b;
2971 case BackendDAE.EQUATION(exp=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), scalar=e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = dcr))) algorithm
2972 43 ne := Expression.negate(de);
2973 then (cr, dcr, e, ne, true);
2974
2975 case BackendDAE.EQUATION(exp=de as DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}), scalar=e as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = dcr))) algorithm
2976 ✗ ne := Expression.negate(de);
2977 then (cr, dcr, e, ne, true);
2978
2979 // -a = -der(b);
2980 case BackendDAE.EQUATION(exp=e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = dcr)), scalar=de as DAE.UNARY(DAE.UMINUS(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}))) algorithm
2981 ✗ ne := Expression.negate(e);
2982 ✗ ne2 := Expression.negate(de);
2983 then (cr, dcr, ne, ne2, false);
2984
2985 case BackendDAE.EQUATION(exp=e as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = dcr)), scalar=de as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)}))) algorithm
2986 ✗ ne := Expression.negate(e);
2987 ✗ ne2 := Expression.negate(de);
2988 then (cr, dcr, ne, ne2, false);
2989
2990 // -der(a) = -b;
2991 case BackendDAE.EQUATION(exp=de as DAE.UNARY(DAE.UMINUS(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})), scalar=e as DAE.UNARY(DAE.UMINUS(_), DAE.CREF(componentRef = dcr))) algorithm
2992 ✗ ne := Expression.negate(e);
2993 ✗ ne2 := Expression.negate(de);
2994 then (cr, dcr, ne, ne2, false);
2995
2996 case BackendDAE.EQUATION(exp=de as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CALL(path = Absyn.IDENT(name = "der"), expLst = {DAE.CREF(componentRef = cr)})), scalar=e as DAE.UNARY(DAE.UMINUS_ARR(_), DAE.CREF(componentRef = dcr))) algorithm
2997 ✗ ne := Expression.negate(e);
2998 ✗ ne2 := Expression.negate(de);
2999 then (cr, dcr, ne, ne2, false);
3000 end match;
3001 end derivativeEquation;
3002
3003 public function addOperation "
3004 Adds symbolic transformation information to equation's source."
3005 input BackendDAE.Equation inEqn;
3006 input DAE.SymbolicOperation inSymOp;
3007 output BackendDAE.Equation outEqn;
3008 algorithm
3009 outEqn := match inEqn
3010 local
3011 BackendDAE.Equation eqn;
3012
3013 case eqn as BackendDAE.EQUATION() algorithm
3014 12580 eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3015 then eqn;
3016
3017 case eqn as BackendDAE.ARRAY_EQUATION() algorithm
3018 41 eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3019 then eqn;
3020
3021 case eqn as BackendDAE.SOLVED_EQUATION() algorithm
3022 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3023 then eqn;
3024
3025 case eqn as BackendDAE.RESIDUAL_EQUATION() algorithm
3026 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3027 then eqn;
3028
3029 case eqn as BackendDAE.ALGORITHM() algorithm
3030 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3031 then eqn;
3032
3033 case eqn as BackendDAE.WHEN_EQUATION() algorithm
3034 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3035 then eqn;
3036
3037 case eqn as BackendDAE.COMPLEX_EQUATION() algorithm
3038 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3039 then eqn;
3040
3041 case eqn as BackendDAE.IF_EQUATION() algorithm
3042 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3043 then eqn;
3044
3045 case eqn as BackendDAE.FOR_EQUATION() algorithm
3046 ✗ eqn.source := ElementSource.addSymbolicTransformation(eqn.source, inSymOp);
3047 then eqn;
3048
3049 else algorithm
3050 ✗ Error.addInternalError("BackendEquation.addOperation failed", sourceInfo());
3051 ✗ then fail();
3052 end match;
3053 end addOperation;
3054
3055 public function isEquationsSystem
3056 input BackendDAE.StrongComponent comp;
3057 output Boolean res;
3058 algorithm
3059 res := match comp
3060 case BackendDAE.EQUATIONSYSTEM() then true;
3061 else false;
3062 end match;
3063 end isEquationsSystem;
3064
3065 public function isTornSystem
3066 input BackendDAE.StrongComponent comp;
3067 output Boolean res;
3068 algorithm
3069 res := match comp
3070 case BackendDAE.TORNSYSTEM() then true;
3071 else false;
3072 end match;
3073 end isTornSystem;
3074
3075 public function isWhenEquation
3076 input BackendDAE.Equation inEqn;
3077 output Boolean b;
3078 algorithm
3079 b := match inEqn
3080 case BackendDAE.WHEN_EQUATION() then true;
3081 else false;
3082 end match;
3083 end isWhenEquation;
3084
3085 public function isWhenEquationOrDiscreteAlgorithm
3086 input BackendDAE.Equation inEqn;
3087 input BackendDAE.Variables vars;
3088 output Boolean b;
3089 algorithm
3090 b := matchcontinue inEqn
3091 local
3092 Boolean b1;
3093 list<DAE.Statement> stmts;
3094 list<DAE.ComponentRef> lhsCrefs;
3095 case BackendDAE.WHEN_EQUATION() then true;
3096 case BackendDAE.ALGORITHM(alg = DAE.ALGORITHM_STMTS(stmts))
3097 algorithm
3098 b1 := true;
3099
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 5 times.
23 for s in stmts loop
3100 18 (lhsCrefs,_) := Expression.extractCrefsStatment(s);
3101
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 16 times.
50 for c in lhsCrefs loop
3102
2/4
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
34 b1 := b1 and BackendVariable.isDiscrete(c,vars);
3103 end for;
3104 end for;
3105 then b1;
3106 else false;
3107 end matchcontinue;
3108 end isWhenEquationOrDiscreteAlgorithm;
3109
3110 public function isArrayEquation
3111 input BackendDAE.Equation inEqn;
3112 output Boolean b;
3113 algorithm
3114 b := match inEqn
3115 case BackendDAE.ARRAY_EQUATION() then true;
3116 else false;
3117 end match;
3118 end isArrayEquation;
3119
3120 public function isAlgorithm
3121 input BackendDAE.Equation inEqn;
3122 output Boolean b;
3123 algorithm
3124 b := match inEqn
3125 case BackendDAE.ALGORITHM() then true;
3126 else false;
3127 end match;
3128 end isAlgorithm;
3129
3130 public function isComplexEquation
3131 input BackendDAE.Equation inEqn;
3132 output Boolean b;
3133 algorithm
3134 b := match inEqn
3135 case BackendDAE.COMPLEX_EQUATION() then true;
3136 else false;
3137 end match;
3138 end isComplexEquation;
3139
3140 public function isEquation
3141 input BackendDAE.Equation inEqn;
3142 output Boolean b;
3143 algorithm
3144 b := match inEqn
3145 case BackendDAE.EQUATION() then true;
3146 else false;
3147 end match;
3148 end isEquation;
3149
3150 public function isNotAlgorithm
3151 input BackendDAE.Equation inEqn;
3152 output Boolean b;
3153 algorithm
3154 34942 b := not isAlgorithm(inEqn);
3155 end isNotAlgorithm;
3156
3157 public function markDifferentiated"sets differentiated=true in EquationAttributes"
3158 input BackendDAE.Equation inEqn;
3159 output BackendDAE.Equation outEqn;
3160 algorithm
3161 outEqn := match inEqn
3162 local
3163 BackendDAE.Equation eqn;
3164
3165 case eqn as BackendDAE.EQUATION() algorithm
3166 7513 eqn.attr := markDifferentiated2(eqn.attr);
3167 then eqn;
3168
3169 case eqn as BackendDAE.ARRAY_EQUATION() algorithm
3170 ✗ eqn.attr := markDifferentiated2(eqn.attr);
3171 then eqn;
3172
3173 case eqn as BackendDAE.SOLVED_EQUATION() algorithm
3174 ✗ eqn.attr := markDifferentiated2(eqn.attr);
3175 then eqn;
3176
3177 case eqn as BackendDAE.RESIDUAL_EQUATION() algorithm
3178 ✗ eqn.attr := markDifferentiated2(eqn.attr);
3179 then eqn;
3180
3181 case eqn as BackendDAE.COMPLEX_EQUATION() algorithm
3182 ✗ eqn.attr := markDifferentiated2(eqn.attr);
3183 then eqn;
3184
3185 case BackendDAE.ALGORITHM()
3186 then inEqn;
3187
3188 case BackendDAE.WHEN_EQUATION()
3189 then inEqn;
3190
3191 case eqn as BackendDAE.IF_EQUATION() algorithm
3192 ✗ eqn.attr := markDifferentiated2(eqn.attr);
3193 ✗ eqn.eqnstrue := List.mapList(eqn.eqnstrue, markDifferentiated);
3194 ✗ eqn.eqnsfalse := List.map(eqn.eqnsfalse, markDifferentiated);
3195 then eqn;
3196 end match;
3197 end markDifferentiated;
3198
3199 protected function markDifferentiated2
3200 input output BackendDAE.EquationAttributes attr;
3201 algorithm
3202 7513 attr.differentiated := true;
3203 end markDifferentiated2;
3204
3205 public function isDifferentiated
3206 input BackendDAE.Equation inEqn;
3207 output Boolean diffed;
3208 algorithm
3209 diffed := match inEqn
3210 local
3211 Boolean b;
3212 BackendDAE.Equation eqn;
3213 case BackendDAE.EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3214 case BackendDAE.ARRAY_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3215 case BackendDAE.SOLVED_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3216 case BackendDAE.RESIDUAL_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3217 case BackendDAE.COMPLEX_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3218 case BackendDAE.ALGORITHM(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b)) then b;
3219 case BackendDAE.WHEN_EQUATION(attr=BackendDAE.EQUATION_ATTRIBUTES(differentiated=b))then b;
3220 ✗ case BackendDAE.IF_EQUATION(eqnsfalse=eqn::_) then isDifferentiated(eqn);
3221 end match;
3222 end isDifferentiated;
3223
3224 public function replaceDerOpInEquationList
3225 "Replaces all der(cref) with $DER.cref in a list of equations."
3226 input list<BackendDAE.Equation> inEqns;
3227 output list<BackendDAE.Equation> outEqns;
3228 algorithm
3229 13325 (outEqns, ) := traverseExpsOfEquationList(inEqns, Expression.replaceDerOpInExpCond, NONE());
3230 end replaceDerOpInEquationList;
3231
3232 public function getEquationRHS"gets the right hand side expression of an equation.
3233 author:Waurich TUD 2014-10"
3234 input BackendDAE.Equation eq;
3235 output DAE.Exp rhs;
3236 algorithm
3237 rhs := match eq
3238 local
3239 DAE.Exp exp1;
3240 case BackendDAE.EQUATION(scalar = exp1)
3241 then exp1;
3242 case BackendDAE.ARRAY_EQUATION(right = exp1)
3243 then exp1;
3244 case BackendDAE.SOLVED_EQUATION(exp = exp1)
3245 then exp1;
3246 case BackendDAE.COMPLEX_EQUATION(right = exp1)
3247 then exp1;
3248 case BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS(condition=DAE.BCONST(bool=true),whenStmtLst={BackendDAE.ASSIGN(right=exp1)}))
3249 then exp1;
3250 else
3251 //equation print("BackendEquation.getEquationRHS failed!\n!");
3252 then fail();
3253 end match;
3254 end getEquationRHS;
3255
3256 public function getEquationLHS"gets the left hand side expression of an equation.
3257 author:Waurich TUD 2014-10"
3258 input BackendDAE.Equation eq;
3259 output DAE.Exp lhs;
3260 algorithm
3261 lhs := match eq
3262 local
3263 DAE.Exp exp1;
3264 DAE.ComponentRef cref;
3265 case BackendDAE.EQUATION(exp = exp1)
3266 then exp1;
3267 case BackendDAE.ARRAY_EQUATION(left = exp1)
3268 then exp1;
3269 case BackendDAE.SOLVED_EQUATION(componentRef = cref)
3270 92 then Expression.crefExp(cref);
3271 case BackendDAE.COMPLEX_EQUATION(left = exp1)
3272 then exp1;
3273 case BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS(condition=DAE.BCONST(bool=true),whenStmtLst={BackendDAE.ASSIGN(left=exp1)}))
3274 then exp1;
3275 else
3276 //equation print("BackendEquation.getEquationLHS failed!\n");
3277 then fail();
3278 end match;
3279 end getEquationLHS;
3280
3281 public function scalarComplexEquations
3282 "This function splits tuples and record in single equations,
3283 to avoid non-linear loops.
3284 e.g.: R(a,b) = R(2*x,3*y) => r.a = 2*x; r.b = 3*y
3285 (a,b) = (2*g(x)[1],3*g(x)[2]) => a = 2*g(x)[1]; b = 3*g(x)[2]
3286 Used after some equations have been differentiated.
3287 "
3288 input BackendDAE.Equation inEquation;
3289 input AvlTreePathFunction.Tree funcTree;
3290 output list<BackendDAE.Equation> outEquations;
3291 algorithm
3292
3293 outEquations := match inEquation
3294 local
3295 DAE.Exp e1, e2;
3296 DAE.ElementSource source;
3297 list<DAE.Exp> explst, explst2;
3298 list<BackendDAE.Equation> eqns;
3299 BackendDAE.EquationAttributes attr;
3300
3301 case BackendDAE.COMPLEX_EQUATION(left=DAE.TUPLE(explst), right=DAE.TUPLE(explst2), source=source, attr=attr)
3302 algorithm
3303
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 true := listLength(explst) == listLength(explst2);
3304 4 eqns := List.threadMap2(explst, explst2, generateEquation, source, attr);
3305 then eqns;
3306
3307 case BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source, attr=attr)
3308 guard ((Expression.isRecordCall(e1, funcTree) or Expression.isRecord(e1)) and
3309 (Expression.isRecordCall(e2, funcTree) or Expression.isRecord(e2))
3310 )
3311 algorithm
3312 27 explst := Expression.splitRecord(e1, Expression.typeof(e1));
3313 27 explst2 := Expression.splitRecord(e2, Expression.typeof(e2));
3314
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
27 true := listLength(explst) == listLength(explst2);
3315 27 eqns := List.threadMap2(explst, explst2, generateEquation, source, attr);
3316 then eqns;
3317
3318 else
3319 then {inEquation};
3320
3321 end match;
3322 end scalarComplexEquations;
3323
3324 public function allAlgorithmsLst
3325 input list<BackendDAE.Equation> eqn_lst;
3326 output Boolean b;
3327 algorithm
3328 b := match eqn_lst
3329 local
3330 list<BackendDAE.Equation> rest;
3331 case {} then true;
3332 case BackendDAE.ALGORITHM()::{} then true;
3333 ✗ case BackendDAE.ALGORITHM()::rest then allAlgorithmsLst(rest);
3334 else false;
3335 end match;
3336 end allAlgorithmsLst;
3337
3338 public function createResidualExp
3339 input BackendDAE.Equation eqn;
3340 output DAE.Exp res;
3341 algorithm
3342 res := match eqn
3343 local
3344 DAE.Exp e1, e2;
3345 DAE.ComponentRef cr;
3346 case BackendDAE.EQUATION(exp = e1, scalar = e2)
3347 7045 then Expression.createResidualExp(e1, e2);
3348 case BackendDAE.ARRAY_EQUATION(left = e1, right = e2)
3349 4 then Expression.createResidualExp(e1, e2);
3350 case BackendDAE.SOLVED_EQUATION(componentRef = cr, exp = e2)
3351 ✗ then Expression.createResidualExp(DAE.CREF(cr, ComponentReference.crefTypeFull(cr)), e2);
3352 case BackendDAE.RESIDUAL_EQUATION(exp = e1)
3353 then e1;
3354 case BackendDAE.COMPLEX_EQUATION(left = e1, right = e2)
3355 ✗ then Expression.createResidualExp(e1, e2);
3356 /*
3357 Need FOR_EXPRESSION for this?
3358 case BackendDAE.FOR_EQUATION()
3359 */
3360 else fail();
3361 end match;
3362 end createResidualExp;
3363
3364 public function hasAnyUnknown
3365 input BackendDAE.Equation eqn;
3366 input BackendDAE.Variables vars;
3367 output Boolean b;
3368 algorithm
3369 2 b := not listEmpty(equationVars(eqn, vars));
3370 end hasAnyUnknown;
3371
3372 annotation(__OpenModelica_Interface="backend");
3373 end BackendEquation;
3374