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

Commit 46705f7

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
[NF] Evaluate cat and promote operators
The cat operator calls ExpressionSimplify.evalCat which has been rewritten to be a higher-order function that allows you to perform cat on any tree structure (to reduce maintenance effort). Belonging to [master]: - #2243
1 parent 85e6162 commit 46705f7

File tree

3 files changed

+124
-25
lines changed

3 files changed

+124
-25
lines changed

Compiler/FrontEnd/Expression.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3564,6 +3564,16 @@ algorithm
35643564
outArray := DAE.ARRAY(inType, inScalar, inElements);
35653565
end makeArray;
35663566

3567+
public function makeArrayFromList
3568+
input list<DAE.Exp> inElements;
3569+
output DAE.Exp outArray;
3570+
protected
3571+
DAE.Type ty;
3572+
algorithm
3573+
ty := typeof(listHead(inElements));
3574+
outArray := DAE.ARRAY(ty, not Types.isArray(ty), inElements);
3575+
end makeArrayFromList;
3576+
35673577
public function makeScalarArray
35683578
"Constructs an array of the given scalar type."
35693579
input list<DAE.Exp> inExpLst;

Compiler/FrontEnd/ExpressionSimplify.mo

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ algorithm
10971097
Real r1;
10981098
array<array<DAE.Exp>> marr;
10991099
String name, s1, s2;
1100+
list<Integer> dims;
11001101

