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 |