Skip to content

Commit

Permalink
Improving typing of dimensions in relaxed contexts (#11098)
Browse files Browse the repository at this point in the history
Fixes #11088
  • Loading branch information
perost committed Aug 29, 2023
1 parent 1ab4f06 commit e947c52
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 29 deletions.
86 changes: 57 additions & 29 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -679,41 +679,17 @@ algorithm
then
fail();

// An untyped binding, type the expression only as much as is needed
// to get the dimension we're looking for.
case Binding.UNTYPED_BINDING()
algorithm
dim_index := index + parent_dims;
(dim, oexp, ty_err) := typeExpDim(b.bindingExp, dim_index, InstContext.set(context, NFInstContext.DIMENSION), info);

// If the deduced dimension is unknown, evaluate the binding and try again.
if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then
exp := if isSome(oexp) then Util.getOption(oexp) else b.bindingExp;
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
(dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index);
end if;
then
(dim, ty_err);
then deduceDimensionFromExp(b.bindingExp, NONE(), index, parent_dims, component, context, info);

// A typed binding, get the dimension from the binding's type.
case Binding.TYPED_BINDING()
algorithm
dim_index := index + parent_dims;
(dim, ty_err) := nthDimensionBoundsChecked(b.bindingType, dim_index);

// If the deduced dimension is unknown, evaluate the binding and try again.
if Dimension.isUnknown(dim) and not TypingError.isError(ty_err) then
exp := Ceval.evalExp(b.bindingExp, Ceval.EvalTarget.DIMENSION(component, index, b.bindingExp, info));
(dim, ty_err) := nthDimensionBoundsChecked(Expression.typeOf(exp), dim_index);
end if;
then
(dim, ty_err);

then deduceDimensionFromExp(b.bindingExp, SOME(b.bindingType), index, parent_dims, component, context, info);
else (dimension, TypingError.NO_ERROR());
end match;

() := match ty_err
case TypingError.OUT_OF_BOUNDS()
guard not InstContext.inRelaxed(context)
algorithm
Error.addSourceMessage(Error.DIMENSION_DEDUCTION_FROM_BINDING_FAILURE,
{String(index), InstNode.name(component), Binding.toString(b)}, info);
Expand All @@ -723,12 +699,18 @@ algorithm
else ();
end match;

// Make sure the dimension is constant evaluted, and also mark it as structural.
// Make sure the dimension is constant evaluated, and also mark it as structural.
dim := match dim
case Dimension.EXP(exp = exp)
algorithm
Structural.markExp(exp);
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));

if InstContext.inRelaxed(context) then
exp := Ceval.tryEvalExp(exp);
else
exp := Ceval.evalExp(exp, Ceval.EvalTarget.DIMENSION(component, index, exp, info));
end if;

exp := subscriptDimExp(exp, component);
then
Dimension.fromExp(exp, dim.var);
Expand All @@ -752,6 +734,52 @@ algorithm
end match;
end typeDimension;

function deduceDimensionFromExp
input Expression exp;
input Option<Type> ty;
input Integer index;
input Integer parentDims;
input InstNode component;
input InstContext.Type context;
input SourceInfo info;
output Dimension dim;
output TypingError error;
protected
Option<Expression> oe;
Expression e;
Integer dim_index;
algorithm
// If the binding expression comes from a parent of the component rather than
// the component iself the dimension index needs to be offset by the number of
// dimensions of the parent(s).
dim_index := index + parentDims;

if isSome(ty) then
// If the type is known, take the dimension directly from it.
(dim, error) := nthDimensionBoundsChecked(Util.getOption(ty), dim_index);
oe := NONE();
else
// If the type is unknown, try to type the expression only as much as is
// needed to get the dimension we're looking for.
(dim, oe, error) := typeExpDim(exp, dim_index,
InstContext.set(context, NFInstContext.DIMENSION), info);
end if;

// If the deduced dimension is unknown, evaluate the binding and try again.
if Dimension.isUnknown(dim) and not TypingError.isError(error) then
// Use the typed expression from typeExpDim if it was returned.
e := if isSome(oe) then Util.getOption(oe) else exp;

if InstContext.inRelaxed(context) then
e := Ceval.tryEvalExp(e);
else
e := Ceval.evalExp(e, Ceval.EvalTarget.DIMENSION(component, index, e, info));
end if;

(dim, error) := nthDimensionBoundsChecked(Expression.typeOf(e), dim_index);
end if;
end deduceDimensionFromExp;

function subscriptDimExp
"Tries to fix dimension expressions that are lacking subscripts after having
been evaluated."
Expand Down
76 changes: 76 additions & 0 deletions testsuite/openmodelica/instance-API/GetModelInstanceDim1.mos
@@ -0,0 +1,76 @@
// name: GetModelInstanceDim1
// keywords:
// status: correct
// cflags: -d=newInst
//
//

loadString("
model M
parameter Integer n;
parameter Real x[:] = ones(n);
end M;
");

getModelInstance(M, prettyPrint = true);
getErrorString();

// Result:
// true
// "{
// \"name\": \"M\",
// \"restriction\": \"model\",
// \"elements\": [
// {
// \"$kind\": \"component\",
// \"name\": \"n\",
// \"type\": \"Integer\",
// \"prefixes\": {
// \"variability\": \"parameter\"
// }
// },
// {
// \"$kind\": \"component\",
// \"name\": \"x\",
// \"type\": \"Real\",
// \"dims\": {
// \"absyn\": [
// \":\"
// ],
// \"typed\": [
// \"n\"
// ]
// },
// \"modifiers\": \"ones(n)\",
// \"value\": {
// \"binding\": {
// \"$kind\": \"call\",
// \"name\": \"fill\",
// \"arguments\": [
// 1,
// {
// \"$kind\": \"cref\",
// \"parts\": [
// {
// \"name\": \"n\"
// }
// ]
// }
// ]
// }
// },
// \"prefixes\": {
// \"variability\": \"parameter\"
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 2,
// \"columnStart\": 3,
// \"lineEnd\": 5,
// \"columnEnd\": 8
// }
// }"
// ""
// endResult
1 change: 1 addition & 0 deletions testsuite/openmodelica/instance-API/Makefile
Expand Up @@ -30,6 +30,7 @@ GetModelInstanceConnection3.mos \
GetModelInstanceDerived1.mos \
GetModelInstanceDerived2.mos \
GetModelInstanceDerived3.mos \
GetModelInstanceDim1.mos \
GetModelInstanceDuplicate1.mos \
GetModelInstanceEnum1.mos \
GetModelInstanceEnum2.mos \
Expand Down

0 comments on commit e947c52

Please sign in to comment.