Big state machines

Vance Shipley <>
Tue Apr 19 16:17:52 CEST 2005


On Tue, Apr 19, 2005 at 06:54:18AM +0200, Ulf Wiger wrote:
}  
}  I may read your message wrong, but the problem with the UML approach
}  is that you cannot easily say, for a given state: "match these
}  expected messages, but implicitly refer any other message". This
}  is the semantics needed for all transient states, since a transient
}  state may _never_ discard a message it doesn't recognize.

I don't know UML, and maybe never will as you've told us it isn't
very helpful in Erlang.  :)

In SDL an unspecified signal is implicitly handled by consuming it
and transitioning back to the current state.  My point was that this 
default behaviour is important to have.

SDL graphical representation:
         ___
        (_s_)
          |
       +--+--+
     __|_  __|_ 
     >_a_| >_b_|
      _|_   _|_ 
     (_x_) (_y_) 
     
SDL textual representation:

     state s;
        input a;
           nextstate x;
        input b;
           nextstate y;
     endstate s;

Plain erlang implementation:

     s(S) ->
         receive 
             a ->
                 x(S);
             b ->
                 y(S);
             _ ->
                 s(S)
         end.
  
SDL does provide the 'save' construct which specifies that the 
referenced signal should be left in the input queue.  For your
transient state you would probably want to use the asterisk save:
            ___
           (_s_)
             |
       +-----+------+
     __|_  __|_   __|_
     >_a_| >_b_| /_*_/
      _|_   _|_ 
     (_x_) (_y_) 
     
     state s;
        input a;
           nextstate x;
        input b;
           nextstate y;
        save *;
     endstate s;

     s(S) ->
         receive 
             a ->
                 x(S);
             b ->
                 y(S)
         end.
  
You can also specify the signals you want to save and in the absence
of an asterisk input other signals will be consumed:
            ___
           (_s_)
             |
       +-----+------+-----+
     __|_  __|_   __|_  __|_
     >_a_| >_b_| /_c_/ /_d_/
      _|_   _|_ 
     (_x_) (_y_) 

     state s;
        input a;
           nextstate x;
        input b;
           nextstate y;
        save c;
        save d;
     endstate s;

     s(S) ->
         receive 
             a ->
                 x(S);
             b ->
                 y(S);
             X when X /= c, X /= d ->
                 s(S)
         end.


}  In Erlang, you don't have to worry much about transient states,
}  because they can be hidden behind a function call. The classic

I sometimes need to handle a save construct in the context of external
signals (protocols) and gen_fsm doesn't provide the syntax, although
erlang does.

So the short answer I guess is that should I really need to do this
I should implement my own system process and abandon gen_fsm.  It's
probably a better idea than the ugliness which results from further
bastardizing Erlang in the pursuit of retaining gen_fsm semantics.

	-Vance




More information about the erlang-questions mailing list