5 | 5 |
|
6 | 6 |
import Data.Char (digitToInt)
|
7 | 7 |
|
8 | |
-- Function to generate Turmac rules for writing a string
|
9 | |
generateTapeWriter :: String -> String
|
10 | |
generateTapeWriter input = unlines $
|
|
8 |
import Language.Turmac.Model
|
|
9 |
|
|
10 |
|
|
11 |
-- Function to generate Turmac rules for writing a sequence of symbols to the tape
|
|
12 |
generateTapeWriter :: [Symbol] -> [TMRule]
|
|
13 |
generateTapeWriter symbols = unlines $
|
11 | 14 |
-- Header line
|
12 | 15 |
["in state,if the symbol is,write the symbol,move the head,go to state"] ++
|
13 | 16 |
-- Rules for writing each symbol
|
|
16 | 19 |
moveBackRules
|
17 | 20 |
where
|
18 | 21 |
-- Generate rules for writing each digit in sequence
|
19 | |
writeRules = zipWith makeWriteRule [0..] (map digitToInt input)
|
|
22 |
writeRules = zipWith makeWriteRule [0..] symbols
|
20 | 23 |
|
21 | 24 |
-- Generate rules for moving back to start
|
22 | 25 |
moveBackRules =
|
23 | |
if null input
|
|
26 |
if null symbols
|
24 | 27 |
then []
|
25 | |
else makeBackwardRules (length input) (length input)
|
|
28 |
else makeBackwardRules (length symbols) (length symbols)
|
26 | 29 |
|
27 | |
renderRule :: Int -> Int -> Int -> Char -> Int -> String
|
28 | |
renderRule state1 sym1 sym2 dir state2 =
|
29 | |
let
|
30 | |
st1 = "S" ++ (show state1)
|
31 | |
st2 = if state2 == -1 then "H" else "S" ++ (show state2)
|
32 | |
in
|
33 | |
st1 ++ "," ++ (show sym1) ++ "," ++ (show sym2) ++ "," ++ [dir] ++ "," ++ st2
|
34 | |
|
35 | |
-- Create a rule for writing a single digit
|
36 | |
makeWriteRule :: Int -> Int -> String
|
37 | |
makeWriteRule state digit =
|
38 | |
renderRule state 0 digit 'R' (state + 1)
|
|
30 |
-- Create a rule for writing a single symbol
|
|
31 |
makeWriteRule :: Int -> Symbol -> TMRule
|
|
32 |
makeWriteRule state symbol =
|
|
33 |
("S" ++ show state, "_", symbol, "S" ++ show (state + 1), 1)
|
39 | 34 |
|
40 | 35 |
-- Create rules for moving back to start
|
41 | |
makeBackwardRules :: Int -> Int -> [String]
|
|
36 |
makeBackwardRules :: StateId -> Int -> [TMRule]
|
42 | 37 |
makeBackwardRules state numMoves =
|
43 | 38 |
let
|
44 | 39 |
moves = replicate numMoves 'L'
|
|
47 | 42 |
lastState = if null moves then state else state + numMoves
|
48 | 43 |
-- For each state in backtracking phase, generate rules for all possible symbols
|
49 | 44 |
rules = concatMap (\(s, ns, dir) ->
|
50 | |
[renderRule s sym sym dir ns | sym <- [0..2]]) -- Handle symbols 0, 1, and 2
|
|
45 |
[(s, sym, sym, ns, dir) | sym <- ["S0", "S1", "S2"]]) -- Handle symbols 0, 1, and 2
|
51 | 46 |
(zip3 states (init nextStates) moves)
|
52 | 47 |
-- Final state also needs rules for all symbols
|
53 | 48 |
finalRules =
|
54 | |
[renderRule (lastState -1) sym sym 'L' (-1) | sym <- [0..2]]
|
|
49 |
[((lastState - 1), sym, sym, "H", (-1)) | sym <- ["S0", "S1", "S2"]]
|
55 | 50 |
in
|
56 | 51 |
rules ++ finalRules
|