Skip to content

Commit

Permalink
- add condition to when equation
Browse files Browse the repository at this point in the history
- handle elsewhen branches in incidence matrix 

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@12292 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Jens Frenkel committed Jul 5, 2012
1 parent 6e0a8ad commit fdf9c94
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 117 deletions.
3 changes: 2 additions & 1 deletion Compiler/BackEnd/BackendDAE.mo
Expand Up @@ -167,7 +167,8 @@ end Equation;
public
uniontype WhenEquation "- When Equation"
record WHEN_EQ
Integer index "Index in when clauses" ;
.DAE.Exp condition "The when-condition" ;
Integer index "Index in when clauses" ;
.DAE.ComponentRef left "Left hand side of equation" ;
.DAE.Exp right "Right hand side of equation" ;
Option<WhenEquation> elsewhenPart "elsewhen equation with the same cref on the left hand side.";
Expand Down
66 changes: 42 additions & 24 deletions Compiler/BackEnd/BackendDAECreate.mo
Expand Up @@ -1302,14 +1302,14 @@ algorithm

case (DAE.WHEN_EQUATION(condition = cond,equations = eqnl,elsewhen_ = NONE(),source=source),i,_,whenList)
equation
(res,reinit) = lowerWhenEqn2(listReverse(eqnl), i, functionTree, {}, {});
(cond,source) = Inline.inlineExp(cond, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(res,reinit) = lowerWhenEqn2(listReverse(eqnl), cond, i, functionTree, {}, {});
equation_count = listLength(res);
reinit_count = listLength(reinit);
hasReinit = (reinit_count > 0);
extra = Util.if_(hasReinit, 1, 0);
tot_count = equation_count + extra;
i_1 = i + tot_count;
(cond,source) = Inline.inlineExp(cond, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
whenClauseList1 = makeWhenClauses(equation_count, cond, {});
whenClauseList2 = makeWhenClauses(extra, cond, reinit);
whenClauseList3 = listAppend(whenClauseList2, whenClauseList1);
Expand All @@ -1320,7 +1320,8 @@ algorithm
case (DAE.WHEN_EQUATION(condition = cond,equations = eqnl,elsewhen_ = SOME(elsePart),source=source),i,_,whenList)
equation
(elseEqnLst,nextWhenIndex,elseClauseList) = lowerWhenEqn(elsePart,i,functionTree,whenList);
(trueEqnLst,reinit) = lowerWhenEqn2(listReverse(eqnl), nextWhenIndex, functionTree, {}, {});
(cond,source) = Inline.inlineExp(cond, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(trueEqnLst,reinit) = lowerWhenEqn2(listReverse(eqnl), cond,nextWhenIndex, functionTree, {}, {});
equation_count = listLength(trueEqnLst);
reinit_count = listLength(reinit);
hasReinit = (reinit_count > 0);
Expand Down Expand Up @@ -1349,6 +1350,7 @@ protected function lowerWhenEqn2
"function lowerWhenEqn2
Helper function to lowerWhenEqn. Lowers the equations inside a when clause"
input list<DAE.Element> inDAEElementLst "The List of equations inside a when clause";
input DAE.Exp cond;
input Integer inWhenClauseIndex;
input DAE.FunctionTree functionTree;
input list<BackendDAE.Equation> iEquationLst;
Expand All @@ -1357,66 +1359,82 @@ protected function lowerWhenEqn2
output list<BackendDAE.WhenOperator> outReinitStatementLst;
algorithm
(outEquationLst,outReinitStatementLst):=
matchcontinue (inDAEElementLst,inWhenClauseIndex,functionTree,iEquationLst,iReinitStatementLst)
matchcontinue (inDAEElementLst,cond,inWhenClauseIndex,functionTree,iEquationLst,iReinitStatementLst)
local
Integer i,size;
list<BackendDAE.Equation> eqnl;
list<BackendDAE.WhenOperator> reinit;
DAE.Exp cre,e,cond;
DAE.ComponentRef cr;
list<DAE.Element> xs;
list<DAE.Element> xs,eqns;
DAE.Element el;
DAE.ElementSource source;
DAE.Dimensions ds;
list<DAE.Exp> expl;
list<list<DAE.Element>> eqnslst;
Boolean b;
String s;

case ({},_,_,_,_) then (iEquationLst,iReinitStatementLst);
case ((DAE.EQUATION(exp = (cre as DAE.CREF(componentRef = cr)),scalar = e, source = source) :: xs),i,_,_,_)
case ({},_,_,_,_,_) then (iEquationLst,iReinitStatementLst);
case ((DAE.EQUATION(exp = (cre as DAE.CREF(componentRef = cr)),scalar = e, source = source) :: xs),_,i,_,_,_)
equation
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i + 1, functionTree, BackendDAE.WHEN_EQUATION(1,BackendDAE.WHEN_EQ(i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i + 1, functionTree, BackendDAE.WHEN_EQUATION(1,BackendDAE.WHEN_EQ(cond,i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
then
(eqnl,reinit);

case ((DAE.COMPLEX_EQUATION(lhs = (cre as DAE.CREF(componentRef = cr)),rhs = e,source = source) :: xs),i,_,_,_)
case ((DAE.COMPLEX_EQUATION(lhs = (cre as DAE.CREF(componentRef = cr)),rhs = e,source = source) :: xs),_,i,_,_,_)
equation
size = Expression.sizeOf(Expression.typeof(cre));
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i + 1, functionTree, BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i + 1, functionTree, BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(cond,i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
then
(eqnl,reinit);

case (((el as DAE.IF_EQUATION(condition1=expl,equations2=eqnslst,equations3=eqns, source = source)) :: xs),_,i,_,_,_)
equation
(expl,source) = Inline.inlineExps(expl, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
b = not Flags.getConfigBool(Flags.CHECK_MODEL);
s = Debug.bcallret1(b, DAEDump.dumpElementsStr, {el}, "");
Debug.bcall3(b,Error.addSourceMessage,Error.IF_EQUATION_WARNING, {s}, DAEUtil.getElementSourceFileInfo(source));
// ToDo: lower IfEquation in When clause, see ModelicaSpec(3.3) page 85.

(eqnl,reinit) = lowerWhenEqn2(xs,cond, i + 1, functionTree, iEquationLst, iReinitStatementLst);
then
(eqnl,reinit);

case ((DAE.ARRAY_EQUATION(dimension=ds,exp = (cre as DAE.CREF(componentRef = cr)),array = e,source = source) :: xs),i,_,_,_)
case ((DAE.ARRAY_EQUATION(dimension=ds,exp = (cre as DAE.CREF(componentRef = cr)),array = e,source = source) :: xs),_,i,_,_,_)
equation
size = List.fold(Expression.dimensionsSizes(ds),intMul,1);
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i + 1, functionTree, BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i + 1, functionTree, BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(cond,i,cr,e,NONE()),source) :: iEquationLst, iReinitStatementLst);
then
(eqnl,reinit);

case ((DAE.ASSERT(condition=cond,message = e,source = source) :: xs),i,_,_,_)
case ((DAE.ASSERT(condition=cond,message = e,source = source) :: xs),_,i,_,_,_)
equation
(cond,source) = Inline.inlineExp(cond, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i, functionTree, iEquationLst, BackendDAE.ASSERT(cond,e,source) :: iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i, functionTree, iEquationLst, BackendDAE.ASSERT(cond,e,source) :: iReinitStatementLst);
then
(eqnl,reinit);

case ((DAE.REINIT(componentRef = cr,exp = e,source = source) :: xs),i,_,_,_)
case ((DAE.REINIT(componentRef = cr,exp = e,source = source) :: xs),_,i,_,_,_)
equation
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i, functionTree, iEquationLst, BackendDAE.REINIT(cr,e,source) :: iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i, functionTree, iEquationLst, BackendDAE.REINIT(cr,e,source) :: iReinitStatementLst);
then
(eqnl,reinit);

case ((DAE.TERMINATE(message = e,source = source) :: xs),i,_,_,_)
case ((DAE.TERMINATE(message = e,source = source) :: xs),_,i,_,_,_)
equation
(e,source) = Inline.inlineExp(e, (SOME(functionTree),{DAE.NORM_INLINE()}), source);
(eqnl,reinit) = lowerWhenEqn2(xs, i, functionTree, iEquationLst, BackendDAE.TERMINATE(e,source) :: iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs,cond, i, functionTree, iEquationLst, BackendDAE.TERMINATE(e,source) :: iReinitStatementLst);
then
(eqnl,reinit);

// failure
case ((el::xs), i,_,_,_)
case ((el::xs),_,_,_,_,_)
equation
true = Flags.isSet(Flags.FAILTRACE);
Debug.traceln("- BackendDAECreate.lowerWhenEqn2 failed on:" +& DAEDump.dumpElementsStr({el}));
Expand All @@ -1426,10 +1444,10 @@ algorithm
// adrpo: 2010-09-26
// allow to continue when checking the model
// just ignore this equation.
case ((el::xs), i,_,_,_)
case ((el::xs),_,i,_,_,_)
equation
true = Flags.getConfigBool(Flags.CHECK_MODEL);
(eqnl,reinit) = lowerWhenEqn2(xs, i + 1, functionTree,iEquationLst,iReinitStatementLst);
(eqnl,reinit) = lowerWhenEqn2(xs, cond, i + 1, functionTree,iEquationLst,iReinitStatementLst);
then
(eqnl, reinit);
end matchcontinue;
Expand Down Expand Up @@ -3112,7 +3130,7 @@ algorithm
matchcontinue (trueEqnList, elseEqnList, trueClauses, elseClauses, nextWhenClauseIndex)
local
DAE.ComponentRef cr;
DAE.Exp rightSide;
DAE.Exp rightSide,cond;
Integer ind;
BackendDAE.Equation res;
list<BackendDAE.Equation> trueEqns;
Expand All @@ -3128,10 +3146,10 @@ algorithm
DAE.ElementSource source;
Integer size;

case (BackendDAE.WHEN_EQUATION(size=size,whenEquation=BackendDAE.WHEN_EQ(index = ind,left = cr,right=rightSide),source=source)::trueEqns, elseEqns,trueCls,elseCls,nextInd)
case (BackendDAE.WHEN_EQUATION(size=size,whenEquation=BackendDAE.WHEN_EQ(condition=cond,index = ind,left = cr,right=rightSide),source=source)::trueEqns, elseEqns,trueCls,elseCls,nextInd)
equation
(foundEquation, elseEqnsRest) = getWhenEquationFromVariable(cr,elseEqns);
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(ind,cr,rightSide,SOME(foundEquation)),source);
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(cond,ind,cr,rightSide,SOME(foundEquation)),source);
(resRest, outNextIndex, outClauseList) = mergeClauses(trueEqns,elseEqnsRest,trueCls, elseCls,nextInd);
then (res::resRest, outNextIndex, outClauseList);

Expand Down
2 changes: 1 addition & 1 deletion Compiler/BackEnd/BackendDAEOptimize.mo
Expand Up @@ -6655,7 +6655,7 @@ algorithm
Debug.fcall(Flags.JAC_DUMP, print,"BackendDAEOptimize.derive: discrete equation has been removed.\n");
then {};

case(currEquation as BackendDAE.WHEN_EQUATION(_, _), vars, functions, inputVars, paramVars, stateVars, knownVars, _, _, _) equation
case(currEquation as BackendDAE.WHEN_EQUATION(size=_), vars, functions, inputVars, paramVars, stateVars, knownVars, _, _, _) equation
Debug.fcall(Flags.JAC_DUMP, print,"BackendDAEOptimize.derive: WHEN_EQUATION has been removed.\n");
then {};

Expand Down
16 changes: 9 additions & 7 deletions Compiler/BackEnd/BackendDAETransform.mo
Expand Up @@ -3311,7 +3311,7 @@ public function traverseBackendDAEExpsEqnWithSymbolicOperation
algorithm
(outEquation,outWhenClauseLst,outTypeA) := matchcontinue (inEquation,inWhenClauseLst,func,inTypeA)
local
DAE.Exp e1_1,e2_1,e1,e2;
DAE.Exp e1_1,e2_1,e1,e2,cond;
DAE.ComponentRef cr,cr1;
Integer ds,indx,i,size;
list<DAE.Exp> expl,expl1,in_,in_1,out,out1;
Expand Down Expand Up @@ -3360,24 +3360,26 @@ algorithm
source = List.foldr(ops, DAEUtil.addSymbolicTransformation, source);
then (BackendDAE.ALGORITHM(size,DAE.ALGORITHM_STMTS(statementLst),source),wclst,ext_arg_1);
case (BackendDAE.WHEN_EQUATION(size=size,whenEquation =
BackendDAE.WHEN_EQ(index = i,left = cr,right = e1,elsewhenPart=NONE()),source = source),wclst,_,_)
BackendDAE.WHEN_EQ(condition=cond,index = i,left = cr,right = e1,elsewhenPart=NONE()),source = source),wclst,_,_)
equation
e2 = Expression.crefExp(cr);
((e1_1,(ops,ext_arg_1))) = func((e1,({},inTypeA)));
((DAE.CREF(cr1,_),(ops,ext_arg_2))) = func((e2,(ops,ext_arg_1)));
((cond,(ops,ext_arg_3))) = func((cond,(ops,ext_arg_2)));
source = List.foldr(ops, DAEUtil.addSymbolicTransformation, source);
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(i,cr1,e1_1,NONE()),source);
(wclst1,(_,ext_arg_3)) = traverseBackendDAEExpsWhenClause(SOME(i),wclst,func,({} /*TODO: Save me?*/,ext_arg_2));
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(cond,i,cr1,e1_1,NONE()),source);
(wclst1,(_,ext_arg_3)) = traverseBackendDAEExpsWhenClause(SOME(i),wclst,func,({} /*TODO: Save me?*/,ext_arg_3));
then
(res,wclst1,ext_arg_3);

