New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specification is too lax regarding the grammar of equations in equation sections #2462
Comments
I think you're missing some operators, i.e. |
Also, an equation like |
In addition to the previous cases we also have e.g. Modelica.Fluid.Utilities.checkBoundary (and Modelica.Media.R134a.R134a_ph.phaseBoundaryAssert). As an example the model Modelica.Fluid.Sources.Boundary_ph contains a call of Modelica.Fluid.Utilities.checkBoundary - which is perfectly ok. That is actually explicitly mentioned in https://specification.modelica.org/master/Ch12.html#pure-modelica-functions saying:
And finally a when-clause according to the grammar contain equations, and inside a when-clause it is normal to have more complicated "procedure" calls as they are only triggered according to the when-clause (thus the statements about unpredictability are not relevant). We could obviously separate what is allowed inside when-clause from what is allowed at the top - but that will make the grammar more complicated for no obvious gain. Thus it seems this is based on a misunderstanding and the issue shall be closed. |
Before we close the issue, I would like to get some comments from my colleagues that are actually writing the compiler. Let me try to summarize what are the possible occurrences of the
There are also some other potential uses mentioned by @adrpo:
Regarding these two, there is no explicit mention of how those should be handled in the specification. Even if we do not change the grammar, I believe that we should say something about how those are expected to be handled, more specifically how and when they are expected to be called. |
Perhaps it is a misunderstanding.
It seems to me that Modelica language specification allows a model to contain functions calls that the compiler is supposed to erase. This is the case of pure functions in the previously mentioned case. There is the case of assertion checks, which are functions with a defined semantics. However, the lack of specification regarding the timing when those assertions should be verified leaves open the possibility to implement assertion checks before the initialization problem, or after the simulation. Eventually, there is the case of functions that do not fit any of the previous cases.
Although the first two cases have a semantic which is a bit confusing (at least for computer science engineers), we believe it is the latter case that needs a little more attention. |
No, the compiler is allowed to erase the call - not supposed to.
Clearly not before the initialization in most cases: If the code contains And merely checking that Restricting the grammar for equations wouldn't help you, as the same problem you perceive exists for
also occurs for
|
This makes more sense. However, it is not what I understood from the statement.
We understand there are possible schedules that do not make sense. |
If the compiler is allowed to elide a call but not required to, assuming this function can raise an error, a benchmark can be made that fails with one compiler and works with another, despite both being standard-conforming. Also, does the specification say whether asserts (or functions in general) are to be called also for rejected time steps of the solver? In my opinion that's another gray area. |
This is not a general forum for discussing how to implement a Modelica tool.
That is generally what happens when optimizations are allowed. The alternative would be to require that
If an assert triggers for a rejected time step it will just reject it for an additional reason. Note that assert does not stop the simulation, as it effect is instead: "The current evaluation is aborted. The simulation may continue with another evaluation." |
We are simply pointing out parts of the specification that lacks of detail, when such deficiencies might impact on the simulation output. Is this the right place to discuss Modelica specification ambiguities? |
Form my understanding, it appears that some part of the Modelica specification are based on a "common sense" shared among current Modelica implementers, but not explicitly written in the specification. The goal of this discussion is to possibly improve and clarify the specification. In detail, the semantics of when functions are called (whether they are assert or not) appears to be unspecified, to the point that a restriction of the current specification to meaningful cases only is an option to be considered. For example, how many times shall this program print "test"?
By the way, other languages such as C/C++ would call |
Since Modelica is a declarative, equation-based language, this question may actually be ill posed. For example, the related question 'how many times is the sine function computed by this program'
is not meaningful, since it is commonly accepted (except perhaps by our friend Sébastien Furic, who eventually left the gang) that the Modelica semantics stops at describing a system of equations, but then does not enter into the "trivial" detail of how the solution to those equations is actually computed and stored. Experiment annotations provide some indications, but they are not mandatory and can be overridden at runtime, etc. The problem I see is that if we mix equations with statements that potentially have side effects such as initializing an external function or printing a value on a screen, the thing becomes murkier.
We left a lot of these issues dangling in Modelica before we tried to clarify the distinction between pure and impure functions. The situation improved a lot after that, but my impression is that the issue raised by this ticket is still not completely clear. |
I would expect that a good Modelica tool does not call
I guess the problem here is that functions have a different semantics when showing up in actual equations (whereby their output value is the only thing that matters), and when showing up alone as Maybe this would be worth a brief explanation in the Specification. |
If that were the case there would be something to discuss. However, that requires that you read the specification and list those cases, or have a supervisor that can help you. Now instead Adrian and I had to make that effort, and that is not the purpose. I looked back on the original comment (not by you) and could only find misunderstandings based on an incomplete reading of the actual specification. |
For the record, after some discussion with my esteemed colleagues at Politecnico, I took the initiative of starting this discussion. I take full responsibility for that, even though I guess everybody agrees that my main experience and ability is that of a modeller, not of a compiler designer. I obviously missed some instances of the I tend to agree that the set of those instances is too varied to be worth the effort of expanding the grammar to fit them, and only them, though my colleagues could disagree, in which case I invite them to provide some concrete proposals that could make the design of a compiler easier. Again, I do not consider myself an expert in compiler design. From this point of view, I agree that this issue as it was originally formulated can be closed. However, if the grammar gives you complete freedom to put any function-call-like statement in an equation section, I do think that we still have an issue with the Specification regarding the semantics of those cases that are currently not covered anywere in the text, e.g.
As a modeller, I find the fact that I can add this stuff to an equation section without the foggiest clue about what this actually means rather odd, and I am definitely convinced the specification can be improved from this point of view. Is it ok if I open a new issue on this specific topic? Thanks! |
I analyzed this issue together with @fedetft, @albertoleva, @skeru, @silseva, @drblallo, @agosta, and @nikolicmarina, while working on the implementation of an experimental Modelica compiler.
The Modelica Specification, Section 8.3 allows generic
component-reference function-call-args
non-terminals in equation sections.However, if we are not mistaken, the semantics is only specified in three very specific cases, namely:
reinit()
in Section 8.3.6assert()
in Section 8.3.7terminate()
in Section 8.3.8Compilers such as OpenModelica and Dymola actually follow the grammar and also accept arbitrary function calls, such as
Modelica.Utilities.Streams.print(x)
, orsin(2*x)
which have no definite meaning in the context of equations, that can be reordered arbitrarily, and hence produce a meaningless and implementation-dependent result.We can see no use for function calls in equations sections, only in algorithm sections they make actual sense. In any case, the semantics of anything beyond the three cases mentioned above is currently unspecified, which is not good.
Our suggestion is to restrict the grammar to indicate that only those three cases are accepted. This makes building a new compiler much easier. If there are other meaningful use cases, their semantics should be clearly defined somewhere in the specification.
The text was updated successfully, but these errors were encountered: