Skip to content

Commit

Permalink
- Rewrite of Expression.factors (using match and an accumulator inste…
Browse files Browse the repository at this point in the history
…ad of matchcontinue and listAppend)

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7584 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Dec 29, 2010
1 parent 58a30eb commit b609c34
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 76 deletions.
6 changes: 3 additions & 3 deletions Compiler/BackEnd/ExpressionSolve.mo
Expand Up @@ -277,7 +277,7 @@ algorithm
case(e1,e2,(crexp as DAE.CREF(componentRef = cr)),_)
equation
({invCr},factors) = Util.listSplitOnTrue1(listAppend(Expression.factors(e1),Expression.factors(e2)),isInverseCref,cr);
rhs_1 = Expression.makeProductLst(Expression.inverseFactors(factors));
rhs_1 = Expression.makeProductLst(Util.listMap(factors, Expression.inverseFactors));
false = Expression.expContains(rhs_1, crexp);
then
(rhs_1,{});
Expand All @@ -293,7 +293,7 @@ algorithm
se1 = ExpressionDump.printExpStr(e1);
se2 = ExpressionDump.printExpStr(e2);
sa = ExpressionDump.printExpStr(a);
estr = stringAppendList({"Singulare expression ",se1," = ",se2," because ",sa," is Zero!"});
estr = stringAppendList({"Singular expression ",se1," = ",se2," because ",sa," is Zero!"});
then
(rhs_1,DAE.STMT_ASSERT(DAE.RELATION(a,DAE.NEQUAL(tp),z),DAE.SCONST(estr),DAE.emptyElementSource)::asserts);

Expand All @@ -308,7 +308,7 @@ algorithm
se1 = ExpressionDump.printExpStr(e1);
se2 = ExpressionDump.printExpStr(e2);
sa = ExpressionDump.printExpStr(a);
estr = stringAppendList({"Singulare expression ",se1," = ",se2," because ",sa," is Zero!"});
estr = stringAppendList({"Singular expression ",se1," = ",se2," because ",sa," is Zero!"});
then
(rhs_1,DAE.STMT_ASSERT(DAE.RELATION(a,DAE.NEQUAL(tp),z),DAE.SCONST(estr),DAE.emptyElementSource)::asserts);

Expand Down
180 changes: 108 additions & 72 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -1934,104 +1934,140 @@ public function factors
input DAE.Exp inExp;
output list<DAE.Exp> outExpLst;
algorithm
outExpLst:=
matchcontinue (inExp)
local
list<DAE.Exp> f1,f2,f1_1,f2_1,res,f2_2;
DAE.Exp e1,e2,e;
ComponentRef cr;
case (DAE.BINARY(exp1 = e1,operator = DAE.MUL(ty = _),exp2 = e2))
equation
f1 = factors(e1) "Both subexpression has factors" ;
f2 = factors(e2);
f1_1 = noFactors(f1, e1);
f2_1 = noFactors(f2, e2);
res = listAppend(f1_1, f2_1);
then
res;
case (DAE.BINARY(exp1 = e1,operator = DAE.DIV(ty = DAE.ET_REAL()),exp2 = e2))
equation
f1 = factors(e1);
f2 = factors(e2);
f1_1 = noFactors(f1, e1);
f2_1 = noFactors(f2, e2);
f2_2 = inverseFactors(f2_1);
res = listAppend(f1_1, f2_2);
then
res;
case ((e as DAE.CREF(componentRef = cr))) then {e};
case ((e as DAE.BINARY(exp1 = _))) then {e};
case ((e as DAE.ICONST(integer = _))) then {e};
case ((e as DAE.RCONST(real = _))) then {e};
case ((e as DAE.SCONST(string = _))) then {e};
case ((e as DAE.UNARY(operator = _))) then {e};
case ((e as DAE.IFEXP(expCond = _))) then {e};
case ((e as DAE.CALL(path = _))) then {e};
case ((e as DAE.PARTEVALFUNCTION(path = _))) then {e};
case ((e as DAE.ARRAY(ty = _))) then {e};
case ((e as DAE.MATRIX(ty = _))) then {e};
case ((e as DAE.RANGE(ty = _))) then {e};
case ((e as DAE.CAST(ty = _))) then {e};
case ((e as DAE.ASUB(exp = _))) then {e};
case ((e as DAE.SIZE(exp = _))) then {e};
case ((e as DAE.REDUCTION(path = _))) then {e};
case (_) then {};
end matchcontinue;
// TODO: Remove this listReverse as it is pointless.
// It transforms a*b to b*a, but the testsuite expects this :(
outExpLst := listReverse(factorsWork(inExp,{},false,false));
end factors;

