Skip to content

Commit

Permalink
Fix for #2743:
Browse files Browse the repository at this point in the history
- Extended Expression.transposeArray to handle >2 dimensions.
- Removed evaluation of transpose from Static and Ceval, let ExpressionSimplify
  handle it instead.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@21387 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed Jul 1, 2014
1 parent 8f16a5d commit 26bf7aa
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 194 deletions.
43 changes: 0 additions & 43 deletions Compiler/FrontEnd/Ceval.mo
Expand Up @@ -1132,7 +1132,6 @@ algorithm
case "min" then cevalBuiltinMin;
case "rem" then cevalBuiltinRem;
case "diagonal" then cevalBuiltinDiagonal;
case "transpose" then cevalBuiltinTranspose;
case "differentiate" then cevalBuiltinDifferentiate;
case "simplify" then cevalBuiltinSimplify;
case "sign" then cevalBuiltinSign;
Expand Down Expand Up @@ -4298,48 +4297,6 @@ algorithm
end matchcontinue;
end cevalBuiltinCross;

protected function cevalBuiltinTranspose "This function transposes the two first dimension of an array A."
input Env.Cache inCache;
input Env.Env inEnv;
input list<DAE.Exp> inExpExpLst;
input Boolean inBoolean;
input Option<GlobalScript.SymbolTable> inST;
input Absyn.Msg inMsg;
input Integer numIter;
output Env.Cache outCache;
output Values.Value outValue;
output Option<GlobalScript.SymbolTable> outInteractiveInteractiveSymbolTableOption;
algorithm
(outCache,outValue,outInteractiveInteractiveSymbolTableOption):=
matchcontinue (inCache,inEnv,inExpExpLst,inBoolean,inST,inMsg,numIter)
local
list<Values.Value> vlst,vlst2,vlst_1;
Integer i1,i2;
list<Integer> il;
Env.Env env;
DAE.Exp exp;
Boolean impl;
Option<GlobalScript.SymbolTable> st;
Absyn.Msg msg;
Env.Cache cache;
Absyn.Info info;

case (cache,env,{exp},impl,st,msg,_)
equation
(cache,Values.ARRAY(vlst,i1::_),_) = ceval(cache,env,exp,impl,st,msg,numIter+1);
(Values.ARRAY(valueLst = _, dimLst = i2::il) :: _) = vlst;
vlst_1 = cevalBuiltinTranspose2(vlst, 1, i2::i1::il);
then
(cache,Values.ARRAY(vlst_1,i2::i1::il),st);
case (_,_,_,_,_,Absyn.MSG(info = info),_)
equation
Error.addSourceMessage(Error.COMPILER_ERROR,
{"Could not evaluate transpose. Celab.cevalBuildinTranspose failed."}, info);
then
fail();
end matchcontinue;
end cevalBuiltinTranspose;

protected function cevalBuiltinTranspose2 "author: PA
Helper function to cevalBuiltinTranspose"
input list<Values.Value> inValuesValueLst1;
Expand Down
42 changes: 35 additions & 7 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -1569,6 +1569,31 @@ algorithm
DAE.ARRAY(array=es) := e;
end getArrayContents;

public function getArrayOrMatrixContents
"Returns the contents of an array or matrix as a list of expressions."
input DAE.Exp inExp;
output list<DAE.Exp> outContents;
algorithm
outContents := match(inExp)
local
list<DAE.Exp> expl;
list<list<DAE.Exp>> mat;
DAE.Type ty, el_ty;
DAE.Dimensions dims;
DAE.TypeSource src;
Boolean sc;

case DAE.ARRAY(array = expl) then expl;
case DAE.MATRIX(ty = DAE.T_ARRAY(el_ty, _ :: dims, src), matrix = mat)
equation
ty = DAE.T_ARRAY(el_ty, dims, src);
sc = Types.basicType(el_ty);
then
List.map2(mat, Expression.makeArray, ty, sc);

end match;
end getArrayOrMatrixContents;

public function getComplexContents "returns the list of expressions from a complex structure like array,record,call,tuple...
author:Waurich TUD 2014-04"
input DAE.Exp e;
Expand Down Expand Up @@ -10482,29 +10507,32 @@ algorithm
local
DAE.Type ty, row_ty;
DAE.Dimension dim1, dim2;
DAE.Dimensions rest_dims;
DAE.TypeSource ty_src;
list<Exp> expl;
list<list<Exp>> matrix;
Integer i;

case DAE.ARRAY(DAE.T_ARRAY(ty, {dim1, dim2}, ty_src), _, {})
then (DAE.ARRAY(DAE.T_ARRAY(ty, {dim2, dim1}, ty_src), false, {}), true);
// Empty array, just transpose the type.
case DAE.ARRAY(DAE.T_ARRAY(ty, dim1 :: dim2 :: rest_dims, ty_src), _, {})
then (DAE.ARRAY(DAE.T_ARRAY(ty, dim2 :: dim1 :: rest_dims, ty_src), false, {}), true);

