+Start :: *World -> *World
+Start w
+# (io, w) = stdio w
+# (puzzle, io) = parseFromFile io
+# io = io <<< encode puzzle <<< "\n"
+= snd (fclose io w)
+
+encode :: SokobanPuzzle -> String
+encode p = foldr ((+++) o (+++) "\n") "" ([
+ "MODULE",
+ "main",
+ "VAR":encodeBoxes p maxX maxY])
+ where
+ annot = annotate p
+ (maxX, maxY) = getMetrics annot
+
+:: AnnotatedSokoban :== [(Int, Int, SokobanTile)]
+
+annotate :: SokobanPuzzle -> AnnotatedSokoban
+annotate (Sokoban p) = flatten [[(x, y, t)\\t<-r & x<-[0..]]\\r<-p & y<-[0..]]
+
+getMetrics :: AnnotatedSokoban -> (Int, Int)
+getMetrics p = (maxList (map fst3 p),maxList (map snd3 p))
+
+getBoxes :: AnnotatedSokoban -> [(Int, Int)]
+getBoxes p = [t\\t=:(_, _, Box)<-p] ++
+
+ where
+ getBox` _ [] = []
+ getBox` x [b:bs] = let r = getBox` (x+1) bs in case b of
+ Box = [x:r]
+ TargetBox = [x:r]
+ _ = r
+
+(<+) infixr 5 :: a b -> String | toString a & toString b
+(<+) a b = toString a +++ toString b
+
+encodeBoxes :: SokobanPuzzle Int Int -> [String]
+encodeBoxes p mx my = [
+ "\tbox" <+ i <+ "x: " <+ "0 .. " <+ mx <+ ";\n\tbox" <+
+ i <+ "y: " <+ "0 .. " <+ my <+ ";"\\(bx, by)<-getBoxes p & i<-[0..]]