ModelicaSpecification
ModelicaSpecification copied to clipboard
Difference between pre and previous of clocked variable
Is the following use of pre on a clocked variable legal, and if so, what is the expected simulation result?
model ClockedEventIteration
Integer i(start = 0, fixed = true);
equation
when Clock(1) then
i = pre(i) + 1;
end when;
end ClockedEventIteration;
In particular, would there be any reason for not performing an event iteration until pre(i) = i?
For comparison, if pre is replaced by previous, the semantics are crystal clear, and i is increased by 1 at each clock activation:
when Clock(1) then
i = previous(i) + 1;
end when;
Is the following use of
preon a clocked variable legal, and if so, what is the expected simulation result?model ClockedEventIteration Integer i(start = 0, fixed = true); equation when Clock(1) then i = pre(i) + 1; end when; end ClockedEventIteration;In particular, would there be any reason for not performing an event iteration until
pre(i) = i?
I am not investigating what the current standard is saying in the following; instead I like to explain what I think it should do. If we find agreement on this, we should check if that is the case in the spec.
Is the use of pre in clocked partitions permitted: Yes.
What is its semantic: pre(v) is the value of v right before the last event changing v.
Can clocked partitions contain events / require event iteration: Yes. Such must be handled by the solver method used for the clocked partition -- this may result in model errors in case the solver method can not handle the events / equation system.
Is pre(v) always previous(v) in a clocked partition: No. If solving the clocked partition requires event iteration pre(v) might be different to previous(v).
When is prev(v) equal to previous(v): Whenever there is no sequence of events throughout a single activation of the clocked partition (i.e., tick) causing iterative evaluation yielding a sequence of prev(v) values throughout iterative solving.
Why is prev(v) equal to previous(v) if there is no event iteration for a single tick: Because the clock tick as such is an event. And the prev(v) value of v right before the clock ticks is previous(v), i.e., the value of v after the last solving of the clocked partition finished.
Regarding the need of event iteration for clocked discretized continuous-time partitions
My motivation is to make existing continuous models with pre behave reasonable when packed into clocked partitions.
And somehow pre now should take care of events throughout a single evaluation of the clocked partition (events triggered within the clocked partition), but also needs to relate to the last value of the previous evaluation of the clocked partition at the very beginning of its evaluation (i.e., if there are no events triggered throughout the current evaluation yet). In other words, it looks naturally to me that as long as there are no events triggered yet, throughout a single evaluation of a clocked partition, pre(v) should be previous(v).
That something is packed into a clocked partition doesn't imply that its simulation always terminates. That something may still require iteration (event & normal integration) and we have no guarantees in general that such iteration terminates.
The only catch is, that such iteration is done by the clock's solver for the clock partition's equations only (and therefore also only for its events). Or put differently, events outside the clock partition do not trigger iterations within it -- the clock partition and outside are mutually exclusive event spaces.
Edit:
My first answer to the example of @henrikt-ma was wrong, I overlooked that i = pre(i) + 1; causes infinite many events. The clocked partition requires an event iteration which won't terminate.
Note, that this is consistent with my above answer. At first evaluation of pre(i) we have pre(i) == previous(i); then i gets a new value, triggering an event due to i depending on pre(i) and so one.
I think what you say needs to be harmonized with this rule for pre:
A new event is triggered if there is at least for one variable \lstinline!v! such that \lstinline!pre(v) <> v! after the active model equations are evaluated at an event instant. In this case the model is at once reevaluated. This evaluation sequence is called \emph{event iteration}. The integration is restarted once \lstinline!pre(v) == v! for all \lstinline!v! appearing inside \lstinline!pre($\ldots$)!.
That is, there is not just a single event, since the change in i combined with the presence of pre(i) leads to a new event, and so forth.
I think what you say needs to be harmonized with this rule for
pre:A new event is triggered if there is at least for one variable \lstinline!v! such that \lstinline!pre(v) <> v! after the active model equations are evaluated at an event instant. In this case the model is at once reevaluated. This evaluation sequence is called \emph{event iteration}. The integration is restarted once \lstinline!pre(v) == v! for all \lstinline!v! appearing inside \lstinline!pre($\ldots$)!.
That is, there is not just a single event, since the change in
icombined with the presence ofpre(i)leads to a new event, and so forth.
YES! You are absolutely right.
This is not straight forward. I also strugeled with this when trying to formulate
When is prev(v) equal to previous(v): Whenever there is no sequence of events throughout a single activation of the clocked partition (i.e., tick) causing iterative evaluation yielding a sequence of prev(v) values throughout iterative solving.
As I said, my answer is not likely what we have in the specification right now.
My motivation is to make existing continuous models with pre behave reasonable when packed into clocked partitions.
And somehow pre now should take care of events throughout a single evaluation of the clocked partition (events triggered within the clocked partition), but also needs to relate to the last value of the previous evaluation of the clocked partition at the very beginning of its evaluation (i.e., if there are no events triggered throughout the current evaluation yet). In other words, it looks naturally to me that as long as there are no events triggered yet, throughout a single evaluation of a clocked partition, pre(v) should be previous(v).
In your example, the question really is, if i = pre(i) + 1; should cause its own event that triggers event iteration. Which of course would then go add-infinitum. I have overlooked that! In the continuous model this equation is also not well formed. I guess you are right -- i has no fixpoint. The system is not event free as I assumed, because i = pre(i) + 1; triggers a modification event for i, which triggers its reevaluation and so one. Since that is the case in the continuous system it should also be like that in the clocked.
In other words your example has no simulation result. Its simulation doesn't terminate.
That something is packed into a clocked partition doesn't imply that its simulation always terminates. That something may still require iteration (event & normal integration) and we have no guarantees in general that such iteration terminates.
The only catch is, that such iteration is done by the clock's solver for the clock partition's equations only (and therefore also only for its events). Or put differently, events outside the clock partition do not trigger iterations of it -- the clock partition and outside are mutually exclusive event spaces.
In other words your example has no simulation result. Its simulation doesn't terminate.
OK, this is at least consistent with how it works in System Modeler today. Still, think this would at least deserve a non-normative explanation somewhere.
Trying to figure out these answers form the specification is also made harder by the fact that the presentation of the synchronous features still doesn't appear well integrated with the rest of the specification. By not looking well integrated, it makes the reader wonder to which extent the rest of the specification is valid in the context of the synchronous features. I think that a good start would be to move many of the synchronous operator definitions out of the chapter, and let the focus of the chapter be the semantics of the synchronous evaluation model.
pre(..) is only allowed on discrete-time expressions (see section3.24). Usage of pre(..) on clocked variables is not allowed.
pre(..) is only allowed on discrete-time expressions (see section3.24). Usage of pre(..) on clocked variables is not allowed.
Note that there's an exception for this for "clocked discretized continuous-time partition" (which requires that it has a solver method even if the specific method doesn't matter); and clarifying that is an ongoing effort.
pre(..) is only allowed on discrete-time expressions (see section3.24). Usage of pre(..) on clocked variables is not allowed.
@MartinOtter: That may be what we have right now, but is not what we want. As Hans mentioned above, it makes sense to support pre in clocked discretized continuous-time partitions. Otherwise, we exclude to many models for Modelica clocked -- in fact, the MSL would become useless for application in clocked partitions.
What I think we would like, I already summarized in my first answer.
The idea of clocked discretized continuous-time-partitions is to integrate at clock ticks from the previous to the current clock tick. Of course, any continuous-time model is allowed here, and this model can have any operators from continuous-time partitions including pre(..). However, one has to strictly distinguish between continuous-time and clocked-partitions. In particular, at a clock tick no event iteration should take place (only, locally, inside a clocked discretized continuous-time partition this is possible). Otherwise, when you start to allow global event iterations over clock partitions, the nice simplicity of clocked partitions (to be used in a real-time system) is gone. I think we need a web meeting, in case you really want to go into this direction. Either, I am not understanding the issue and your proposal or you destroy the whole idea of clocked systems in Modelica
@MartinOtter: I don't think that we are on different pages here (except one point that needs clarification, cf. below). It seems you misunderstood what we want.
The idea of clocked discretized continuous-time-partitions is to integrate at clock ticks from the previous to the current clock tick. Of course, any continuous-time model is allowed here, and this model can have any operators from continuous-time partitions including pre(..).
Hence, event iteration for pre usage within a single sampling step for the solving/integration of a single clocked discretized continuous-time partition may be needed. That is objective of the used solver method.
However, one has to strictly distinguish between continuous-time and clocked-partitions. In particular, at a clock tick no event iteration should take place (only, locally, inside a clocked discretized continuous-time partition this is possible).
Hence, at a clock tick no global -- continuous time partition including -- event iteration should take place. But a clock partition local event iteration may be needed.
Otherwise, when you start to allow global event iterations over clock partitions, the nice simplicity of clocked partitions (to be used in a real-time system) is gone.
That is all well understood.
Please read my first comment on the issue; quotes from there:
Can clocked partitions contain events / require event iteration: Yes. Such must be handled by the solver method used for the clocked partition -- this may result in model errors in case the solver method can not handle the events / equation system.
Is pre(v) always previous(v) in a clocked partition: No. If solving the clocked partition requires event iteration pre(v) might be different to previous(v).
When is prev(v) equal to previous(v): Whenever there is no sequence of events throughout a single activation of the clocked partition (i.e., tick) causing iterative evaluation yielding a sequence of prev(v) values throughout iterative solving.
The only catch is, that such iteration is done by the clock's solver for the clock partition's equations only (and therefore also only for its events). Or put differently, events outside the clock partition do not trigger iterations within it -- the clock partition and outside are mutually exclusive event spaces.
I can not see in how far this is in any conflict with what you say.
I am confused with the following you say however:
Otherwise, when you start to allow global event iterations over clock partitions, the nice simplicity of clocked partitions (to be used in a real-time system) is gone.
Because it sounds to me as if you are saying that clocked partitions are guaranteed to be real-time suited. That is not true. If we have a clocked discretized continuous-time-partition, it can have events which cause it to go into an infinite event loop for a single clock tick. That is why I said above:
That something is packed into a clocked partition doesn't imply that its simulation always terminates. That something may still require iteration (event & normal integration) and we have no guarantees in general that such iteration terminates.
Of course, there exist clocked partitions where we can conclude this is not the case. But since any equation systems can be subject to a clocked partition, I claim the issue is undecideable (there exists no algorithm that can decide for an arbitrary equation system if a single sampling step always terminates).
Note, that this is not just about pre. We have mixed equation systems, reinit, when clauses etc, which all need event iteration when within a clocked partition. I hope you do not want to forbid all of these!