case (BackendDAE.WHEN_EQUATION(size=size,whenEquation =
BackendDAE.WHEN_EQ(index = i,left = cr,right = e1,elsewhenPart=SOME(elsepart)),source = source),wclst,_,_)
BackendDAE.WHEN_EQ(condition=cond,index = i,left = cr,right = e1,elsewhenPart=SOME(elsepart)),source = source),wclst,_,_)
equation
((e1_1,(ops,ext_arg_1))) = func((e1,({},inTypeA)));
((cond,(ops,ext_arg_2))) = func((cond,(ops,ext_arg_1)));
source = List.foldr(ops, DAEUtil.addSymbolicTransformation, source);
(BackendDAE.WHEN_EQUATION(whenEquation=elsepartRes,source=source),wclst1,ext_arg_2) = traverseBackendDAEExpsEqnWithSymbolicOperation(BackendDAE.WHEN_EQUATION(size,elsepart,source),wclst,func,ext_arg_1);
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(i,cr,e1_1,SOME(elsepartRes)),source);
(BackendDAE.WHEN_EQUATION(whenEquation=elsepartRes,source=source),wclst1,ext_arg_2) = traverseBackendDAEExpsEqnWithSymbolicOperation(BackendDAE.WHEN_EQUATION(size,elsepart,source),wclst,func,ext_arg_2);
res = BackendDAE.WHEN_EQUATION(size,BackendDAE.WHEN_EQ(cond,i,cr,e1_1,SOME(elsepartRes)),source);
(wclst2,(_,ext_arg_3)) = traverseBackendDAEExpsWhenClause(SOME(i),wclst1,func,({} /* TODO: Save me?*/,ext_arg_2));
then
(res,wclst2,ext_arg_3);
Expand Down

0 comments on commit fdf9c94

Please sign in to comment.