Skip to content

Commit

Permalink
Fix elab/simplify/ceval for identity and diagonal
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@24029 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Jan 13, 2015
1 parent 62ab4d1 commit 43b807b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 211 deletions.
138 changes: 15 additions & 123 deletions Compiler/FrontEnd/Ceval.mo
Expand Up @@ -1849,25 +1849,23 @@ algorithm
(outCache,outValue,outInteractiveInteractiveSymbolTableOption):=
match (inCache,inEnv,inExpExpLst,inBoolean,inST,inMsg,numIter)
local
Integer dim_int,dim_int_1;
Integer dimension;
list<DAE.Exp> expl;
list<Values.Value> retExp;
FCore.Graph env;
DAE.Exp dim;
Boolean impl;
Option<GlobalScript.SymbolTable> st;
Absyn.Msg msg;
FCore.Cache cache;
FCore.Cache cache;
Values.Value res;

case (cache,env,{dim},impl,st,msg,_)
equation
(cache,Values.INTEGER(dim_int),_) = ceval(cache,env,dim,impl,st,msg,numIter+1);
dim_int_1 = dim_int + 1;
expl = List.fill(DAE.ICONST(1), dim_int);
(cache,retExp) = cevalBuiltinDiagonal2(cache,env, DAE.ARRAY(DAE.T_INTEGER_DEFAULT,true,expl), impl, st, dim_int_1,
1, {},msg,numIter+1);
algorithm
(cache,Values.INTEGER(dimension),_) := ceval(cache,env,dim,impl,st,msg,numIter+1);
res := Values.ARRAY(list(Values.ARRAY(list(if i==j then Values.INTEGER(1) else Values.INTEGER(0) for i in 1:dimension),{dimension}) for j in 1:dimension), {dimension,dimension});
then
(cache,ValuesUtil.makeArray(retExp),st);
(cache,res,st);

end match;
end cevalBuiltinIdentity;
Expand Down Expand Up @@ -4008,7 +4006,7 @@ algorithm
(outCache,outValue,outInteractiveInteractiveSymbolTableOption):=
matchcontinue (inCache,inEnv,inExpExpLst,inBoolean,inST,inMsg,numIter)
local
list<Values.Value> rv2,retExp;
list<Values.Value> vals,retExp;
Integer dimension,correctDimension;
FCore.Graph env;
DAE.Exp exp;
Expand All @@ -4018,13 +4016,15 @@ algorithm
FCore.Cache cache;
Values.Value res;
SourceInfo info;
Values.Value zero;
DAE.Type ty;

case (cache,env,{exp},impl,st,msg,_)
equation
(cache,Values.ARRAY(_,{dimension}),_) = ceval(cache,env,exp,impl,st,msg,numIter+1);
correctDimension = dimension + 1;
(cache,retExp) = cevalBuiltinDiagonal2(cache,env, exp, impl, st, correctDimension, 1, {},msg,numIter+1);
res = Values.ARRAY(retExp,{dimension,dimension});
algorithm
DAE.T_ARRAY(ty=ty) := Expression.typeof(exp);
(cache,Values.ARRAY(vals,{dimension}),_) := ceval(cache,env,exp,impl,st,msg,numIter+1);
zero := ValuesUtil.makeZero(ty);
res := Values.ARRAY(list(Values.ARRAY(list(if i==j then listGet(vals,i) else zero for i in 1:dimension),{dimension}) for j in 1:dimension), {dimension,dimension});
then
(cache,res,st);
case (_,_,_,_,_,Absyn.MSG(info = info),_)
Expand All @@ -4036,114 +4036,6 @@ algorithm
end matchcontinue;
end cevalBuiltinDiagonal;

protected function cevalBuiltinDiagonal2 " This is a help function that is calling itself recursively to
generate the a nxn matrix with some special diagonal elements.
See cevalBuiltinDiagonal."
input FCore.Cache inCache;
input FCore.Graph inEnv1;
input DAE.Exp inExp2;
input Boolean inBoolean3;
input Option<GlobalScript.SymbolTable> inST4;
input Integer inInteger5 "matrix dimension";
input Integer inInteger6 "row";
input list<Values.Value> inValuesValueLst7;
input Absyn.Msg inMsg8;
input Integer numIter;
output FCore.Cache outCache;
output list<Values.Value> outValuesValueLst;
algorithm
(outCache,outValuesValueLst) :=
matchcontinue (inCache,inEnv1,inExp2,inBoolean3,inST4,inInteger5,inInteger6,inValuesValueLst7,inMsg8,numIter)
local
Real rv2;
Integer correctDim,correctPlace,newRow,matrixDimension,row,iv2;
list<Values.Value> zeroList,listWithElement,retExp,appendedList,listIN,list_;
FCore.Graph env;
DAE.Exp s1,s2;
Boolean impl;
Option<GlobalScript.SymbolTable> st;
Absyn.Msg msg;
FCore.Cache cache;
Values.Value v;
SourceInfo info;
String str;

case (cache,env,s1,impl,st,matrixDimension,row,{},msg,_)
equation
s2 = DAE.ICONST(row);
(cache,Values.REAL(rv2),_) = ceval(cache,env, Expression.makeASUB(s1,{s2}), impl, st,msg,numIter+1);
correctDim = matrixDimension - 1;
zeroList = List.fill(Values.REAL(0.0), correctDim);
listWithElement = List.replaceAt(Values.REAL(rv2), row, zeroList);
newRow = row + 1;
v = ValuesUtil.makeArray(listWithElement);
(cache,retExp) = cevalBuiltinDiagonal2(cache,env, s1, impl, st, matrixDimension, newRow, {v},msg,numIter);
then
(cache,retExp);

case (cache,env,s1,impl,st,matrixDimension,row,listIN,msg,_)
equation
s2 = DAE.ICONST(row);
(cache,Values.REAL(rv2),_) = ceval(cache,env, Expression.makeASUB(s1,{s2}), impl, st,msg,numIter+1);

false = intEq(matrixDimension, row);

correctDim = matrixDimension - 1;
zeroList = List.fill(Values.REAL(0.0), correctDim);
listWithElement = List.replaceAt(Values.REAL(rv2), row, zeroList);
newRow = row + 1;
v = ValuesUtil.makeArray(listWithElement);
appendedList = listAppend(listIN, {v});
(cache,retExp)= cevalBuiltinDiagonal2(cache,env, s1, impl, st, matrixDimension, newRow, appendedList,msg,numIter);
then
(cache,retExp);

case (cache,env,s1,impl,st,matrixDimension,row,{},msg,_)
equation
s2 = DAE.ICONST(row);
(cache,Values.INTEGER(iv2),_) = ceval(cache,env, Expression.makeASUB(s1,{s2}), impl, st,msg,numIter+1);
correctDim = matrixDimension - 1;
zeroList = List.fill(Values.INTEGER(0), correctDim);
listWithElement = List.replaceAt(Values.INTEGER(iv2), row, zeroList);
newRow = row + 1;
v = ValuesUtil.makeArray(listWithElement);
(cache,retExp) = cevalBuiltinDiagonal2(cache,env, s1, impl, st, matrixDimension, newRow, {v},msg,numIter);
then
(cache,retExp);

case (cache,env,s1,impl,st,matrixDimension,row,listIN,msg,_)
equation
s2 = DAE.ICONST(row);
(cache,Values.INTEGER(iv2),_) = ceval(cache,env, Expression.makeASUB(s1,{s2}), impl, st,msg,numIter+1);

false = intEq(matrixDimension, row);

correctDim = matrixDimension - 1;
zeroList = List.fill(Values.INTEGER(0), correctDim);
listWithElement = List.replaceAt(Values.INTEGER(iv2), row, zeroList);
newRow = row + 1;
v = ValuesUtil.makeArray(listWithElement);
appendedList = listAppend(listIN, {v});
(cache,retExp) = cevalBuiltinDiagonal2(cache,env, s1, impl, st, matrixDimension, newRow, appendedList, msg, numIter);
then
(cache,retExp);

case (cache,_,_,_,_,matrixDimension,row,listIN,_,_)
equation
true = intEq(matrixDimension, row);
then
(cache,listIN);

case (_,_,_,_,_,_,_,_,Absyn.MSG(info = info),_)
equation
true = Flags.isSet(Flags.CEVAL);
str = Error.infoStr(info);
Debug.traceln(str + " Ceval.cevalBuiltinDiagonal2 failed");
then
fail();
end matchcontinue;
end cevalBuiltinDiagonal2;

protected function cevalBuiltinCross "
x,y => {x[2]*y[3]-x[3]*y[2],x[3]*y[1]-x[1]*y[3],x[1]*y[2]-x[2]*y[1]}"
input FCore.Cache inCache;
Expand Down
67 changes: 10 additions & 57 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -304,7 +304,7 @@ protected function simplifyCall
algorithm
outExp := matchcontinue inExp
local
DAE.Exp e,e1,e2,exp;
DAE.Exp e,e1,e2,exp,zero;
list<DAE.Exp> matrix,expl;
DAE.CallAttributes attr;
DAE.Type tp;
Expand Down Expand Up @@ -381,9 +381,17 @@ algorithm
// simplify identity
case DAE.CALL(path = Absyn.IDENT(name = "identity"), expLst = {DAE.ICONST(n)})
equation
matrix = simplifyIdentity(1,n);
matrix = list(DAE.ARRAY(DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(n)},DAE.emptyTypeSource),false,list(if i==j then DAE.ICONST(1) else DAE.ICONST(0) for i in 1:n)) for j in 1:n);
then DAE.ARRAY(DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(n),DAE.DIM_INTEGER(n)},DAE.emptyTypeSource),false,matrix);

case DAE.CALL(path = Absyn.IDENT(name = "diagonal"), expLst = {DAE.ARRAY(array=expl,ty=tp)})
equation
n = listLength(expl);
tp = Types.arrayElementType(tp);
zero = Expression.makeConstZero(tp);
matrix = list(DAE.ARRAY(DAE.T_ARRAY(tp,{DAE.DIM_INTEGER(n)},DAE.emptyTypeSource),false,list(if i==j then listGet(expl,i) else zero for i in 1:n)) for j in 1:n);
then DAE.ARRAY(DAE.T_ARRAY(tp,{DAE.DIM_INTEGER(n),DAE.DIM_INTEGER(n)},DAE.emptyTypeSource),false,matrix);

// arcxxx(xxx(e)) => e; xxx(arcxxx(e)) => e
case (DAE.CALL(path=Absyn.IDENT("sin"),expLst={DAE.CALL(path=Absyn.IDENT("asin"),expLst={e})}))
then e;
Expand Down Expand Up @@ -1633,61 +1641,6 @@ algorithm
end matchcontinue;
end simplifyBuiltinConstantCalls;

protected function simplifyIdentity ""
input Integer row;
input Integer n;
output list<DAE.Exp> outExp;
algorithm
outExp := matchcontinue(row,n)
local
list<DAE.Exp> rowExps;
DAE.Exp arrExp;

case(_,_) // bottom right
equation
true = intEq(row,n);
rowExps = simplifyIdentityMakeRow(n,1,row);
then
{DAE.ARRAY(DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(n)}, DAE.emptyTypeSource),true,rowExps)};

else // bottom right
equation
true = row < n;
rowExps = simplifyIdentityMakeRow(n,1,row);
outExp = simplifyIdentity(row+1,n);
arrExp = DAE.ARRAY(DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT,{DAE.DIM_INTEGER(n)}, DAE.emptyTypeSource),true,rowExps);
then
arrExp::outExp;
end matchcontinue;
end simplifyIdentity;

protected function simplifyIdentityMakeRow ""
input Integer n;
input Integer col;
input Integer row;
output list<DAE.Exp> expl;
algorithm
expl := matchcontinue(n,col,row)
local
Integer i;

case(_,_,_)
equation
true = intEq(n,col);
i = if intEq(col,row) then 1 else 0;
then
{DAE.ICONST(i)};

else
equation
true = col < n;
i = if intEq(col,row) then 1 else 0;
expl = simplifyIdentityMakeRow(n,col+1,row);
then
DAE.ICONST(i)::expl;
end matchcontinue;
end simplifyIdentityMakeRow;

protected function simplifyCref
" Function for simplifying
x[{y,z,q}] to {x[y], x[z], x[q]}"
Expand Down
32 changes: 1 addition & 31 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -5380,39 +5380,9 @@ algorithm
outProperties := DAE.PROP(ty, c);
ty := Types.simplifyType(ty);

try
DAE.ARRAY(array = expl) := exp;
outExp := elabBuiltinDiagonal2(expl, ty);
else
outExp := Expression.makePureBuiltinCall("diagonal", {exp}, ty);
end try;
outExp := Expression.makePureBuiltinCall("diagonal", {exp}, ty);
end elabBuiltinDiagonal;

protected function elabBuiltinDiagonal2
"Tries to symbolically simplify diagonal.
For instance diagonal({a,b}) => {a,0;0,b}"
input list<DAE.Exp> inExpl;
input DAE.Type inType;
output DAE.Exp outRes;
protected
Integer dim, row_idx;
list<DAE.Exp> row;
list<list<DAE.Exp>> mat := {};
DAE.Exp zero_exp;
algorithm
dim := listLength(inExpl);
row_idx := 0;
zero_exp := Expression.makeConstZero(inType);

for e in inExpl loop
mat := listAppend(list(zero_exp for i in 1:row_idx),
e :: list(zero_exp for i in (row_idx + 2):dim)) :: mat;
row_idx := row_idx + 1;
end for;

outRes := DAE.MATRIX(inType, dim, listReverse(mat));
end elabBuiltinDiagonal2;

protected function elabBuiltinSimplify "This function elaborates the simplify function.
The call in mosh is: simplify(x+yx-x,\"Real\") if the variable should be
Real or simplify(x+yx-x,\"Integer\") if the variable should be Integer
Expand Down
9 changes: 9 additions & 0 deletions Compiler/FrontEnd/ValuesUtil.mo
Expand Up @@ -162,6 +162,15 @@ algorithm
end match;
end isZero;

public function makeZero "Returns a zero value based on a DAE.Type"
input DAE.Type ty;
output Values.Value zero;
algorithm
zero := match ty
case DAE.T_REAL() then Values.REAL(0.0);
case DAE.T_INTEGER() then Values.INTEGER(0);
end match;
end makeZero;

public function isArray "Return true if Value is an array."
input Values.Value inValue;
Expand Down

0 comments on commit 43b807b

Please sign in to comment.