+encodeGoalState :: [Int] [(Int, Int)] -> String
+encodeGoalState boxes targets = join " |\n\t" $ map encodeOneGoal boxtargets
+ where
+ boxtargets = map (zip2 targets) (permutations boxes)
+
+ encodeOneGoal :: [((Int, Int), Int)] -> String
+ encodeOneGoal p = "(" <+ join " & " (encodeOneGoal` p) <+ ")"
+
+ encodeOneGoal` :: [((Int, Int), Int)] -> [String]
+ encodeOneGoal` [] = []
+ encodeOneGoal` [((x, y), b):xs] = [
+ "b" <+ b <+ ".x = " <+ x <+ " & " <+
+ "b" <+ b <+ ".y = " <+ y:encodeOneGoal` xs]
+
+
+encodeBlockMovement :: [Int] -> String
+encodeBlockMovement bs = join "\n" $ map ebm bs
+ where
+ ebm :: Int -> String
+ ebm i =
+ "TRANS next(b" <+ i <+ ".x) = case\n" <+
+ "\t\tnext(agent.x) != b" <+ i <+ ".x | " <+
+ "next(agent.y) != b" <+ i <+ ".y: b" <+ i <+ ".x;\n" <+
+ "\t\tTRUE: b" <+ i <+ ".x + dx;\n" <+
+ "\tesac;\n" <+
+ "TRANS next(b" <+ i <+ ".y) = case\n" <+
+ "\t\tnext(agent.x) != b" <+ i <+ ".x | " <+
+ "next(agent.y) != b" <+ i <+ ".y: b" <+ i <+ ".x;\n" <+
+ "\t\tTRUE: b" <+ i <+ ".y + dy;\n" <+
+ "\tesac;"
+
+encodeAgentNotOnBox :: [Int] -> String
+encodeAgentNotOnBox bs = join " &\n\t" [
+ "(b" <+ i <+ ".x != agent.x & b" <+ i <+ ".y != agent.y)"\\i<-bs]
+
+encodeObjectPositions :: [(Int, Int)] -> String
+encodeObjectPositions p = join " | " ["x="<+x<+" & "<+"y="<+y\\(x, y)<-p]
+
+encodeAgent :: AnnotatedSokoban -> String
+encodeAgent [x:xs] = case x of
+ (x, y, Agent) = "ob(" <+ x <+ "," <+ y <+ ", movement);"
+ (x, y, TargetAgent) = "ob(" <+ x <+ "," <+ y <+ ", movement);"
+ _ = encodeAgent xs
+
+encodeBoxes :: [(Int, Int)] -> String
+encodeBoxes p = join "\n"
+ ["\tb" <+ i <+ ": ob(" <+ bx <+ ", " <+ by <+ ", movement);"
+ \\(bx, by)<-p & i<-[0..]]