modelica / ModelicaSpecification

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

Introduce built-in operators enteringState() and exitingState() for state machines #1356

Closed modelica-trac-importer closed 3 years ago

modelica-trac-importer commented 6 years ago

Reported by otter on 21 Nov 2013 08:36 UTC Before Modelica 3.3 was released, the following built-in operators had been defined (but had been removed from the 3.3 release, see issues below):

enteringState() True at the first clock tick when a state was activated.

exitingState() True when the currently active state is just about to be deactivated. This function can only be used in a state for which there are no immediate transitions from it.

In the minutes of the 75 design meeting, the following discussion is present:

enteringState: Definition not complete clear. Which value for a self-transition?

Hilding: Discussion on entering states exiting states. Francois: What is the behavior of exiting states in hierarchical state machines. Francois: exiting states is a function that you call which returns true on exit. The questions what about premptive exit, will it return true in that case? Brought up yesterday. Either redesign the feature or postpone it for a future version. Sven-Erik: there are simple cases, entering is not true if you get a loop. The same with reset. Entering states is not true. Is this the meaning we want? Hilding: two issues:

  1. entering state when loop back
  2. reset when looping back Agreement to remove enteringState and exitingState from Lang spec 3.3.

This discussion should be finalized in order that these two important built-in operators can be introduced in the next language relese


Migrated-From: https://trac.modelica.org/Modelica/ticket/1356

modelica-trac-importer commented 6 years ago

Comment by otter on 21 Nov 2013 10:03 UTC Here is a proposal for the definition of the first operator:

enteringState() This function is only allowed to be called within a state of a state machine. Assume that this function is called in state A. The function returns true, if A is active at the first clock tick, or if A is active at the current clock tick i, but was not active at the previous clock tick i-1. In all other cases it returns false. [Note, this means that enteringState will return false for self-transitions.]

It seems not possible to define exitingState() in a meaningful way, because when the equations of a state are evaluated, it is impossible to determine whether in the follow-up clock tick the state will be de-activated (the code to determine the follow-up state is only executed after the code of the state is executed).

Probably, another concept is needed. One possibility would be to introduce a new section: Assume that at clock tick i state A1 is active and at clock tick i+1 state A2 is active. Then the "exiting section" code of A1 is executed at clock tick i+1, before the equations of A2 are executed. However, this seems to become a quite complicated construction.

modelica-trac-importer commented 6 years ago

Comment by otter on 25 Nov 2013 14:29 UTC Replying to [comment:1 otter]:

Here is a proposal for the definition of the first operator:

enteringState() This function is only allowed to be called within a state of a state machine. Assume that this function is called in state A. The function returns true, if A is active at the first clock tick, or if A is active at the current clock tick i, but was not active at the previous clock tick i-1. In all other cases it returns false. [Note, this means that enteringState will return false for self-transitions.]

I recognized that this definition does not make sense: If a self transition would be present, and the only effect of this transition would be that the state machine remains in the state if the condition is true, then the transition can as well be removed. It only makes sense to model a self transition, if the "effect" is different, as if the transition is not present. Therefore, it is more useful that "enteringState()" returns true for a self transition.

New proposal:

enteringState() This function is only allowed to be called within a state of a state machine. Assume that this function is called in state A. The function returns true,

  1. if A is active at the first clock tick, or
  2. if A is active at the current clock tick i, but was not active at the previous clock tick i-1, or
  3. if A is active at the current clock tick i, was active at the previous clock tick i-1 and a transition fired at clock tick i-1.

In all other cases it returns false. [Note, this means that enteringState() will return true for self-transitions.]

To formally define the semantics of enteringState, the semantic definition of state machines in chapter 17.3.4 of the Modelica 3.3 Specification could be extended in the following way:

  Boolean first(start=true) "Used to identify first clock tick";
  Boolean enteringState = previous(first) or                         // rule (1)
                          activeState <> selectedState or            // rule (2)
                          activeState == selectedState and fired > 0 // rule (3)
equation
  when Clock() then
     first = false;
  end when;
modelica-trac-importer commented 6 years ago

Comment by otter on 25 Nov 2013 15:11 UTC The definition is not yet complete. Forgot one rule. The corrected definition is:

enteringState() This function is only allowed to be called within a state of a state machine. Assume that this function is called in active state A. The function returns true,

  1. if state machine is reset to state A, or
  2. if A is active at the first clock tick, or
  3. if A is active at the current clock tick i, but was not active at the previous clock tick i-1, or
  4. if A is active at the current clock tick i, was active at the previous clock tick i-1 and a transition fired at clock tick i-1.

