Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit e14b054

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Improve handling of if-equations.
- Delay branch selection for if-equations to flattening (for if-equations containing connects) or model simplification (for other if-equations). Belonging to [master]: - #2725 - OpenModelica/OpenModelica-testsuite#1051
1 parent 9595dac commit e14b054

File tree

11 files changed

+309
-53
lines changed

11 files changed

+309
-53
lines changed

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ public
334334
ComponentRef rest_cref;
335335
list<Subscript> cref_subs;
336336

337-
case CREF(origin = Origin.CREF, subscripts = cref_subs)
337+
case CREF(subscripts = cref_subs)
338338
algorithm
339339
(subscripts, rest_cref) := applySubscripts2(subscripts, cref.restCref);
340340

Compiler/NFFrontEnd/NFConvertDAE.mo

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,12 @@ algorithm
548548
(conds, branches) := match branch
549549
case Equation.Branch.BRANCH()
550550
then (branch.condition :: conds, branch.body :: branches);
551+
552+
case Equation.Branch.INVALID_BRANCH()
553+
algorithm
554+
Equation.Branch.triggerErrors(branch);
555+
then
556+
fail();
551557
end match;
552558
end for;
553559

@@ -564,6 +570,8 @@ algorithm
564570
end if;
565571

566572
dconds := listReverse(Expression.toDAE(c) for c in conds);
573+
dbranches := listReverseInPlace(dbranches);
574+
567575
ifEquation := if isInitial then
568576
DAE.Element.INITIAL_IF_EQUATION(dconds, dbranches, else_branch, source) else
569577
DAE.Element.IF_EQUATION(dconds, dbranches, else_branch, source);
@@ -596,7 +604,7 @@ function convertInitialEquations
596604
input list<Equation> equations;
597605
input output list<DAE.Element> elements = {};
598606
algorithm
599-
for eq in equations loop
607+
for eq in listReverse(equations) loop
600608
elements := convertInitialEquation(eq, elements);
601609
end for;
602610
end convertInitialEquations;

Compiler/NFFrontEnd/NFEquation.mo

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ encapsulated uniontype NFEquation
3737
import DAE;
3838
import ComponentRef = NFComponentRef;
3939
import NFPrefixes.Variability;
40+
import Error;
4041

4142
protected
4243
import Equation = NFEquation;
@@ -52,12 +53,37 @@ public
5253
list<Equation> body;
5354
end BRANCH;
5455

56+
record INVALID_BRANCH
57+
Branch branch;
58+
list<Error.TotalMessage> errors;
59+
end INVALID_BRANCH;
60+
5561
function toString
5662
input Branch branch;
5763
output String str;
5864
algorithm
59-
str := Expression.toString(branch.condition) + " then\n" + toStringList(branch.body);
65+
str := match branch
66+
case BRANCH()
67+
then Expression.toString(branch.condition) + " then\n" + toStringList(branch.body);
68+
69+
case INVALID_BRANCH()
70+
then toString(branch.branch);
71+
end match;
6072
end toString;
73+
74+
function triggerErrors
75+
input Branch branch;
76+
algorithm
77+
() := match branch
78+
case INVALID_BRANCH()
79+
algorithm
80+
Error.addTotalMessages(branch.errors);
81+
then
82+
fail();
83+
84+
else ();
85+
end match;
86+
end triggerErrors;
6187
end Branch;
6288

6389
record EQUALITY
@@ -525,6 +551,96 @@ public
525551
end match;
526552
end foldExp;
527553

554+
function contains
555+
input Equation eq;
556+
input PredFn func;
557+
output Boolean res;
558+
559+
partial function PredFn
560+
input Equation eq;
561+
output Boolean res;
562+
end PredFn;
563+
algorithm
564+
if func(eq) then
565+
res := true;
566+
return;
567+
end if;
568+
569+
res := match eq
570+
case FOR() then containsList(eq.body, func);
571+
572+
case IF()
573+
algorithm
574+
for b in eq.branches loop
575+
() := match b
576+
case Branch.BRANCH()
577+
algorithm
578+
if containsList(b.body, func) then
579+
res := true;
580+
return;
581+
end if;
582+
then
583+
();
584+
585+
else ();
586+
end match;
587+
end for;
588+
then
589+
false;
590+
591+
case WHEN()
592+
algorithm
593+
for b in eq.branches loop
594+
() := match b
595+
case Branch.BRANCH()
596+
algorithm
597+
if containsList(b.body, func) then
598+
res := true;
599+
return;
600+
end if;
601+
then
602+
();
603+
604+
else ();
605+
end match;
606+
end for;
607+
then
608+
false;
609+
610+
else false;
611+
end match;
612+
end contains;
613+
614+
function containsList
615+
input list<Equation> eql;
616+
input PredFn func;
617+
output Boolean res;
618+
619+
partial function PredFn
620+
input Equation eq;
621+
output Boolean res;
622+
end PredFn;
623+
algorithm
624+
for eq in eql loop
625+
if contains(eq, func) then
626+
res := true;
627+
return;
628+
end if;
629+
end for;
630+
631+
res := false;
632+
end containsList;
633+
634+
function isConnect
635+
input Equation eq;
636+
output Boolean isConnect;
637+
algorithm
638+
isConnect := match eq
639+
case CONNECT() then true;
640+
else false;
641+
end match;
642+
end isConnect;
643+
528644
function toString
529645
input Equation eq;
530646
output String str;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3854,6 +3854,16 @@ public
38543854
end match;
38553855
end isInteger;
38563856

3857+
function isBoolean
3858+
input Expression exp;
3859+
output Boolean isBool;
3860+
algorithm
3861+
isBool := match exp
3862+
case BOOLEAN() then true;
3863+
else false;
3864+
end match;
3865+
end isBoolean;
3866+
38573867
function isRecord
38583868
input Expression exp;
38593869
output Boolean isRecord;

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ algorithm
894894
Equation.CONNECT(e1, e2, eql, eq.source) :: equations;
895895

896896
case Equation.IF()
897-
then flattenIfEquation(eq.branches, prefix, eq.source, equations);
897+
then flattenIfEquation(eq, prefix, equations);
898898

899899
case Equation.WHEN()
900900
algorithm
@@ -934,25 +934,40 @@ algorithm
934934
end flattenEquation;
935935

936936
function flattenIfEquation
937-
input list<Equation.Branch> branches;
937+
input Equation eq;
938938
input ComponentRef prefix;
939-
input DAE.ElementSource source;
940939
input output list<Equation> equations;
941940
protected
942-
list<Equation.Branch> bl = {};
941+
list<Equation.Branch> branches, bl = {};
943942
Expression cond;
944943
list<Equation> eql;
945944
Variability var;
945+
Boolean has_connect;
946+
DAE.ElementSource src;
946947
algorithm
948+
Equation.IF(branches = branches, source = src) := eq;
949+
has_connect := Equation.contains(eq, isConnectEq);
950+
947951
for b in branches loop
948952
bl := match b
949953
case Equation.Branch.BRANCH(cond, var, eql)
950954
algorithm
951-
// flatten the condition first
955+
// Flatten the condition and body of the branch.
952956
cond := flattenExp(cond, prefix);
953-
// flatten the equations
954957
eql := flattenEquations(eql, prefix);
955958

959+
// Force branch selection if the if-equation contains connects.
960+
if has_connect then
961+
cond := Ceval.evalExp(cond);
962+
963+
if not Expression.isBoolean(cond) then
964+
Error.addInternalError(
965+
"Failed to evaluate branch condition in if equation containing connect equations: `" +
966+
Expression.toString(cond) + "`", Equation.info(eq));
967+
fail();
968+
end if;
969+
end if;
970+
956971
if Expression.isTrue(cond) and listEmpty(bl) then
957972
// If the condition is literal true and we haven't collected any other
958973
// branches yet, replace the if equation with this branch.
@@ -966,17 +981,45 @@ algorithm
966981
then
967982
bl;
968983

984+
// An invalid branch must have a false condition if the if-equation
985+
// contains connects, anything else is an error.
986+
case Equation.Branch.INVALID_BRANCH(branch = Equation.Branch.BRANCH(condition = cond))
987+
guard has_connect
988+
algorithm
989+
cond := Ceval.evalExp(cond);
990+
991+
if not Expression.isFalse(cond) then
992+
Equation.Branch.triggerErrors(b);
993+
end if;
994+
then
995+
bl;
996+
969997
else b :: bl;
970998
end match;
971999
end for;
9721000

9731001
// Add the flattened if equation to the list of equations if we got this far,
9741002
// and there are any branches still remaining.
9751003
if not listEmpty(bl) then
976-
equations := Equation.IF(listReverseInPlace(bl), source) :: equations;
1004+
equations := Equation.IF(listReverseInPlace(bl), src) :: equations;
9771005
end if;
9781006
end flattenIfEquation;
9791007

