Skip to content

Commit

Permalink
- Implemented expansion of asub slices in ExpressionSimplify.
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@16096 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
perost committed May 20, 2013
1 parent 382efa8 commit c3d083f
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 0 deletions.
17 changes: 17 additions & 0 deletions Compiler/FrontEnd/Expression.mo
Original file line number Diff line number Diff line change
Expand Up @@ -9133,6 +9133,23 @@ algorithm
exp := makeCrefExp(ComponentReference.crefPrependIdent(cr, n, {}, ty), ty);
end splitRecord2;

public function splitArray
"Splits an array into a list of elements."
input DAE.Exp inExp;
output list<DAE.Exp> outExp;
algorithm
outExp := match(inExp)
local
list<DAE.Exp> expl;
list<list<DAE.Exp>> mat;

case DAE.ARRAY(array = expl) then expl;
case DAE.MATRIX(matrix = mat) then List.flatten(mat);
else {inExp};

end match;
end splitArray;

public function equationExpEqual
input DAE.EquationExp exp1;
input DAE.EquationExp exp2;
Expand Down
38 changes: 38 additions & 0 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,13 @@ algorithm
true = Config.acceptMetaModelicaGrammar();
then ((simplifyMetaModelica(e),(true,options)));

// Simplify asubs where some of the subscripts are slices.
case ((DAE.ASUB(exp = e, sub = subs), (_, options)))
equation
e = simplifyAsubSlicing(e, subs);
then
((e, (true, options)));

// other subscripting/asub simplifications where e is not simplified first.
case ((DAE.ASUB(exp = e,sub = subs),(_,options)))
equation
Expand Down Expand Up @@ -3201,6 +3208,37 @@ algorithm
end matchcontinue;
end simplifyAsubOperator;

protected function simplifyAsubSlicing
"Simplifies asubs where some of the subscripts are slices.
Ex: x[i, 1:3] => {x[i, 1], x[i, 2], x[i, 3]}"
input DAE.Exp inExp;
input list<DAE.Exp> inSubscripts;
output DAE.Exp outAsubArray;
protected
list<list<DAE.Exp>> indices;
list<DAE.Exp> asubs;
Integer sz;
DAE.Exp elem;
DAE.Type ty;
algorithm
// Expand the subscripts.
indices := List.map(inSubscripts, Expression.splitArray);
// Make asubs from all combinations of the subscript indices.
asubs := List.combinationMap1(indices, simplifyAsubSlicing2, inExp);
// Make sure one or more dimensions were sliced, i.e. we got more than one element.
elem :: _ :: _ := asubs;
// Make an array expression from the asub list.
ty := Expression.typeof(elem);
outAsubArray := Expression.makeScalarArray(asubs, ty);
end simplifyAsubSlicing;

protected function simplifyAsubSlicing2
input list<DAE.Exp> inSubscripts;
input DAE.Exp inExp;
output DAE.Exp outAsub;
algorithm
outAsub := Expression.makeASUB(inExp, inSubscripts);
end simplifyAsubSlicing2;

protected function simplifyBinaryConst
"function: simplifyBinaryConst
Expand Down
173 changes: 173 additions & 0 deletions Compiler/Util/List.mo
Original file line number Diff line number Diff line change
Expand Up @@ -8819,4 +8819,177 @@ algorithm
end matchcontinue;
end splitEqualPrefix_tail;

public function combinationMap
"Takes a two-dimensional list and calls the given function on the combinations
given by the cartesian product of the sublists.

Ex: combinationMap({{1, 2}, {3}, {4, 5}}, func) =>
{func({1, 3, 4}), func({1, 3, 5}), func({2, 3, 4}), func({2, 3, 5})}
"
input list<list<ElementInType>> inElements;
input MapFunc inMapFunc;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
output ElementOutType outElement;
end MapFunc;
protected
list<list<ElementInType>> elems;
algorithm
elems := listReverse(inElements);
outElements := combinationMap_tail(elems, inMapFunc, {}, {});
end combinationMap;