protected function noFactors
"function noFactors
Helper function to factors.
If a factor list is empty, the expression has no subfactors.
But the complete expression is then a factor for larger
expressions, returned by this function."
input list<DAE.Exp> inExpLst;
protected function factorsWork
"function: factors
Returns the factors of the expression if any as a list of expressions"
input DAE.Exp inExp;
input list<DAE.Exp> acc;
input Boolean noFactors "Decides if the default is the empty list or not";
input Boolean doInverseFactors "Decides if a factor e should be 1/e instead";
output list<DAE.Exp> outExpLst;
algorithm
outExpLst:=
matchcontinue (inExpLst,inExp)
outExpLst := match (inExp,acc,noFactors,doInverseFactors)
local
DAE.Exp e;
list<DAE.Exp> lst;
case ({},e) then {e};
case (lst,_) then lst;
end matchcontinue;
end noFactors;
list<DAE.Exp> f1,f2,f1_1,f2_1,res,f2_2;
DAE.Exp e1,e2,e;
ComponentRef cr;
case (DAE.BINARY(exp1 = e1,operator = DAE.MUL(ty = _),exp2 = e2),acc,noFactors,doInverseFactors)
equation
acc = factorsWork(e1,acc,true,doInverseFactors);
acc = factorsWork(e2,acc,true,doInverseFactors);
then acc;
case (DAE.BINARY(exp1 = e1,operator = DAE.DIV(ty = DAE.ET_REAL()),exp2 = e2),acc,noFactors,doInverseFactors)
equation
acc = factorsWork(e1,acc,true,doInverseFactors);
acc = factorsWork(e2,acc,true,not doInverseFactors);
then acc;
case ((e as DAE.CREF(componentRef = cr)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.BINARY(exp1 = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.ICONST(integer = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.RCONST(real = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.SCONST(string = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.UNARY(operator = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.IFEXP(expCond = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.CALL(path = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.PARTEVALFUNCTION(path = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.ARRAY(ty = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.MATRIX(ty = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.RANGE(ty = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.CAST(ty = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.ASUB(exp = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.SIZE(exp = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.REDUCTION(path = _)),acc,noFactors,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case (e,acc,true,doInverseFactors)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case (_,acc,false,_)
then acc;
end match;
end factorsWork;

public function inverseFactors
"function inverseFactors
Takes a list of expressions and returns
each expression in the list inversed.
For example: inverseFactors {a, 3+b} => {1/a, 1/3+b}"
input list<DAE.Exp> inExpLst;
output list<DAE.Exp> outExpLst;
input DAE.Exp inExp;
output DAE.Exp outExp;
algorithm
outExpLst:=
matchcontinue (inExpLst)
outExp := matchcontinue (inExp)
local
list<DAE.Exp> es_1,es;
Type tp2,tp;
DAE.Exp e1,e2,e;
case ({}) then {};
case ((DAE.BINARY(exp1 = e1,operator = DAE.POW(ty = tp),exp2 = e2) :: es))
DAE.Operator op;
case (DAE.BINARY(exp1 = e1,operator = DAE.POW(ty = tp),exp2 = e2))
equation
es_1 = inverseFactors(es);
tp2 = typeof(e2);
then
(DAE.BINARY(e1,DAE.POW(tp),DAE.UNARY(DAE.UMINUS(tp2),e2)) :: es_1);
case ((e :: es))
DAE.BINARY(e1,DAE.POW(tp),DAE.UNARY(DAE.UMINUS(tp2),e2));
case (DAE.BINARY(exp1 = e1,operator = op as DAE.DIV(ty = _),exp2 = e2))
then
DAE.BINARY(e2,op,e1);
case e
equation
DAE.ET_REAL() = typeof(e);
es_1 = inverseFactors(es);
then
(DAE.BINARY(DAE.RCONST(1.0),DAE.DIV(DAE.ET_REAL()),e) :: es_1);
case ((e :: es))
DAE.BINARY(DAE.RCONST(1.0),DAE.DIV(DAE.ET_REAL()),e);
case e
equation
DAE.ET_INT() = typeof(e);
es_1 = inverseFactors(es);
then
(DAE.BINARY(DAE.ICONST(1),DAE.DIV(DAE.ET_INT()),e) :: es_1);
DAE.BINARY(DAE.ICONST(1),DAE.DIV(DAE.ET_INT()),e);
end matchcontinue;
end inverseFactors;

Expand Down
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -1781,7 +1781,7 @@ algorithm
equation
e1_lst = Expression.factors(e1);
e2_lst = Expression.factors(e2);
e2_lst_1 = Expression.inverseFactors(e2_lst);
e2_lst_1 = Util.listMap(e2_lst, Expression.inverseFactors);
e_lst = listAppend(e1_lst, e2_lst_1);
e_lst_1 = simplifyMul(e_lst);
res = Expression.makeProductLst(e_lst_1);
Expand Down

0 comments on commit b609c34

Please sign in to comment.