case DAE.ARRAY(DAE.T_ARRAY(ty, {dim1, dim2}, ty_src), _, expl)
case DAE.ARRAY(DAE.T_ARRAY(ty, dim1 :: dim2 :: rest_dims, ty_src), _, expl)
equation
row_ty = DAE.T_ARRAY(ty, {dim1}, ty_src);
matrix = List.map(expl, getArrayContents);
row_ty = DAE.T_ARRAY(ty, dim1 :: rest_dims, ty_src);
matrix = List.map(expl, getArrayOrMatrixContents);
matrix = List.transposeList(matrix);
expl = List.map2(matrix, makeArray, row_ty, true);
then
(DAE.ARRAY(DAE.T_ARRAY(ty, {dim2, dim1}, ty_src), false, expl), true);
(DAE.ARRAY(DAE.T_ARRAY(ty, dim2 :: dim1 :: rest_dims, ty_src), false, expl), true);

case DAE.MATRIX (matrix=matrix,ty=DAE.T_ARRAY(ty, {dim1, dim2}, ty_src))
equation
matrix = List.transposeList(matrix);
ty = DAE.T_ARRAY(ty, {dim2, dim1}, ty_src);
i = listLength(matrix);
then (DAE.MATRIX(ty,i,matrix), true);
then
(DAE.MATRIX(ty,i,matrix), true);

else (inArray, false);

Expand Down
168 changes: 24 additions & 144 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -3654,159 +3654,39 @@ algorithm
end match;
end elabBuiltinClassDirectory;

protected function elabBuiltinTranspose "This function elaborates the builtin operator transpose
The input is the arguments to fill as Absyn.Exp expressions and the environment Env.Env"
protected function elabBuiltinTranspose
"Elaborates the builtin operator transpose."
input Env.Cache inCache;
input Env.Env inEnv;
input list<Absyn.Exp> inAbsynExpLst;
input list<Absyn.Exp> inPosArgs;
input list<Absyn.NamedArg> inNamedArg;
input Boolean inBoolean;
input Boolean inImpl;
input Prefix.Prefix inPrefix;
input Absyn.Info info;
input Absyn.Info inInfo;
output Env.Cache outCache;
output DAE.Exp outExp;
output DAE.Properties outProperties;
algorithm
(outCache,outExp,outProperties) := matchcontinue (inCache,inEnv,inAbsynExpLst,inNamedArg,inBoolean,inPrefix,info)
local
DAE.Type tp;
Boolean sc, impl;
list<DAE.Exp> expl,exp_2;
DAE.Dimension d1,d2;
DAE.Type eltp,newtp;
Integer dim1,dim2,dimMax;
DAE.Properties prop;
DAE.Const c;
Env.Env env;
Absyn.Exp matexp;
DAE.Exp exp_1,exp;
Env.Cache cache;
Prefix.Prefix pre;
list<list<DAE.Exp>> mexpl,mexp_2;
Integer i;

// try symbolically transpose the ARRAY expression
case (cache,env,{matexp},_,impl,pre,_)
equation
(cache,DAE.ARRAY(tp,sc,expl),DAE.PROP(DAE.T_ARRAY(ty = DAE.T_ARRAY(ty = eltp, dims = {d2}), dims = {d1}), c),_)
= elabExpInExpression(cache,env, matexp, impl,NONE(),true,pre,info);
dim1 = Expression.dimensionSize(d1);
exp_2 = elabBuiltinTranspose2(expl, 1, dim1);
newtp = DAE.T_ARRAY(DAE.T_ARRAY(eltp, {d1}, DAE.emptyTypeSource), {d2}, DAE.emptyTypeSource);
prop = DAE.PROP(newtp,c);
tp = transposeExpType(tp);
then
(cache,DAE.ARRAY(tp,sc,exp_2),prop);

// try symbolically transpose the MATRIX expression
case (cache,env,{matexp},_,impl,pre,_)
equation
(cache,DAE.MATRIX(tp,i,mexpl),DAE.PROP(DAE.T_ARRAY(dims = {d1}, ty = DAE.T_ARRAY(dims = {d2}, ty = eltp)),c),_)
= elabExpInExpression(cache,env, matexp, impl,NONE(),true,pre,info);
dim1 = Expression.dimensionSize(d1);
dim2 = Expression.dimensionSize(d2);
dimMax = intMax(dim1, dim2);
mexp_2 = elabBuiltinTranspose3(mexpl, 1, dimMax);
newtp = DAE.T_ARRAY(DAE.T_ARRAY(eltp, {d1}, DAE.emptyTypeSource), {d2}, DAE.emptyTypeSource);
prop = DAE.PROP(newtp,c);
tp = transposeExpType(tp);
then
(cache,DAE.MATRIX(tp,i,mexp_2),prop);

