Add DFA constructor function

Also cleanes up the naming scheme, just like the last commit.
This commit is contained in:
Joscha 2019-10-24 22:40:24 +00:00
parent 89a5683ba2
commit edd7a44d02

View file

@ -1,5 +1,12 @@
module Rextra.Dfa where
-- TODO don't export internals
module Rextra.Dfa
( Dfa
, dfa
, dfa'
, stateMap
, entryState
, transition
, State(..)
) where
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
@ -11,22 +18,36 @@ data State s t = State
}
data Dfa s t = Dfa
{ dfaStates :: Map.Map s (State s t)
, dfaEntryState :: s
{ stateMap :: Map.Map s (State s t)
, entryState :: s
}
{-
- Constructing and modifying a DFA
- Constructing a DFA
-}
-- TODO
integrityCheck :: (Ord s) => Dfa s t -> Bool
integrityCheck dfa =
let states = Map.elems $ stateMap dfa
transitionStates = concatMap (Map.elems . transitions) states
defaultTransitionStates = map defaultTransition states
referencedStates = Set.fromList $ concat [[entryState dfa], transitionStates, defaultTransitionStates]
in referencedStates `Set.isSubsetOf` Map.keysSet (stateMap dfa)
dfa :: (Ord s) => Map.Map s (State s t) -> s -> Maybe (Dfa s t)
dfa stateMap entryState =
let myDfa = Dfa{stateMap=stateMap, entryState=entryState}
in if integrityCheck myDfa then Just myDfa else Nothing
dfa' :: (Ord s) => [(s, State s t)] -> s -> Maybe (Dfa s t)
dfa' states entryState = dfa (Map.fromList states) entryState
{-
- "Executing" a DFA
-}
getState :: (Ord s) => Dfa s t -> s -> State s t
getState dfa s = dfaStates dfa Map.! s
getState dfa s = stateMap dfa Map.! s
transition :: (Ord s, Ord t) => Dfa s t -> s -> t -> s
transition dfa s t =