protected function combinationMap_tail
input list<list<ElementInType>> inElements;
input MapFunc inMapFunc;
input list<ElementInType> inCombination;
input list<ElementInType> inAccumElems;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
output ElementOutType outElement;
end MapFunc;
algorithm
outElements := match(inElements, inMapFunc, inCombination, inAccumElems)
local
ElementInType elem;
list<ElementInType> head;
list<list<ElementInType>> rest;

case ({}, _, _, _)
equation
elem = inMapFunc(inCombination);
then
elem :: inAccumElems;

case (head :: rest, _, _, _)
then combinationMap_tail2(head, rest, inMapFunc, inCombination, inAccumElems);

end match;
end combinationMap_tail;

protected function combinationMap_tail2
input list<ElementInType> inHead;
input list<list<ElementInType>> inRest;
input MapFunc inMapFunc;
input list<ElementInType> inCombination;
input list<ElementInType> inAccumElems;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
output ElementOutType outElement;
end MapFunc;
algorithm
outElements := match(inHead, inRest, inMapFunc, inCombination, inAccumElems)
local
ElementInType head;
list<ElementInType> rest, accum, comb;

case (head :: rest, _, _, comb, accum)
equation
accum = combinationMap_tail(inRest, inMapFunc, head :: comb, accum);
accum = combinationMap_tail2(rest, inRest, inMapFunc, comb, accum);
then
accum;

case ({}, _, _, _, _)
then inAccumElems;

end match;
end combinationMap_tail2;

public function combinationMap1
"Takes a two-dimensional list and calls the given function on the combinations
given by the cartesian product of the sublists. Also takes an extra constant
argument that is sent to the function.

Ex: combinationMap({{1, 2}, {3}, {4, 5}}, func, x) =>
{func({1, 3, 4}, x), func({1, 3, 5}, x), func({2, 3, 4}, x), func({2, 3, 5}, x)}
"
input list<list<ElementInType>> inElements;
input MapFunc inMapFunc;
input ArgType1 inArg;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
input ArgType1 inArg;
output ElementOutType outElement;
end MapFunc;
protected
list<list<ElementInType>> elems;
algorithm
elems := listReverse(inElements);
outElements := combinationMap1_tail(elems, inMapFunc, inArg, {}, {});
end combinationMap1;

protected function combinationMap1_tail
input list<list<ElementInType>> inElements;
input MapFunc inMapFunc;
input ArgType1 inArg;
input list<ElementInType> inCombination;
input list<ElementInType> inAccumElems;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
input ArgType1 inArg;
output ElementOutType outElement;
end MapFunc;
algorithm
outElements := match(inElements, inMapFunc, inArg, inCombination, inAccumElems)
local
ElementInType elem;
list<ElementInType> head;
list<list<ElementInType>> rest;

case ({}, _, _, _, _)
equation
elem = inMapFunc(inCombination, inArg);
then
elem :: inAccumElems;

case (head :: rest, _, _, _, _)
then combinationMap1_tail2(head, rest, inMapFunc, inArg, inCombination, inAccumElems);

end match;
end combinationMap1_tail;

protected function combinationMap1_tail2
input list<ElementInType> inHead;
input list<list<ElementInType>> inRest;
input MapFunc inMapFunc;
input ArgType1 inArg;
input list<ElementInType> inCombination;
input list<ElementInType> inAccumElems;
output list<ElementOutType> outElements;

partial function MapFunc
input list<ElementInType> inElements;
input ArgType1 inArg;
output ElementOutType outElement;
end MapFunc;
algorithm
outElements := match(inHead, inRest, inMapFunc, inArg, inCombination, inAccumElems)
local
ElementInType head;
list<ElementInType> rest, accum, comb;

case (head :: rest, _, _, _, comb, accum)
equation
accum = combinationMap1_tail(inRest, inMapFunc, inArg, head :: comb, accum);
accum = combinationMap1_tail2(rest, inRest, inMapFunc, inArg, comb, accum);
then
accum;

case ({}, _, _, _, _, _)
then inAccumElems;

end match;
end combinationMap1_tail2;

end List;

0 comments on commit c3d083f

Please sign in to comment.