Skip to content

Instantly share code, notes, and snippets.

@smithcommajoseph
Last active September 23, 2020 18:35
Show Gist options
  • Save smithcommajoseph/79ff0695b0f3c3d15e3feca50a6a7306 to your computer and use it in GitHub Desktop.
Save smithcommajoseph/79ff0695b0f3c3d15e3feca50a6a7306 to your computer and use it in GitHub Desktop.
A simple DFA implemented in Haskell
module Dfa
(
stateFactory
, alphabet
, allStates
, firstState
, acceptStates
, allTransitions
, transFromState
, transLabel
, transToState
, findTransition
, findNextState
, dfaAccept
) where
-- Custom types
type State = [Char]
type Letter = [Char]
type Transition = (State, Letter, State)
type DFA = ([State], [Letter], State, [State], [Transition])
-- Private functions
getFirstStateItem :: DFA -> [State]
getFirstStateItem (x, _, _, _, _) = x
getSecondStateItem :: DFA -> [Letter]
getSecondStateItem (_, x, _, _, _)= x
getThirdStateItem :: DFA -> State
getThirdStateItem (_, _, x, _, _) = x
getFourthStateItem :: DFA -> [State]
getFourthStateItem (_, _, _, x, _) = x
getFifthStateItem :: DFA -> [Transition]
getFifthStateItem (_, _, _, _, x) = x
-- Public functions
stateFactory :: () -> DFA
stateFactory () = (states, epsilon, startState, endStates, transitions)
where
states = ["q0", "q1", "q2", "q3", "q4"]
epsilon = ["0", "1", "."]
startState = "q0"
endStates = ["q3"]
transitions = [ ("q0", "0", "q1")
, ("q0", "1", "q1")
, ("q0", ".", "q2")
, ("q1", "0", "q1")
, ("q1", "1", "q1")
, ("q1", ".", "q3")
, ("q2", "0", "q3")
, ("q2", "1", "q3")
, ("q2", ".", "q4")
, ("q3", "0", "q3")
, ("q3", "1", "q3")
, ("q3", ".", "q4")
, ("q4", "0", "q4")
, ("q4", "1", "q4")
, ("q4", ".", "q4") ]
allStates :: (() -> DFA) -> [State]
allStates (stateFactory) = getFirstStateItem (stateFactory())
alphabet :: (() -> DFA) -> [Letter]
alphabet (stateFactory) = getSecondStateItem (stateFactory())
firstState :: (() -> DFA) -> State
firstState (stateFactory) = getThirdStateItem (stateFactory())
acceptStates :: (() -> DFA) -> [State]
acceptStates (stateFactory) = getFourthStateItem (stateFactory())
allTransitions :: (() -> DFA) -> [Transition]
allTransitions (stateFactory) = getFifthStateItem (stateFactory())
transFromState :: Transition -> State
transFromState (x, _, _) = x
transLabel :: Transition -> Letter
transLabel (_, x, _) = x
transToState :: Transition -> State
transToState (_, _, x) = x
findTransition :: State -> Letter -> [Transition] -> [Transition]
findTransition curState label transitions = [transition | transition <- transitions
, transFromState transition == curState
, transLabel transition == label]
findNextState :: (() -> DFA) -> [Char] -> State
findNextState stateFactory "" = firstState stateFactory
findNextState stateFactory input = transToState (head (findTransition (findNextState stateFactory (init input)) [(last input)] (allTransitions(stateFactory))))
dfaAccept :: (() -> DFA) -> [Char] -> Bool
dfaAccept stateFactory input = finalState `elem` finalStates
where
finalState = findNextState stateFactory input
finalStates = acceptStates stateFactory
@smithcommajoseph
Copy link
Author

*Dfa> :l Dfa.hs
[1 of 1] Compiling Dfa              ( Dfa.hs, interpreted )
Ok, one module loaded.
*Dfa> dfaAccept stateFactory "1.0"
True
*Dfa> dfaAccept stateFactory "1.0.1"
False
*Dfa> dfaAccept stateFactory "1.000001"
True
*Dfa> dfaAccept stateFactory ".000"
True
*Dfa> dfaAccept stateFactory ".000."
False
*Dfa>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment