ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Assignments and variability of record constructor expressions

Open henrikt-ma opened this issue 2 years ago • 5 comments

I'd like to get confirmation that both assignments in the following model have variability violations:

model RecordAssignmentVariability
  record R
    Real x;
    Integer k;
  end R;

  function makeR "Wrapper around record constructor for R"
    input Real x;
    input Integer k;
    output R r(x = x, k = k);
  end makeR;

  R r1, r2;
algorithm
  r1 := makeR(x = time, k = integer(time)); /* Error: RHS function call has continuous-time variability. */
  r2 := R(x = time, k = integer(time)); /* Error: Explicit use of record constructor doesn't help. */
end RecordAssignmentVariability;

In other words, statements don't have anything corresponding to the discrete-valued equation variability rule that allows an equation to be treated member by member for records.

Maybe this is something we could clarify as part of #3135?

Note that the specification is at least rather clearly stating that the component variability of the record components is discrete-time: https://specification.modelica.org/master/class-predefined-types-and-declarations.html#variability-of-structured-entities

henrikt-ma avatar Mar 23 '22 07:03 henrikt-ma

I thought that the variability check would be first performed on records (r1 is continuous and so is RHS) and then based on the rule in 6.7, it would just be performed based on the named elements.

It is interesting that in 8.3.1 Simple Equality Equations, there is a requirement of type compatibility (and, hence, the explanation of how to perform it on records):

The types of the left-hand-side and the right-hand-side of an equation need to be compatible in the same way as two arguments of binary operators (section 6.7).

But there is no mention of type compatibility in 11.2.1 Simple Assignment Statements, so, in a way, nothing about assignments on records is specified.

eshmoylova avatar Mar 30 '22 18:03 eshmoylova

Note that the specification is at least rather clearly stating that the component variability of the record components is discrete-time: https://specification.modelica.org/master/class-predefined-types-and-declarations.html#variability-of-structured-entities

My interpretation of that rule (backed up by the examples under) is that r1.x is a continuous-time variable and r1.k is a discrete-time variable.

eshmoylova avatar Apr 12 '22 17:04 eshmoylova

My interpretation of that rule (backed up by the examples under) is that r1.x is a continuous-time variable and r1.k is a discrete-time variable.

Looks like there is some room for clarification here. :)

My careless interpretation of the examples ignored the use of the out-of-place term variable. As I'm not sure we consider, for instance, a.pi a component, my reading of the examples was actually about the component reference expressions:

parameter A a;
  // a.pi has constant variability
  // a.y and a.i have parameter variability
A b;
  // b.pi has constant variability
  // b.y has continuous-time variability
  // b.i has discrete-time variability

henrikt-ma avatar Apr 13 '22 06:04 henrikt-ma

I thought that the variability check would be first performed on records (r1 is continuous and so is RHS) and then based on the rule in 6.7, it would just be performed based on the named elements.

The treatment of r1 as continuous-time in the LHS is exactly the thing we need to address. It would be (currently is) a failure of the variability rules that we cannot directly reject the assignment of a continuous-time expression to r1, as r1 contains parts that can only be allowed to change at events.

Of course, this variability rule is just a convenience that allows tools to report potential model problems as errors with clear support in the specification, but to me treating r1 as continuous-time on the LHS of an assignment would be equivalent to allowing this model:

model M
  Real x;
  discrete Real k(start = 0.0, fixed = true);
equation
  when time > 0.5 then
    k = 1.0;
  end when;
algorithm
  k := x; /* Variability violation. */
end M;

Note that the model above wouldn't be a problem for a tool to handle, but that the variability rule enforces assignments to agree with "common intuition" about variability, making them somewhat easier to reason about.

henrikt-ma avatar Apr 13 '22 06:04 henrikt-ma

To further illustrate this problem, I invite representatives of all tools to provide current behavior for this model, including the quality of the simulation result for r.k, if any:

model RecordAssignmentVariability
  record R
    Real x;
    Integer k;
  end R;

  function f
    input Real t;
    output R y(x = t, k = if t ^ 2 < 2 then 1 else 2);
  end f;

  R r;
algorithm
  r := f(time);
  annotation(experiment(StopTime = 5.0, Interval = 0.5));
end RecordAssignmentVariability;

henrikt-ma avatar Aug 24 '22 13:08 henrikt-ma

I am also surprised how anyone expects the description of how RecordConstructor are automatically generated to pass variability checking.

record R
   constant Real x ;
end R;

is supposed to be turned into

function R
  input Real x;
  output R $special_not_used(x = x);
end R;

except $special_not_used.x is constant and x has discrete variability in the best interpretation possible.

qlambert-pro avatar Nov 04 '22 14:11 qlambert-pro

There is also the question of the validity of the following model:

model RecordFieldVariabilityInFunctions
  record R
    constant Integer n = 3;
    parameter Real a[n] = fill(1, n);
    parameter Real b[n] = a[1:end];
  end R;

  function f
    input R r;
    output Real o = 2;
  end f;

  parameter R r;
  Real x = f(r);
end RecordFieldVariabilityInFunctions;

I am not sure what to think of the definition of a constant as input to a function when it is the field of a record.

qlambert-pro avatar Nov 07 '22 10:11 qlambert-pro

Seems we need to return to this.

HansOlsson avatar Nov 13 '22 19:11 HansOlsson