Advertisement
LdDl

Эмулятор машины Тьюринга (Хаскель)

Jan 10th, 2016
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-|
  2. @Author:: lopanov@edu
  3. @applied_mathematics
  4. -}
  5. {-|
  6. Эмулятор машины Тьюринга (Пример в конце файла)
  7. Для инициализации начального состояния и таблицы:
  8. >> mapM_ print "название машины" без ковычек
  9. mapM - категории Клейсли
  10. mapM_ - категории Клейсли с побочными эффектами монады
  11. Длина ленты: take "длина"
  12. -}
  13. data Step = Step_Left | Step_Right | Stand_Still deriving (Show, Eq)
  14. data Tape a = Tape a [a] [a]
  15. data Movement current_state val = Movement val Step current_state deriving (Show)
  16.  
  17. instance (Show a) => Show (Tape a) where
  18.   show (Tape pos lll rrr) = concat $ left_side ++ [head] ++ right_side
  19.                           where head = "<" ++ show pos ++ ">"
  20.                                 left_side = map show $ reverse $ take 15 lll
  21.                                 right_side = map show $ take 15 rrr
  22. {-|
  23. Движение каретки
  24. -}
  25. step initialize_rules (current_state, Tape pos (left_to:lll) (right_to:rrr)) = (current_state', tape')
  26.      where  Movement pos' dir current_state' = initialize_rules current_state pos
  27.             tape' = move dir
  28.            move Stand_Still = Tape pos' (left_to:lll) (right_to:rrr)
  29.             move Step_Left = Tape left_to lll (pos':right_to:rrr)
  30.            move Step_Right = Tape right_to (pos':left_to:lll) rrr
  31. run_machine initialize_rules stop start tape = steps ++ [last_step]
  32.       where (steps, last_step:_) = break ((== stop) . fst) $ iterate (step initialize_rules) (start, tape)
  33.  
  34. {-|
  35. Инициализация полосы
  36. -}
  37. tape lam lll rrr | null rrr = Tape lam left_side lam_s
  38.                    | otherwise = Tape (head rrr) left_side right_side
  39.                    where lam_s = repeat lam
  40.                          left_side = reverse lll ++ lam_s
  41.                          right_side = tail rrr ++ lam_s  
  42.  
  43. -- Машина Тьюринга
  44. {-|
  45. Формат составленной машины:
  46. tm "состояние" Значение = Действие Значение Направление_Каретки "Состояние"
  47. и т.д.
  48. НазваниеЛенты = tape "Обозначение пустых ячеек - оно же Лямбда"" [] ["Входные данные"]
  49. Название машины = run_machine tm "Состояние остановки" "Начальное состояние" НазваниеЛенты
  50. Step_Left - Лево.
  51. Step_Right - Право.
  52. Stand_Still - Нейтрально.
  53. Пример:
  54. Алфавит {pos1,pos2...,posN} содержит две буквы. {a,b} ( или {1,2} ).
  55. Пустые ячейки на ленте - 0.
  56. Ввести слово состоящие из букв "a" и "b" (a=1, b=2).
  57. Оставить слово неизменным, если кол-во "a" (1) - нечётно.
  58. Изменить всё слово на слово "bb" (22), если кол-во "a" (1) - чётно.
  59.  
  60. Составленая по условию задачи машина:
  61. Алфавит:     1 ("a") | 2 ("b") | 0 ("лямбда")
  62. Состояния:             |         |
  63.     s1      1.П->1 | 2.П->1  | 0.Л->2
  64.     s2      1.Л->3 | 2.Л->2  | 0.П->4
  65.     s3      1.Л->2  | 2.Л->3  | 0.Н0
  66.     s4      2.П->5 | 2.П->5  | 2.П->5
  67.     s5      2.П->6 | 2.П->6  | 2.П->6
  68.     s6      0.П->6 | 0.П->6  | 0.Н0
  69. Итого таблица будет состоять из 6*3 = 18 строк,
  70. где 6 - это кол-во состояний, а 3 - число букв в алфавите + одна лямбда.
  71. -}
  72. tm "s1" 1 = Movement 1 Step_Right "s1"
  73. tm "s1" 2 = Movement 2 Step_Right "s1"
  74. tm "s1" 0 = Movement 0 Step_Left  "s2"
  75.  
  76. tm "s2" 1 = Movement 1 Step_Left  "s3"
  77. tm "s2" 2 = Movement 2 Step_Left  "s2"
  78. tm "s2" 0 = Movement 0 Step_Right  "s4"
  79.  
  80. tm "s3" 1 = Movement 1 Step_Left  "s2"
  81. tm "s3" 2 = Movement 2 Step_Left  "s3"
  82. tm "s3" 0 = Movement 0 Stand_Still  "Neutral"
  83.  
  84. tm "s4" 1 = Movement 2 Step_Right  "s5"
  85. tm "s4" 2 = Movement 2 Step_Right  "s5"
  86. tm "s4" 0 = Movement 2 Step_Right  "s5"
  87.  
  88. tm "s5" 1 = Movement 2 Step_Right  "s6"
  89. tm "s5" 2 = Movement 2 Step_Right  "s6"
  90. tm "s5" 0 = Movement 2 Step_Right  "s6"
  91.  
  92. tm "s6" 1 = Movement 0 Step_Right  "s6"
  93. tm "s6" 2 = Movement 0 Step_Right  "s6"
  94. tm "s6" 0 = Movement 0 Step_Right  "Neutral"
  95.  
  96. -- Тест для "baabb". Ответ должен быть: "bb"
  97. tape1 = tape 0 [] [2,1,1,2,2]
  98. test1 = run_machine tm "Neutral" "s1" tape1
  99.  
  100. -- Тест для "babb". Ответ должен быть: "babb"
  101. tape2 = tape 0 [] [2,1,2,2]
  102. test2 = run_machine tm "Neutral" "s1" tape2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement