module Turing where import Data.List ---------------------- type Symbol = Char blankSymbol :: Symbol blankSymbol = '0' ---------------------- -- tape with head data Tape = Tape { pos :: Int -- head position , left :: [Symbol] -- elems before the head , right :: [Symbol] -- elem at the head and elems after the head } instance Eq Tape where (==) (Tape p l r) (Tape p' l' r') = p == p' && eq l l' && eq r r' where eq [] [] = True eq (h:t) (h':t') = h==h' && eq t t' eq left right = eq (extend left) (extend right) extend :: [Symbol] -> [Symbol] extend [] = [blankSymbol] extend l = l symbolAtHead :: Tape -> Symbol symbolAtHead t = head $ extend $ right t blankTape :: Tape blankTape = Tape 0 [] [] showTape :: Int -> Tape -> String showTape i (Tape p l r) | n > 0 = replicate n ' ' ++ l' | otherwise = drop (-n) l' where n = i - length l + p l' = map tr $ reverse l ++ r tr x | x == blankSymbol = ' ' tr x = x -------------------- data Shift = L | R deriving (Eq, Ord, Show, Read) shift :: Shift -> Tape -> Tape shift L (Tape p l r) = case extend l of h:t -> Tape (p-1) t (h: r) shift R (Tape p l r) = case extend r of h:t -> Tape (p+1) (h: l) t write :: Symbol -> Tape -> Tape write s (Tape p l r) = case extend r of _:t -> Tape p l (s:t) goToMiddle :: Tape -> Tape goToMiddle t = case compare (pos t) 0 of EQ -> t LT -> goToMiddle $ shift R t GT -> goToMiddle $ shift L t ----------------------- type State = Char initialState, haltingState :: State initialState = 'A' haltingState = 'H' ----------- type Transition = ((State, Symbol), (Symbol, Shift, State)) type Machine = [Transition] run :: Machine -> State -> Tape -> [Tape] run _ s _ | s == haltingState = [] run m s t = case lookup (s, symbolAtHead t) m of Nothing -> [] Just (sym, sh, next) -> let t' = write sym t in t': run m next (shift sh t')