2

I was experimenting a bit with generation of Sokoban levels in PDDL and found out that many levels in Sokoban, which appear easy to humans, seem to be quite hard for PDDL planners (to be honest I also found vice versa examples).

So I wonder whether there is a planner out there which can - on medium hardware like i7 16GB memory - find a solution in at most a day for this Sokoban level (Playable on https://sokoban.info/?1_2 ), which is just the second level of the original Sokoban game und appears to be fairly easy for humans:

############
#..--#-----###
#..--#-$--$--#
#..--#$####--#
#..----@-##--#
#..--#-#--$-##
######-##$-$-#
--#-$--$-$-$-#
--#----#-----#
--############

This level is encoded in the following PDDL files (tell me if you think that this presentation is rather unsuitable for PDDL planners - I don't think so). I carefully checked the PDDL files using an emulation and could successfully acquire the goal with a manually created plan.

However with the planners I could get my hands on (Fast Downward, ArvandHerd, siw-then-bfsf) this takes long (hours/days) until the process is killed by using up too much memory.

So do you have a planner that solves this puzzle with reasonable resources?!

Domain:

(define (domain sokoban)
  (:requirements :strips :negative-preconditions)
  (:predicates (adjwe ?h1 ?h2) (adjsn ?v1 ?v2)
        (sokoban_at ?h ?v) (wall_at ?h ?v) (crate_at ?h ?v)
  )
  (:action move-n
   :parameters (?x1 ?y0 ?y1)
   :precondition (and
        (adjsn ?y0 ?y1)

        (sokoban_at ?x1 ?y0)
        (not (crate_at ?x1 ?y1)) (not (wall_at ?x1 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y0))
        (sokoban_at ?x1 ?y1)
    )
  )
  (:action push-n
   :parameters (?x1 ?y0 ?y1 ?y2)
   :precondition (and
        (adjsn ?y0 ?y1) (adjsn ?y1 ?y2)

        (sokoban_at ?x1 ?y0) (crate_at ?x1 ?y1)
        (not (crate_at ?x1 ?y2)) (not (wall_at ?x1 ?y2))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y0)) (not (crate_at ?x1 ?y1))
        (sokoban_at ?x1 ?y1) (crate_at ?x1 ?y2)
    )
  )
  (:action move-s
   :parameters (?x1 ?y0 ?y1)
   :precondition (and
        (adjsn ?y1 ?y0)

        (sokoban_at ?x1 ?y0)
        (not (crate_at ?x1 ?y1)) (not (wall_at ?x1 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y0))
        (sokoban_at ?x1 ?y1)
    )
  )
  (:action push-s
   :parameters (?x1 ?y0 ?y1 ?y2)
   :precondition (and
        (adjsn ?y1 ?y0) (adjsn ?y2 ?y1)

        (sokoban_at ?x1 ?y0) (crate_at ?x1 ?y1)
        (not (crate_at ?x1 ?y2)) (not (wall_at ?x1 ?y2))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y0)) (not (crate_at ?x1 ?y1))
        (sokoban_at ?x1 ?y1) (crate_at ?x1 ?y2)
    )
  )
  (:action move-e
   :parameters (?x1 ?x2 ?y1)
   :precondition (and
        (adjwe ?x1 ?x2)

        (sokoban_at ?x1 ?y1)
        (not (crate_at ?x2 ?y1)) (not (wall_at ?x2 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y1))
        (sokoban_at ?x2 ?y1)
    )
  )
  (:action push-e
   :parameters (?x1 ?x2 ?x3 ?y1)
   :precondition (and
        (adjwe ?x1 ?x2) (adjwe ?x2 ?x3)

        (sokoban_at ?x1 ?y1) (crate_at ?x2 ?y1)
        (not (crate_at ?x3 ?y1)) (not (wall_at ?x3 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y1)) (not (crate_at ?x2 ?y1))
        (sokoban_at ?x2 ?y1) (crate_at ?x3 ?y1)
    )
  )
  (:action move-w
   :parameters (?x1 ?x2 ?y1)
   :precondition (and
        (adjwe ?x2 ?x1)

        (sokoban_at ?x1 ?y1)
        (not (crate_at ?x2 ?y1)) (not (wall_at ?x2 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y1))
        (sokoban_at ?x2 ?y1)
    )
  )
  (:action push-w
   :parameters (?x1 ?x2 ?x3 ?y1)
   :precondition (and
        (adjwe ?x2 ?x1) (adjwe ?x3 ?x2)

        (sokoban_at ?x1 ?y1) (crate_at ?x2 ?y1)
        (not (crate_at ?x3 ?y1)) (not (wall_at ?x3 ?y1))
    )
   :effect (and
        (not (sokoban_at ?x1 ?y1)) (not (crate_at ?x2 ?y1))
        (sokoban_at ?x2 ?y1) (crate_at ?x3 ?y1)
    )
  )
)

