Skip to content

Commit 68e8900

Browse files
committed
[NF] Handle if-expressions better.
- Handle if-expressions that have branches with different dimensions better.
1 parent cf46c5d commit 68e8900

File tree

4 files changed

+78
-32
lines changed

4 files changed

+78
-32
lines changed

OMCompiler/Compiler/NFFrontEnd/NFConnectEquations.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,11 @@ algorithm
807807

808808
if isSome(attr_oexp) then
809809
SOME(attr_exp) := attr_oexp;
810+
811+
if Expression.variability(attr_exp) <= Variability.STRUCTURAL_PARAMETER then
812+
attr_exp := Ceval.evalExp(attr_exp);
813+
end if;
814+
810815
isZero := Expression.isZero(Expression.getBindingExp(attr_exp));
811816
else
812817
isZero := false;

OMCompiler/Compiler/NFFrontEnd/NFTypeCheck.mo

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,5 +3197,66 @@ algorithm
31973197
end for;
31983198
end checkSumComplexType;
31993199

3200+
function matchIfBranches
3201+
input output Expression trueBranch;
3202+
input Type trueType;
3203+
input output Expression falseBranch;
3204+
input Type falseType;
3205+
input Expression condition;
3206+
input Variability conditionVar;
3207+
input Boolean allowUnknown = false;
3208+
output Type compatibleType;
3209+
output MatchKind matchKind;
3210+
protected
3211+
Expression tdim_exp, fdim_exp;
3212+
Type tety, fety;
3213+
list<Dimension> tdims, fdims, dims;
3214+
Dimension fdim;
3215+
Variability var;
3216+
algorithm
3217+
tety := Type.arrayElementType(trueType);
3218+
fety := Type.arrayElementType(falseType);
3219+
tdims := Type.arrayDims(trueType);
3220+
fdims := Type.arrayDims(falseType);
3221+
3222+
// Both branches must have the same number of dimensions.
3223+
if listLength(tdims) <> listLength(fdims) then
3224+
matchKind := MatchKind.NOT_COMPATIBLE;
3225+
compatibleType := trueType;
3226+
return;
3227+
end if;
3228+
3229+
(trueBranch, falseBranch, compatibleType, matchKind) :=
3230+
matchExpressions(trueBranch, tety, falseBranch, fety);
3231+
3232+
// Both branches must have the same element type.
3233+
if isIncompatibleMatch(matchKind) then
3234+
return;
3235+
end if;
3236+
3237+
dims := {};
3238+
3239+
for tdim in tdims loop
3240+
fdim :: fdims := fdims;
3241+
3242+
if Dimension.isEqual(tdim, fdim) then
3243+
dims := tdim :: dims;
3244+
elseif conditionVar <= Variability.PARAMETER and
3245+
Dimension.isKnown(tdim, allowExp = true) and
3246+
Dimension.isKnown(fdim, allowExp = true) then
3247+
tdim_exp := Dimension.sizeExp(tdim);
3248+
fdim_exp := Dimension.sizeExp(fdim);
3249+
var := Prefixes.variabilityMax(Expression.variability(tdim_exp),
3250+
Expression.variability(fdim_exp));
3251+
dims := Dimension.fromExp(Expression.IF(condition, tdim_exp, fdim_exp), var) :: dims;
3252+
else
3253+
matchKind := MatchKind.NOT_COMPATIBLE;
3254+
return;
3255+
end if;
3256+
end for;
3257+
3258+
compatibleType := Type.liftArrayLeftList(compatibleType, listReverse(dims));
3259+
end matchIfBranches;
3260+
32003261
annotation(__OpenModelica_Interface="frontend");
32013262
end NFTypeCheck;

OMCompiler/Compiler/NFFrontEnd/NFTyping.mo

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,39 +2219,19 @@ algorithm
22192219
fail();
22202220
end if;
22212221

2222-
if cond_var <= Variability.STRUCTURAL_PARAMETER and
2223-
not Expression.contains(cond, isNonConstantIfCondition) then
2224-
// If the condition is constant, always do branch selection.
2225-
if evaluateCondition(cond, origin, info) then
2226-
(ifExp, ty, var) := typeExp(tb, next_origin, info);
2227-
else
2228-
(ifExp, ty, var) := typeExp(fb, next_origin, info);
2229-
end if;
2230-
else
2231-
// Otherwise type both of the branches.
2232-
(tb, tb_ty, tb_var) := typeExp(tb, next_origin, info);
2233-
(fb, fb_ty, fb_var) := typeExp(fb, next_origin, info);
2234-
2235-
(tb2, fb2, ty, ty_match) := TypeCheck.matchExpressions(tb, tb_ty, fb, fb_ty);
2222+
(tb, tb_ty, tb_var) := typeExp(tb, next_origin, info);
2223+
(fb, fb_ty, fb_var) := typeExp(fb, next_origin, info);
2224+
(tb2, fb2, ty, ty_match) := TypeCheck.matchIfBranches(tb, tb_ty, fb, fb_ty, cond, cond_var);
22362225

2237-
if TypeCheck.isIncompatibleMatch(ty_match) then
2238-
if cond_var <= Variability.PARAMETER then
2239-
// If the branches have different types but the condition is a parameter
2240-
// expression, do branch selection.
2241-
(ifExp, ty, var) := if evaluateCondition(cond, origin, info) then (tb, tb_ty, tb_var) else (fb, fb_ty, fb_var);
2242-
else
2243-
// Otherwise give a type mismatch error.
2244-
Error.addSourceMessage(Error.TYPE_MISMATCH_IF_EXP,
2245-
{"", Expression.toString(tb), Type.toString(tb_ty),
2246-
Expression.toString(fb), Type.toString(fb_ty)}, info);
2247-
fail();
2248-
end if;
2249-
else
2250-
// If the types match, return a typed if-expression.
2251-
ifExp := Expression.IF(cond, tb2, fb2);
2252-
var := Prefixes.variabilityMax(cond_var, Prefixes.variabilityMax(tb_var, fb_var));
2253-
end if;
2226+
if TypeCheck.isIncompatibleMatch(ty_match) then
2227+
Error.addSourceMessage(Error.TYPE_MISMATCH_IF_EXP,
2228+
{"", Expression.toString(tb), Type.toString(tb_ty),
2229+
Expression.toString(fb), Type.toString(fb_ty)}, info);
2230+
fail();
22542231
end if;
2232+
2233+
ifExp := Expression.IF(cond, tb2, fb2);
2234+
var := Prefixes.variabilityMax(cond_var, Prefixes.variabilityMax(tb_var, fb_var));
22552235
end typeIfExpression;
22562236

22572237
function evaluateCondition

testsuite/flattening/modelica/scodeinst/IfExpression4.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ end IfExpression4;
1515
// Real x[1];
1616
// Real x[2];
1717
// equation
18-
// x = {1.0, 2.0};
18+
// x = if b then {1.0, 2.0} else {3.0, 4.0, 5.0};
1919
// end IfExpression4;
2020
// endResult

0 commit comments

Comments
 (0)