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 Per Östlund, 5 years ago

Component: ParserFrontend
Owner: changed from Martin Sjölund to somebody

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:

class TestInt
  Real x(start = 1.0);
  Integer y;
equation
  der(x) = x;
  /*Real*/(y) = x;
end TestInt;

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.

comment:2 by Francesco Casella, 5 years ago

Component: FrontendBackend
Milestone: Future2.0.0
Owner: changed from somebody to Andreas Heuermann
Priority: lowcritical
Status: newassigned
Type: discussiondefect

@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...

in reply to:  2 ; comment:3 by Per Östlund, 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.

in reply to:  3 comment:4 by Francesco Casella, 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.

comment:5 by Andreas Heuermann, 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.

in reply to:  5 comment:6 by Per Östlund, 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 Francesco Casella, 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.

Note: See TracTickets for help on using tickets.