Simple enumerated state machine impossible in C#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Shawnk

    Simple enumerated state machine impossible in C#

    This post is intended to verify that true value semantics DO NOT EXIST for the
    Enum class (relative to boolean operations).

    If this is true then (thus and therefore) you can not design state machines in
    C# where the machine can use the enumerated 'state' to execute (thus the term
    'machine' as in 'state machine') the machine operations as this requires
    boolean operations to be performed on the state.

    .....

    I would like to design a simple enumerated state machine
    with a 'switcher' and an enumerated 'bit map' ([flags] enum) to hold the
    state.

    The 'switcher' is a replacement for a switch statement when state/operational
    mapping's are from 10 to 100 (or more). This high operational cardinality is
    commonly seen in metric analysis probes whose engine is based on a 'state
    machine'.

    Smaller operational cardinalities (1 to 10) are common for process engines
    where the state controls a workflow process.

    Thus a simple elegant state machine is a handy item to have around...

    .....

    The state machine would support any enum type (specified during construction).

    So I need to perform boolean iteration and operations (switcher aspect
    delegate
    execution semantics) as well as enumerated state operations and iteration
    (state
    aspect of the machine - set, get, test, state semantics).

    The 'switcher' maps various states to delegates. It executes the current
    state based
    on one of several execution algorithms.

    An example of use (for the state machine) is a workflow process machine with
    the
    sequence of enumerated process steps defined in the current state of the
    bitmap.

    The question (for verification) is as follows.

    ---- You can do boolean operations on enum types but NOT on Enum types ----

    Therefore it is IMPOSSIBLE to design a 'SIMPLE' enumerated state machine
    WHEREBY the machine state has value semantics (for boolean operations)
    and state semantics (meaningful state via enumeration (VS meaningless
    boolean values that lack state semantics useful to programmers).

    It is possible to design a COMPLEX and convoluted state machine in C#
    (reminds me of early Java) where state and operational (delegate command
    and control) are separate. Enums as keys to collections, Enums translated
    to BitArrays comes to mind.

    See the compiler error CS0019 below for an example of the poor value
    semantics of Enum.

    Since state machines are so fundamental I'm hoping I'm missing something
    and you can do value semantics on Enum (it IS a structure).

    If anyone has a better approach that would be very useful.

    Thanks ahead of time for any replies or ideas. I've looked at various state
    machine patterns (on the Internet) but none of the good ones use C# for this
    reason (I suspect :-).

    Shawnk

    PS. The switcher needs to be configurable for various delegate execution
    modes
    (Value mapped sequential, bit mapped sequential, heuristic sequence/rule
    engine,
    etc). Thus the boolean operational aspect of the enumerated (state semantics)
    machine execution semantics.

    ---------

    using System;

    public class Demo
    {

    [Flags]
    private enum portState
    {
    Unknown = 0
    , Open = 1
    , Active = 2
    , Secure = 4
    }

    static void Main(string[] args)
    {
    portState l_ps = portState.Unkno wn;
    l_ps |= portState.Secur e | portState.Open;
    Console.WriteLi ne(l_ps.ToStrin g());

    // output is Open, Secure

    Enum l_state_enm;
    int l_initial_value = 3;

    l_state_enm = (Enum) Enum.ToObject( typeof (portState),
    l_initial_value );

    Console.WriteLi ne( l_state_enm.Get Type().Name );
    Console.WriteLi ne( l_state_enm );

    // output is portState

    l_state_enm = portState.Unkno wn;

    // Can not use boolean operations on Enumeration

    l_state_enm |= portState.Secur e | portState.Open; // Compiler Error CS0019
    }



  • Mohammad Shalabi

    #2
    Re: Simple enumerated state machine impossible in C#

    Hi,
    I think you want to be able to change your machine state from one state to
    another by using the enum. The issue with that is you may end up entering an
    invalid state. Even though you can put some code to validate the state, you
    still need to provide complicated error handling. The best way i can see is
    to use the State Design Pattern. this pattern has no switch statment and
    every state will know how to transform to the next state based on diffrent
    input to the system. by doing that your code will be much cleaner and easier
    to use.

    Thank you.

    "Shawnk" <Shawnk@discuss ions.microsoft. com> wrote in message
    news:E8D7804E-5E79-45C2-A001-BEAA9F12698B@mi crosoft.com...[color=blue]
    > This post is intended to verify that true value semantics DO NOT EXIST for
    > the
    > Enum class (relative to boolean operations).
    >
    > If this is true then (thus and therefore) you can not design state
    > machines in
    > C# where the machine can use the enumerated 'state' to execute (thus the
    > term
    > 'machine' as in 'state machine') the machine operations as this requires
    > boolean operations to be performed on the state.
    >
    > ....
    >
    > I would like to design a simple enumerated state machine
    > with a 'switcher' and an enumerated 'bit map' ([flags] enum) to hold the
    > state.
    >
    > The 'switcher' is a replacement for a switch statement when
    > state/operational
    > mapping's are from 10 to 100 (or more). This high operational cardinality
    > is
    > commonly seen in metric analysis probes whose engine is based on a 'state
    > machine'.
    >
    > Smaller operational cardinalities (1 to 10) are common for process engines
    > where the state controls a workflow process.
    >
    > Thus a simple elegant state machine is a handy item to have around...
    >
    > ....
    >
    > The state machine would support any enum type (specified during
    > construction).
    >
    > So I need to perform boolean iteration and operations (switcher aspect
    > delegate
    > execution semantics) as well as enumerated state operations and iteration
    > (state
    > aspect of the machine - set, get, test, state semantics).
    >
    > The 'switcher' maps various states to delegates. It executes the current
    > state based
    > on one of several execution algorithms.
    >
    > An example of use (for the state machine) is a workflow process machine
    > with
    > the
    > sequence of enumerated process steps defined in the current state of the
    > bitmap.
    >
    > The question (for verification) is as follows.
    >
    > ---- You can do boolean operations on enum types but NOT on Enum
    > types ----
    >
    > Therefore it is IMPOSSIBLE to design a 'SIMPLE' enumerated state machine
    > WHEREBY the machine state has value semantics (for boolean operations)
    > and state semantics (meaningful state via enumeration (VS meaningless
    > boolean values that lack state semantics useful to programmers).
    >
    > It is possible to design a COMPLEX and convoluted state machine in C#
    > (reminds me of early Java) where state and operational (delegate command
    > and control) are separate. Enums as keys to collections, Enums translated
    > to BitArrays comes to mind.
    >
    > See the compiler error CS0019 below for an example of the poor value
    > semantics of Enum.
    >
    > Since state machines are so fundamental I'm hoping I'm missing something
    > and you can do value semantics on Enum (it IS a structure).
    >
    > If anyone has a better approach that would be very useful.
    >
    > Thanks ahead of time for any replies or ideas. I've looked at various
    > state
    > machine patterns (on the Internet) but none of the good ones use C# for
    > this
    > reason (I suspect :-).
    >
    > Shawnk
    >
    > PS. The switcher needs to be configurable for various delegate execution
    > modes
    > (Value mapped sequential, bit mapped sequential, heuristic sequence/rule
    > engine,
    > etc). Thus the boolean operational aspect of the enumerated (state
    > semantics)
    > machine execution semantics.
    >
    > ---------
    >
    > using System;
    >
    > public class Demo
    > {
    >
    > [Flags]
    > private enum portState
    > {
    > Unknown = 0
    > , Open = 1
    > , Active = 2
    > , Secure = 4
    > }
    >
    > static void Main(string[] args)
    > {
    > portState l_ps = portState.Unkno wn;
    > l_ps |= portState.Secur e | portState.Open;
    > Console.WriteLi ne(l_ps.ToStrin g());
    >
    > // output is Open, Secure
    >
    > Enum l_state_enm;
    > int l_initial_value = 3;
    >
    > l_state_enm = (Enum) Enum.ToObject( typeof (portState),
    > l_initial_value );
    >
    > Console.WriteLi ne( l_state_enm.Get Type().Name );
    > Console.WriteLi ne( l_state_enm );
    >
    > // output is portState
    >
    > l_state_enm = portState.Unkno wn;
    >
    > // Can not use boolean operations on Enumeration
    >
    > l_state_enm |= portState.Secur e | portState.Open; // Compiler Error
    > CS0019
    > }
    >
    >
    >[/color]


    Comment

    • Shawnk

      #3
      Re: Simple enumerated state machine impossible in C#

      Mohammed,

      Thanks for your suggestion. I am familiar with the GOF State Design pattern.
      I do not want to use this pattern however. I am looking for;

      1. High state cardinality
      2. Operational mapping (state to delegate)
      3. Generalized enumerations (use Enum instead of enum)
      4. Configurable processing of invalid states
      5. Configurable processing of non-defined states (default response)
      6. Implementation flexibility relative to which objects process the state
      7. External operations (operational methods are not part of the state machine)

      These features are best found in 'engine' designs where the engine provides
      the operations that 'surround' the state machine. A specific engine design
      defines the state, operations and mapping by initializing the state machine.

      Since the system has four operational categories of
      states are;

      A - Command states
      B - Ignored states - No operation necessary (default response)
      C - Invalid states - Must be enumerated
      D - Error states -

      Since the system must be deterministic the determining mechanism
      can be a switch statement, if/then/else, lookup table, distributed
      state check, etc.

      A snippet describing the state design pattern (ubiquitous on the Internet)
      reads as follows -

      This real-world code demonstrates the State pattern which allows an Account to
      behave differently depending on its balance. The difference in behavior is
      delegated to State objects called RedState, SilverState and GoldState. These
      states represent overdrawn accounts, starter accounts, and accounts in good
      standing.

      This approach has a DISTRIBUTED 'state check' embedded in 'state objects'.
      I want a CENTRALIZED 'state check' based on a single 'current state' (because
      of the high cardinality). Also the state objects are generally known in GOF
      state machines whereas I can used simple delegates in a 'switcher design'.

      This would allow (for example) a lexicon to be defined for the state machine
      mapping a command set to states and then to operations (via delegates).

      So I prefer a 'centralized state delegate' approach (with a switcher
      pattern participant) rather than a the 'distributed state object'
      approach (with a state object participant).

      Thanks just the same. I do appreciate your response. Its always good to
      re-examine the design reasoning from time to time.

      Shawnk

      PS. If I had a small state cardinality, specific purpose, enum targeted design
      then I would use the GOF State Design pattern.

      PPS. If you have comments on this design review please feel free to correct
      me if I have missed something.

      --------
      [color=blue]
      >I think you want to be able to change your machine state from one state to
      >another by using the enum.[/color]

      True
      [color=blue]
      >The issue with that is you may end up entering an
      >invalid state......[/color]

      False. But an interesting point (invalid states). The switcher in my
      current design optionally (modal configuration) funnels all unmapped states to
      to a client delegate for processing. The default mode is to ignore unmapped
      states.
      True 'invalid states' have their own mapping to their own processes.

      My issue is that I can NOT use the enum (specific machine design). I need to
      use the Enum structure to
      generalize the machine design to any enum (generalized machine design).
      [color=blue]
      >this pattern has no switch statement and every state will know how to transform
      >to the next state based on different input to the system.[/color]

      See my comments above regarding distributed/centralized switching in the
      machine.
      [color=blue]
      >by doing that your code will be much cleaner and easier to use.[/color]

      Respectfully I disagree.

      [Cleaner] : A centralized switch mechanism (independent of its design)
      is vital (IMHO) in a high cardinality state machine to 'simplify' the switch
      complexity
      into one location (vs distributing state detection all over the place as in
      GOF State Design patterns - abstract inheritance of state change methods).

      [Easier to use] : A delegate oriented architecture decouples any object/base
      class/
      interface concerns and uses a simple signature. Further more a simple
      state-to-delegate
      registration process loads the state machine on initialization. The
      initialization
      method (of the client code that uses the state machine) provides a single
      point
      of expression for the operational binding. I feel the flexibility to bind to
      delegates in one place far easier than a GOF design such as -

      Learn how to use the C# State design pattern to allow an object to alter its behavior when its internal state changes, with quick and easy examples. 100% Source code.


      where the operational binding is distributed as a mechanism of abstract
      inheritance.

      Also the operational map provides that many states can be mapped to the same
      delegate
      providing for flexibility in handling whole categories of states such as
      invalid states
      or quiescent states (default do nothing states).


      Comment

      • Larry Lard

        #4
        Re: Simple enumerated state machine impossible in C#


        Shawnk wrote:[color=blue]
        > This post is intended to verify that true value semantics DO NOT EXIST for the
        > Enum class (relative to boolean operations).[/color]
        [snip]

        I'm not qualified to address all this theory; I just fix code.

        [color=blue]
        > // Can not use boolean operations on Enumeration
        >
        > l_state_enm |= portState.Secur e | portState.Open; // Compiler Error CS0019[/color]

        l_state_enm = (Enum)((portSta te)l_state_enm | portState.Secur e
        | portState.Open) ;

        No compiler error.

        Perhaps something with generics would neaten things up.

        --
        Larry Lard
        Replies to group please

        Comment

        • Shawnk

          #5
          Re: Simple enumerated state machine impossible in C#

          Larry,

          You're a good man :-)

          I tried the 'casting approach' but, unfortunately that does not work since I
          can
          not 'hard code' the enum type in a generalized state machine (as in your
          suggestion).

          A generalized state machine would have the following 'generalized' semantics
          as follows ---

          ------

          Type l_enm_typ = typeof ( portState );
          Enum l_incoming_enm = portState.Secur e | portState.Open;

          // With a generalized state machine no 'hard coded' enums can be used

          l_state_enm = (Enum)( ( l_enm_typ ) l_state_enm | ( l_enm_typ )
          l_incoming_enm ); // -- Compiler Error CS0246

          l_state_enm = (Enum)( ( portState ) l_state_enm | ( portState )
          l_incoming_enm ); // NO Compiler Error CS0246

          ------

          But I really like you're suggestion because I tried it with a Type variable
          (as above).
          and am gratified that others would try the same idea (a casting approach).

          Do you know of a way to cast variables using a Type instance variable???

          Also I started out with a generic approach but ran into problems because (I
          think)
          generics has some problems with enum.

          [1] You can not use Enum as a constraint (you need to use a Struct as a
          value constraint - which sort of sucks) as in ---

          public static void AssertEnumMembe r<TEnum>(TEnum enumValue) where TEnum :
          struct
          .....

          [2] Generics seems to have some issues with Enum as in the following forum
          snippet

          N.B: One more - using those enums as generics arguments can lead to code bloat
          (I'm unsure - need somebody to check) as generics code is NOT shared between
          instances that use value type arguments. Generics code shared only for
          reference classes used as type arguments.

          [3] In coding an Enum <T> I just ran into some problems and decided to do a
          non-generic approach first.

          To close out the 'cast approach' if you know of a way to cast using a 'Type
          l_target_enm_ty p' variable let me know!!!

          Thanks again for your input.

          Shawnk



          "Larry Lard" wrote:
          [color=blue]
          >
          > Shawnk wrote:[color=green]
          > > This post is intended to verify that true value semantics DO NOT EXIST for the
          > > Enum class (relative to boolean operations).[/color]
          > [snip]
          >
          > I'm not qualified to address all this theory; I just fix code.
          >
          >[color=green]
          > > // Can not use boolean operations on Enumeration
          > >
          > > l_state_enm |= portState.Secur e | portState.Open; // Compiler Error CS0019[/color]
          >
          > l_state_enm = (Enum)((portSta te)l_state_enm | portState.Secur e
          > | portState.Open) ;
          >
          > No compiler error.
          >
          > Perhaps something with generics would neaten things up.
          >
          > --
          > Larry Lard
          > Replies to group please
          >
          >[/color]

          Comment

          Working...