ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

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

Open maltelenz opened this issue 1 year ago • 7 comments

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 avatar Feb 01 '24 16:02 maltelenz

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

maltelenz avatar Feb 01 '24 16:02 maltelenz

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:

  • It is deterministic
  • It does not cause loop
  • It unifies the handling in initial algorithms (so the same for parameters, discrete and continuous-time variables)

HansOlsson avatar Jul 02 '24 12:07 HansOlsson

  • Does anyone have a preference for pre(dv) over the start-value for initial algorithms?
  • Are there any cases where pre(dv) actually works for initial algorithms?

If not I would propose the change above.

HansOlsson avatar Aug 08 '24 12:08 HansOlsson

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.

casella avatar Aug 09 '24 10:08 casella

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.

henrikt-ma avatar Aug 12 '24 07:08 henrikt-ma

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

  • OMC does not complain about the initial algebraic loop, so it is not adding the dv = pre(dv) equation as actually required by the MLS
  • if I set the start attribute for i (e.g., Integer i(start = 3)), I get an initial value of 1 if StartTime = 0, but I get 3 if StartTime = 2, when the equation in the initial algorithm is skipped

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 avatar Aug 13 '24 17:08 casella

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

casella avatar Aug 13 '24 17:08 casella