small clean-up
[mc1516pa.git] / code / SokobanCoord.icl
1 module SokobanCoord
2
3 import StdList, StdInt, StdBool, StdChar, StdMisc, StdClass, StdString, StdFile, StdArray, StdTuple, Data.Maybe, Data.Map, Control.Monad, Data.Tuple, Data.Void
4 import Sokoban
5
6 inpath :== "screen.2001"
7 outpath :== "solver.smv"
8
9 checkX :: [[SokobanTile]] Int -> Int
10 checkX p x = if (x > (length p - 1)) (-1) x
11
12 checkY :: [[SokobanTile]] Int Int -> Int
13 checkY p x y
14 | ((x < 0) || (x > (length p - 1))) = -1
15 | otherwise = if (y > (length (p !! x) - 1)) (-1) y
16
17 genField :: [[SokobanTile]] Int Int -> String
18 genField p x y = " init(x" +++ toString x +++ "_" +++ toString y +++ ") := " +++ fromTile ((p !! x) !! y) +++ ";\n"
19
20 genVars :: Int Int -> String
21 genVars x y = " x" +++ toString x +++ "_" +++ toString y +++ " : {Wall, Free, Box, BoxOnTarget, Target, Agent, AgentOnTarget};\n"
22
23 genCoord :: [[SokobanTile]] Int Int -> [String]
24 genCoord p x y = [" next(x" +++ toString x +++ "_" +++ toString y +++ ") := case\n",
25 " x" +++ toString x +++ "_" +++ toString y +++ " = Wall: Wall;\n",
26 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Agent & move = Left: Agent;\n",
27 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Agent & move = Up: Agent;\n",
28 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Agent & move = Right : Agent;\n",
29 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Agent & move = Down : Agent;\n",
30 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+2)) +++ " = Agent & move = Left: Box;\n",
31 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Box & x" +++ toString (checkX p (x+2)) +++ "_" +++ toString (checkY p (x+2) y) +++ " = Agent & move = Up: Box;\n",
32 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-2)) +++ " = Agent & move = Right : Box;\n",
33 " x" +++ toString x +++ "_" +++ toString y +++ " = Free & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Box & x" +++ toString (checkX p (x-2)) +++ "_" +++ toString (checkY p (x-2) y) +++ " = Agent & move = Down : Box;\n",
34 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Target) & move = Right: Free;\n",
35 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Free | x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p x y) +++ " = Target) & move = Down: Free;\n",
36 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Target) & move = Left : Free;\n",
37 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ "= Free | x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Target) & move = Up : Free;\n",
38
39 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Box & x"
40 +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+2)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+2)) +++ " = Target) & move = Right: Free;\n",
41 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p x y) +++ " = Box & x"
42 +++ toString (checkX p (x+2)) +++ "_" +++ toString (checkY p (x+2) y) +++ " = Free | x" +++ toString (checkX p (x+2)) +++ "_" +++ toString (checkY p (x+2) y) +++ " = Target) & move = Down: Free;\n",
43 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Box & x"
44 +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-2)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-2)) +++ " = Target) & move = Left: Free;\n",
45 " x" +++ toString x +++ "_" +++ toString y +++ " = Agent & (x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Box & x"
46 +++ toString (checkX p (x-2)) +++ "_" +++ toString (checkY p (x-2) y) +++ " = Free | x" +++ toString (checkX p (x-2)) +++ "_" +++ toString (checkY p (x-2) y) +++ " = Target) & move = Up: Free;\n",
47
48 " x" +++ toString x +++ "_" +++ toString y +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Target) & move = Left: Agent;\n",
49 " x" +++ toString x +++ "_" +++ toString y +++ " = Box & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Agent & (x" +++ toString (x-1) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Free | x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Target) & move = Up: Agent;\n",
50 " x" +++ toString x +++ "_" +++ toString y +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Target) & move = Right : Agent;\n",
51 " x" +++ toString x +++ "_" +++ toString y +++ " = Box & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Agent & (x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Free | x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p x y) +++ " = Target) & move = Down : Agent;\n",
52 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Agent & move = Left: AgentOnTarget;\n",
53 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Agent & move = Up: AgentOnTarget;\n",
54 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Agent & move = Right : AgentOnTarget;\n",
55 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Agent & move = Down : AgentOnTarget;\n",
56 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+2)) +++ " = Agent & move = Left: BoxOnTarget;\n",
57 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Box & x" +++ toString (checkX p (x+2)) +++ "_" +++ toString (checkY p (x+2) y) +++ " = Agent & move = Up: BoxOnTarget;\n",
58 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Box & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-2)) +++ " = Agent & move = Right : BoxOnTarget;\n",
59 " x" +++ toString x +++ "_" +++ toString y +++ " = Target & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Box & x" +++ toString (checkX p (x-2)) +++ "_" +++ toString (checkY p (x-2) y) +++ " = Agent & move = Down : BoxOnTarget;\n",
60 " x" +++ toString x +++ "_" +++ toString y +++ " = AgentOnTarget & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Target) & move = Right: Target;\n",
61 " x" +++ toString x +++ "_" +++ toString y +++ " = AgentOnTarget & (x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Free | x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Target) & move = Down: Target;\n",
62 " x" +++ toString x +++ "_" +++ toString y +++ " = AgentOnTarget & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Target) & move = Left : Target;\n",
63 " x" +++ toString x +++ "_" +++ toString y +++ " = AgentOnTarget & (x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Free | x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Target) & move = Up : Target;\n",
64 " x" +++ toString x +++ "_" +++ toString y +++ " = BoxOnTarget & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Free | x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Target) & move = Left: AgentOnTarget;\n",
65 " x" +++ toString x +++ "_" +++ toString y +++ " = BoxOnTarget & x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Agent & (x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Free | x" +++ toString (checkX p (x-1)) +++ "_"
66 +++ toString (checkY p (x-1) y) +++ " = Target) & move = Up: AgentOnTarget;\n",
67 " x" +++ toString x +++ "_" +++ toString y +++ " = BoxOnTarget & x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y-1)) +++ " = Agent & (x" +++ toString (checkX p x) +++ "_" +++ toString (checkY p x (y+1)) +++ " = Free | x" +++ toString x +++ "_" +++ toString (checkY p x (y+1)) +++ " = Target) & move = Right : AgentOnTarget;\n",
68 " x" +++ toString x +++ "_" +++ toString y +++ " = BoxOnTarget & x" +++ toString (checkX p (x-1)) +++ "_" +++ toString (checkY p (x-1) y) +++ " = Agent & (x" +++ toString (checkX p (x+1)) +++ "_" +++ toString (checkY p (x+1) y) +++ " = Free | x" +++ toString (checkX p (x+1)) +++ "_"
69 +++ toString (checkY p (x+1) y) +++ " = Target) & move = Down : AgentOnTarget;\n",
70 " TRUE : x" +++ toString x +++ "_" +++ toString y +++ ";\n",
71 " esac;\n"
72 ]
73
74 instance == SokobanTile
75 where
76 (==) Wall Wall = True
77 (==) Free Free = True
78 (==) Box Box = True
79 (==) Agent Agent = True
80 (==) Target Target = True
81 (==) TargetBox TargetBox = True
82 (==) TargetAgent TargetAgent = True
83 (==) _ _ = False
84
85 fromTile :: SokobanTile -> String
86 fromTile Wall = "Wall"
87 fromTile Free = "Free"
88 fromTile Box = "Box"
89 fromTile Target = "Target"
90 fromTile Agent = "Agent"
91 fromTile TargetAgent = "AgentOnTarget"
92 fromTile TargetBox = "BoxOnTarget"
93
94 genCond :: [[SokobanTile]] Int Int -> String
95 genCond p x y
96 | x < 0 || y < 0 || x > (length p) - 1 = ""
97 | otherwise
98 | y > (length (p !! x) - 1) = ""
99 | otherwise = if ((p !! x) !! y == Target) ("x" +++ toString x +++ "_" +++ toString y +++ " = BoxOnTarget") ""
100
101 addLogic :: [String] -> [String]
102 addLogic [] = []
103 addLogic [x] = [x]
104 addLogic [x:xs] = [x +++ " & ": addLogic xs]
105
106 genAll :: SokobanPuzzle -> [String]
107 genAll puzzle = let (Sokoban p) = puzzle in
108 [
109 "MODULE main\n",
110 "VAR\n"
111 ]
112 ++ [genVars x y \\ x <- [0..(length p - 1)], y <- [0..(length (p !! x) - 1)]]
113 ++ [" move : {Up, Down, Left, Right};\n"]
114 ++ [
115 " ASSIGN\n",
116 " init(move) := {Up, Down, Left, Right};\n"
117 ]
118 ++ [genField p x y \\ x <- [0..(length p - 1)], y <- [0..(length (p !! x) - 1)]]
119 ++ flatten [filter (\x -> not (contains '-' x)) (genCoord p x y) \\ x <- [0..(length p - 1)], y <- [0..(length (p !! x) - 1)]]
120 ++ [" next(move) := {Up, Down, Left, Right};\n"]
121 ++ ["INVARSPEC !("]
122 ++ addLogic (filter (\x -> x <> "" ) [genCond p x y \\ x <- [0..(length p - 1)], y <- [0..(length (p !! x) - 1)]])
123 ++ [")\n"]
124
125 contains :: Char String -> Bool
126 contains char str = not (isEmpty [c\\c<-:str | char == c])
127
128 readLines :: File -> [String]
129 readLines file
130 | sfend file = []
131 # (line, file) = sfreadline file
132 | otherwise = [line: readLines file]
133
134 writeLines :: [String] *File -> *File
135 writeLines [] file = file
136 writeLines [l:ls] file = writeLines ls (file <<< l)
137
138 openInpFile :: *World String -> (File, *World)
139 openInpFile world path
140 # (ok, file, world) = sfopen path 0 world
141 | not ok = abort "Error reading the file."
142 = (file, world)
143
144 openOutFile :: *World String -> (*File, *World)
145 openOutFile world path
146 # (ok, file, world) = fopen path 1 world
147 | not ok = abort "Can not write to a file."
148 = (file, world)
149
150 closeFile :: *World *File -> (Bool, *World)
151 closeFile world file
152 # world = fclose file world
153 = world
154
155 Start :: *World -> *World
156 Start w
157 # (p, w) = parse inpath w
158 # s = genAll p
159 # (f, w) = openOutFile w outpath
160 # f = writeLines s f
161 # (ok, w) = closeFile w f
162 = w