Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 12.4% 32 / 0 / 259
Functions: -% 0 / 1 / 1
Branches: 4.8% 6 / 0 / 126

OMCompiler/Compiler/Util/VarTransform.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 VarTransform
37 " file: VarTransform.mo
38 package: VarTransform
39 description: VarTransform contains a Binary Tree representation of variable replacements.
40
41
42 This module contain a Binary tree representation of variable replacements
43 along with some functions for performing replacements of variables in equations"
44
45 public import DAE;
46 public import HashTable2;
47 public import HashTable3;
48 public import SCode;
49 protected import MetaModelica.Dangerous.listReverseInPlace;
50
51 public
52 uniontype VariableReplacements
53 "VariableReplacements consists of a mapping between variables and expressions, the first binary tree of this type.
54 To eliminate a variable from an equation system a replacement rule varname->expression is added to this
55 datatype.
56 To be able to update these replacement rules incrementally a backward lookup mechanism is also required.
57 For instance, having a rule a->b and adding a rule b->c requires to find the first rule a->b and update it to
58 a->c. This is what the second binary tree is used for."
59 record REPLACEMENTS
60 HashTable2.HashTable hashTable "src -> dst, used for replacing. src is variable, dst is expression.";
61 HashTable3.HashTable invHashTable "dst -> list of sources. dst is a variable, sources are variables.";
62 end REPLACEMENTS;
63
64 end VariableReplacements;
65
66 protected import Absyn;
67 protected import BaseHashTable;
68 protected import ComponentReference;
69 protected import ComponentReferenceBasics;
70 //protected import Debug;
71 protected import Expression;
72 protected import ExpressionBasics;
73 protected import ExpressionDump;
74 protected import ExpressionSimplify;
75 protected import List;
76 protected import Util;
77
78 public function applyReplacementsDAE "Apply a set of replacement rules on a DAE "
79 input DAE.DAElist dae;
80 input VariableReplacements repl;
81 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
82 output DAE.DAElist outDae;
83 partial function FuncTypeExp_ExpToBoolean
84 input DAE.Exp inExp;
85 output Boolean outBoolean;
86 end FuncTypeExp_ExpToBoolean;
87 algorithm
88 outDae := match dae
89 local list<DAE.Element> elts;
90 case DAE.DAE(elementLst=elts)
91 algorithm
92 ✗ elts := applyReplacementsDAEElts(elts,repl,condExpFunc);
93 ✗ then (DAE.DAE(elts));
94 end match;
95 end applyReplacementsDAE;
96
97 public function applyReplacementsDAEElts "Help function to applyReplacementsDAE, goes though the element list"
98 input list<DAE.Element> inDae;
99 input VariableReplacements repl;
100 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
101 output list<DAE.Element> outDae;
102 partial function FuncTypeExp_ExpToBoolean
103 input DAE.Exp inExp;
104 output Boolean outBoolean;
105 end FuncTypeExp_ExpToBoolean;
106 algorithm
107 ✗ if BaseHashTable.hashTableCurrentSize(repl.hashTable)==0 then
108 outDae := inDae;
109 ✗ return;
110 end if;
111 ✗ outDae := list(match elt
112 local
113 DAE.ComponentRef cr,cr2,cr1,cr1_2;
114 list<DAE.Element> elist,elist2,elist22;
115 DAE.Element elt2;
116 DAE.VarKind kind;
117 DAE.VarDirection dir;
118 DAE.Type tp;
119 DAE.Exp bindExp,bindExp2,e,e2,e22,e1,e11,e3,e32;
120 DAE.InstDims dims;
121 DAE.ConnectorType ct;
122 DAE.ElementSource source "the origin of the element";
123 Option<DAE.VariableAttributes> attr;
124 Option<SCode.Comment> cmt;
125 Absyn.InnerOuter io;
126 Boolean ie;
127 DAE.Dimensions idims;
128 DAE.Ident id;
129 list<DAE.Statement> stmts,stmts2;
130 DAE.VarParallelism prl;
131 DAE.VarVisibility prot;
132 list<list<DAE.Element>> tbs,tbs_1;
133 list<DAE.Exp> conds,conds_1;
134
135 case DAE.VAR(cr,kind,dir,prl,prot,tp,SOME(bindExp),dims,ct,source,attr,cmt,io,ie)
136 algorithm
137 ✗ (bindExp2,_) := replaceExp(bindExp, repl, condExpFunc);
138 ✗ attr := applyReplacementsVarAttr(attr, repl, condExpFunc);
139 /* TODO: Add operation to source */
140 ✗ then DAE.VAR(cr,kind,dir,prl,prot,tp,SOME(bindExp2),dims,ct,source,attr,cmt,io,ie);
141
142 case DAE.VAR(cr,kind,dir,prl,prot,tp,NONE(),dims,ct,source,attr,cmt,io,ie)
143 algorithm
144 ✗ attr := applyReplacementsVarAttr(attr,repl,condExpFunc);
145 ✗ then DAE.VAR(cr,kind,dir,prl,prot,tp,NONE(),dims,ct,source,attr,cmt,io,ie);
146
147 case DAE.DEFINE(cr,e,source)
148 algorithm
149 ✗ (e2,_) := replaceExp(e, repl, condExpFunc);
150 ✗ (DAE.CREF(cr2,_),_) := replaceExp(Expression.crefExp(cr), repl, condExpFunc);
151 /* TODO: Add operation to source */
152 ✗ then DAE.DEFINE(cr2,e2,source);
153
154 case DAE.INITIALDEFINE(cr,e,source)
155 algorithm
156 ✗ (e2,_) := replaceExp(e, repl, condExpFunc);
157 ✗ (DAE.CREF(cr2,_),_) := replaceExp(Expression.crefExp(cr), repl, condExpFunc);
158 /* TODO: Add operation to source */
159 ✗ then DAE.INITIALDEFINE(cr2,e2,source);
160
161 case DAE.EQUEQUATION(cr,cr1,source)
162 algorithm
163 ✗ (DAE.CREF(cr2,_),_) := replaceExp(Expression.crefExp(cr), repl, condExpFunc);
164 ✗ (DAE.CREF(cr1_2,_),_) := replaceExp(Expression.crefExp(cr1), repl, condExpFunc);
165 /* TODO: Add operation to source */
166 ✗ then DAE.EQUEQUATION(cr2,cr1_2,source);
167
168 case DAE.EQUATION(e1,e2,source)
169 algorithm
170 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
171 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
172 /* TODO: Add operation to source */
173 ✗ then DAE.EQUATION(e11,e22,source);
174
175 case DAE.ARRAY_EQUATION(idims,e1,e2,source)
176 algorithm
177 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
178 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
179 /* TODO: Add operation to source */
180 ✗ then DAE.ARRAY_EQUATION(idims,e11,e22,source);
181
182 case DAE.INITIAL_ARRAY_EQUATION(idims,e1,e2,source)
183 algorithm
184 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
185 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
186 /* TODO: Add operation to source */
187 ✗ then DAE.INITIAL_ARRAY_EQUATION(idims,e11,e22,source);
188
189 case DAE.WHEN_EQUATION(e1,elist,SOME(elt2),source)
190 algorithm
191 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
192 /* TODO: Add operation to source */
193 ✗ {elt2} := applyReplacementsDAEElts({elt2},repl,condExpFunc);
194 ✗ elist2 := applyReplacementsDAEElts(elist,repl,condExpFunc);
195 ✗ then DAE.WHEN_EQUATION(e11,elist2,SOME(elt2),source);
196
197 case DAE.WHEN_EQUATION(e1,elist,NONE(),source)
198 algorithm
199 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
200 /* TODO: Add operation to source */
201 ✗ elist2 := applyReplacementsDAEElts(elist,repl,condExpFunc);
202 ✗ then DAE.WHEN_EQUATION(e11,elist2,NONE(),source);
203
204 case DAE.IF_EQUATION(conds,tbs,elist2,source)
205 algorithm
206 ✗ (conds_1,_) := replaceExpList(conds, repl, condExpFunc);
207 /* TODO: Add operation to source */
208 ✗ tbs_1 := List.map2(tbs,applyReplacementsDAEElts,repl,condExpFunc);
209 ✗ elist22 := applyReplacementsDAEElts(elist2,repl,condExpFunc);
210 ✗ then DAE.IF_EQUATION(conds_1,tbs_1,elist22,source);
211
212 case DAE.INITIAL_IF_EQUATION(conds,tbs,elist2,source)
213 algorithm
214 ✗ (conds_1,_) := replaceExpList(conds, repl, condExpFunc);
215 /* TODO: Add operation to source */
216 ✗ tbs_1 := List.map2(tbs,applyReplacementsDAEElts,repl,condExpFunc);
217 ✗ elist22 := applyReplacementsDAEElts(elist2,repl,condExpFunc);
218 ✗ then DAE.INITIAL_IF_EQUATION(conds_1,tbs_1,elist22,source);
219
220 case DAE.INITIALEQUATION(e1,e2,source)
221 algorithm
222 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
223 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
224 /* TODO: Add operation to source */
225 ✗ then DAE.INITIALEQUATION(e11,e22,source);
226
227 case DAE.ALGORITHM(DAE.ALGORITHM_STMTS(stmts),source)
228 algorithm
229 ✗ (stmts2,_) := replaceEquationsStmts(stmts,repl,condExpFunc);
230 /* TODO: Add operation to source */
231 ✗ then DAE.ALGORITHM(DAE.ALGORITHM_STMTS(stmts2),source);
232
233 case DAE.INITIALALGORITHM(DAE.ALGORITHM_STMTS(stmts),source)
234 algorithm
235 ✗ (stmts2,_) := replaceEquationsStmts(stmts,repl,condExpFunc);
236 /* TODO: Add operation to source */
237 ✗ then DAE.INITIALALGORITHM(DAE.ALGORITHM_STMTS(stmts2),source);
238
239 case DAE.COMP(id,elist,source,cmt)
240 algorithm
241 ✗ elist := applyReplacementsDAEElts(elist,repl,condExpFunc);
242 ✗ then DAE.COMP(id,elist,source,cmt);
243
244 case DAE.EXTOBJECTCLASS()
245 then elt;
246
247 case DAE.ASSERT(e1,e2,e3,source)
248 algorithm
249 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
250 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
251 ✗ (e32,_) := replaceExp(e3, repl, condExpFunc);
252 /* TODO: Add operation to source */
253 ✗ then DAE.ASSERT(e11,e22,e32,source);
254
255 case DAE.INITIAL_ASSERT(e1,e2,e3,source)
256 algorithm
257 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
258 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
259 ✗ (e32,_) := replaceExp(e3, repl, condExpFunc);
260 /* TODO: Add operation to source */
261 ✗ then DAE.INITIAL_ASSERT(e11,e22,e32,source);
262
263 case DAE.TERMINATE(e1,source)
264 algorithm
265 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
266 /* TODO: Add operation to source */
267 ✗ then DAE.TERMINATE(e11,source);
268
269 case DAE.INITIAL_TERMINATE(e1,source)
270 algorithm
271 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
272 /* TODO: Add operation to source */
273 ✗ then DAE.INITIAL_TERMINATE(e11,source);
274
275 case DAE.REINIT(cr,e1,source)
276 algorithm
277 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
278 /* TODO: Add operation to source */
279 ✗ (DAE.CREF(cr2,_),_) := replaceExp(Expression.crefExp(cr), repl, condExpFunc);
280 ✗ then DAE.REINIT(cr2,e11,source);
281
282 case DAE.COMPLEX_EQUATION(e1,e2,source)
283 algorithm
284 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
285 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
286 /* TODO: Add operation to source */
287 ✗ then DAE.COMPLEX_EQUATION(e11,e22,source);
288
289 case DAE.INITIAL_COMPLEX_EQUATION(e1,e2,source)
290 algorithm
291 ✗ (e11,_) := replaceExp(e1, repl, condExpFunc);
292 ✗ (e22,_) := replaceExp(e2, repl, condExpFunc);
293 /* TODO: Add operation to source */
294 ✗ then DAE.INITIAL_COMPLEX_EQUATION(e11,e22,source);
295
296 // failtrace. adrpo: TODO! FIXME! this SHOULD NOT FAIL!
297 else
298 algorithm
299 // Debug.fprintln(Flags.FAILTRACE, "- VarTransform.applyReplacementsDAEElts could not apply replacements to: " + DAEDump.dumpElementsStr({elt}));
300 ✗ Error.addInternalError("applyReplacementsDAEElts should not fail", sourceInfo());
301 ✗ then fail();
302 end match
303 for elt in inDae);
304 end applyReplacementsDAEElts;
305
306 protected function applyReplacementsVarAttr "Help function to applyReplacementsDAEElts"
307 input Option<DAE.VariableAttributes> attr;
308 input VariableReplacements repl;
309 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
310 output Option<DAE.VariableAttributes> outAttr;
311 partial function FuncTypeExp_ExpToBoolean
312 input DAE.Exp inExp;
313 output Boolean outBoolean;
314 end FuncTypeExp_ExpToBoolean;
315 algorithm
316 outAttr := match attr
317 local
318 Option<DAE.Exp> quantity,unit,displayUnit,min,max,initial_,fixed,nominal;
319 Option<DAE.StartOrigin> startOrigin;
320 Option<DAE.StateSelect> stateSelect;
321 Option<DAE.Uncertainty> unc;
322 Option<DAE.Distribution> dist;
323 Option<DAE.Exp> eb;
324 Option<Boolean> ip,fn;
325
326 case SOME(DAE.VAR_ATTR_REAL(quantity,unit,displayUnit,min,max,initial_,fixed,nominal,stateSelect,unc,dist,eb,ip,fn,startOrigin))
327 algorithm
328 ✗ quantity := replaceExpOpt(quantity,repl,condExpFunc);
329 ✗ unit := replaceExpOpt(unit,repl,condExpFunc);
330 ✗ displayUnit := replaceExpOpt(displayUnit,repl,condExpFunc);
331 ✗ min := replaceExpOpt(min,repl,condExpFunc);
332 ✗ max := replaceExpOpt(max,repl,condExpFunc);
333 ✗ initial_ := replaceExpOpt(initial_,repl,condExpFunc);
334 ✗ fixed := replaceExpOpt(fixed,repl,condExpFunc);
335 ✗ nominal := replaceExpOpt(nominal,repl,condExpFunc);
336 //TODO: replace expressions also in uncertainty attributes (unc and dist)
337 ✗ then SOME(DAE.VAR_ATTR_REAL(quantity,unit,displayUnit,min,max,initial_,fixed,nominal,stateSelect,unc,dist,eb,ip,fn,startOrigin));
338
339 case SOME(DAE.VAR_ATTR_INT(quantity,min,max,initial_,fixed,unc,dist,eb,ip,fn,startOrigin))
340 algorithm
341 ✗ quantity := replaceExpOpt(quantity,repl,condExpFunc);
342 ✗ min := replaceExpOpt(min,repl,condExpFunc);
343 ✗ max := replaceExpOpt(max,repl,condExpFunc);
344 ✗ initial_ := replaceExpOpt(initial_,repl,condExpFunc);
345 ✗ fixed := replaceExpOpt(fixed,repl,condExpFunc);
346 ✗ then SOME(DAE.VAR_ATTR_INT(quantity,min,max,initial_,fixed,unc,dist,eb,ip,fn,startOrigin));
347
348 case SOME(DAE.VAR_ATTR_BOOL(quantity,initial_,fixed,eb,ip,fn,startOrigin))
349 algorithm
350 ✗ quantity := replaceExpOpt(quantity,repl,condExpFunc);
351 ✗ initial_ := replaceExpOpt(initial_,repl,condExpFunc);
352 ✗ fixed := replaceExpOpt(fixed,repl,condExpFunc);
353 ✗ then SOME(DAE.VAR_ATTR_BOOL(quantity,initial_,fixed,eb,ip,fn,startOrigin));
354
355 case SOME(DAE.VAR_ATTR_STRING(quantity,initial_,fixed,eb,ip,fn,startOrigin))
356 algorithm
357 ✗ quantity := replaceExpOpt(quantity,repl,condExpFunc);
358 ✗ initial_ := replaceExpOpt(initial_,repl,condExpFunc);
359 ✗ fixed := replaceExpOpt(fixed,repl,condExpFunc);
360 ✗ then SOME(DAE.VAR_ATTR_STRING(quantity,initial_,fixed,eb,ip,fn,startOrigin));
361
362 case NONE() then NONE();
363 end match;
364 end applyReplacementsVarAttr;
365
366 public function applyReplacements "This function takes a VariableReplacements and two component references.
367 It applies the replacements to each component reference.
368 "
369 input VariableReplacements inVariableReplacements1;
370 input DAE.ComponentRef inComponentRef2;
371 input DAE.ComponentRef inComponentRef3;
372 output DAE.ComponentRef outComponentRef1;
373 output DAE.ComponentRef outComponentRef2;
374 algorithm
375 (outComponentRef1,outComponentRef2):=
376 match (inVariableReplacements1,inComponentRef2,inComponentRef3)
377 local
378 DAE.ComponentRef cr1_1,cr2_1,cr1,cr2;
379 VariableReplacements repl;
380 case (repl,cr1,cr2)
381 algorithm
382 ✗ (DAE.CREF(cr1_1,_),_) := replaceExp(Expression.crefExp(cr1), repl,NONE());
383 ✗ (DAE.CREF(cr2_1,_),_) := replaceExp(Expression.crefExp(cr2), repl,NONE());
384 then
385 (cr1_1,cr2_1);
386 end match;
387 end applyReplacements;
388
389 public function applyReplacementList " Author: BZ, 2008-11
390
391 This function takes a VariableReplacements and a list of component references.
392 It applies the replacements to each component reference.
393 "
394 input VariableReplacements repl;
395 input list<DAE.ComponentRef> increfs;
396 output list<DAE.ComponentRef> ocrefs;
397 algorithm ocrefs:= match increfs
398 local
399 DAE.ComponentRef cr1_1,cr1;
400 case {} then {};
401 case cr1::ocrefs
402 algorithm
403 ✗ (DAE.CREF(cr1_1,_),_) := replaceExp(Expression.crefExp(cr1), repl,NONE());
404 ✗ ocrefs := applyReplacementList(repl,ocrefs);
405 then
406 cr1_1::ocrefs;
407 end match;
408 end applyReplacementList;
409
410 public function applyReplacementsExp "
411
412 Similar to applyReplacements but for expressions instead of component references.
413 "
414 input VariableReplacements repl;
415 input DAE.Exp inExp1;
416 input DAE.Exp inExp2;
417 output DAE.Exp outExp1;
418 output DAE.Exp outExp2;
419 algorithm
420 (outExp1,outExp2):=
421 match (inExp1, inExp2)
422 local
423 DAE.Exp e1,e2;
424 case (e1, e2)
425 algorithm
426 ✗ (e1,_) := replaceExp(e1, repl, NONE());
427 ✗ (e2,_) := replaceExp(e2, repl, NONE());
428 ✗ (e1,_) := ExpressionSimplify.simplify1(e1);
429 ✗ (e2,_) := ExpressionSimplify.simplify1(e2);
430 then
431 (e1,e2);
432 end match;
433 end applyReplacementsExp;
434
435 public function emptyReplacementsArray "create an array of n empty replacements"
436 input Integer n;
437 output array<VariableReplacements> repl;
438 algorithm
439 ✗ repl := listArray(emptyReplacementsArray2(n));
440 end emptyReplacementsArray;
441
442 protected function emptyReplacementsArray2 "help function"
443 input Integer n;
444 output list<VariableReplacements> replLst;
445 algorithm
446 replLst := matchcontinue n
447 local VariableReplacements r;
448 case 0 then {};
449 case _
450 algorithm
451 ✗ true := n < 0;
452 ✗ print("Internal error, emptyReplacementsArray2 called with negative n!");
453 ✗ then fail();
454 else
455 algorithm
456 ✗ true := n > 0;
457 ✗ r := emptyReplacements();
458 ✗ replLst := emptyReplacementsArray2(n-1);
459 then r::replLst;
460 end matchcontinue;
461 end emptyReplacementsArray2;
462
463 public function emptyReplacements "
464 Returns an empty set of replacement rules
465 "
466 output VariableReplacements outVariableReplacements;
467 algorithm
468 outVariableReplacements:=
469 match ()
470 local HashTable2.HashTable ht;
471 HashTable3.HashTable invHt;
472 case ()
473 algorithm
474 355 ht := HashTable2.emptyHashTable();
475 355 invHt := HashTable3.emptyHashTable();
476 355 then
477 REPLACEMENTS(ht,invHt);
478 end match;
479 end emptyReplacements;
480
481 public function emptyReplacementsSized "
482 Returns an empty set of replacement rules, giving a size of hashtables to allocate
483 "
484 input Integer size;
485 output VariableReplacements outVariableReplacements;
486 algorithm
487 outVariableReplacements:=
488 match size
489 local HashTable2.HashTable ht;
490 HashTable3.HashTable invHt;
491 case _
492 algorithm
493 ✗ ht := HashTable2.emptyHashTableSized(size);
494 ✗ invHt := HashTable3.emptyHashTableSized(size);
495 ✗ then
496 REPLACEMENTS(ht,invHt);
497 end match;
498 end emptyReplacementsSized;
499
500 public function replaceEquationsStmts "
501 Helper function to replace_equations,
502 Handles the replacement of DAE.Statement.
503 "
504 input list<DAE.Statement> inAlgorithmStatementLst;
505 input VariableReplacements repl;
506 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
507 output list<DAE.Statement> outAlgorithmStatementLst;
508 output Boolean replacementPerformed;
509 partial function FuncTypeExp_ExpToBoolean
510 input DAE.Exp inExp;
511 output Boolean outBoolean;
512 end FuncTypeExp_ExpToBoolean;
513 algorithm
514 (outAlgorithmStatementLst,replacementPerformed) :=
515 matchcontinue inAlgorithmStatementLst
516 local
517 DAE.Exp e_1,e_2,e,e1,e2,e3,e_3;
518 list<DAE.Exp> expl1,expl2;
519 list<DAE.Statement> xs_1,xs,stmts,stmts2;
520 DAE.Type tp;
521 DAE.Statement x;
522 Boolean b1,b2,b3;
523 String id1;
524 DAE.ElementSource source;
525 Option<DAE.Statement> ew,ew_1;
526 list<DAE.ComponentRef> conditions;
527 Boolean initialCall,iterIsArray;
528 DAE.Else el,el_1;
529 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
530
531 case {} then ({},false);
532 case DAE.STMT_ASSIGN(type_ = tp,exp1 = e2,exp = e,source = source) :: xs
533 algorithm
534 ✗ (e_1,b1) := replaceExp(e, repl, condExpFunc);
535 ✗ (e_2,b2) := replaceExp(e2, repl, condExpFunc);
536 ✗ true := b1 or b2;
537 /* TODO: Add operation to source; do simplify? */
538 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
539 ✗ then
540 (DAE.STMT_ASSIGN(tp,e_2,e_1,source) :: xs_1,true);
541 case DAE.STMT_TUPLE_ASSIGN(type_ = tp,expExpLst = expl1, exp = e,source = source) :: xs
542 algorithm
543 ✗ (e_1,b1) := replaceExp(e, repl, condExpFunc);
544 ✗ (expl2,b2) := replaceExpList(expl1, repl, condExpFunc);
545 ✗ true := b1 or b2;
546 /* TODO: Add operation to source; do simplify? */
547 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
548 ✗ then
549 (DAE.STMT_TUPLE_ASSIGN(tp,expl2,e_1,source) :: xs_1,true);
550 case DAE.STMT_ASSIGN_ARR(type_ = tp, lhs = e1, exp = e2, source = source) :: xs
551 algorithm
552 ✗ (e_1,b1) := replaceExp(e1, repl, condExpFunc);
553 ✗ (e_2,b2) := replaceExp(e2, repl, condExpFunc);
554 ✗ true := b1 or b2;
555 /* TODO: Add operation to source; do simplify? */
556 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
557 ✗ then
558 (DAE.STMT_ASSIGN_ARR(tp,e_1,e_2,source) :: xs_1,true);
559 // case ((DAE.STMT_ASSIGN_ARR(type_ = tp,componentRef = cr, exp = e,source = source) :: xs),_,_)
560 // equation
561 // (e_1,true) = replaceExp(e, repl, condExpFunc);
562 // /* TODO: Add operation to source; do simplify? */
563 // (xs_1,_) = replaceEquationsStmts(xs, repl,condExpFunc);
564 // then
565 // (DAE.STMT_ASSIGN_ARR(tp,cr,e_1,source) :: xs_1,true);
566 case (DAE.STMT_IF(exp=e,statementLst=stmts,else_ = el,source = source)) :: xs
567 algorithm
568 ✗ (el_1,b1) := replaceEquationsElse(el,repl,condExpFunc);
569 ✗ (stmts2,b2) := replaceEquationsStmts(stmts,repl,condExpFunc);
570 ✗ (e_1,b3) := replaceExp(e, repl, condExpFunc);
571 ✗ true := b1 or b2 or b3;
572 /* TODO: Add operation to source; do simplify? */
573 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
574 ✗ then
575 (DAE.STMT_IF(e_1,stmts2,el_1,source) :: xs_1,true);
576 case (DAE.STMT_FOR(type_=tp,iterIsArray=iterIsArray,iter=id1,range=e,statementLst=stmts,source = source,sub_iters=sub_iters)) :: xs
577 algorithm
578 ✗ (stmts2,b1) := replaceEquationsStmts(stmts,repl,condExpFunc);
579 ✗ (e_1,b2) := replaceExp(e, repl, condExpFunc);
580 ✗ true := b1 or b2;
581 /* TODO: Add operation to source; do simplify? */
582 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
583 ✗ then
584 (DAE.STMT_FOR(tp,iterIsArray,id1,e_1,stmts2,source,sub_iters) :: xs_1,true);
585 case (DAE.STMT_WHILE(exp = e,statementLst=stmts,source = source)) :: xs
586 algorithm
587 ✗ (stmts2,b1) := replaceEquationsStmts(stmts,repl,condExpFunc);
588 ✗ (e_1,b2) := replaceExp(e, repl, condExpFunc);
589 ✗ true := b1 or b2;
590 /* TODO: Add operation to source; do simplify? */
591 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
592 ✗ then
593 (DAE.STMT_WHILE(e_1,stmts2,source) :: xs_1,true);
594 case (DAE.STMT_WHEN(exp=e,conditions=conditions,initialCall=initialCall,statementLst=stmts,elseWhen=ew,source=source))::xs
595 algorithm
596 ✗ (ew_1,b1) := replaceOptEquationsStmts(ew,repl,condExpFunc);
597 ✗ (stmts2,b2) := replaceEquationsStmts(stmts,repl,condExpFunc);
598 ✗ (e_1,b3) := replaceExp(e, repl, condExpFunc);
599 ✗ true := b1 or b2 or b3;
600 /* TODO: Add operation to source; do simplify? */
601 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
602 ✗ then
603 (DAE.STMT_WHEN(e_1,conditions,initialCall,stmts2,ew_1,source)::xs_1, true);
604 case (DAE.STMT_ASSERT(cond=e,msg=e2,level=e3,source=source)) :: xs
605 algorithm
606 ✗ (e_1,b1) := replaceExp(e, repl, condExpFunc);
607 ✗ (e_2,b2) := replaceExp(e2, repl, condExpFunc);
608 ✗ (e_3,b3) := replaceExp(e3, repl, condExpFunc);
609 ✗ true := b1 or b2 or b3;
610 /* TODO: Add operation to source; do simplify? */
611 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
612 ✗ then
613 (DAE.STMT_ASSERT(e_1,e_2,e_3,source) :: xs_1, true);
614 case (DAE.STMT_TERMINATE(msg = e,source = source)) :: xs
615 algorithm
616 ✗ (e_1,true) := replaceExp(e, repl, condExpFunc);
617 /* TODO: Add operation to source; do simplify? */
618 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
619 ✗ then
620 (DAE.STMT_TERMINATE(e_1,source) :: xs_1, true);
621
622 case (DAE.STMT_REINIT(var = e,value=e2,source = source)) :: xs
623 algorithm
624 ✗ (e_1,b1) := replaceExp(e, repl, condExpFunc);
625 ✗ (e_2,b2) := replaceExp(e2, repl, condExpFunc);
626 ✗ true := b1 or b2;
627 /* TODO: Add operation to source; do simplify? */
628 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
629 ✗ then
630 (DAE.STMT_REINIT(e_1,e_2,source) :: xs_1, true);
631
632 case (DAE.STMT_NORETCALL(exp = e,source = source)) :: xs
633 algorithm
634 ✗ (e_1,true) := replaceExp(e, repl, condExpFunc);
635 /* TODO: Add operation to source; do simplify? */
636 ✗ (xs_1,_) := replaceEquationsStmts(xs, repl,condExpFunc);
637 ✗ then
638 (DAE.STMT_NORETCALL(e_1,source) :: xs_1, true);
639
640 case x :: xs
641 algorithm
642 ✗ (xs_1, b1) := replaceEquationsStmts(xs, repl,condExpFunc);
643 ✗ then
644 (x :: xs_1, b1);
645 end matchcontinue;
646
647 end replaceEquationsStmts;
648
649 protected function replaceEquationsElse "
650 Helper function for replaceEquationsStmts, replaces DAE.Else"
651 input DAE.Else inElse;
652 input VariableReplacements repl;
653 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
654 output DAE.Else outElse;
655 output Boolean replacementPerformed;
656 partial function FuncTypeExp_ExpToBoolean
657 input DAE.Exp inExp;
658 output Boolean outBoolean;
659 end FuncTypeExp_ExpToBoolean;
660 algorithm
661 (outElse,replacementPerformed) := matchcontinue inElse
662 local
663 DAE.Exp e,e_1;
664 list<DAE.Statement> st,st_1;
665 DAE.Else el,el_1;
666 Boolean b1,b2,b3;
667 case DAE.ELSEIF(e,st,el)
668 algorithm
669 ✗ (el_1,b1) := replaceEquationsElse(el,repl,condExpFunc);
670 ✗ (st_1,b2) := replaceEquationsStmts(st,repl,condExpFunc);
671 ✗ (e_1,b3) := replaceExp(e, repl, condExpFunc);
672 ✗ true := b1 or b2 or b3;
673 ✗ then (DAE.ELSEIF(e_1,st_1,el_1),true);
674 case DAE.ELSE(st)
675 algorithm
676 ✗ (st_1,true) := replaceEquationsStmts(st,repl,condExpFunc);
677 ✗ then (DAE.ELSE(st_1),true);
678 else (inElse,false);
679 end matchcontinue;
680 end replaceEquationsElse;
681
682 protected function replaceOptEquationsStmts "
683 Helper function for replaceEquationsStmts, replaces optional statement"
684 input Option<DAE.Statement> optStmt;
685 input VariableReplacements inVariableReplacements;
686 input Option<FuncTypeExp_ExpToBoolean> condExpFunc;
687 output Option<DAE.Statement> outAlgorithmStatementLst;
688 output Boolean replacementPerformed;
689 partial function FuncTypeExp_ExpToBoolean
690 input DAE.Exp inExp;
691 output Boolean outBoolean;
692 end FuncTypeExp_ExpToBoolean;
693 algorithm
694 (outAlgorithmStatementLst,replacementPerformed) := matchcontinue optStmt
695 local
696 DAE.Statement stmt,stmt2;
697 case SOME(stmt)
698 algorithm
699 ✗ ({stmt2},true) := replaceEquationsStmts({stmt},inVariableReplacements,condExpFunc);
700 then (SOME(stmt2),true);
701 else (optStmt,false);
702 end matchcontinue;
703 end replaceOptEquationsStmts;
704
705 public function dumpReplacements
706 "Prints the variable replacements on form var1 -> var2"
707 input VariableReplacements inVariableReplacements;
708 algorithm
709 ():=
710 match inVariableReplacements
711 local
712 String str,len_str;
713 Integer len;
714 HashTable2.HashTable ht;
715 list<tuple<DAE.ComponentRef,DAE.Exp>> tplLst;
716 case REPLACEMENTS(hashTable= ht)
717 algorithm
718 ✗ tplLst := BaseHashTable.hashTableList(ht);
719 ✗ str := stringDelimitList(List.map(tplLst,printReplacementTupleStr),"\n");
720 ✗ print("Replacements: (");
721 ✗ len := listLength(tplLst);
722 ✗ len_str := intString(len);
723 ✗ print(len_str);
724 ✗ print(")\n");
725 ✗ print("=============\n");
726 ✗ print(str);
727 ✗ print("\n");
728 then
729 ();
730 end match;
731 end dumpReplacements;
732
733 public function dumpReplacementsStr "
734 Author BZ 2009-04
735 Function for dumping replacements to string.
736 "
737 input VariableReplacements inVariableReplacements;
738 output String ostr;
739 algorithm ostr := match inVariableReplacements
740 local
741 String str,s1;
742 HashTable2.HashTable ht;
743 list<tuple<DAE.ComponentRef,DAE.Exp>> tplLst;
744 case REPLACEMENTS(hashTable = ht)
745 algorithm
746 ✗ tplLst := BaseHashTable.hashTableList(ht);
747 ✗ str := stringDelimitList(List.map(tplLst,printReplacementTupleStr),"\n");
748 ✗ s1 := "Replacements: (" + intString(listLength(tplLst)) + ")\n=============\n" + str + "\n";
749 then
750 s1;
751 end match;
752 end dumpReplacementsStr;
753
754 public function getAllReplacements "
755 Author BZ 2009-04
756 Extract all crefs -> exp to two separate lists.
757 "
758 input VariableReplacements inVariableReplacements;
759 output list<DAE.ComponentRef> crefs;
760 output list<DAE.Exp> dsts;
761 algorithm (crefs,dsts) := match inVariableReplacements
762 local
763 HashTable2.HashTable ht;
764 list<tuple<DAE.ComponentRef,DAE.Exp>> tplLst;
765 case REPLACEMENTS(hashTable = ht)
766 algorithm
767 ✗ tplLst := BaseHashTable.hashTableList(ht);
768 ✗ crefs := List.map(tplLst,Util.tuple21);
769 ✗ dsts := List.map(tplLst,Util.tuple22);
770 then
771 (crefs,dsts);
772 end match;
773 end getAllReplacements;
774
775 protected function printReplacementTupleStr "help function to dumpReplacements"
776 input tuple<DAE.ComponentRef,DAE.Exp> tpl;
777 output String str;
778 algorithm
779 // optional exteded type debugging
780 //str := ComponentReference.debugPrintComponentRefTypeStr(Util.tuple21(tpl)) + " -> " + ExpressionDump.debugPrintComponentRefExp(Util.tuple22(tpl));
781 // Normal debugging, without type&dimension information on crefs.
782 ✗ str := ComponentReferenceBasics.printComponentRefStr(Util.tuple21(tpl)) + " -> " + ExpressionBasics.printExpStr(Util.tuple22(tpl));
783 end printReplacementTupleStr;
784
785 public function replacementSources "Returns all sources of the replacement rules"
786 input VariableReplacements repl;
787 output list<DAE.ComponentRef> sources;
788 algorithm
789 sources := match repl
790 local HashTable2.HashTable ht;
791 case REPLACEMENTS(ht,_)
792 algorithm
793 ✗ sources := BaseHashTable.hashTableKeyList(ht);
794 then sources;
795 end match;
796 end replacementSources;
797
798 public function replacementTargets "Returns all targets of the replacement rules"
799 input VariableReplacements repl;
800 output list<DAE.ComponentRef> sources;
801 algorithm
802 sources := match repl
803 local
804 list<DAE.Exp> targets;
805 list<DAE.ComponentRef> targets2;
806 HashTable2.HashTable ht;
807
808 case REPLACEMENTS(ht,_)
809 algorithm
810 ✗ targets := BaseHashTable.hashTableValueList(ht);
811 ✗ targets2 := List.flatten(List.map(targets,Expression.extractCrefsFromExp));
812 then
813 targets2;
814 end match;
815 end replacementTargets;
816
817 public function addReplacementLst " adds several replacements given by list of crefs and list of expressions by repeatedly calling addReplacement"
818 input VariableReplacements inRepl;
819 input list<DAE.ComponentRef> crs;
820 input list<DAE.Exp> dsts;
821 output VariableReplacements repl;
822 algorithm
823 repl := match (inRepl,crs,dsts)
824 local
825 DAE.ComponentRef cr;
826 DAE.Exp dst;
827 list<DAE.ComponentRef> crrest;
828 list<DAE.Exp> dstrest;
829
830 case (repl,{},{}) then repl;
831 case (repl,cr::crrest,dst::dstrest) algorithm
832 ✗ repl := addReplacement(repl,cr,dst);
833 ✗ repl := addReplacementLst(repl,crrest,dstrest);
834 then repl;
835 end match;
836 end addReplacementLst;
837
838 public function addReplacement "
839 Adds a replacement rule to the set of replacement rules given as argument.
840 If a replacement rule a->b already exists and we add a new rule b->c then
841 the rule a->b is updated to a->c. This is done using the make_transitive
842 function.
843 "
844 input VariableReplacements repl;
845 input DAE.ComponentRef inSrc;
846 input DAE.Exp inDst;
847 output VariableReplacements outRepl;
848 algorithm
849 outRepl:=
850 matchcontinue (repl,inSrc,inDst)
851 local
852 DAE.ComponentRef src,src_1;
853 DAE.Exp dst,dst_1;
854 HashTable2.HashTable ht,ht_1;
855 HashTable3.HashTable invHt,invHt_1;
856 // PA: Commented out this, since it will only slow things down without adding any functionality.
857 // Once match is available as a complement to matchcontinue, this case could be useful again.
858 //case ((repl as REPLACEMENTS(ht,invHt)),src,dst) /* source dest */
859 // equation
860 // olddst = BaseHashTable.get(src, ht) "if rule a->b exists, fail" ;
861 // then
862 // fail();
863
864 case ((REPLACEMENTS()),src,dst)
865 algorithm
866 17944 (REPLACEMENTS(ht,invHt),src_1,dst_1) := makeTransitive(repl, src, dst);
867 /*s1 = ComponentReferenceBasics.printComponentRefStr(src);
868 s2 = ExpressionBasics.printExpStr(dst);
869 s3 = ComponentReferenceBasics.printComponentRefStr(src_1);
870 s4 = ExpressionBasics.printExpStr(dst_1);
871 s = stringAppendList(
872 {"add_replacement(",s1,", ",s2,") -> add_replacement(",s3,
873 ", ",s4,")\n"});
874 print(s);
875 Debug.fprint(Flags.ADD_REPL, s);*/
876 17944 ht_1 := BaseHashTable.add((src_1, dst_1),ht);
877 17944 invHt_1 := addReplacementInv(invHt, src_1, dst_1);
878 17944 then
879 REPLACEMENTS(ht_1,invHt_1);
880 else
881 algorithm
882 ✗ print("-add_replacement failed\n");
883 ✗ then
884 fail();
885 end matchcontinue;
886 end addReplacement;
887
888 public function addReplacementNoTransitive "Similar to addReplacement but
889 does not make transitive replacement rules.
890 "
891 input VariableReplacements repl;
892 input DAE.ComponentRef src;
893 input DAE.Exp dst;
894 output VariableReplacements outRepl = repl;
895 protected
896 HashTable2.HashTable ht;
897 HashTable3.HashTable invHt;
898 algorithm
899 66341 REPLACEMENTS(ht,invHt) := outRepl;
900 66341 ht := BaseHashTable.add((src, dst), ht);
901 66341 invHt := addReplacementInv(invHt, src, dst);
902 66341 outRepl := REPLACEMENTS(ht,invHt);
903 end addReplacementNoTransitive;
904
905 protected function addReplacementInv "
906 Helper function to addReplacement
907 Adds the inverse rule of a replacement to the second binary tree
908 of VariableReplacements.
909 "
910 input HashTable3.HashTable invHt;
911 input DAE.ComponentRef src;
912 input DAE.Exp dst;
913 output HashTable3.HashTable outInvHt;
914 algorithm
915 outInvHt:=
916 match dst
917 local
918 HashTable3.HashTable invHt_1;
919 list<DAE.ComponentRef> dests;
920 case _ algorithm
921 84285 dests := Expression.extractCrefsFromExp(dst);
922 84285 invHt_1 := List.fold1r(dests,addReplacementInv2,src,invHt);
923 then
924 invHt_1;
925 end match;
926 end addReplacementInv;
927
928 protected function addReplacementInv2 "
929 Helper function to addReplacementInv
930 Adds the inverse rule for one of the variables of a replacement to the second binary tree
931 of VariableReplacements.
932 Since a replacement is on the form var -> expression of vars(v1,v2,...,vn) the inverse binary tree
933 contains rules for v1 -> var, v2 -> var, ...., vn -> var so that any of the variables of the expression
934 will update the rule.
935 "
936 input HashTable3.HashTable invHt;
937 input DAE.ComponentRef dst;
938 input DAE.ComponentRef src;
939 output HashTable3.HashTable outInvHt;
940 protected
941 list<DAE.ComponentRef> srcs;
942 algorithm
943
2/2
✓ Branch 1 taken 21554 times.
✓ Branch 2 taken 440334 times.
461888 if BaseHashTable.hasKey(dst,invHt) then
944 // previous elt for dst -> src, append.
945 21554 srcs := BaseHashTable.get(dst,invHt);
946 21554 srcs := amortizeUnion(src::srcs);//List.union({},src::srcs);
947 21554 outInvHt := BaseHashTable.add((dst, srcs),invHt);
948 else
949 // No previous elt for dst -> src
950 440334 outInvHt := BaseHashTable.add((dst, {src}),invHt);
951 end if;
952 end addReplacementInv2;
953
954 protected function amortizeUnion "performs listUnion but in an 'amortized' way, by only doing it occasionally"
955 input list<DAE.ComponentRef> inCrefs;
956 output list<DAE.ComponentRef> crefs;
957 algorithm
958 crefs := match inCrefs
959 case _ guard intMod(listLength(inCrefs),7)==0 // Experiments performed on different values: {{5, 102}, {6, 99}, {7, 98.8}, {8, 101}, {10, 101}, 20, 104}}
960 330 then List.union({},inCrefs);
961 else inCrefs;
962 end match;
963 end amortizeUnion;
964
965 public function addReplacementIfNot "Calls addReplacement() if condition (first argument) is false,
966 otherwise does nothing.
967
968 Author: asodja, 2010-03-03
969 "
970 input Boolean condition;
971 input VariableReplacements repl;
972 input DAE.ComponentRef inSrc;
973 input DAE.Exp inDst;
974 output VariableReplacements outRepl;
975 algorithm
976 outRepl:= match (condition, inSrc, inDst)
977 local
978 DAE.ComponentRef src;
979 DAE.Exp dst;
980 VariableReplacements repl_1;
981 case (false, src, dst) /* source dest */
982 algorithm
983 ✗ repl_1 := addReplacement(repl,src,dst);
984 then repl_1;
985 case (true, _, _)
986 then repl;
987 end match;
988 end addReplacementIfNot;
989
990 protected function makeTransitive "
991 This function takes a set of replacement rules and a new replacement rule
992 in the form of two ComponentRef:s and makes sure the new replacement rule
993 is replaced with the transitive value.
994 For example, if we have the rule a->b and a new rule c->a it is changed to c->b.
995 Also, if we have a rule a->b and a new rule b->c then the -old- rule a->b is changed
996 to a->c.
997 For arbitrary expressions: if we have a rule ax-> expr(b1,..,bn) and a new rule c->expr(a1,ax,..,an)
998 it is changed to c-> expr(a1,expr(b1,...,bn),..,an).
999 And similary for a rule ax -> expr(b1,bx,..,bn) and a new rule bx->expr(c1,..,cn) then old rule is changed to
1000 ax -> expr(b1,expr(c1,..,cn),..,bn).
1001 "
1002 input VariableReplacements repl;
1003 input DAE.ComponentRef src;
1004 input DAE.Exp dst;
1005 output VariableReplacements outRepl;
1006 output DAE.ComponentRef outSrc;
1007 output DAE.Exp outDst;
1008 algorithm
1009 (outRepl,outSrc,outDst):=
1010 match dst
1011 local
1012 VariableReplacements repl_1,repl_2;
1013 DAE.ComponentRef src_1,src_2;
1014 DAE.Exp dst_1,dst_2,dst_3;
1015
1016 case _
1017 algorithm
1018 17944 (repl_1,src_1,dst_1) := makeTransitive1(repl, src, dst);
1019 17944 (repl_2,src_2,dst_2) := makeTransitive2(repl_1, src_1, dst_1);
1020 17944 (dst_3,_) := ExpressionSimplify.simplify1(dst_2) "to remove e.g. --a";
1021
1/2
✓ Branch 0 taken 17944 times.
✗ Branch 1 not taken.
17944 then
1022 (repl_2,src_2,dst_3);
1023 end match;
1024 end makeTransitive;
1025
1026 protected function makeTransitive1 "
1027 helper function to makeTransitive
1028 "
1029 input VariableReplacements repl;
1030 input DAE.ComponentRef src;
1031 input DAE.Exp dst;
1032 output VariableReplacements outRepl;
1033 output DAE.ComponentRef outSrc;
1034 output DAE.Exp outDst;
1035 algorithm
1036 (outRepl,outSrc,outDst):=
1037 matchcontinue repl
1038 local
1039 list<DAE.ComponentRef> lst;
1040 VariableReplacements repl_1,singleRepl;
1041 HashTable3.HashTable invHt;
1042 // old rule a->expr(b1,..,bn) must be updated to a->expr(c_exp,...,bn) when new rule b1->c_exp
1043 // is introduced
1044 case REPLACEMENTS(_,invHt)
1045 algorithm
1046 17944 lst := BaseHashTable.get(src, invHt);
1047 ✗ singleRepl := addReplacementNoTransitive(emptyReplacementsSized(53),src,dst);
1048 ✗ repl_1 := makeTransitive12(lst,repl,singleRepl);
1049 then
1050 (repl_1,src,dst);
1051 else (repl,src,dst);
1052 end matchcontinue;
1053 end makeTransitive1;
1054
1055 protected function makeTransitive12 "Helper function to makeTransitive1
1056 For each old rule a->expr(b1,..,bn) update dest by applying the new rule passed as argument
1057 in singleRepl."
1058 input list<DAE.ComponentRef> lst;
1059 input VariableReplacements repl;
1060 input VariableReplacements singleRepl "contain one replacement rule: the rule to be added";
1061 output VariableReplacements outRepl;
1062 algorithm
1063 outRepl := match(lst, repl)
1064 local
1065 DAE.Exp crDst;
1066 DAE.ComponentRef cr;
1067 list<DAE.ComponentRef> crs;
1068 VariableReplacements repl1,repl2;
1069 HashTable2.HashTable ht;
1070 case({}, _) then repl;
1071 case(cr::crs, REPLACEMENTS(hashTable=ht))
1072 algorithm
1073 ✗ crDst := BaseHashTable.get(cr,ht);
1074 ✗ (crDst,_) := replaceExp(crDst,singleRepl,NONE());
1075 ✗ repl1 := addReplacementNoTransitive(repl,cr,crDst) "add updated old rule";
1076 ✗ repl2 := makeTransitive12(crs,repl1,singleRepl);
1077 then repl2;
1078 end match;
1079 end makeTransitive12;
1080
1081 protected function makeTransitive2 "
1082 Helper function to makeTransitive
1083 "
1084 input VariableReplacements repl;
1085 input DAE.ComponentRef src;
1086 input DAE.Exp dst;
1087 output VariableReplacements outRepl;
1088 output DAE.ComponentRef outSrc;
1089 output DAE.Exp outDst;
1090 algorithm
1091 (outRepl,outSrc,outDst):=
1092 matchcontinue dst
1093 local
1094 DAE.Exp dst_1;
1095 // for rule a->b1+..+bn, replace all b1 to bn's in the expression;
1096 case _
1097 algorithm
1098 17944 (dst_1,_) := replaceExp(dst,repl,NONE());
1099 then
1100 (repl,src,dst_1);
1101 // replace Exp failed, keep old rule.
1102 else (repl,src,dst); /* dst has no own replacement, return */
1103 end matchcontinue;
1104 end makeTransitive2;
1105
1106 public function getReplacement "
1107 Retrives a replacement variable given a set of replacement rules and a
1108 source variable.
1109 "
1110 input VariableReplacements inVariableReplacements;
1111 input DAE.ComponentRef inComponentRef;
1112 output DAE.Exp outComponentRef;
1113 algorithm
1114 outComponentRef:=
1115 match (inVariableReplacements,inComponentRef)
1116 local
1117 DAE.ComponentRef src;
1118 DAE.Exp dst;
1119 HashTable2.HashTable ht;
1120 case (REPLACEMENTS(hashTable=ht),src)
1121 algorithm
1122 940940 dst := BaseHashTable.get(src,ht);
1123 then
1124 dst;
1125 end match;
1126 end getReplacement;
1127
1128 public function replaceExpOpt "Similar to replaceExp but takes Option<Exp> instead of Exp"
1129 input Option<DAE.Exp> inExp;
1130 input VariableReplacements repl;
1131 input Option<FuncTypeExp_ExpToBoolean> funcOpt;
1132 output Option<DAE.Exp> outExp;
1133 partial function FuncTypeExp_ExpToBoolean
1134 input DAE.Exp inExp;
1135 output Boolean outBoolean;
1136 end FuncTypeExp_ExpToBoolean;
1137 algorithm
1138 outExp := match inExp
1139 local DAE.Exp e;
1140 case SOME(e)
1141 algorithm
1142 /* TODO: Propagate this boolean? */
1143 ✗ (e,_) := replaceExp(e,repl,funcOpt);
1144 then SOME(e);
1145 else NONE();
1146 end match;
1147 end replaceExpOpt;
1148
1149 public function avoidDoubleHashLookup "
1150 Author BZ 200X-XX modified 2008-06
1151 When adding replacement rules, we might not have the correct type availible at the moment.
1152 Then DAE.T_UNKNOWN_DEFAULT is used, so when replacing exp and finding DAE.T_UNKNOWN(_), we use the
1153 type of the expression to be replaced instead.
1154 TODO: find out why array residual functions containing arrays as xloc[] does not work,
1155 doing that will allow us to use this function for all crefs."
1156 input DAE.Exp inExp;
1157 input DAE.Type inType;
1158 output DAE.Exp outExp;
1159 algorithm outExp := matchcontinue inExp
1160 local DAE.ComponentRef cr;
1161 ✗ case DAE.CREF(cr,DAE.T_UNKNOWN()) then Expression.makeCrefExp(cr,inType);
1162 else inExp;
1163 end matchcontinue;
1164 end avoidDoubleHashLookup;
1165
1166 public function replaceExpRepeated "similar to replaceExp but repeats the replacements until expression no longer changes.
1167 Note: This is only required/useful if replacements are built with addReplacementNoTransitive."
1168 input DAE.Exp e;
1169 input VariableReplacements repl;
1170 input Option<VisitFunc> func;
1171 input Integer maxIter "max iterations";
1172 output DAE.Exp outExp;
1173
1174 partial function VisitFunc
1175 input DAE.Exp exp;
1176 output Boolean res;
1177 end VisitFunc;
1178
1179 algorithm
1180 ✗ outExp := replaceExpRepeated2(e,repl,func,maxIter,1,false);
1181 end replaceExpRepeated;
1182
1183 public function replaceExpRepeated2 "help function to replaceExpRepeated"
1184 input DAE.Exp e;
1185 input VariableReplacements repl;
1186 input Option<VisitFunc> func;
1187 input Integer maxIter;
1188 input Integer i;
1189 input Boolean equal;
1190 output DAE.Exp outExp;
1191
1192 partial function VisitFunc
1193 input DAE.Exp exp;
1194 output Boolean res;
1195 end VisitFunc;
1196
1197 protected
1198 DAE.Exp e1;
1199 Boolean b;
1200 algorithm
1201 ✗ if i > maxIter or equal then
1202 outExp := e;
1203 else
1204 ✗ (e1,b) := replaceExp(e,repl,func);
1205 ✗ outExp := replaceExpRepeated2(e1,repl,func,maxIter,i+1,not b /*ExpressionBasics.expEqual(e,e1)*/);
1206 end if;
1207 end replaceExpRepeated2;
1208
1209 public function replaceExp
1210 input DAE.Exp inExp;
1211 input VariableReplacements inVarReplacements;
1212 input Option<FuncTypeExp_ExpToBoolean> inCondition;
1213 output DAE.Exp outExp;
1214 output Boolean replacementPerformed;
1215 partial function FuncTypeExp_ExpToBoolean
1216 input DAE.Exp inExp;
1217 output Boolean outBoolean;
1218 end FuncTypeExp_ExpToBoolean;
1219 algorithm
1220
1221 outExp := inExp;
1222
1223
1/2
✓ Branch 1 taken 85783 times.
✗ Branch 2 not taken.
85783 if replaceExpCond(inCondition, inExp) then
1224 85783 (outExp, _) := Expression.traverseExpBottomUp(inExp, function replaceExpCref(inVarReplacements = inVarReplacements, inCondition=inCondition), true);
1225 end if;
1226
1227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85783 times.
85783 replacementPerformed := not referenceEq(outExp, inExp);
1228 end replaceExp;
1229
1230
1231 protected function replaceExpCref
1232 input DAE.Exp inExp;
1233 input VariableReplacements inVarReplacements;
1234 input Option<FuncTypeExp_ExpToBoolean> inCondition;
1235 input Boolean inReplacementPerformed;
1236 output DAE.Exp outExp;
1237 output Boolean replacementPerformed;
1238 partial function FuncTypeExp_ExpToBoolean
1239 input DAE.Exp inExp;
1240 output Boolean outBoolean;
1241 end FuncTypeExp_ExpToBoolean;
1242 algorithm
1243
1244
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2947311 times.
2947311 if not replaceExpCond(inCondition, inExp) then
1245 ✗ Error.addInternalError("Got exp to replace when condition is not allowing replacements. Check traversal.", sourceInfo());
1246 end if;
1247
1248 replacementPerformed := false;
1249 outExp := inExp;
1250
1251 () := match inExp
1252 local
1253 DAE.ComponentRef cr;
1254
1255 case DAE.CREF(componentRef = cr) algorithm
1256 try
1257 878967 outExp := getReplacement(inVarReplacements, cr);
1258 10791 outExp := avoidDoubleHashLookup(outExp, inExp.ty);
1259 replacementPerformed := true;
1260 else
1261 end try;
1262 then ();
1263
1264 else ();
1265
1266 end match;
1267 end replaceExpCref;
1268
1269 public function replaceExpList
1270 input list<DAE.Exp> iexpl;
1271 input VariableReplacements repl;
1272 input Option<FuncTypeExp_ExpToBoolean> cond;
1273 output list<DAE.Exp> outExpl;
1274 output Boolean replacementPerformed;
1275 partial function FuncTypeExp_ExpToBoolean
1276 input DAE.Exp inExp;
1277 output Boolean outBoolean;
1278 end FuncTypeExp_ExpToBoolean;
1279 protected
1280 list<DAE.Exp> acc1 = {};
1281 Boolean acc2 = false;
1282 Boolean c;
1283 algorithm
1284 ✗ for exp in iexpl loop
1285 ✗ (exp,c) := replaceExp(exp,repl,cond);
1286 ✗ acc2 := acc2 or c;
1287 acc1 := exp::acc1;
1288 end for;
1289 ✗ outExpl := listReverseInPlace(acc1);
1290 replacementPerformed := acc2;
1291 end replaceExpList;
1292
1293 protected function replaceExpCond "function replaceExpCond(cond,e) => true &
1294
1295 Helper function to replace_Expression. Evaluates a condition function if
1296 SOME otherwise returns true.
1297 "
1298 input Option<FuncTypeExp_ExpToBoolean> inFuncTypeExpExpToBooleanOption;
1299 input DAE.Exp inExp;
1300 output Boolean outBoolean;
1301 partial function FuncTypeExp_ExpToBoolean
1302 input DAE.Exp inExp;
1303 output Boolean outBoolean;
1304 end FuncTypeExp_ExpToBoolean;
1305 algorithm
1306 outBoolean:=
1307 match (inFuncTypeExpExpToBooleanOption,inExp)
1308 local
1309 Boolean res;
1310 FuncTypeExp_ExpToBoolean cond;
1311 DAE.Exp e;
1312 case (SOME(cond),e) /* cond e */
1313 algorithm
1314 ✗ res := cond(e);
1315 then
1316 res;
1317 else true;
1318 end match;
1319 end replaceExpCond;
1320
1321 protected function replaceExpMatrix "author: PA
1322 Helper function to replaceExp, traverses Matrix expression list."
1323 input list<list<DAE.Exp>> inTplExpExpBooleanLstLst;
1324 input VariableReplacements inVariableReplacements;
1325 input Option<FuncTypeExp_ExpToBoolean> inFuncTypeExpExpToBooleanOption;
1326 output list<list<DAE.Exp>> outTplExpExpBooleanLstLst;
1327 output Boolean replacementPerformed;
1328 partial function FuncTypeExp_ExpToBoolean
1329 input DAE.Exp inExp;
1330 output Boolean outBoolean;
1331 end FuncTypeExp_ExpToBoolean;
1332 protected
1333 list<list<DAE.Exp>> acc1 = {};
1334 Boolean acc2 = false;
1335 Boolean c;
1336 algorithm
1337 ✗ for exp in inTplExpExpBooleanLstLst loop
1338 ✗ (exp,c) := replaceExpList(exp, inVariableReplacements, inFuncTypeExpExpToBooleanOption);
1339 ✗ acc2 := acc2 or c;
1340 acc1 := exp::acc1;
1341 end for;
1342 ✗ outTplExpExpBooleanLstLst := listReverseInPlace(acc1);
1343 replacementPerformed := acc2;
1344 end replaceExpMatrix;
1345
1346 annotation(__OpenModelica_Interface="frontend_base");
1347 end VarTransform;
1348