From 887e2d63c75de383a4454bb9ea1fa8be6e7d102b Mon Sep 17 00:00:00 2001 From: joachimschmidt557 Date: Wed, 20 Feb 2019 18:49:45 +0100 Subject: [PATCH] Maybe finished NFAs --- DFA.fs | 2 +- IsNumericChecker.fs | 19 +++++++++++++++++++ NFA.fs | 26 +++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/DFA.fs b/DFA.fs index af38170..cabfe0a 100644 --- a/DFA.fs +++ b/DFA.fs @@ -49,7 +49,7 @@ let processChar (dfa: DFA) (state: State) (char: Char) = let rec processCharArray (dfa: DFA) (state: State) (charArr: Char list) = match charArr with | [] -> state - | _ -> processCharArray dfa (processChar dfa state charArr.Head) charArr.Tail + | head :: tail -> processCharArray dfa (processChar dfa state head) tail let acceptsWord (dfa: DFA) (word: String) = dfa.acceptingStates diff --git a/IsNumericChecker.fs b/IsNumericChecker.fs index c998d0f..5247b45 100644 --- a/IsNumericChecker.fs +++ b/IsNumericChecker.fs @@ -2,6 +2,7 @@ module Tests open System open DFA +open NFA let numericDFA:DFA = { sigma = Seq.toList "01ab"; @@ -19,9 +20,27 @@ let numericDFA:DFA = { acceptingStates = [{name = "yes"}] } +let numericNFA:NFA = { + sigma = Seq.toList "01ab"; + states = [ + {name = "yes"} + ]; + delta = (fun x y -> + match (x, y) with + | ({name = "yes"}, '0') -> [{name = "yes"}] + | ({name = "yes"}, '1') -> [{name = "yes"}] + | _ -> [] + ); + beginState = {name = "yes"}; + acceptingStates = [{name = "yes"}] +} + let test = printfn "Testing numeric checker DFA" printfn "Is valid DFA: %b" (DFA.validateDFA numericDFA) printfn "0101: %b" (DFA.acceptsWord numericDFA "0101") printfn "01a1: %b" (DFA.acceptsWord numericDFA "01a1") + printfn "Testing numeric checker NFA" + printfn "0101: %A" (NFA.acceptsWord numericNFA "0101") + printfn "01a1: %b" (NFA.acceptsWord numericNFA "01a1") 0 \ No newline at end of file diff --git a/NFA.fs b/NFA.fs index 03ecc6f..db62d96 100644 --- a/NFA.fs +++ b/NFA.fs @@ -14,4 +14,28 @@ type NFA = { } let processChar (nfa: NFA) (state: State) (char: Char) = - nfa.delta state char \ No newline at end of file + 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