Skip to content

afern-git/box-world-json

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Box-World JSON Planner Interface (v1)

This repository provides a Python tool for specifying box rearrangement planning problems in a structured JSON format, compiling them into PDDL problem instances for the BOX-WORLD domain, and optionally solving them using an external planner (e.g., Fast Downward).

The tool supports two modes:

  • convert — JSON → PDDL problem file
  • solve — JSON → PDDL → planner → JSON plan output

Quick Start (assumes Fast Downward installation)


./json-to-pddl.py convert ./examples/tiny-test.json -o tiny-test.pddl
./json-to-pddl.py solve ./examples/tiny-test.json --plan-json-out tiny-test.plan.json

Dependencies and Installation (Fast Downward)


The solve mode of this tool requires an external PDDL planner. It has been tested with Fast Downward 24.06.1.

Fast Downward is not included in this repository and must be installed separately.


Installing Fast Downward (Tarball Method)


1. Download the Fast Downward tarball

Download the latest Fast Downward release tarball from:

https://www.fast-downward.org/latest/releases/

For example:

wget https://www.fast-downward.org/latest/files/release24.06/fast-downward-24.06.1.tar.gz

2. Extract the tarball

tar -xzf fast-downward-24.06.1.tar.gz
cd fast-downward-24.06.1

This will create a directory containing the Fast Downward source code.


3. Build Fast Downward

python3 build.py

This compiles Fast Downward and creates the launcher script:

fast-downward.py

4. Verify the installation

./fast-downward.py --help

You should see the Fast Downward help message.


5. Using Fast Downward with this tool

By default, the solver assumes the planner is available at:

./fast-downward-24.06.1/fast-downward.py

You can override the planner path explicitly:

./json-to-pddl.py solve problem.json \
  --planner /path/to/fast-downward.py \
  --plan-json-out plan.json

Tested Configuration


  • Fast Downward 24.06.1
  • Python 3.9+
  • Linux / WSL environments

Command-Line Usage


Convert JSON to PDDL

./json-to-pddl.py convert problem.json -o problem.pddl

If -o is omitted, the generated PDDL problem is printed to stdout.


Solve JSON problem and return a plan

./json-to-pddl.py solve problem.json \
  --domain box-world-domain.pddl \
  --planner ./fast-downward.py \
  --plan-json-out plan.json

If --plan-json-out is omitted, the plan JSON is printed to stdout.

The planner is expected to write multiple plan files of the form:

plan.1, plan.2, ..., plan.N

Larger numeric suffixes correspond to better plans.
The tool automatically selects the best plan.


JSON Input Format


2.1 Top-Level Structure

{
  "problem_name": "...",
  "locations": [... or {...}],
  "boxes": [... or {...}],
  "initial_state": { ... },
  "forbidden_stack": [...],   // optional
  "goal": { ... }
}

Required fields:

  • problem_name
  • locations
  • boxes
  • initial_state
  • goal

Optional fields:

  • forbidden_stack

Locations


Locations may be specified in either minimal or property-annotated form.

Minimal form

"locations": ["L1", "L2", "L3"]

With properties

"locations": {
  "L1": { "color": "white" },
  "L2": { "color": "black" },
  "L3": {}
}

Supported property:

  • color: "black" | "white"

These map to PDDL predicates:

  • (black L)
  • (white L)

Unknown properties are ignored by the generator.


Boxes


Boxes follow the same structure and semantics as locations.

Minimal form

"boxes": ["B1", "B2", "B3"]

With properties

"boxes": {
  "B1": { "color": "black" },
  "B2": {},
  "B3": { "color": "white" }
}

Properties are optional and handled identically to location properties.


5. Initial State


The entire initial world state is specified under initial_state.

Example

"initial_state": {
  "robot_at": "L1",
  "holding": null,
  "stacks": {
    "L1": ["B1", "B2", "B3"]
  }
}

Fields:

  • robot_at (required)
    Starting location of the robot.

  • holding (optional)
    Name of a box the robot starts holding, or null.
    If omitted or null, the robot starts with empty hands.

  • stacks (required)
    Mapping from non-empty locations to stacks of boxes.

Stack Ordering (IMPORTANT)

Stacks are listed from top to bottom.

"L1": ["B1", "B2", "B3"]

represents:

B1   (top)
B2
B3   (bottom)
L1   (location)

Locations omitted from stacks are assumed empty.


