module NFA open System type State = { name: String } /// A non-deterministic finite automaton type NFA = { sigma: Char list states: State list delta: State -> Char -> State list beginState: State acceptingStates: State list } let processChar (nfa: NFA) (state: State) (char: Char) = nfa.delta state char let rec processCharArray (nfa: NFA) (states: State list) (charArr: Char list) : State list = match charArr with | [] -> states | head :: tail -> processCharArray nfa ( states |> List.map (fun x -> processChar nfa x head) |> List.filter (List.isEmpty >> not) |> (fun x -> if not (List.isEmpty x) then List.reduce List.append x else []) ) tail let acceptsWord nfa word = match processCharArray nfa [nfa.beginState] (Seq.toList word) with | [] -> false | x -> x |> List.map (fun x -> List.contains x nfa.acceptingStates) |> List.exists id