Skip to content

Commit

Permalink
Alias replacement for external object array equations (#11429)
Browse files Browse the repository at this point in the history
* [BE] add array equation support for external object alias

---------

Co-authored-by: kabdelhak <karim.abdelhak@hsbi.de>
  • Loading branch information
AnHeuermann and kabdelhak committed Oct 24, 2023
1 parent 7d33402 commit dab3069
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 12 deletions.
91 changes: 79 additions & 12 deletions OMCompiler/Compiler/BackEnd/BackendDAECreate.mo
Expand Up @@ -592,35 +592,79 @@ 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<list<BackendDAE.Var>,BackendVarTransform.VariableReplacements> tplIn;
output tuple<list<BackendDAE.Var>,BackendVarTransform.VariableReplacements> tplOut;
protected
BackendDAE.Equation eq;
BackendDAE.Var v1,v2,simVar,aliasVar;
list<DAE.ComponentRef> crefs;
list<DAE.ComponentRef> crefs_lhs, crefs_rhs;
list<BackendDAE.Var> extAliasVars;
BackendVarTransform.VariableReplacements repl;
algorithm
(extAliasVars,repl) := tplIn;
({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<DAE.ComponentRef> crefs_lhs;
input list<DAE.ComponentRef> crefs_rhs;
input BackendDAE.Variables extVars;
input output list<BackendDAE.Var> 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;
Expand Down Expand Up @@ -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<DAE.ComponentRef> extCrefs;
Expand All @@ -659,17 +703,40 @@ algorithm
local
list<BackendDAE.Equation> 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;
Expand Down
14 changes: 14 additions & 0 deletions OMCompiler/Compiler/BackEnd/BackendEquation.mo
Expand Up @@ -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<DAE.ComponentRef> lhs_lst;
output list<DAE.ComponentRef> 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<DAE.ComponentRef> cr_lst;
Expand Down

0 comments on commit dab3069

Please sign in to comment.