Add DFA and NFA representations

This commit is contained in:
Joscha 2019-10-24 12:28:47 +00:00
parent a6fdf546c3
commit 4cae9af848
3 changed files with 84 additions and 0 deletions

View file

@ -21,6 +21,9 @@ description: Please see the README on GitHub at <https://github.com/gith
dependencies: dependencies:
- base >= 4.7 && < 5 - base >= 4.7 && < 5
- transformers >= 0.5.6 && < 0.6
- containers >= 0.6 && < 0.7
# algebraic-graphs >= 0.4 && < 0.5
library: library:
source-dirs: src source-dirs: src

36
src/Rextra/Dfa.hs Normal file
View file

@ -0,0 +1,36 @@
module Rextra.Dfa where
-- TODO don't export internals
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
data State s t = State
{ transitions :: Map.Map t s
, defaultTransition :: s
, accepting :: Bool
}
data Dfa s t = Dfa
{ dfaStates :: Map.Map s (State s t)
, dfaEntryState :: s
}
{-
- Constructing and modifying a DFA
-}
-- TODO
{-
- "Executing" a DFA
-}
getState :: (Ord s) => Dfa s t -> s -> State s t
getState dfa s = dfaStates dfa Map.! s
transition :: (Ord s, Ord t) => Dfa s t -> s -> t -> s
transition dfa s t =
let state = getState dfa s
in case transitions state Map.!? t of
(Just nextState) -> nextState
Nothing -> defaultTransition state

45
src/Rextra/Nfa.hs Normal file
View file

@ -0,0 +1,45 @@
module Rextra.Nfa where
-- TODO don't export internals
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
data TransitionCondition t
= Only (Set.Set t)
| AllExcept (Set.Set t)
specialStates :: TransitionCondition t -> Set.Set t
specialStates (Only s) = s
specialStates (AllExcept s) = s
accepts :: (Ord t) => TransitionCondition t -> t -> Bool
accepts (Only s) t = Set.member t s
accepts (AllExcept s) t = Set.notMember t s
type State s t = [(TransitionCondition t, s)]
data Nfa s t = Nfa
{ nfaStates :: Map.Map s (State s t)
, nfaEntryState :: s
, nfaExitStates :: Set.Set s
}
{-
- Constructing and modifying a NFA
-}
-- TODO
{-
- "Executing" a NFA
-}
getState :: (Ord s) => Nfa s t -> s -> State s t
getState nfa s = nfaStates nfa Map.! s
-- * Starting from a state, find all the states that it can transition to with token 't'.
nextStates :: (Ord s, Ord t) => State s t -> t -> Set.Set s
nextStates state t = Set.fromList . map snd . filter (\(cond, _) -> cond `accepts` t) $ state
nfaTransition :: (Ord s, Ord t) => Nfa s t -> Set.Set s -> t -> Set.Set s
nfaTransition nfa ss t = foldMap (\s -> nextStates (getState nfa s) t) ss