Skip to content

Commit

Permalink
[NF] Evaluate if-conditions in more cases.
Browse files Browse the repository at this point in the history
- Change the branches of if- and when-equation from tuples to
  uniontypes that also contains variability.
- Evaluate structural if-conditions during model simplification.

Belonging to [master]:
  - OpenModelica/OMCompiler#2518
  - OpenModelica/OpenModelica-testsuite#980
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jun 21, 2018
1 parent 05b3577 commit 5e99170
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 92 deletions.
27 changes: 19 additions & 8 deletions Compiler/NFFrontEnd/NFConvertDAE.mo
Expand Up @@ -521,18 +521,24 @@ algorithm
end convertEquation;

function convertIfEquation
input list<tuple<Expression, list<Equation>>> ifBranches;
input list<Equation.Branch> ifBranches;
input DAE.ElementSource source;
input Boolean isInitial;
output DAE.Element ifEquation;
protected
list<Expression> conds;
list<list<Equation>> branches;
list<Expression> conds = {};
list<list<Equation>> branches = {};
list<DAE.Exp> dconds;
list<list<DAE.Element>> dbranches;
list<DAE.Element> else_branch;
algorithm
(conds, branches) := List.unzipReverse(ifBranches);
for branch in ifBranches loop
(conds, branches) := match branch
case Equation.Branch.BRANCH()
then (branch.condition :: conds, branch.body :: branches);
end match;
end for;

dbranches := if isInitial then
list(convertInitialEquations(b) for b in branches) else
list(convertEquations(b) for b in branches);
Expand All @@ -552,7 +558,7 @@ algorithm
end convertIfEquation;

function convertWhenEquation
input list<tuple<Expression, list<Equation>>> whenBranches;
input list<Equation.Branch> whenBranches;
input DAE.ElementSource source;
output DAE.Element whenEquation;
protected
Expand All @@ -561,9 +567,14 @@ protected
Option<DAE.Element> when_eq = NONE();
algorithm
for b in listReverse(whenBranches) loop
cond := Expression.toDAE(Util.tuple21(b));
els := convertEquations(Util.tuple22(b));
when_eq := SOME(DAE.Element.WHEN_EQUATION(cond, els, when_eq, source));
when_eq := match b
case Equation.Branch.BRANCH()
algorithm
cond := Expression.toDAE(b.condition);
els := convertEquations(b.body);
then
SOME(DAE.Element.WHEN_EQUATION(cond, els, when_eq, source));
end match;
end for;

SOME(whenEquation) := when_eq;
Expand Down
117 changes: 93 additions & 24 deletions Compiler/NFFrontEnd/NFEquation.mo
Expand Up @@ -36,6 +36,7 @@ encapsulated uniontype NFEquation
import NFInstNode.InstNode;
import DAE;
import ComponentRef = NFComponentRef;
import NFPrefixes.Variability;

protected
import Equation = NFEquation;
Expand All @@ -44,6 +45,14 @@ protected
import ElementSource;

public
uniontype Branch
record BRANCH
Expression condition;
Variability conditionVar;
list<Equation> body;
end BRANCH;
end Branch;

record EQUALITY
Expression lhs "The left hand side expression.";
Expression rhs "The right hand side expression.";
Expand Down Expand Up @@ -78,14 +87,12 @@ public
end FOR;

record IF
list<tuple<Expression, list<Equation>>> branches
"List of branches, where each branch is a tuple of a condition and a body.";
list<Branch> branches;
DAE.ElementSource source;
end IF;

record WHEN
list<tuple<Expression, list<Equation>>> branches
"List of branches, where each branch is a tuple of a condition and a body.";
list<Branch> branches;
DAE.ElementSource source;
end WHEN;

Expand All @@ -112,8 +119,18 @@ public
DAE.ElementSource source;
end NORETCALL;

function makeBranch
input Expression condition;
input list<Equation> body;
input Variability condVar = Variability.CONTINUOUS;
output Branch branch;
algorithm
branch := Branch.BRANCH(condition, condVar, body);
annotation(__OpenModelica_EarlyInline=true);
end makeBranch;

function makeIf
input list<tuple<Expression, list<Equation>>> branches;
input list<Branch> branches;
input DAE.ElementSource src;
output Equation eq;
algorithm
Expand Down Expand Up @@ -174,19 +191,33 @@ public
case IF()
algorithm
for b in eq.branches loop
for e in Util.tuple22(b) loop
apply(e, func);
end for;
() := match b
case Branch.BRANCH()
algorithm
for e in b.body loop
apply(e, func);
end for;
then
();
else ();
end match;
end for;
then
();

case WHEN()
algorithm
for b in eq.branches loop
for e in Util.tuple22(b) loop
apply(e, func);
end for;
() := match b
case Branch.BRANCH()
algorithm
for e in b.body loop
apply(e, func);
end for;
then
();
else ();
end match;
end for;
then
();
Expand Down Expand Up @@ -214,15 +245,31 @@ public

case IF()
algorithm
eq.branches := list((Util.tuple21(b), list(map(e, func) for e in Util.tuple22(b)))
for b in eq.branches);
eq.branches := list(
match b
case Branch.BRANCH()
algorithm
b.body := list(map(e, func) for e in b.body);
then
b;
else b;
end match
for b in eq.branches);
then
();