// .. otherwise create transpose call
case (cache,env,{matexp},_,impl,pre,_)
equation
(cache,exp_1,DAE.PROP(DAE.T_ARRAY(dims = {d1}, ty = DAE.T_ARRAY(dims = {d2}, ty = eltp)), c),_)
= elabExpInExpression(cache,env, matexp, impl,NONE(),true,pre,info);
newtp = DAE.T_ARRAY(DAE.T_ARRAY(eltp, {d1}, DAE.emptyTypeSource), {d2}, DAE.emptyTypeSource);
tp = Types.simplifyType(newtp);
exp = Expression.makePureBuiltinCall("transpose", {exp_1}, tp);
prop = DAE.PROP(newtp,c);
then
(cache,exp,prop);
end matchcontinue;
protected
Env.Cache cache;
Absyn.Exp aexp;
DAE.Exp exp;
DAE.Type ty, el_ty;
DAE.Const c;
DAE.Dimension d1, d2;
DAE.TypeSource src1, src2;
algorithm
{aexp} := inPosArgs;
(outCache, exp, DAE.PROP(ty, c), _) :=
elabExp(inCache, inEnv, aexp, inImpl, NONE(), true, inPrefix, inInfo);
// Transpose the type.
DAE.T_ARRAY(DAE.T_ARRAY(el_ty, {d1}, src1), {d2}, src2) := ty;
ty := DAE.T_ARRAY(DAE.T_ARRAY(el_ty, {d2}, src1), {d1}, src2);
outProperties := DAE.PROP(ty, c);
// Simplify the type and make a call to transpose.
ty := Types.simplifyType(ty);
outExp := Expression.makePureBuiltinCall("transpose", {exp}, ty);
end elabBuiltinTranspose;

protected function transposeExpType
"Helper function to elabBuiltinTranspose. Transposes an array type, i.e. swaps
the first two dimensions."
input DAE.Type inType;
output DAE.Type outType;
algorithm
outType := match(inType)
local
DAE.Type ty;
DAE.Dimension dim1, dim2;
DAE.Dimensions dim_rest;
DAE.TypeSource ts;

case (DAE.T_ARRAY(ty = ty, dims = dim1 :: dim2 :: dim_rest, source = ts))
then
DAE.T_ARRAY(ty, dim2 :: dim1 :: dim_rest, ts);
end match;
end transposeExpType;

protected function elabBuiltinTranspose2 "author: PA
Helper function to elab_builtin_transpose.
Tries to symbolically transpose a matrix expression in ARRAY form."
input list<DAE.Exp> inExpExpLst1;
input Integer inInteger2;
input Integer inInteger3;
output list<DAE.Exp> outExpExpLst;
algorithm
outExpExpLst := matchcontinue (inExpExpLst1,inInteger2,inInteger3)
local
DAE.Exp e;
list<DAE.Exp> es,rest,elst;
DAE.Type tp;
Integer indx_1,indx,dim1;

case (elst,indx,dim1)
equation
(indx <= dim1) = true;
indx_1 = indx - 1;
(e :: es) = List.map1(elst, Expression.nthArrayExp, indx_1);
tp = Expression.typeof(e);
indx_1 = indx + 1;
rest = elabBuiltinTranspose2(elst, indx_1, dim1);
then
(DAE.ARRAY(tp,false,(e :: es)) :: rest);

else {};
end matchcontinue;
end elabBuiltinTranspose2;

protected function elabBuiltinTranspose3 "author: PA
Helper function to elab_builtin_transpose. Tries to symbolically transpose
a MATRIX expression list"
input list<list<DAE.Exp>> inMatrix;
input Integer inInteger2;
input Integer inInteger3;
output list<list<DAE.Exp>> outMatrix;
algorithm
outMatrix := matchcontinue (inMatrix,inInteger2,inInteger3)
local
Integer indx_1,indx,dim1;
DAE.Exp e;
list<DAE.Exp> es;
DAE.Exp e_1;
DAE.Type tp;
list<list<DAE.Exp>> rest,res,elst;
case (elst,indx,dim1)
equation
(indx <= dim1) = true;
(e :: es) = List.map1(elst, listGet, indx);
e_1 = e;
_ = Expression.typeof(e_1);
indx_1 = indx + 1;
rest = elabBuiltinTranspose3(elst, indx_1, dim1);
res = listAppend({(e :: es)}, rest);
then
res;
else {};
end matchcontinue;
end elabBuiltinTranspose3;

protected function elabBuiltinSum "This function elaborates the builtin operator sum.
The input is the arguments to fill as Absyn.Exp expressions and the environment Env.Env"
input Env.Cache inCache;
Expand Down

0 comments on commit 26bf7aa

Please sign in to comment.