## A Subtle Point: Actions That Can't Happen

There are two ways actions cannot happen. Either an action is simply not part of the system's interface; or it is, but no state transition occurs if you try to perform it. For example, when you get a pull-down menu on your Mac, only those actions listed are part of the interface. It's simply impossible for you to try to do an action that is not listed. But also, any action that is ``grayed out'' indicates that nothing will happen if you select that action: no state transition occurs.

Consider the Light example. Since ``unplug'' is not in the set of actions, there is no way I can even think of doing such an action. The point is that the only actions that may possibly happen are those that are explicitly given in the state machine's set of actions, A.

However, suppose ``unplug'' were added to Light's set of actions and I keep everything else the same. In particular, its state transitions are still defined only for the action ``flick.'' What happens if I try to unplug the light?

There are four reasonable interpretations:

1. Nothing happens.
2. It's undefined. That is, using functional notation, and . ( , read as ``bottom,'' is the mathematical symbol for ``undefined.'')
3. It's an error. Chaos can occur (core dumped, machine crashes).
4. It can't happen.

We will take the fourth interpretation because we can model the first three explicitly if that's the behavior we want. In the first case, we would define the state transition function such that for each state, , (s, unplug, s). In the state transition diagram, for each state, we would draw an arrow from it to itself and label the arrow with the action ``unplug.'' In the second case, we would introduce a special state called . In our state transition diagram we would simply draw an arrow from the off state to and an arrow from the on state to . Both arrows would be labeled with the action ``unplug.'' In the third case, we would introduce a state called ``error'' and draw arrows similar to those in the second case.

Notice that ``bottom'' means mathematically undefined, which is very different from ``error.'' ``Bottom'' is like trying to divide by zero in Mathematics or where you end up if you find yourself in an infinite loop in Computer Science. ``Error'' is simply a way to denote an error has occurred. In Computer Science we make a distinction between being in an infinite loop (non-termination) and being in a (terminating) ``bad'' state (like core dumped) so it makes sense that we make this distinction in Software Engineering too.

You might ask why we would include an action like ``unplug'' if we can't do anything with it. One answer is that we're setting ourselves up so that we can put state machines together. Suppose we combine Unpluggable Light with a machine for which there is a state transition defined on the action ``unplug''; then we may be able to make sense of doing the unplug action on the combined machine. You'll hear more on this later, when we get to concurrency.