Problem:

(define (problem sokoban02)
    (:domain sokoban)
    (:objects
        h1 h2 h3 h4 h5 h6 h7 h8 h9 h10 h11 h12 h13 h14
        v2 v3 v4 v5 v6 v7 v8 v9 v10 v11
    )
    (:init
        (adjwe h1 h2) (adjwe h2 h3) (adjwe h3 h4) (adjwe h4 h5) (adjwe h5 h6) (adjwe h6 h7) (adjwe h7 h8) (adjwe h8 h9) (adjwe h9 h10) (adjwe h10 h11) (adjwe h11 h12) (adjwe h12 h13) (adjwe h13 h14)
        (adjsn v2 v3) (adjsn v3 v4) (adjsn v4 v5) (adjsn v5 v6) (adjsn v6 v7) (adjsn v7 v8) (adjsn v8 v9) (adjsn v9 v10) (adjsn v10 v11)
        
        (wall_at h1 v11) (wall_at h2 v11) (wall_at h3 v11) (wall_at h4 v11) (wall_at h5 v11) (wall_at h6 v11) (wall_at h7 v11) (wall_at h8 v11) (wall_at h9 v11) (wall_at h10 v11) (wall_at h11 v11) (wall_at h12 v11) (wall_at h1 v10) (wall_at h6 v10) (wall_at h12 v10) (wall_at h13 v10) (wall_at h14 v10) (wall_at h1 v9) (wall_at h6 v9) (wall_at h14 v9) (wall_at h1 v8) (wall_at h6 v8) (wall_at h8 v8) (wall_at h9 v8) (wall_at h10 v8) (wall_at h11 v8) (wall_at h14 v8) (wall_at h1 v7) (wall_at h10 v7) (wall_at h11 v7) (wall_at h14 v7) (wall_at h1 v6) (wall_at h6 v6) (wall_at h8 v6) (wall_at h13 v6) (wall_at h14 v6) (wall_at h1 v5) (wall_at h2 v5) (wall_at h3 v5) (wall_at h4 v5) (wall_at h5 v5) (wall_at h6 v5) (wall_at h8 v5) (wall_at h9 v5) (wall_at h14 v5) (wall_at h3 v4) (wall_at h14 v4) (wall_at h3 v3) (wall_at h8 v3) (wall_at h14 v3) (wall_at h3 v2) (wall_at h4 v2) (wall_at h5 v2) (wall_at h6 v2) (wall_at h7 v2) (wall_at h8 v2) (wall_at h9 v2) (wall_at h10 v2) (wall_at h11 v2) (wall_at h12 v2) (wall_at h13 v2) (wall_at h14 v2)
        (crate_at h8 v9) (crate_at h11 v9) (crate_at h7 v8) (crate_at h11 v6) (crate_at h10 v5) (crate_at h12 v5) (crate_at h5 v4) (crate_at h8 v4) (crate_at h10 v4) (crate_at h12 v4)
        (sokoban_at h8 v7)
    )
    (:goal (and (crate_at h2 v10) (crate_at h3 v10) (crate_at h2 v9) (crate_at h3 v9) (crate_at h2 v8) (crate_at h3 v8) (crate_at h2 v7) (crate_at h3 v7) (crate_at h2 v6) (crate_at h3 v6)))
)
bo198214
  • 178
  • 1
  • 4

1 Answers1

2

Try encoding the coordinates with a single object, i.e. (at pos-x-y) instead of (at x y). It can improve the performance of the planners you are trying. See this example of the IPC Sokoban encoding.

You can also try a Sokoban specific planner, e.g. Festival, the latest iteration introduced recently at SoCS: https://festival-solver.site/

nirlipo
  • 21
  • 1
  • 1
    Rewriting the level with pox-x-y including eliminating the wall_at by modelling it into the adjwe and adjsn didn't really help for solving. But thank you for the link to this new planner/algorithm - in the paper they explicitly state that Sokoban always posed difficulties to previous planners. So my impression was correct. But with this new algorithm they can solve Sokoban levels ultra fast ... – bo198214 Nov 18 '21 at 15:09