Each state of the automaton has been defined by using the decorator:
@asyncio.coroutine
For example, state S0 is defined here:
@asyncio.coroutine
def StartState():
print ("Start State called ")
input_value = randint(0,1)
time.sleep(1)
if (input_value == 0):
result = yield from State2(input_value)
else :
result = yield from State1(input_value)
The transition to the next state is determined by input_value, which is defined by the randint (0,1) function of Python's random module. This function randomly provides a value of 0 or 1.
In this manner, randint randomly determines the state to which the finite state machine will pass:
input_value = randint(0,1)
After determining the values to pass, the coroutine calls the next coroutine using the yield from command:
if (input_value == 0):
result = yield from State2(input_value)
else :
result = yield from State1(input_value)
The result variable is the value that each coroutine returns. It is a string, and, at the end of the computation, we can reconstruct the transition from the initial state of the automaton, start_state, up to end_state.
The main program starts the evaluation inside the event loop:
if __name__ == "__main__":
print("Finite State Machine simulation with Asyncio Coroutine")
loop = asyncio.get_event_loop()
loop.run_until_complete(StartState())
Running the code, we have an output like this:
Finite State Machine simulation with Asyncio Coroutine
Start State called
...evaluating...
...evaluating...
...evaluating...
...evaluating...
...stop computation...
Resume of the Transition :
Start State calling State 1 with transition value = 1
State 1 calling State 2 with transition value = 1
State 2 calling State 1 with transition value = 0
State 1 calling State 3 with transition value = 0
State 3 calling End State with transition value = 1