1008+
function isConnectEq
1009+
input Equation eq;
1010+
output Boolean isConnect;
1011+
algorithm
1012+
isConnect := match eq
1013+
local
1014+
Function fn;
1015+
1016+
case Equation.CONNECT() then true;
1017+
case Equation.NORETCALL(exp = Expression.CALL(call = Call.TYPED_CALL(fn = fn)))
1018+
then Absyn.pathFirstIdent(Function.name(fn)) == "Connections";
1019+
else false;
1020+
end match;
1021+
end isConnectEq;
1022+
9801023
function flattenEqBranch
9811024
input output Equation.Branch branch;
9821025
input ComponentRef prefix;

Compiler/NFFrontEnd/NFInst.mo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2994,14 +2994,15 @@ end markStructuralParamsExp;
29942994

29952995
function markStructuralParamsExp_traverser
29962996
input Expression exp;
2997+
import NFComponentRef.Origin;
29972998
algorithm
29982999
() := match exp
29993000
local
30003001
InstNode node;
30013002
Component comp;
30023003
Option<Expression> binding;
30033004

3004-
case Expression.CREF(cref = ComponentRef.CREF(node = node))
3005+
case Expression.CREF(cref = ComponentRef.CREF(node = node, origin = Origin.CREF))
30053006
algorithm
30063007
if InstNode.isComponent(node) then
30073008
comp := InstNode.component(node);

Compiler/NFFrontEnd/NFOCConnectionGraph.mo

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,9 +1250,9 @@ algorithm
12501250
rooted = setRootDistance(inRoots,table,0,{},NFHashTable.emptyHashTable());
12511251
// BaseHashTable.dumpHashTable(rooted);
12521252
outEquations =
1253-
list(Equation.mapExp(eq,
1254-
function evaluateOperators(inRoots = (rooted,inRoots,graph)))
1255-
for eq in inEquations);
1253+
list(Equation.mapExp(eq,
1254+
function evaluateOperators(inRoots = (rooted,inRoots,graph), info = Equation.info(eq)))
1255+
for eq in inEquations);
12561256
then outEquations;
12571257

12581258
end matchcontinue;
@@ -1261,15 +1261,17 @@ end evalConnectionsOperators;
12611261
function evaluateOperators
12621262
input output Expression exp;
12631263
input tuple<NFHashTable.HashTable,list<ComponentRef>, NFOCConnectionGraph> inRoots;
1264+
input SourceInfo info;
12641265
algorithm
12651266
exp := Expression.map(exp,
1266-
function evalConnectionsOperatorsHelper(inRoots = inRoots));
1267+
function evalConnectionsOperatorsHelper(inRoots = inRoots, info = info));
12671268
end evaluateOperators;
12681269

12691270
protected function evalConnectionsOperatorsHelper
12701271
"Helper function for evaluation of Connections.rooted, Connections.isRoot, Connections.uniqueRootIndices"
12711272
input Expression inExp;
12721273
input tuple<NFHashTable.HashTable,list<ComponentRef>, NFOCConnectionGraph> inRoots;
1274+
input SourceInfo info;
12731275
output Expression outExp;
12741276
algorithm
12751277
outExp := matchcontinue (inExp,inRoots)
@@ -1321,7 +1323,7 @@ algorithm
13211323
end if;
13221324
else // add an error message:
13231325
str := ComponentRef.toString(cref);
1324-
Error.addMessage(Error.OCG_MISSING_BRANCH, {str, str, str});
1326+
Error.addSourceMessage(Error.OCG_MISSING_BRANCH, {str, str, str}, info);
13251327
result := false;
13261328
end try;
13271329
then

Compiler/NFFrontEnd/NFSimplifyModel.mo

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,21 @@ algorithm
381381
then
382382
accum;
383383

384+
case Equation.INVALID_BRANCH(branch =
385+
Equation.Branch.BRANCH(condition = cond, conditionVar = var))
386+
algorithm
387+
if var <= Variability.STRUCTURAL_PARAMETER then
388+
cond := Ceval.evalExp(cond);
389+
end if;
390+
391+
// An invalid branch that can't be removed will trigger the errors
392+
// stored in it.
393+
if not Expression.isFalse(cond) then
394+
Equation.Branch.triggerErrors(branch);
395+
end if;
396+
then
397+
accum;
398+
384399
else branch :: accum;
385400
end match;
386401
end for;

0 commit comments

Comments
 (0)