Skip to content

Commit

Permalink
Various minor NF fixes (#7377)
Browse files Browse the repository at this point in the history
- Change ComponentRef.updateNodeType so it only sets the type of nodes
  that actually have a type.
- Change Dimension.mapExp to use fromExp instead of directly creating an
  EXP dimension, since the new dimension might be e.g. an Integer.
- Improve EvalConstants to better handle constants in dimensions.
- Change EvalConstants.evaluateFunction to use evaluateAlgorithm for the
  function body rather than just mapping the expressions, since
  evaluateAlgorithm also handles e.g. the types of statements.
- Allow evaluation of dimensions to fail in functions, since they might
  be dependent on the input arguments.
  • Loading branch information
perost committed Apr 15, 2021
1 parent d0cf082 commit dde0e4c
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 14 deletions.
14 changes: 14 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -67,6 +67,7 @@ import ElementSource;
import Flags;
import Prefixes = NFPrefixes;
import UnorderedMap;
import ErrorExt;

public
uniontype EvalTarget
Expand Down Expand Up @@ -150,6 +151,19 @@ uniontype EvalTarget
end getInfo;
end EvalTarget;

function tryEvalExp
input output Expression exp;
algorithm
ErrorExt.setCheckpoint(getInstanceName());

try
exp := evalExp(exp);
else
end try;

ErrorExt.rollBack(getInstanceName());
end tryEvalExp;

function evalExp
input output Expression exp;
input EvalTarget target = EvalTarget.IGNORE_ERRORS();
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo
Expand Up @@ -225,7 +225,7 @@ public
input output ComponentRef cref;
algorithm
() := match cref
case CREF()
case CREF() guard InstNode.isComponent(cref.node)
algorithm
cref.ty := InstNode.getType(cref.node);
then
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFDimension.mo
Expand Up @@ -435,7 +435,7 @@ public
algorithm
e2 := Expression.map(e1, func);
then
if referenceEq(e1, e2) then dim else EXP(e2, dim.var);
if referenceEq(e1, e2) then dim else fromExp(e2, dim.var);

else dim;
end match;
Expand Down
29 changes: 22 additions & 7 deletions OMCompiler/Compiler/NFFrontEnd/NFEvalConstants.mo
Expand Up @@ -133,6 +133,19 @@ algorithm
outExp := evaluateExpTraverser(exp, info);
end evaluateExp;

function evaluateExpOpt
input Option<Expression> exp;
input SourceInfo info;
output Option<Expression> outExp;
protected
Expression e;
algorithm
outExp := match exp
case SOME(e) then SOME(evaluateExp(e, info));
else exp;
end match;
end evaluateExpOpt;

function evaluateExpTraverser
input Expression exp;
input SourceInfo info;
Expand Down Expand Up @@ -184,6 +197,9 @@ algorithm
then
outExp;

case Expression.SIZE()
then Expression.SIZE(exp.exp, evaluateExpOpt(exp.dimIndex, info));

else
algorithm
(outExp, outChanged) := Expression.mapFoldShallow(exp,
Expand Down Expand Up @@ -227,12 +243,7 @@ algorithm

case Dimension.EXP()
algorithm
if dim.var <= Variability.STRUCTURAL_PARAMETER and not
Expression.containsAnyIterator(dim.exp, NFInstContext.FOR) then
e := Ceval.evalExp(dim.exp, Ceval.EvalTarget.GENERIC(info));
else
e := evaluateExp(dim.exp, info);
end if;
e := evaluateExp(dim.exp, info);
then
if referenceEq(e, dim.exp) then dim else Dimension.fromExp(e, dim.var);

Expand Down Expand Up @@ -522,7 +533,11 @@ protected
algorithm
if not Function.isEvaluated(func) then
Function.markEvaluated(func);
func := Function.mapExp(func, function evaluateFuncExp(fnNode = func.node));

func := Function.mapExp(func, function evaluateFuncExp(fnNode = func.node),
mapBody = Function.isExternal(func));

func := Function.mapBody(func, evaluateAlgorithm);

for fn_der in func.derivatives loop
for der_fn in Function.getCachedFuncs(fn_der.derivativeFn) loop
Expand Down
17 changes: 17 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -1907,6 +1907,23 @@ uniontype Function
end if;
end mapExpParameter;

function mapBody
input output Function fn;
input MapFn mapFn;

partial function MapFn
input output Algorithm alg;
end MapFn;
protected
Class cls;
Sections sections;
algorithm
cls := InstNode.getClass(fn.node);
sections := Sections.map(Class.getSections(cls), algFn = mapFn);
cls := cls.setSections(sections, cls);
InstNode.updateClass(cls, fn.node);
end mapBody;

function foldExp<ArgT>
input Function fn;
input FoldFunc foldFn;
Expand Down
12 changes: 10 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFSections.mo
Expand Up @@ -194,8 +194,8 @@ public

function map
input output Sections sections;
input EquationFn eqFn;
input AlgorithmFn algFn;
input EquationFn eqFn = eqId;
input AlgorithmFn algFn = algId;
input EquationFn ieqFn = eqFn;
input AlgorithmFn ialgFn = algFn;

Expand All @@ -206,6 +206,14 @@ public
partial function AlgorithmFn
input output Algorithm alg;
end AlgorithmFn;

function eqId
input output Equation eq;
end eqId;

function algId
input output Algorithm alg;
end algId;
protected
list<Equation> eq, ieq;
list<Algorithm> alg, ialg;
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -550,7 +550,7 @@ algorithm
else
// For functions, only evaluate constant and structural parameter expressions.
if var <= Variability.STRUCTURAL_PARAMETER then
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
exp := Ceval.tryEvalExp(exp);
end if;
end if;

Expand Down
52 changes: 52 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FunctionRecordArg3.mo
@@ -0,0 +1,52 @@
// name: FunctionRecordArg3
// keywords:
// status: correct
// cflags: -d=newInst
//

record BaseR
constant Integer n;
parameter Real x[n];
end BaseR;

function f
input BaseR r;
output Real x;
algorithm
x := r.x * r.x;
end f;

record R = BaseR(n = 2);

model FunctionRecordArg3
R r(x = {1, 2});
Real x = f(r);
end FunctionRecordArg3;

// Result:
// function BaseR "Automatically generated record constructor for BaseR"
// constant Integer n;
// input Real[n] x;
// output BaseR res;
// end BaseR;
//
// function R "Automatically generated record constructor for R"
// protected Integer n = 2;
// input Real[2] x;
// output R res;
// end R;
//
// function f
// input BaseR r;
// output Real x;
// algorithm
// x := r.x * r.x;
// end f;
//
// class FunctionRecordArg3
// constant Integer r.n = 2;
// parameter Real r.x[1] = 1.0;
// parameter Real r.x[2] = 2.0;
// Real x = f(r);
// end FunctionRecordArg3;
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -572,6 +572,7 @@ FunctionNoOutput1.mo \
FunctionNonInputOutputParameter.mo \
FunctionRecordArg1.mo \
FunctionRecordArg2.mo \
FunctionRecordArg3.mo \
FunctionRecursive1.mo \
FunctionRecursive2.mo \
FunctionSections1.mo \
Expand Down
4 changes: 2 additions & 2 deletions testsuite/openmodelica/xml/XmlDumpComment.mos
Expand Up @@ -21686,13 +21686,13 @@ readFile("Modelica.Mechanics.MultiBody.Examples.Elementary.Pendulum.xml");
// protected Real c3;
// protected Real c4;
// protected constant Real p4limit = 0.1;
// protected constant Real c4limit = 4.0 * p4limit * p4limit;
// protected constant Real c4limit = 0.04000000000000001;
// algorithm
// c1 := 1.0 + T[1,1] - T[2,2] - T[3,3];
// c2 := 1.0 + T[2,2] - T[1,1] - T[3,3];
// c3 := 1.0 + T[3,3] - T[1,1] - T[2,2];
// c4 := 1.0 + T[1,1] + T[2,2] + T[3,3];
// if c4 &gt; c4limit or c4 &gt; c1 and c4 &gt; c2 and c4 &gt; c3 then
// if c4 &gt; 0.04000000000000001 or c4 &gt; c1 and c4 &gt; c2 and c4 &gt; c3 then
// paux := sqrt(c4) / 2.0;
// paux4 := 4.0 * paux;
// Q := {(T[2,3] - T[3,2]) / paux4, (T[3,1] - T[1,3]) / paux4, (T[1,2] - T[2,1]) / paux4, paux};
Expand Down

0 comments on commit dde0e4c

Please sign in to comment.