Simple enumerated state machine impossible in C#

G

Guest

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.Unknown;
l_ps |= portState.Secure | portState.Open;
Console.WriteLine(l_ps.ToString());

// 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.WriteLine( l_state_enm.GetType().Name );
Console.WriteLine( l_state_enm );

// output is portState

l_state_enm = portState.Unknown;

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error CS0019
}
 
M

Mohammad Shalabi

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 said:
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.Unknown;
l_ps |= portState.Secure | portState.Open;
Console.WriteLine(l_ps.ToString());

// 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.WriteLine( l_state_enm.GetType().Name );
Console.WriteLine( l_state_enm );

// output is portState

l_state_enm = portState.Unknown;

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error
CS0019
}
 
G

Guest

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.

--------
I think you want to be able to change your machine state from one state to
another by using the enum.
True

The issue with that is you may end up entering an
invalid state......

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).
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.

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

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 -

http://www.dofactory.com/Patterns/PatternState.aspx#_self2

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).
 
L

Larry Lard

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

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

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error CS0019

l_state_enm = (Enum)((portState)l_state_enm | portState.Secure
| portState.Open);

No compiler error.

Perhaps something with generics would neaten things up.
 
G

Guest

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.Secure | 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 AssertEnumMember<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_typ' variable let me know!!!

Thanks again for your input.

Shawnk



Larry Lard said:
This post is intended to verify that true value semantics DO NOT EXIST for the
Enum class (relative to boolean operations).
[snip]

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

// Can not use boolean operations on Enumeration

l_state_enm |= portState.Secure | portState.Open; // Compiler Error CS0019

l_state_enm = (Enum)((portState)l_state_enm | portState.Secure
| portState.Open);

No compiler error.

Perhaps something with generics would neaten things up.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top