Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#5763 closed defect (fixed)

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

Reported by: gossen Owned by: perost
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 Changed 4 years ago by casella

  • Component changed from Frontend to New Instantiation
  • Milestone set to 1.16.0
  • Owner changed from somebody to perost
  • Priority changed from high to normal
  • Status changed from new to assigned
  • Summary changed from Connections.isRoot statement outside of if clause results in instantiation failure with no error message to Connections.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 Changed 4 years ago by perost

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 Changed 4 years ago by perost

  • Resolution set to fixed
  • Status changed from assigned to closed

comment:4 follow-up: Changed 4 years ago by casella

BTW, see discussion on this Modelica Specification #2462.

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

comment:5 in reply to: ↑ 4 Changed 4 years ago by perost

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 follow-up: Changed 4 years ago by 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 understand there are many other software standards that have this problem (e.g. IEC 61131), but shouldn't we try to do better?

comment:7 in reply to: ↑ 6 Changed 4 years ago by perost

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 follow-up: Changed 4 years ago by 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.

comment:9 in reply to: ↑ 8 ; follow-up: Changed 4 years ago by perost

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.

comment:10 in reply to: ↑ 9 Changed 4 years ago by casella

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.