diff --git a/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo b/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo index 029819b782d..7fb86eef923 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFSimplifyExp.mo @@ -193,14 +193,7 @@ algorithm callExp; case Call.TYPED_ARRAY_CONSTRUCTOR() then simplifyArrayConstructor(call); - - case Call.TYPED_REDUCTION() - algorithm - call.exp := simplify(call.exp); - call.iters := list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in call.iters); - then - Expression.CALL(call); - + case Call.TYPED_REDUCTION() then simplifyReduction(call); else callExp; end match; end simplifyCall; @@ -345,6 +338,52 @@ algorithm end matchcontinue; end simplifyArrayConstructor; +function simplifyReduction + input Call call; + output Expression outExp; +algorithm + outExp := match call + local + Expression exp, e; + list> iters; + InstNode iter; + Dimension dim; + Integer dim_size; + + case Call.TYPED_REDUCTION() + algorithm + iters := list((Util.tuple21(i), simplify(Util.tuple22(i))) for i in call.iters); + then matchcontinue iters + case {(iter, e)} + algorithm + Type.ARRAY(dimensions = {dim}) := Expression.typeOf(e); + dim_size := Dimension.size(dim); + + if dim_size == 0 then + // Iteration range is empty, return default value for reduction. + SOME(outExp) := call.defaultExp; + elseif dim_size == 1 then + // Iteration range is one, return reduction expression with iterator value applied. + (Expression.ARRAY(elements = {e}), _) := ExpandExp.expand(e); + outExp := Expression.replaceIterator(call.exp, iter, e); + outExp := simplify(outExp); + else + fail(); + end if; + then + outExp; + + else + algorithm + call.exp := simplify(call.exp); + call.iters := iters; + then + Expression.CALL(call); + + end matchcontinue; + end match; +end simplifyReduction; + function simplifySize input output Expression sizeExp; algorithm diff --git a/testsuite/flattening/modelica/scodeinst/FuncBuiltinReduction.mo b/testsuite/flattening/modelica/scodeinst/FuncBuiltinReduction.mo index 0b814148d29..e32b3e57201 100644 --- a/testsuite/flattening/modelica/scodeinst/FuncBuiltinReduction.mo +++ b/testsuite/flattening/modelica/scodeinst/FuncBuiltinReduction.mo @@ -46,25 +46,25 @@ end FuncBuiltinReduction; // Real r3 = sum(/*Real*/(r) * 2.0 for r in 1:10); // Real r4 = product(/*Real*/(r) ^ 2.0 for r in 1:5); // Real r5 = sum(/*Real*/(x * y) for x in 1:4, y in 3:9); -// Real r6 = min(/*Real*/(r) * 2.0 for r in 1:0); -// Real r7 = max(/*Real*/(r) * 2.0 for r in 1:0); -// Real r8 = sum(/*Real*/(r) * 2.0 for r in 1:0); -// Real r9 = product(/*Real*/(r) * 2.0 for r in 1:0); +// Real r6 = 8.777798510069901e+304; +// Real r7 = -8.777798510069901e+304; +// Real r8 = 0.0; +// Real r9 = 1.0; // Integer i1 = min(i - 1 for i in {2, 4, 1}); // Integer i2 = max(i for i in {4, 2, 9}); // Integer i3 = sum(i * i for i in {1, 2, 3}); // Integer i4 = product(i for i in 4:9); -// Integer i5 = min(i for i in 1:0); -// Integer i6 = max(i for i in 1:0); -// Integer i7 = sum(i for i in 1:0); -// Integer i8 = product(i for i in 1:0); +// Integer i5 = 4611686018427387903; +// Integer i6 = -4611686018427387903; +// Integer i7 = 0; +// Integer i8 = 1; // Boolean b1 = min(not b for b in {false, true}); // Boolean b2 = max(i == 2 for i in 1:4); -// Boolean b3 = min(b for b in true:false); -// Boolean b4 = max(b for b in true:false); +// Boolean b3 = true; +// Boolean b4 = false; // enumeration(one, two, three) e1 = min(e for e in E.one:E.three); // enumeration(one, two, three) e2 = max(e for e in {E.one, E.two, E.three}); -// enumeration(one, two, three) e3 = min(e for e in E.three:E.one); -// enumeration(one, two, three) e4 = max(e for e in E.three:E.one); +// enumeration(one, two, three) e3 = E.three; +// enumeration(one, two, three) e4 = E.one; // end FuncBuiltinReduction; // endResult