Из формальное определение детерминированного конечного автомата :
Детерминированный конечный автомат M
представляет собой 5-кортеж Q, Sigma, delta, q0, F
, состоящий из
- конечный набор состояний
Q
- конечный набор входных символов, называемый алфавитом
Sigma
- функция перехода
delta
: Q * Sigma -> Q
- начальное или начальное состояние
q0
в Q
- набор состояний принятия
F
, являющийся подмножеством Q
Вы далидва из пяти, а именно Q = SocketState
и Sigma = Cmd
.Предполагая, что ваше приложение имеет неявное начальное состояние (вероятно, Ready
) и не имеет определенных "принимающих состояний", единственной вещью, необходимой для вашего конечного автомата, является функция перехода .
ИзПо определению, функция перехода имеет тип (SocketState * Cmd) -> SocketState
, но версия с карри SocketState -> Cmd -> SocketState
не менее мощна.
Если у вашего конечного автомата есть внешние входы, добавьте их в качестве параметров в функцию.Если вам нужны побочные эффекты или какой-либо вывод, связанный с самим переходом, вы можете использовать SocketState -> Cmd -> (SomeOutput * SocketState)
.
Редактировать: Переход как отношение (Расширение до ответ keep_learning )
Если вы хотите рассуждать о серии допустимых команд и переходов, вы можете вместо этого закодировать их в троичное отношение.
Сначала давайте определим, чтосоставляет для действительных переходов.
Previous state -> (Command) -> Next state
-----------------------------------------
Ready -> (Open) -> Opened
Opened -> (Send) -> Opened
Opened -> (Close) -> Closed
Затем закодируйте его как троичное отношение.Ниже приведен только пример, похожий на тройки Хоара из моделей языков программирования.
Inductive Transition : SocketState -> Cmd -> SocketState -> Prop :=
| t_open : Transition Ready Open Opened
| t_send : Transition Opened Send Opened
| t_close : Transition Opened Close Closed.
Выше говорилось о одномоментном переходе.А как насчет серии переходов?Мы можем определить рефлексивно-транзитивное замыкание, принимая list
команд (это очень аналогично тройкам Хоара, в том смысле, что оба определяют предусловие, последовательность шагов и постусловие):
From Coq Require Import List.
Import ListNotations.
Inductive TransitionRTC : SocketState -> list Cmd -> SocketState -> Prop :=
| t_rtc_refl : forall s : SocketState, TransitionRTC s [] s
| t_rtc_trans1 : forall s1 c s2 clist s3,
Transition s1 c s2 ->
TransitionRTC s2 clist s3 ->
TransitionRTC s1 (c :: clist) s3.
Функциональным аналогом отношения RTC будет (у fold_left
в Coq последние два аргумента поменялись местами, по сравнению с foldl
Хаскелла или fold_left
у Окамла):
Axiom transition : SocketState -> Cmd -> SocketState.
Definition multistep_transition (state0 : SocketState) (clist : list Cmd) :=
fold_left transition clist state0.