fsharp-finite-automata/DFA.fs
joachimschmidt557 c67110d17f WIP
2019-02-06 22:43:38 +01:00

56 lines
No EOL
1.5 KiB
FSharp

module DFA
open System
type State = { name: String }
///
/// A deterministic finite automaton
///
type DFA = {
sigma: Char list
states: State list
delta: State -> Char -> State
beginState: State
acceptingStates: State list
}
/// Returns true if the DFA is valid, false otherwise
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))