11011102
// If the argument to min/max is an array, try to flatten it.
11021103
case (DAE.CALL(path=Absyn.IDENT(name),expLst={e as DAE.ARRAY()},
@@ -1378,7 +1379,8 @@ algorithm
13781379

13791380
case DAE.CALL(path=Absyn.IDENT("cat"),expLst=DAE.ICONST(i)::es,attr=DAE.CALL_ATTR(ty=tp))
13801381
algorithm
1381-
e := evalCat(i,es);
1382+
(es,dims) := evalCat(i, es, getArrayContents=Expression.getArrayOrMatrixContents, toString=ExpressionDump.printExpStr);
1383+
e := Expression.listToArray(es, list(DAE.DIM_INTEGER(d) for d in dims));
13821384
then e;
13831385

13841386
// promote n-dim to n-dim
@@ -1604,37 +1606,50 @@ algorithm
16041606
end matchcontinue;
16051607
end simplifyCat2;
16061608

1607-
protected function evalCat
1609+
public function evalCat<Exp>
16081610
input Integer dim;
1609-
input list<DAE.Exp> exps;
1610-
output DAE.Exp outExp;
1611+
input list<Exp> exps;
1612+
input GetArrayContents getArrayContents;
1613+
input ToString toString;
1614+
output list<Exp> outExps;
1615+
output list<Integer> outDims;
1616+
partial function GetArrayContents
1617+
input Exp e;
1618+
output list<Exp> es;
1619+
end GetArrayContents;
1620+
partial function MakeArrayFromList
1621+
input list<Exp> es;
1622+
output Exp e;
1623+
end MakeArrayFromList;
1624+
partial function ToString
1625+
input Exp e;
1626+
output String s;
1627+
end ToString;
16111628
protected
1612-
list<DAE.Exp> arr;
1613-
list<list<DAE.Exp>> arrs={};
1629+
list<Exp> arr;
1630+
list<list<Exp>> arrs={};
16141631
list<Integer> dims, firstDims={}, lastDims, reverseDims;
16151632
list<list<Integer>> dimsLst={};
1616-
DAE.Type tp;
16171633
Integer j, k, l, thisDim, lastDim;
1618-
array<DAE.Exp> expArr;
1634+
array<Exp> expArr;
16191635
algorithm
16201636
true := dim >= 1;
16211637
false := listEmpty(exps);
16221638
if 1 == dim then
1623-
arr := listAppend(Expression.getArrayOrMatrixContents(e) for e in exps);
1624-
tp := Expression.typeof(listHead(arr));
1625-
outExp := Expression.makeArray(arr, tp, not Types.isArray(tp));
1639+
outExps := listAppend(getArrayContents(e) for e in exps);
1640+
outDims := {listLength(outExps)};
16261641
return;
16271642
end if;
16281643
for e in listReverse(exps) loop
16291644
// Here we get a linear representation of all expressions in the array
16301645
// and the dimensions necessary to build up the array again
1631-
(arr,dims) := evalCatGetFlatArray(e,dim);
1646+
(arr,dims) := evalCatGetFlatArray(e, dim, getArrayContents=getArrayContents, toString=toString);
16321647
arrs := arr::arrs;
16331648
dimsLst := dims::dimsLst;
16341649
end for;
16351650
for i in 1:(dim-1) loop
16361651
j := min(listHead(d) for d in dimsLst);
1637-
Error.assertion(j == max(listHead(d) for d in dimsLst), getInstanceName() + ": cat got uneven dimensions for dim=" + String(i) + " " + ExpressionDump.printExpStr(DAE.LIST(exps)), sourceInfo());
1652+
Error.assertion(j == max(listHead(d) for d in dimsLst), getInstanceName() + ": cat got uneven dimensions for dim=" + String(i) + " " + stringDelimitList(list(toString(e) for e in exps), ", "), sourceInfo());
16381653
firstDims := j :: firstDims;
16391654
dimsLst := list(listRest(d) for d in dimsLst);
16401655
end for;
@@ -1658,33 +1673,42 @@ algorithm
16581673
end for;
16591674
// Convert the flat array structure to a tree array structure with the
16601675
// correct dimensions
1661-
arr := arrayList(expArr);
1662-
outExp := Expression.listToArray(arr, listReverse(DAE.DIM_INTEGER(d) for d in reverseDims));
1676+
outExps := arrayList(expArr);
1677+
outDims := listReverse(reverseDims);
16631678
end evalCat;
16641679

1665-
protected function evalCatGetFlatArray
1666-
input DAE.Exp e;
1680+
protected function evalCatGetFlatArray<Exp>
1681+
input Exp e;
16671682
input Integer dim;
1668-
output list<DAE.Exp> outExps={};
1683+
input GetArrayContents getArrayContents;
1684+
input ToString toString;
1685+
output list<Exp> outExps={};
16691686
output list<Integer> outDims={};
1687+
partial function GetArrayContents
1688+
input Exp e;
1689+
output list<Exp> es;
1690+
end GetArrayContents;
1691+
partial function ToString
1692+
input Exp e;
1693+
output String s;
1694+
end ToString;
16701695
protected
1671-
list<DAE.Exp> arr;
1696+
list<Exp> arr;
16721697
list<Integer> dims;
1673-
DAE.Type tp;
16741698
Integer i;
16751699
algorithm
16761700
if dim == 1 then
1677-
outExps := Expression.getArrayOrMatrixContents(e);
1701+
outExps := getArrayContents(e);
16781702
outDims := {listLength(outExps)};
16791703
return;
16801704
end if;
16811705
i := 0;
1682-
for exp in listReverse(Expression.getArrayOrMatrixContents(e)) loop
1683-
(arr, dims) := evalCatGetFlatArray(exp, dim-1);
1706+
for exp in listReverse(getArrayContents(e)) loop
1707+
(arr, dims) := evalCatGetFlatArray(exp, dim-1, getArrayContents=getArrayContents, toString=toString);
16841708
if listEmpty(outDims) then
16851709
outDims := dims;
16861710
else
1687-
Error.assertion(valueEq(dims, outDims), getInstanceName() + ": Got unbalanced array from " + ExpressionDump.printExpStr(e), sourceInfo());
1711+
Error.assertion(valueEq(dims, outDims), getInstanceName() + ": Got unbalanced array from " + toString(e), sourceInfo());
16881712
end if;
16891713
outExps := listAppend(arr, outExps);
16901714
i := i+1;

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import NFCall.Call;
4343
import Dimension = NFDimension;
4444
import Type = NFType;
4545
import NFTyping.ExpOrigin;
46+
import ExpressionSimplify;
4647

4748
protected
4849
import NFFunction.Function;
@@ -344,7 +345,7 @@ algorithm
344345
case "asin" then evalBuiltinAsin(listHead(args), target);
345346
case "atan2" then evalBuiltinAtan2(args);
346347
case "atan" then evalBuiltinAtan(listHead(args));
347-
//case "cat" then evalBuiltinCat(args, target);
348+
case "cat" then evalBuiltinCat(listHead(args), listRest(args), target);
348349
case "ceil" then evalBuiltinCeil(listHead(args));
349350
case "cosh" then evalBuiltinCosh(listHead(args));
350351
case "cos" then evalBuiltinCos(listHead(args));
@@ -367,6 +368,7 @@ algorithm
367368
case "noEvent" then listHead(args); // No events during ceval, just return the argument.
368369
case "ones" then evalBuiltinOnes(args);
369370
case "product" then evalBuiltinProduct(listHead(args));
371+
case "promote" then evalBuiltinPromote(listGet(args,1),listGet(args,2));
370372
case "rem" then evalBuiltinRem(args, target);
371373
case "scalar" then evalBuiltinScalar(args);
372374
case "sign" then evalBuiltinSign(listHead(args));
@@ -537,6 +539,30 @@ algorithm
537539
end match;
538540
end evalBuiltinAtan;
539541

542+
function evalBuiltinCat
543+
input Expression argN;
544+
input list<Expression> args;
545+
input EvalTarget target;
546+
output Expression result;
547+
protected
548+
Integer n, nd;
549+
Type ty;
550+
list<Expression> es;
551+
list<Integer> dims;
552+
algorithm
553+
Expression.INTEGER(n) := argN;
554+
ty := Expression.typeOf(listHead(args));
555+
nd := Type.dimensionCount(ty);
556+
if n > nd or n < 1 then
557+
if EvalTarget.hasInfo(target) then
558+
Error.addSourceMessage(Error.ARGUMENT_OUT_OF_RANGE, {String(n), "cat", "1 <= x <= " + String(nd)}, EvalTarget.getInfo(target));
559+
end if;
560+
fail();
561+
end if;
562+
(es,dims) := ExpressionSimplify.evalCat(n, args, getArrayContents=Expression.arrayElements, toString=Expression.toString);
563+
result := Expression.arrayFromList(es, Type.arrayElementType(ty), list(Dimension.INTEGER(d) for d in dims));
564+
end evalBuiltinCat;
565+
540566
function evalBuiltinCeil
541567
input Expression arg;
542568
output Expression result;
@@ -931,6 +957,45 @@ algorithm
931957
end match;
932958
end evalBuiltinProductReal;
933959

960+
function evalBuiltinPromote
961+
input Expression arg, argN;
962+
output Expression result;
963+
protected
964+
Integer n, numToPromote;
965+
Type ty;
966+
algorithm
967+
Expression.INTEGER(n) := argN;
968+
ty := Expression.typeOf(arg);
969+
numToPromote := n - Type.dimensionCount(ty);
970+
result := evalBuiltinPromoteWork(arg, n);
971+
end evalBuiltinPromote;
972+
973+
function evalBuiltinPromoteWork
974+
input Expression arg;
975+
input Integer n;
976+
output Expression result;
977+
protected
978+
Expression exp;
979+
list<Expression> exps;
980+
Type ty;
981+
algorithm
982+
Error.assertion(n >= 1, "Promote called with n<1", sourceInfo());
983+
if n == 1 then
984+
result := Expression.ARRAY(Type.liftArrayLeft(Expression.typeOf(arg),Dimension.INTEGER(1)), {arg});
985+
return;
986+
end if;
987+
result := match arg
988+
case Expression.ARRAY()
989+
algorithm
990+
(exps as (Expression.ARRAY(ty=ty)::_)) := list(evalBuiltinPromoteWork(e, n-1) for e in arg.elements);
991+
then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.INTEGER(listLength(arg.elements))), exps);
992+
else
993+
algorithm
994+
(exp as Expression.ARRAY(ty=ty)) := evalBuiltinPromoteWork(arg, n-1);
995+
then Expression.ARRAY(Type.liftArrayLeft(ty,Dimension.INTEGER(1)), {exp});
996+
end match;
997+
end evalBuiltinPromoteWork;
998+
934999
function evalBuiltinRem
9351000
input list<Expression> args;
9361001
input EvalTarget target;

0 commit comments

Comments
 (0)