Initial State Semantics


For a stack at location L with boxes [t0, t1, ..., tk] (top → bottom), the following PDDL facts are generated:

  • (on t0 t1)
  • (on t{i} t{i+1}) for i = 0..k-1
  • (on tk L)
  • (clear t0)
  • (box-at ti L) for all boxes in the stack

For locations not listed in stacks:

  • (clear L)

Robot hand state:

  • If holding = B: (holding B)
  • Otherwise: (hands-empty)

Invariant: Each box must appear exactly once across {holding} ∪ stacks.


Forbidden Stacking (Optional)


"forbidden_stack": [
  ["B2", "B1"],
  ["B3", "B2"]
]

Each pair [top, bottom] generates:

(forbidden-stack top bottom)

If omitted, no stacking constraints are imposed.


Goal Specification (v1)


Goals describe the desired final configuration of the world.

Structured Goal Predicates

Supported structured predicates:

  • on — box on box or box on location
  • box-at — box is in a stack at a location
  • clear — object (box or location) is clear

All structured goal predicates are implicitly conjoined.

Example

"goal": {
  "on": [
    ["B2", "B3"],
    ["B3", "L2"]
  ],
  "clear": ["B2"]
}

Equivalent PDDL goal:

(and
  (on B2 B3)
  (on B3 L2)
  (clear B2)
)

Verbatim PDDL Goal Formulas

Advanced users may include raw PDDL formulas using the pddl field.

"goal": {
  "pddl": [
    "(robot-at L2)",
    "(exists (?x - box) (and (clear ?x) (not (holding ?x))))"
  ]
}

Notes:

  • Each formula must be a string
  • All formulas are conjoined with structured goals
  • Verbatim formulas are parsed and validated before PDDL is emitted

Supported formula forms:

  • Predicate atoms using holding, hands-empty, robot-at, box-at, forbidden-stack, on, clear, black, or white
  • Logical forms: and, or, not
  • Quantifiers: exists and forall with typed variables
  • Equality: =

Validation rules:

  • Constants must refer to declared boxes or locations.
  • Variables must be bound by an enclosing exists or forall.
  • Predicate arity and argument types must match the BOX-WORLD domain.
  • Supported types are box, location, and object.
  • Full PDDL declarations, actions, effects, numeric expressions, and durative constructs are not supported in goal.pddl.

Example validation error:

Invalid goal.pddl[0]: predicate 'robot-at' expects location, got box term 'B1'

JSON Output Format (Solve Mode)


When run in solve mode, the tool outputs a JSON plan file.

Format

{
  "plan": [
    {"unstack": ["b1", "b2", "l1"]},
    {"locomotion": ["l1", "l2"]},
    {"putdown": ["b1", "l2"]},
    {"locomotion": ["l2", "l1"]},
    {"pickup": ["b2", "l1"]},
    {"locomotion": ["l1", "l2"]},
    {"stack": ["b2", "b1", "l2"]}
  ],
  "cost": 12
}

Fields:

  • plan: ordered list of action strings (as produced by the planner)
  • cost: integer plan cost, or null if unavailable

Plan Actions:

  • {"locomotion": ["l1", "l2"]}: robot moves from location l1 to location l2
  • {"pickup": ["b2", "l1"]}: pickup box b that is directly on location l
  • {"putdown": ["b1", "l2"]}: putdown box b (currently held) directly onto location l (currently clear)
  • {"unstack": ["b1", "b2", "l1"]}: unstack box b1 that is currently on box b2 at location l (b2 may be on l or another box)
  • {"stack": ["b2", "b1", "l2"]}: stack box b1 (currently held) onto box b2 (currently clear) at location l (b2 may be on l or another box)

If --plan-json-out is not specified, this JSON object is printed to stdout.


Minimal Example


{
  "problem_name": "tiny",
  "locations": ["L1", "L2"],
  "boxes": ["B1"],
  "initial_state": {
    "robot_at": "L1",
    "stacks": {
      "L1": ["B1"]
    }
  },
  "goal": {
    "on": [["B1", "L2"]]
  }
}

Version Notes


  • This document describes v1 of the Box-World JSON format.
  • Structured goals are limited to conjunctions.
  • Future versions may add:
    • disjunction (or)
    • quantifiers (exists, forall)
    • richer plan metadata and validation

About

JSON to PDDL converter for Box-World planning problems

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors