From dab3069e3cdb6a328bef5f1f29344706dde1f22b Mon Sep 17 00:00:00 2001 From: Andreas <38031952+AnHeuermann@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:35:03 +0200 Subject: [PATCH] Alias replacement for external object array equations (#11429) * [BE] add array equation support for external object alias --------- Co-authored-by: kabdelhak --- .../Compiler/BackEnd/BackendDAECreate.mo | 91 ++++++++++++++++--- .../Compiler/BackEnd/BackendEquation.mo | 14 +++ 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/OMCompiler/Compiler/BackEnd/BackendDAECreate.mo b/OMCompiler/Compiler/BackEnd/BackendDAECreate.mo index e95a273965d..7c1be28feed 100644 --- a/OMCompiler/Compiler/BackEnd/BackendDAECreate.mo +++ b/OMCompiler/Compiler/BackEnd/BackendDAECreate.mo @@ -592,8 +592,7 @@ algorithm extVarsOut := BackendVariable.listVar(extVarLst); end removeExtAliasBinding; -protected function getExternalObjectAlias3 "Gets the alias var and sim var for the given alias equation and adds a replacement rule -author: waurich TUD 2016-10" +protected function getExternalObjectAlias3 "Gets the alias var and sim var for the given alias equation and adds a replacement rule" input BackendDAE.Equation eqIn; input BackendDAE.Variables extVars; input tuple,BackendVarTransform.VariableReplacements> tplIn; @@ -601,7 +600,7 @@ author: waurich TUD 2016-10" protected BackendDAE.Equation eq; BackendDAE.Var v1,v2,simVar,aliasVar; - list crefs; + list crefs_lhs, crefs_rhs; list extAliasVars; BackendVarTransform.VariableReplacements repl; algorithm @@ -609,18 +608,63 @@ algorithm ({eq},_) := BackendVarTransform.replaceEquations({eqIn},repl,NONE()); try //get alias and sim var - crefs := BackendEquation.equationCrefs(eq); - ({v1,v2},_) := BackendVariable.getVarLst(crefs,extVars); - (simVar,aliasVar) := chooseExternalAlias(v1,v2); - extAliasVars := aliasVar::extAliasVars; - //build replacement rule - repl := BackendVarTransform.addReplacement(repl,BackendVariable.varCref(aliasVar), Expression.crefExp(BackendVariable.varCref(simVar)), NONE()); + (crefs_lhs, crefs_rhs) := BackendEquation.equationCrefsSolved(eq); + // check if there are arrays involved and expand them if needed + (extAliasVars,repl) := match (crefs_lhs, crefs_rhs) + local + DAE.ComponentRef lhs, rhs; + case ({lhs}, {rhs}) algorithm + // no arrays, but crefs might be arrays to expand + crefs_lhs := ComponentReference.expandCref(lhs, true); + crefs_rhs := ComponentReference.expandCref(rhs, true); + (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl); + then (extAliasVars,repl); + case ({lhs}, _) algorithm + // only expand lhs + crefs_lhs := ComponentReference.expandCref(lhs, true); + (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl); + then (extAliasVars,repl); + case (_, {rhs}) algorithm + // only expand rhs + crefs_rhs := ComponentReference.expandCref(rhs, true); + (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl); + then (extAliasVars,repl); + else algorithm + // expand nothing + (extAliasVars, repl) := addExternalObjectReplacementRules(crefs_lhs, crefs_rhs, extVars, extAliasVars, repl); + then (extAliasVars,repl); + end match; tplOut := (extAliasVars,repl); else Error.addMessage(Error.INTERNAL_ERROR,{"BackendDAECreate.getExternalObjectAlias3 failed for " + BackendDump.equationString(eqIn)}); end try; end getExternalObjectAlias3; +function addExternalObjectReplacementRules + "add multiple external object replacement rules" + input list crefs_lhs; + input list crefs_rhs; + input BackendDAE.Variables extVars; + input output list extAliasVars; + input output BackendVarTransform.VariableReplacements repl; +protected + DAE.ComponentRef lhs, rhs; + BackendDAE.Var v1, v2, simVar, aliasVar; +algorithm + if listLength(crefs_lhs) == listLength(crefs_rhs) then + for tpl in List.zip(crefs_lhs, crefs_rhs) loop + (lhs, rhs) := tpl; + ({v1}, _) := BackendVariable.getVar(lhs, extVars); + ({v2}, _) := BackendVariable.getVar(rhs, extVars); + (simVar,aliasVar) := chooseExternalAlias(v1,v2); + extAliasVars := aliasVar::extAliasVars; + repl := BackendVarTransform.addReplacement(repl, BackendVariable.varCref(aliasVar), Expression.crefExp(BackendVariable.varCref(simVar)), NONE()); + end for; + else + fail(); + end if; +end addExternalObjectReplacementRules; + protected function chooseExternalAlias "Chooses a alias variable depending on which variable has a binding author: waurich TUD 2016-10" input BackendDAE.Var var1; @@ -648,7 +692,7 @@ algorithm end if; end chooseExternalAlias; -protected function getExternalObjectAlias2 "Traverser for equations to check if an external alias assignment an be made +protected function getExternalObjectAlias2 "Traverser for equations to check if an external alias assignment can be made author: waurich TUD 2016-10" input BackendDAE.Equation eqIn; input list extCrefs; @@ -659,17 +703,40 @@ algorithm local list noAliasEqs, aliasEqs; DAE.ComponentRef cr1,cr2; + DAE.Exp left, right; + DAE.Type ty1, ty2; case(BackendDAE.COMPLEX_EQUATION(left = DAE.CREF(componentRef=cr1), right = DAE.CREF(componentRef=cr2)),_,(noAliasEqs,aliasEqs)) algorithm true := List.exist1(extCrefs,ComponentReference.crefEqual,cr1) and List.exist1(extCrefs,ComponentReference.crefEqual,cr2); then (noAliasEqs,eqIn::aliasEqs); - case(BackendDAE.EQUATION(exp = DAE.CREF(componentRef= cr1, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ())), - scalar = DAE.CREF(componentRef= cr2, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()))),_,(noAliasEqs,aliasEqs)) + case(BackendDAE.EQUATION(exp = DAE.CREF(componentRef = cr1, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ())), + scalar = DAE.CREF(componentRef = cr2, ty = DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()))),_,(noAliasEqs,aliasEqs)) algorithm true := List.exist1(extCrefs,ComponentReference.crefEqual,cr1) and List.exist1(extCrefs,ComponentReference.crefEqual,cr2); then (noAliasEqs,eqIn::aliasEqs); + // Cases for array equations (cref = arr), (cref = cref), (arr = cref) + case(BackendDAE.ARRAY_EQUATION(_, + left as DAE.CREF(componentRef = cr1, ty = DAE.T_ARRAY(ty = ty1 as DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) )), + right as DAE.ARRAY()), + _, (noAliasEqs,aliasEqs)) + then (noAliasEqs,eqIn::aliasEqs); + + case(BackendDAE.ARRAY_EQUATION(_, + left as DAE.CREF(componentRef = cr1, ty = DAE.T_ARRAY(ty = ty1 as DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) )), + right as DAE.CREF(componentRef = cr2, ty = DAE.T_ARRAY(ty = ty2 as DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) ))), + _, (noAliasEqs,aliasEqs)) + then fail(); + + case(BackendDAE.ARRAY_EQUATION(_, + left as DAE.ARRAY(), + right as DAE.CREF(componentRef = cr2, ty = DAE.T_ARRAY(ty = ty1 as DAE.T_COMPLEX(complexClassType = ClassInf.EXTERNAL_OBJ()) ))), + _, (noAliasEqs,aliasEqs)) + then fail(); + + // Case (arr = arr) ? + else algorithm (noAliasEqs,aliasEqs) := eqTplIn; diff --git a/OMCompiler/Compiler/BackEnd/BackendEquation.mo b/OMCompiler/Compiler/BackEnd/BackendEquation.mo index f86f4c10742..c9b421b9e47 100644 --- a/OMCompiler/Compiler/BackEnd/BackendEquation.mo +++ b/OMCompiler/Compiler/BackEnd/BackendEquation.mo @@ -611,6 +611,20 @@ algorithm (_, (_, outExpComponentRefLst)) := traverseExpsOfEquation(inEquation, Expression.traverseSubexpressionsHelper, (Expression.traversingComponentRefFinder, {})); end equationCrefs; +public function equationCrefsSolved "author: kabdelhak + From one solved equation return all occurring variables/component references from lhs and rhs." + input BackendDAE.Equation inEquation; + output list lhs_lst; + output list rhs_lst; +protected + DAE.Exp lhs, rhs; +algorithm + lhs := getEquationLHS(inEquation); + rhs := getEquationRHS(inEquation); + lhs_lst := Expression.extractCrefsFromExp(lhs); + rhs_lst := Expression.extractCrefsFromExp(rhs); +end equationCrefsSolved; + public function getAllCrefFromEquations input BackendDAE.EquationArray inEqns; output list cr_lst;