Opened 5 years ago
Last modified 5 years ago
#5531 assigned defect
Implicit cast from Real to Integer
Reported by: | Andreas Heuermann | Owned by: | Andreas Heuermann |
---|---|---|---|
Priority: | critical | Milestone: | 2.0.0 |
Component: | Backend | Version: | v1.14.0-dev-nightly |
Keywords: | Cc: |
Description
Is the following model legal Modelica syntax?
model TestInt Real x(start=1); Integer y; equation der(x) = x; y = x; end TestInt;
A real is casted to an integer and no warning or error is printed by OMC. In my opinion it is not 100% defined what should happen an the user should explicit state what he wants, e.g. use ceil(x)
, floor(x)
or integer(x)
.
Dymola will report:
Translation of TestInt: The problem is structurally singular. It has 2 scalar unknowns and 2 scalar equations. The Real part has 1 unknowns and 2 equations. The Integer part has 1 unknowns and 0 equations. The Boolean part has 0 unknowns and 0 equations. The String part has 0 unknowns and 0 equations. Attempting to further localize singularity. Singularity of TestInt is at the top level. The model TestInt is structurally singular. The problem is structurally singular for the element type Real. The number of scalar Real unknown elements are 1. The number of scalar Real equation elements are 2. Part of the problem for Real elements is overdetermined. There are 1 scalar equations too many in the set: y = x; der(x) = x; which was derived from der(x) = x; The problem is structurally singular for the element type Integer. The number of scalar Integer unknown elements are 1. The number of scalar Integer equation elements are 0. The following variables are considered as unknowns, but are not appearing in the equations. y Translation aborted. WARNINGS have been issued. ERRORS have been issued.
My suggestion: Throw an error (while parsing or from the Frontend) and only accept a correct version like:
model TestInt Real x(start=1); Integer y; equation der(x) = x; y = integer(x); end TestInt;
Or give a warning and implicit cast all non-real variables to integers like above.
For the example above it's pretty clear what should happen. But what is the correct solution for the following model?
model TestInt2 Real x(start=1); Real y; Integer z; equation der(x) = x; z = x; der(y) = z; end TestInt2;
der(y)
should now be discrete (equals 1 up to time=0.69 and after that equals 2) but it's computed solution is in fact equal to der(x)
. Whit a warning or error a user would notice that this model doesn't make much sense.
Change History (7)
comment:1 by , 5 years ago
Component: | Parser → Frontend |
---|---|
Owner: | changed from | to
follow-up: 3 comment:2 by , 5 years ago
Component: | Frontend → Backend |
---|---|
Milestone: | Future → 2.0.0 |
Owner: | changed from | to
Priority: | low → critical |
Status: | new → assigned |
Type: | discussion → defect |
@perost, from a Modelica semantics standpoint you are right.
However, the resulting model is structurally singular, so it should be eventually rejected. x
is a state variable, so it is known at each point in time. The first equation allows to compute der(x)
, but then the second equation cannot be solved for y
, because of the cast operation. It could only be solved backwards to compute x
given y
, but that's not possible here.
The question is whether the front-end is smart enough to worry about these issues, or whether this ought to be addressed by the back-end.
I understand the OMC FE does not distinguish between Real and Integer equations, since checkModel outputs:
Check of TestInt completed successfully. Class TestInt has 2 equation(s) and 2 variable(s). 1 of these are trivial equation(s).
so it looks like it's a backend issue. BTW, the simulation result is completely wrong, because y jumps from 1 to 2 at some point, which clearly is not consistent with the typecast equation
/*Real*/(y) = x;
This shouldn't really happen...
follow-up: 4 comment:3 by , 5 years ago
Replying to casella:
The question is whether the front-end is smart enough to worry about these issues, or whether this ought to be addressed by the back-end.
Checking whether the model is structurally singular or not is the backend's task. As far as the frontend is concerned everything is type compatible, so it's all fine.
If it's as easy as counting Real and Integer (or continuous and discrete?) variables/equations separately it could probably be implemented for checkModel, which lives in the gray zone between the frontend and backend. But in that case it's a "backend checkModel" issue, i.e. something best fixed by one of the backend developers.
comment:4 by , 5 years ago
Replying to perost:
If it's as easy as counting Real and Integer (or continuous and discrete?) variables/equations separately
I guess we should count continuous and discrete (i.e., within when clause) equations and variables separately. In this case, there is one continuous variable and one discrete equation, so it is easy to determine that the model is structurally singular even without performing the matching algorithm.
follow-up: 6 comment:5 by , 5 years ago
I would suggest to be even more strict and don't allow equations with implicit casts, except for parameters and constants. Does the Modelica Standard has to say something about this kind of equations? I could not find anything.
The models TestInt and TestInt2 without integer(x)
are strucutual singular. To detect this in the later case we need to adapt removeSimpleEquations to check for identical types (and dont remove stuff like int_a=real_b
) and after that find this kind of error while matching.
But is it even possible to have a valid equation with int_something=real_something
,ignoring parameters and constants again?
So Frontend or Backend could solve this with some work, but all in all I don't see a high priority to this problem. We simply stumbled about it yesterday.
comment:6 by , 5 years ago
Replying to AnHeuermann:
I would suggest to be even more strict and don't allow equations with implicit casts, except for parameters and constants. Does the Modelica Standard has to say something about this kind of equations? I could not find anything.
8.3.1 in the specification states that equations must be type compatible according to section 6.6, which says:
If A is a Real expression then B must be a Real or Integer expression and the type compatible expression is Real.
comment:7 by , 5 years ago
Andreas, there is nothing wrong with this model
model M Integer i; Real x; equation when sample(0,1) then i = pre(i)+1; end when; x = i; end M;
Events are generated by the integer equations, while x = i;
is a continuous equation, determining a Real variable, which happens to be equal to an integer expression. No big deal, same situation as when writing x = 0;
. Why should we ask for explicit casting? We would break 30% of existing models, or possibly more :)
Of course one could also write
model M Integer i; Real x; equation when sample(0,1) then i = pre(i)+1; end when; i = x; end M;
which is equivalent to the other one, and thus also valid. The only way to understand if the model is really valid is after causality analysis.
This is not a case of Real to Integer cast, but the opposite. Flattening the model with either the OF or the NF gives identical results:
As you can see it's actually
y
that's cast to Real to satisfy the type constraints in the equation, and that's completely legal.