Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#5763 closed defect (fixed)

Connections.isRoot statement outside equation results in instantiation failure with no error message

Reported by: Maksimov Doe Owned by: Per Östlund
Priority: normal Milestone: 1.16.0
Component: New Instantiation Version: v1.16.0-dev
Keywords: Cc:

Description

model InvalidIsRootModel
  Modelica.Mechanics.MultiBody.Interfaces.Frame frame;

equation
  Connections.isRoot(frame.R);

end InvalidIsRootModel;

//Output: Internal error Instantiation of InvalidIsRootModel failed with no error message.

Change History (10)

comment:1 by Francesco Casella, 5 years ago

Component: FrontendNew Instantiation
Milestone: 1.16.0
Owner: changed from somebody to Per Östlund
Priority: highnormal
Status: newassigned
Summary: Connections.isRoot statement outside of if clause results in instantiation failure with no error messageConnections.isRoot statement outside equation results in instantiation failure with no error message

The Connection.isRoot operator returns a boolean parameter, so it is expected to be used in an equation, not to be called by itself.

 model ValidIsRootModel
   Modelica.Mechanics.MultiBody.Interfaces.Frame frame;
   Boolean b;

 equation
   b = Connections.isRoot(frame.R);

 end ValidIsRootModel;

That said, the front end should not fail without an explanation.

comment:2 by Per Östlund, 5 years ago

Fixed in 6715c62.

The issue was actually not related to isRoot specifically, the NF would fail on any standalone function call except for certain Connections operators (but only if the model actually contained any Connections operators, otherwise the whole overconstrained connection handling is skipped).

Fixing this revealed another issue, which was that the isRoot operator in the example model wasn't evaluated in the flat model. This happened because both the NF and OF skipped evaluating overconstrained connection operators if the overconstrained graph was empty. I changed this so that the operators are always evaluated if present, since the model will otherwise fail to compile.

With these changes the isRoot call is now evaluated to false, which is subsequently removed from the model since it doesn't have any effect.

comment:3 by Per Östlund, 5 years ago

Resolution: fixed
Status: assignedclosed

comment:4 by Francesco Casella, 5 years ago

BTW, see discussion on this Modelica Specification #2462.

@perost, should I go ahead with another ticket there?

in reply to:  4 comment:5 by Per Östlund, 5 years ago

Replying to casella:

BTW, see discussion on this Modelica Specification #2462.

@perost, should I go ahead with another ticket there?

You mean another ticket on the Modelica tracker? I guess it might make sense to at least warn users if they call a function with no side effects and discard the result, but I'm not sure if it needs to be forbidden. I think that's something that can be left to the discretion of the tool developers.

comment:6 by Francesco Casella, 5 years ago

I find it a bit weird that one can write legal Modelica code whose semantics is left at the discretion of tool developers.

I understand there are many other software standards that have this problem (e.g. IEC 61131), but shouldn't we try to do better?

in reply to:  6 comment:7 by Per Östlund, 5 years ago

Replying to casella:

I find it a bit weird that one can write legal Modelica code whose semantics is left at the discretion of tool developers.

I didn't realize there's a semantic issue. What I meant was that it's often best to leave it to the tool developers to detect meaningless elements of a model and warn the user about them, since it can be very hard to specify such cases formally. The semantics should of course be specified though, even if the semantics might not make any sense in certain cases.

comment:8 by Francesco Casella, 5 years ago

Maybe I'm not using the correct terminology (I'm not really a compiler developer). What I mean, as I tried to explain in that PR, is that the Modelica syntax allows to put standalone "function calls" in the equation section, but then what they actually mean is only explained in a few cases, e.g. terminate().

Their meaning in other cases is unspecified, in particular what is the effect of putting function calls to functions with (or without) side effects. I think this should be rather be specified.

in reply to:  8 ; comment:9 by Per Östlund, 5 years ago

Replying to casella:

Maybe I'm not using the correct terminology (I'm not really a compiler developer). What I mean, as I tried to explain in that PR, is that the Modelica syntax allows to put standalone "function calls" in the equation section, but then what they actually mean is only explained in a few cases, e.g. terminate().

Their meaning in other cases is unspecified, in particular what is the effect of putting function calls to functions with (or without) side effects. I think this should be rather be specified.

Ok, I just assumed they'd be executed like normally, with any return values being discarded. The order such calls are executed in is of course not specified, but that's not really the case for any functions calls inside an equation section as far as I know.

But I guess I'm not the best person to comment on the issue since I'm more of a "traditional" programmer where such calls are perfectly normal.

in reply to:  9 comment:10 by Francesco Casella, 5 years ago

Replying to perost:

Ok, I just assumed they'd be executed like normally, with any return values being discarded. The order such calls are executed in is of course not specified, but that's not really the case for any functions calls inside an equation section as far as I know.

Actual equations in equation sections describe the mathematical relationships among variables, with the goal of describing a complete system of equations, whose solution is the sought-after output of the whole game. Functions inside these equations will be called whenever this is required to solve the equations, so the order is somehow specified by the solution process.

Standalone function calls are not really equations, so they don't really fit this framework. I understand the usual interpretation is that the functions get called once their argument have been computed, but this is somewhat ambiguous. For example, how many times is a function call if its arguments are all parameters? One would say only once, at initialization, but if you try you sometimes get two or three times. Which is quite confusing, particularly if the function has indeed some side effects.

Note: See TracTickets for help on using tickets.