Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
Move parameter record bindings to initial equations
Browse files Browse the repository at this point in the history
Previously, parameter bindings that failed constant evaluation would be
silently discarded. Now we move them to the initial section and set
fixed=false, in addition to giving a notification stating that we did
this (it might influence some heuristics for matching, etc).

Belonging to [master]:
  - #1773
  - OpenModelica/OpenModelica-testsuite#678
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Oct 13, 2017
1 parent 37e75ad commit a9268a9
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 60 deletions.
17 changes: 17 additions & 0 deletions Compiler/FrontEnd/DAEUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -6499,6 +6499,23 @@ algorithm

end mergeAlgorithmSections;

public function moveElementToInitialSection "Converts DAE.Element from the equation section to the initial equation section"
input output DAE.Element elt;
algorithm
elt := match elt
case DAE.EQUATION() then DAE.INITIALEQUATION(elt.exp, elt.scalar, elt.source);
case DAE.DEFINE() then DAE.INITIALDEFINE(elt.componentRef, elt.exp, elt.source);
case DAE.ARRAY_EQUATION() then DAE.INITIAL_ARRAY_EQUATION(elt.dimension, elt.exp, elt.array, elt.source);
case DAE.COMPLEX_EQUATION() then DAE.INITIAL_COMPLEX_EQUATION(elt.lhs, elt.rhs, elt.source);
case DAE.IF_EQUATION() then DAE.INITIAL_IF_EQUATION(elt.condition1, elt.equations2, elt.equations3, elt.source);
case DAE.ALGORITHM() then DAE.INITIALALGORITHM(elt.algorithm_, elt.source);
case DAE.ASSERT() then DAE.INITIAL_ASSERT(elt.condition, elt.message, elt.level, elt.source);
case DAE.TERMINATE() then DAE.INITIAL_TERMINATE(elt.message, elt.source);
case DAE.NORETCALL() then DAE.INITIAL_NORETCALL(elt.exp, elt.source);
else elt;
end match;
end moveElementToInitialSection;

annotation(__OpenModelica_Interface="frontend");
end DAEUtil;

136 changes: 77 additions & 59 deletions Compiler/FrontEnd/InstUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -7033,88 +7033,106 @@ This function modifies equations into bindings for parameters"
input DAE.DAElist inVarsDae;
input DAE.DAElist inEquationsDae "Note: functions from here are not considered";
output DAE.DAElist outVarsDae;
protected
list<DAE.Element> vars, vars1, equations, equations1;
DAE.Element v1;
Integer i;
list<Integer> is;
DAE.Exp e;
DAE.ComponentRef cr;
Absyn.Path path;
algorithm
outVarsDae := matchcontinue(inVarsDae,inEquationsDae)
local
list<DAE.Element> vars, vars1, equations;
DAE.Element var;
DAE.Exp e;
DAE.ComponentRef componentRef;
DAE.VarKind kind;
DAE.VarDirection direction;
DAE.VarParallelism parallelism;
DAE.VarVisibility protection;
DAE.Type ty;
DAE.InstDims dims;
DAE.ConnectorType ct;
Option<DAE.VariableAttributes> variableAttributesOption;
Option<SCode.Comment> absynCommentOption;
Absyn.InnerOuter innerOuter;
DAE.ElementSource source "the origin of the element";
case (DAE.DAE(vars),DAE.DAE({})) then DAE.DAE(vars);
case (DAE.DAE({}),_) then DAE.DAE({});
case (DAE.DAE(DAE.VAR(componentRef,kind,direction,parallelism,protection,ty,NONE(),
dims,ct,source,variableAttributesOption,
absynCommentOption,innerOuter)::vars), DAE.DAE(equations))
equation
SOME(e)=findCorrespondingBinding(componentRef, equations);
DAE.DAE(vars1) = propagateBinding(DAE.DAE(vars),DAE.DAE(equations));
then
DAE.DAE(DAE.VAR(componentRef,kind,direction,parallelism,protection,ty,SOME(e),dims,
ct,source,variableAttributesOption, absynCommentOption,innerOuter)::vars1);