In all other cases it returns false. [Note, this means that enteringState() will return true for self-transitions.]

To formally define the semantics of enteringState, the semantic definition of state machines in chapter 17.3.4 of the Modelica 3.3 Specification could be extended in the following way:

  Boolean first(start=true) "Used to identify first clock tick";
  Boolean enteringState = reset or                                   // rule (1)
                          previous(first) or                         // rule (2)
                          activeState <> selectedState or            // rule (3)
                          activeState == selectedState and fired > 0 // rule (4)
equation
  when Clock() then
     first = false;
  end when;
modelica-trac-importer commented 6 years ago

Modified by otter on 25 Nov 2013 15:15 UTC

modelica-trac-importer commented 6 years ago

Modified by otter on 25 Nov 2013 15:17 UTC

modelica-trac-importer commented 6 years ago

Comment by otter on 25 Nov 2013 16:24 UTC Still an unclear issue:

Assume a state machine B consists of states B1, B2, B3, ..., with B1 the initial state, and a state machine A consists of state A1, A2, ..., with A1 the initial state, and that B is contained in A2. Furthermore, assume that at the last activation of A2, B was in state B2.

Case 1: Assume that a transition in A fires so that A2 becomes active. If this transition defines "reset=true", then at this clock tick B1 becomes active, otherwise B2. The question is whether enteringState()=true in the active state of B for this clock tick. Probably yes.

Case 2: Assume that B was in state B2 and that a transition in A changes the active state from A2 to A3. After some while a transition fires so that A2 becomes active again and the transition defines reset=false. In such a case state machine B continues at B2. The question is whether in B2 enteringState()=true at this clock tick. Probably yes, because the first transition from A2 to A3 "counts" also as a transition to leave B2 and the transition to A2 "counts" also as a transition to enter B2 again.

The scenario above is not yet handled with the proposed semantic rules. The semantic rules could probably be modified in the following way (requiring an additional new input):

model StateMachineSemantics "Semantics of state machines"
  ...
  input Boolean enteringStateOfSuperState "= enteringState of the state in which this state machine is present"; 
  ...
  Boolean first(start=true) "Used to identify first clock tick";
  Boolean enteringState = enteringStateOfSuperState or
                          previous(first) or                         // rule (2)
                          activeState <> selectedState or            // rule (3)
                          activeState == selectedState and fired > 0 // rule (4)
equation
  when Clock() then
     first = false;
  end when;
modelica-trac-importer commented 6 years ago

Comment by otter on 25 Nov 2013 17:50 UTC The desired operator "exitingState()" is much more critical as the operator "enteringState()". The reason is that also for state machines the "single assignment rule" of Modelica holds.

Assume, a variable j is defined in a state A1, and that the following equation is present in A1:

j = if enteringState() then 1 else
    if exitingState()  then 0 else previous(i) + 1;

At every clock tick the following sequence of evaluations takes place (this follows from the semantic rule how transitions are mapped to equations and from the sorting of all equations).

  1. Evaluate the conditions of the outgoing transitions of the active state
  2. Based on the conditions (and whether they fire or not), set the next active state.
  3. Evaluate the equations of the active state.

Assume in the example above that state A1 is active at clock tick i-1 and state A2 is active at clock tick i. Then the equations of A1 are evaluated at clock tick i-1. At this time instant the next state is not known, so exitingState()=false. At clock tick i, the new active state A2 is determined and the equations of A2 are evaluated. As a result the equation for j in state A1 is not evaluated and therefore j is not set to 0.

This seems to indicate that an operator "exitingState()" makes no sense in a synchronous state machine.

Providing a new "exitingState" section does not help either, because then at clock tick i the equations for j in the "exitingState" section are evaluated, and then at the same clock tick "j" might be evaluated again in the new active state. So, this is against the "single assignment rule".

Note, if "j" is an outer output variable, then "exitingState()" might be emulated by providing the exitingState equation for "j" in the target states of all outgoing transitions of state A1 as "enteringState()" equation (e.g in A2 there is an enteringState() equation for j). Of course, this might become cumbersome.

modelica-trac-importer commented 6 years ago

Comment by otter on 17 Jun 2014 16:36 UTC Since these are new built-in operators, not present in Modelica 3.3, they should not be introduced in Modelica 3.3 rev. 1. Therefore, changed milestone to 3.4.

modelica-trac-importer commented 6 years ago

Modified by otter on 18 May 2016 08:02 UTC

modelica-trac-importer commented 6 years ago

Modified by otter on 5 Aug 2016 05:59 UTC

modelica-trac-importer commented 6 years ago

Modified by beutlich on 10 Jan 2018 08:22 UTC