modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
104 stars 40 forks source link

Implicit dv := pre(dv) in initial algorithm? #3472

Open maltelenz opened 10 months ago

maltelenz commented 10 months ago

Consider:

model DiscreteInit2
  Integer i;
initial algorithm
  if time < 1 then
    i := 1;
  end if;
equation
  when false then
    i = pre(i);
  end when;
end DiscreteInit2;

From what I read here about algorithms:

A discrete-time variable v is initialized with pre(v).

and here about when equations:

If a when-clause equation v = expr; is not active during the initialization phase, the equation v = pre(v) is added for initialization.

my interpretation is that the initialization problem to be solved for this model is:

initial algorithm
  i := pre(i);
  if time < 1 then
    i := 1;
  end if;
equation
  i = pre(i);

which, swapping pre(i) => prei for readability, conceptually is similar to (pseudo code):

function f
  input Integer prei;
  input Integer i;
  output Integer i_out;
algorithm
  i_out := prei;
  if time < 1 then
    i_out := 1;
  end if;
end f;

i = f(prei, i);
i = prei;

which reveals that we have a cycle/mutually dependent equations in the variables {i, prei}, turning this into an illegal model.

Is this interpretation correct?

maltelenz commented 10 months ago

Note relation to #2639. I'm trying to get clarity on the initialization-specific aspects in this new issue.

HansOlsson commented 5 months ago

Clearly discrete variables that are not unconditionally assigned should have deterministic value at the start of the initial algorithm to get deterministic results.

However, using pre(dv) will mostly cause loops that cannot be solved (uniquely), unless the variable is assigned a value (independent of its initial value) and in that case the initial value didn't matter. That just seems bad.

For parameters we instead have the special rule that they are initialized to their start-value in initial algorithms, and that seems like a solution that could be generalized to all variables in initial algorithms giving the following benefits:

HansOlsson commented 3 months ago

If not I would propose the change above.

casella commented 3 months ago

dv = pre(dv) looks to me like a steady-state condition, which of course can be hard to solve for in some cases. I think using the start attribute makes a lot more sense.

henrikt-ma commented 3 months ago

I like the idea of unifying the handling and breaking loops, but it's a non-trivial change of semantics that should be evaluated using test-implementations rather than by listening to gut feelings.

casella commented 3 months ago

I played around with the MWE by @maltelenz and I came to the conclusion that OMC already implements the proposed new semantics 😅:

This means, the OMC generated code first initializes those discrete variables with their start attributes, and then possibly overwrites their value when executing the initial algorithm. So, we already have a working test implementation, and it's been around for a while 😃

Is there any further tests cases you'd like to analyze with it?

casella commented 3 months ago

keeping @phannebohm and @kabdelhak in the loop, maybe they can further comment about this specific issue.