Я ищу способы реализовать FSM, что привело к моей первой встрече с сопрограммами.
Я видел несколько примеров (здесь, здесь и здесь), которые намекают на то, что конечный автомат может быть реализован одной сопрограммой. Однако я заметил, что все эти машины объединяет то, что, исключая циклы, они представляют собой деревья, то есть существует единственный путь (исключая циклы) от начального узла к каждому другому узлу, и это хорошо соответствует иерархическому управлению. поток, обеспечиваемый вложенными if
s. Конечный автомат, который я пытаюсь смоделировать, имеет по крайней мере одно состояние с более чем одним путем от начального узла к нему (если циклы исключены, это ориентированный ациклический граф). и я не могу представить, какой поток управления (кроме goto
s) может достичь этого, и возможно ли это вообще.
В качестве альтернативы я могу использовать отдельную сопрограмму для обработки каждого состояния и передать какую-то сопрограмму диспетчера. Однако я не вижу особых преимуществ использования сопрограмм по сравнению с обычными функциями в этой настройке.
Вот простой конечный автомат, с моделированием которого у меня проблемы:
A --'a'--> B
A --'b'--> C
B --'a'--> C
B --'b'--> A
C --'a'--> A
C --'b'--> B
И вот что у меня пока есть. Окончательная реализация будет на C++ с использованием Boost, но я использую Python для прототипирования.
#!/usr/bin/python3
def StateMachine():
while True:
print(" Entered state A")
input = (yield)
if input == "a":
print(" Entered state B")
input = (yield)
if input == "a":
# How to enter state C from here?
pass
elif input == "b":
continue
elif input == "b":
print(" Entered state C")
input = (yield)
if input == "b":
continue
elif input == "a":
# How to enter state B from here?
pass
if __name__ == "__main__":
sm = StateMachine()
sm.__next__()
while True:
for line in input():
sm.send(line)
Можно ли исправить эту сопрограмму, чтобы правильно моделировать конечный автомат? Или я должен пойти другим путем об этом?