fsharp-finite-automata/NFA.fs
2019-02-20 19:31:18 +01:00

56 lines
1.7 KiB
FSharp

module NFA
open System
/// A non-deterministic finite automaton
type NFA = {
/// All possible characters
sigma: Char list
/// All possible states
states: String list
/// All possible transitions
delta: String -> Char -> String list
/// The state this NFA begins in
beginState: String
/// The states in which this NFA accepts
/// the word
acceptingStates: String list
}
/// Returns a list of possible states after this charater
/// was read
let processChar (nfa: NFA) state (char: Char) =
nfa.delta state char
/// Returns a list of possible states after this character
/// list was read
let rec processCharArray (nfa: NFA) (states: String list) (charArr: Char list) : String list =
match charArr with
| [] -> states
| head :: tail ->
processCharArray
nfa
(
// Look at all states
states
// Where are we going to from each state
// if we read this character
|> List.map (fun x -> processChar nfa x head)
// Which entries are not empty
|> List.filter (List.isEmpty >> not)
// If there are no states left,
// return an empty list
|> (fun x ->
if not (List.isEmpty x) then
List.reduce List.append x
else [])
)
tail
/// Returns whether this NFA accepts this word
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