ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Variability of external objects

Open MarkusOlssonModelon opened this issue 2 years ago • 8 comments

I could not find anything in the specification about the variability of external objects. In #2661 it is discussed if non-parameter arguments should be allowed in the constructor, but not how it affects the variability of the external object.

Are uses of external objects without variability prefixes considered parameter expressions? Is the following model OK (assuming external object EO and function f can be found)?

model Example
    EO eo = EO();
    parameter Real p = f(eo); // is this binding equation OK?
end Example;

Based on how external objects work, I would assume that they are always parameters, even if not declared as such. However, the definitions of parameter expressions and parameter variables in the specification do not support this assumption.

MarkusOlssonModelon avatar Feb 02 '22 11:02 MarkusOlssonModelon

Based on how external objects work, I would assume that they are always parameters, even if not declared as such. However, the definitions of parameter expressions and parameter variables in the specification do not support this assumption.

I would say that external objects should be seen as more variable, and that the model should be rejected.

Consider an external object representing an FMU - if you ask the FMU for a specific variable reference that value will change at least as a discrete-time expression, and possibly as a continuous-time expression, since you send in new values to the FMU that will influence the output (and the FMU also has an internal state).

As indicated in #2661 there are also "read-only" external objects (like tables), and one way of showing the difference would be (or even have parameter in the object type):

model Bad
    EO eo = EO();
    parameter Real p = f(eo);
end Bad;
model Good
    parameter EO eo = EO();
    parameter Real p = f(eo);
end Good;

The problems are that:

  • It is not specified
  • It is not clear how it prevents accidentally modifying the external object. If parameter is part of the external object type it would be clearer, but that needs additional specification work.

HansOlsson avatar Feb 02 '22 11:02 HansOlsson

Proposal: A component of a class derived from ExternalObject shall be seen as its declared variability even if there is nothing explicitly modifying it. Thus:

model Normal
   EO eo=EO();
   Real x=f(eo);
end Normal;
model Bad
    EO eo = EO();
    parameter Real p = f(eo);
end Bad;
model Good
    parameter EO eo = EO();
    parameter Real p = f(eo);
end Good;

Here Normal is ok, and its x has an implicit dependency on time. Bad is illegal, since f(eo) is more variable than p, and Good is legal.

HansOlsson avatar Feb 09 '22 14:02 HansOlsson

Can we use pure for separating non-modifying from modifying use external object? (Both for initialization and later.) Also consider reconstructing them.

HansOlsson avatar Feb 09 '22 16:02 HansOlsson

Can we use pure for separating non-modifying from modifying use external object? (Both for initialization and later.) Also consider reconstructing them.

Thinking more I don't think that makes sense in general; consider:

pure function readValue
   input EO eo;
   output Real y;
end readValue;
impure function writeValue
   input EO eo;
   input Real y;
end writeValue;

That would allow:

model M
   EO eo=EO();
   Real x=readValue(eo);
equation 
    when sample(1,1) then
       writeValue(eo, time);
    end when;
end M;

But if we instead of considering different functions for one external object, we only consider a completely "read-only" external object then declaring it as parameter makes more sense, except that there's nothing preventing us from declaring eo as parameter in this example.

HansOlsson avatar Mar 03 '22 16:03 HansOlsson

Can we get input on the proposed text:

A component of a class derived from ExternalObject shall be seen as its declared variability even if there is nothing explicitly modifying it.

It seems it is already used a bit, but I also see that it doesn't prevent you from modifying the external object.

Select one of the emojis for this one:

  • Thumb up (in favor)
  • Thumb down (against)
  • Eyes (we need to discuss it and have more eyes on it)

HansOlsson avatar Jul 01 '22 13:07 HansOlsson

I reacted with eyes because I think that the proposed text needs to be accompanied by some semantical restrictions for the use of the external object. For example, shouldn't it be required that all functions acting on a parameter external object are pure?

henrikt-ma avatar Jul 02 '22 23:07 henrikt-ma

I reacted with eyes because I think that the proposed text needs to be accompanied by some semantical restrictions for the use of the external object. For example, shouldn't it be required that all functions acting on a parameter external object are pure?

I totally agree that a semantic restriction that they don't modify the external object would make sense.

However, I'm not sure that we should mix that with 'pure' in its current form - one is about modifying (or depending on) an external object sent as argument - another is about the global environment.

Saying that a function modifying the external object sent as argument is impure seems confusing to me - and would miss optimizations, especially if they involve multiple external objects; if you send an argument one FMU you don't expect different results from the other FMU. So it is not modifying the external environment but the given external object.

To me it would be better to mark whether the given external object is modified or not by the function (corresponding to different between const and non-const references/member functions in C++) - which would be something different.

And in contrast to pure the default should be that the function modifies the external object. (Saying that this is what pure means for functions taking external objects seems more confusing than helpful to me.)

HansOlsson avatar Jul 15 '22 14:07 HansOlsson

On a related subject, shouldn't there be a parametric restriction on the constructor call/binding equation.

qlambert-pro avatar Aug 29 '22 06:08 qlambert-pro

Conclusion from the phone meeting is that

model Example
    EO eo = EO();
    parameter Real p = f(eo); // is this binding equation OK?
end Example;

is currently forbidden, since eo is time-varying (this is especially the case if there are other calls that may modify the external object). If you wanted to get this result you could use a parameter with fixed=false and an initial equation.

Additional changes like specifying that some external objects are "parametric" and some functions don't change their external object argument, and parameter restriction on the constructor are post-poned.

HansOlsson avatar Sep 13 '22 09:09 HansOlsson