case (DAE.DAE(var::vars), DAE.DAE(equations))
equation
DAE.DAE(vars1)=propagateBinding(DAE.DAE(vars),DAE.DAE(equations));
then
DAE.DAE(var::vars1);
end matchcontinue;
DAE.DAE(vars) := inVarsDae;
DAE.DAE(equations) := inEquationsDae;
if listEmpty(vars) or listEmpty(equations) then
outVarsDae := inVarsDae;
return;
end if;
vars1 := {};
is := {};
for v in vars loop
v1 := matchcontinue v
case v1 as DAE.VAR()
algorithm
(e,i) := findCorrespondingBinding(v1.componentRef, equations);
v1.binding := SOME(e);
is := i::is;
then v1;
else v;
end matchcontinue;
vars1 := v1::vars1;
end for;
vars1 := listReverse(vars1);
equations1 := List.deletePositions(equations, is);
equations1 := list(DAEUtil.moveElementToInitialSection(eq) for eq in equations);
i := 0;
for eq in equations1 loop
_ := match eq
case DAE.INITIALEQUATION(exp1=DAE.CREF(ty=DAE.T_COMPLEX()), exp2=DAE.CALL(path=path))
guard Absyn.pathLastIdent(path)=="constructor"
algorithm
// Don't duplicate constructor calls
is := i::is;
then ();
case DAE.INITIAL_COMPLEX_EQUATION(lhs=DAE.CREF(componentRef=cr))
algorithm
vars1 := list(match v
case DAE.VAR(binding=SOME(_)) guard ComponentReference.crefPrefixOf(cr, v.componentRef)
algorithm
is := i::is;
then v;
// Moving parameter bindings into initial equation section means we need to force fixed=false...
case DAE.VAR(binding=NONE()) guard ComponentReference.crefPrefixOf(cr, v.componentRef)
algorithm
v.variableAttributesOption := DAEUtil.setFixedAttr(v.variableAttributesOption, SOME(DAE.BCONST(false)));
Error.addSourceMessage(Error.MOVING_PARAMETER_BINDING_TO_INITIAL_EQ_SECTION, {ComponentReference.printComponentRefStr(v.componentRef)}, eq.source.info);
then v;
else v;
end match for v in vars1);
then ();
else /* algorithm print(anyString(eq)); */ then ();
end match;
i := i+1;
end for;
equations1 := List.deletePositions(equations1, is);
outVarsDae := DAE.DAE(listAppend(equations1, vars1));
end propagateBinding;

protected function findCorrespondingBinding "
Helper function for propagateBinding"
input DAE.ComponentRef inCref;
input list<DAE.Element> inEquations;
output Option<DAE.Exp> outExp;
output DAE.Exp outExp;
input output Integer i=0;
algorithm
outExp:=matchcontinue(inCref, inEquations)
outExp :=match (inCref, inEquations)
local
DAE.ComponentRef cref,cref2,cref3;
DAE.Exp e;
list<DAE.Element> equations;

case (_, {}) then NONE();

case (cref, DAE.DEFINE(componentRef=cref2, exp=e)::_)
equation
true = ComponentReference.crefEqual(cref,cref2);
then
SOME(e);
guard ComponentReference.crefEqual(cref,cref2)
then e;

case (cref, DAE.EQUATION(exp=DAE.CREF(cref2,_),scalar=e)::_)
equation
true = ComponentReference.crefEqual(cref,cref2);
then
SOME(e);
guard ComponentReference.crefEqual(cref,cref2)
then e;

case (cref, DAE.EQUEQUATION(cr1=cref2,cr2=cref3)::_)
equation
true = ComponentReference.crefEqual(cref,cref2);
e = Expression.crefExp(cref3);
then
SOME(e);
guard ComponentReference.crefEqual(cref,cref2)
then Expression.crefExp(cref3);

case (cref, DAE.COMPLEX_EQUATION(lhs=DAE.CREF(cref2,_),rhs=e)::_)
equation
true = ComponentReference.crefEqual(cref,cref2);
then
SOME(e);
guard ComponentReference.crefEqual(cref,cref2)
then e;

case (cref, _::equations)
then
findCorrespondingBinding(cref,equations);
algorithm
(outExp,i) := findCorrespondingBinding(cref,equations,i+1);
then outExp;

end matchcontinue;
end match;
end findCorrespondingBinding;

public function isPartial
Expand Down
2 changes: 2 additions & 0 deletions Compiler/Util/Error.mo
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,8 @@ public constant Message EQN_NO_SPACE_TO_SOLVE = MESSAGE(581, SYMBOLIC(), WARNING
Util.gettext("Equation %s (size: %s) %s is not big enough to solve for enough variables.\n Remaining unsolved variables are: %s\n Already solved: %s\n Equations used to solve those variables:%s"));
public constant Message VAR_NO_REMAINING_EQN = MESSAGE(582, SYMBOLIC(), WARNING(),
Util.gettext("Variable %s does not have any remaining equation to be solved in.\n The original equations were:%s"));
public constant Message MOVING_PARAMETER_BINDING_TO_INITIAL_EQ_SECTION = MESSAGE(582, TRANSLATION(), NOTIFICATION(),
Util.gettext("Moving binding to equation section and setting fixed attribute of %s to false. This is done to work around a compiler design flaw (there is no good way to represent bindings that span multiple variables)."));

public constant Message MATCH_SHADOWING = MESSAGE(5001, TRANSLATION(), ERROR(),
Util.gettext("Local variable '%s' shadows another variable."));
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Util/List.mo
Original file line number Diff line number Diff line change
Expand Up @@ -6221,7 +6221,7 @@ public function deletePositions<T>
protected
list<Integer> sorted_pos;
algorithm
sorted_pos := sort(inPositions, intGt);
sorted_pos := sortedUnique(sort(inPositions, intGt), intEq);
outList := deletePositionsSorted(inList, sorted_pos);
end deletePositions;

Expand Down

0 comments on commit a9268a9

Please sign in to comment.