β¨ A Python wrapper using JuliaPy for the PDDL.jl parser package and implementing its own planners. β¨
Loved the project? Please consider donating to help it improve!
- β¨ Built to be expanded: easy to add new planners
- π₯οΈ Supported on MacOS and Ubuntu
- π Built with Julia and Python
- π Uninformed Planners (DFS, BFS)
- π§ Informed Planners (Dijkstra, A*, Greedy Best First)
- π Several general purpose heuristics (Goal Count, Delete Relaxation [Hmax, Hadd], Critical Path [H1, H2, H3], Relaxed Critical Path [H1, H2, H3])
- π» Maintained (Incoming: Landmarks Heuristics...)
You can also use the project in a docker container using docker-pythonpddl
-
Install Python (3.7.5 is the tested version)
-
Install Julia
$ wget https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.2-linux-x86_64.tar.gz
$ tar -xvzf julia-1.5.2-linux-x86_64.tar.gz
$ sudo cp -r julia-1.5.2 /opt/
$ sudo ln -s /opt/julia-1.5.2/bin/julia /usr/local/bin/julia
- Install Julia dependencies
$ julia --color=yes -e 'using Pkg; Pkg.add(Pkg.PackageSpec(path="https://github.com/APLA-Toolbox/PDDL.jl"))'
$ julia --color=yes -e 'using Pkg; Pkg.add(Pkg.PackageSpec(path="https://github.com/JuliaPy/PyCall.jl"))'
- Package installation (only if used as library, not needed to run the scripts)
$ python3 -m pip install --upgrade pip
$ python3 -m pip install jupyddl
- Clone the project :
$ git clone https://github.com/APLA-Toolbox/PythonPDDL
$ cd PythonPDDL
$ python3 -m pip install -r requirements.txt
$ git submodule update --init // Only if you need PDDL files for testing
- Run the script :
$ cd scripts/
$ python ipc.py "path_to_domain.pddl" "path_to_problem.pddl" "path_to_desired_output_file"
The output file will show the path with a list of state, the path with a list of action and the metrics proposed by IPC2018.
If using the jupyddl pip package:
- If you want to use the data analysis tool, create a pddl-examples folder with pddl instances subfolders containing "problem.pddl" and "domain.pddl". (refer to APLA-Toolbox/pddl-examples)
If you want to use it by cloning the project:
$ git clone https://github.com/APLA-Toolbox/PythonPDDL
$ cd PythonPDDL
$ python3 -m pip install -r requirements.txt
$ git submodule update --init
You should have a pddl-examples
folder containing PDDL instances.
from jupyddl import AutomatedPlanner # takes some time because it has to instantiate the Julia interface
apl = AutomatedPlanner("pddl-examples/dinner/domain.pddl", "pddl-examples/dinner/problem.pddl)
apl.available_heuristics
["basic/zero", "basic/goal_count", "delete_relaxation/h_max", "delete_relaxation/h_add"]
apl.initial_state
<PyCall.jlwrap PDDL.State(Set(Julog.Term[row(r1), column(c3), row(r3), row(r2), column(c2), column(c1)]), Set(Julog.Term[white(r2, c1), white(r1, c2), white(r3, c2), white(r2, c3)]), Dict{Symbol,Any}())>
actions = apl.available_actions(apl.initial_state)
[<PyCall.jlwrap flip_row(r1)>, <PyCall.jlwrap flip_row(r3)>, <PyCall.jlwrap flip_row(r2)>, <PyCall.jlwrap flip_column(c3)>, <PyCall.jlwrap flip_column(c2)>, <PyCall.jlwrap flip_column(c1)>]
apl.satisfies(apl.problem.goal, apl.initial_state)
False
apl.transition(apl.initial_state, actions[0])
<PyCall.jlwrap PDDL.State(Set(Julog.Term[row(r1), column(c3), row(r3), row(r2), column(c2), column(c1)]), Set(Julog.Term[white(r2, c1), white(r1, c1), white(r3, c2), white(r2, c3), white(r1, c3)]), Dict{Symbol,Any}())>
path = apl.breadth_first_search() # computes path ([]State) with BFS
print(apl.get_state_def_from_path(path))
[<PyCall.jlwrap PDDL.State(Set(Julog.Term[row(r1), column(c3), row(r3), row(r2), column(c2), column(c1)]), Set(Julog.Term[white(r2, c1), white(r1, c1), white(r3, c2), white(r2, c3), white(r1, c3)]), Dict{Symbol,Any}())>, <PyCall.jlwrap PDDL.State(Set(Julog.Term[row(r1), column(c3), row(r3), row(r2), column(c2), column(c1)]), Set(Julog.Term[white(r2, c1), white(r1, c1), white(r2, c3), white(r1, c3), white(r3, c3), white(r3, c1)]), Dict{Symbol,Any}())>, <PyCall.jlwrap PDDL.State(Set(Julog.Term[row(r1), column(c3), row(r3), row(r2), column(c2), column(c1)]), Set(Julog.Term[white(r2, c1), white(r1, c1), white(r1, c2), white(r3, c2), white(r2, c3), white(r1, c3), white(r3, c3), white(r3, c1), white(r2, c2)]), Dict{Symbol,Any}())>]
print(apl.get_actions_from_path(path))
[<PyCall.jlwrap flip_row(r1)>, <PyCall.jlwrap flip_row(r3)>, <PyCall.jlwrap flip_column(c2)>]
Make sure you have a pddl-examples folder where you run your environment that contains independent folders with "domain.pddl" and "problem.pddl" files, with those standard names. ( if you didn't generate with git submodule update )
from jupyddl import DataAnalyst
da = DataAnalyst()
da.plot_astar() # plots complexity statistics for all the problem.pddl/domain.pddl couples in the pddl-examples/ folder
da.plot_astar(problem="pddl-examples/dinner/problem.pddl", domain="pddl-examples/dinner/domain.pddl") # scatter complexity statistics for the provided pddl
da.plot_astar(heuristic_key="basic/zero") # use h=0 instead of goal_count for your computation
da.plot_dfs() # same as astar
da.comparative_data_plot() # Run all planners on the pddl-examples folder and plots them on the same figure, data is stored in a data.json file
da.comparative_data_plot(astar=False) # Exclude astar from the comparative plot
da.comparative_data_plot(heuristic_key="basic/zero") # use zero heuristic for h based planners
da.comparative_data_plot(collect_new_data=False) # uses data.json to plot the data
da.comparative_astar_heuristic_plot() # compare results of astar with all available heuristics
If you use the project in your work, please consider citing it with:
@misc{https://doi.org/10.13140/rg.2.2.22418.89282,
doi = {10.13140/RG.2.2.22418.89282},
url = {http://rgdoi.net/10.13140/RG.2.2.22418.89282},
author = {Erwin Lejeune},
language = {en},
title = {Jupyddl, an extensible python library for PDDL planning and parsing},
publisher = {Unpublished},
year = {2021}
}
List of publications & preprints using jupyddl
(please open a pull request to add missing entries):
- name (month year)
Please see docs/CONTRIBUTING.md
for more details on contributing!
- Erwin Lejeune
- Sampreet Sarkar