module DFA open System type State = { name: String } type DFA = { sigma: Char list states: State list delta: State -> Char -> State beginState: State acceptingStates: State list } let validateDFA (dfa:DFA) = let allAcceptingStatesAreStates = dfa.acceptingStates |> List.map (fun x -> List.contains x dfa.states) |> List.filter not |> List.length |> (<) 1 let deltaIsComplete = // Gets the cartesian product of states * sigma dfa.states |> List.collect (fun x -> dfa.sigma |> List.map (fun y -> (x, y))) // Processes all tuples through delta |> List.map (fun x -> dfa.delta (fst x) (snd x)) // Checks if there is any result from delta which is not // a valid state |> List.filter (fun x -> not (List.contains x dfa.states)) |> List.length |> (<) 1 List.contains dfa.beginState dfa.states || allAcceptingStatesAreStates || deltaIsComplete let processChar (dfa: DFA) (state: State) (char: Char) = dfa.delta state char let rec processCharArray (dfa: DFA) (state: State) (charArr: Char list) = match charArr with | [] -> state | _ -> processCharArray dfa (processChar dfa state charArr.Head) charArr.Tail let acceptsWord (dfa: DFA) (word: String) = dfa.acceptingStates |> List.contains (processCharArray dfa dfa.beginState (Seq.toList word))