case WHEN()
algorithm
eq.branches := list((Util.tuple21(b), list(map(e, func) for e in Util.tuple22(b)))
for b in eq.branches);
eq.branches := list(
match b
case Branch.BRANCH()
algorithm
b.body := list(map(e, func) for e in b.body);
then
b;
else b;
end match
for b in eq.branches);
then
();

Expand Down Expand Up @@ -328,16 +375,22 @@ public
end mapExp;

function mapExpBranch
input output tuple<Expression, list<Equation>> branch;
input output Branch branch;
input MapExpFn func;
protected
Expression cond;
list<Equation> eql;
algorithm
(cond, eql) := branch;
cond := func(cond);
eql := list(mapExp(e, func) for e in eql);
branch := (cond, eql);
branch := match branch
case Branch.BRANCH()
algorithm
cond := func(branch.condition);
eql := list(mapExp(e, func) for e in branch.body);
then
Branch.BRANCH(cond, branch.conditionVar, eql);

else branch;
end match;
end mapExpBranch;

function foldExpList<ArgT>
Expand Down Expand Up @@ -400,17 +453,33 @@ public
case Equation.IF()
algorithm
for b in eq.branches loop
arg := func(Util.tuple21(b), arg);
arg := foldExpList(Util.tuple22(b), func, arg);
() := match b
case Branch.BRANCH()
algorithm
arg := func(b.condition, arg);
arg := foldExpList(b.body, func, arg);
then
();

else ();
end match;
end for;
then
();

case Equation.WHEN()
algorithm
for b in eq.branches loop
arg := func(Util.tuple21(b), arg);
arg := foldExpList(Util.tuple22(b), func, arg);
() := match b
case Branch.BRANCH()
algorithm
arg := func(b.condition, arg);
arg := foldExpList(b.body, func, arg);
then
();

else ();
end match;
end for;
then
();
Expand Down
59 changes: 38 additions & 21 deletions Compiler/NFFrontEnd/NFFlatten.mo
Expand Up @@ -706,29 +706,37 @@ algorithm
end flattenEquation;

function flattenIfEquation
input list<tuple<Expression, list<Equation>>> branches;
input list<Equation.Branch> branches;
input ComponentRef prefix;
input DAE.ElementSource source;
input output list<Equation> equations;
protected
list<tuple<Expression, list<Equation>>> bl = {};
list<Equation.Branch> bl = {};
Expression cond;
list<Equation> eql;
Variability var;
algorithm
for b in branches loop
(cond, eql) := b;
eql := flattenEquations(eql, prefix);

if Expression.isTrue(cond) and listEmpty(bl) then
// If the condition is literal true and we haven't collected any other
// branches yet, replace the if equation with this branch.
equations := listAppend(eql, equations);
return;
elseif not Expression.isFalse(cond) then
// Only add the branch to the list of branches if the condition is not
// literal false, otherwise just drop it since it will never trigger.
bl := (cond, eql) :: bl;
end if;
bl := match b
case Equation.Branch.BRANCH(cond, var, eql)
algorithm
eql := flattenEquations(eql, prefix);

if Expression.isTrue(cond) and listEmpty(bl) then
// If the condition is literal true and we haven't collected any other
// branches yet, replace the if equation with this branch.
equations := listAppend(eql, equations);
return;
elseif not Expression.isFalse(cond) then
// Only add the branch to the list of branches if the condition is not
// literal false, otherwise just drop it since it will never trigger.
bl := Equation.makeBranch(cond, eql, var) :: bl;
end if;
then
bl;

else b :: bl;
end match;
end for;

// Add the flattened if equation to the list of equations if we got this far,
Expand All @@ -739,16 +747,17 @@ algorithm
end flattenIfEquation;

function flattenEqBranch
input output tuple<Expression, list<Equation>> branch;
input output Equation.Branch branch;
input ComponentRef prefix;
protected
Expression exp;
list<Equation> eql;
Variability var;
algorithm
(exp, eql) := branch;
Equation.Branch.BRANCH(exp, var, eql) := branch;
exp := flattenExp(exp, prefix);
eql := flattenEquations(eql, prefix);
branch := (exp, listReverseInPlace(eql));
branch := Equation.makeBranch(exp, listReverseInPlace(eql), var);
end flattenEqBranch;

function unrollForLoop
Expand Down Expand Up @@ -1042,11 +1051,19 @@ algorithm
end collectEquationFuncs;

function collectEqBranchFuncs
input tuple<Expression, list<Equation>> branch;
input Equation.Branch branch;
input output FunctionTree funcs;
algorithm
funcs := collectExpFuncs(Util.tuple21(branch), funcs);
funcs := List.fold(Util.tuple22(branch), collectEquationFuncs, funcs);
() := match branch
case Equation.Branch.BRANCH()
algorithm
funcs := collectExpFuncs(branch.condition, funcs);
funcs := List.fold(branch.body, collectEquationFuncs, funcs);
then
();

else ();
end match;
end collectEqBranchFuncs;

function collectAlgorithmFuncs
Expand Down

0 comments on commit 5e99170

Please sign in to comment.