Code Monkey home page Code Monkey logo

pythonpddl's Introduction

Logo

Python PDDL

✨ A Python wrapper using JuliaPy for the PDDL.jl parser package and implementing its own planners. ✨

tests build codecov CodeFactor Percentage of issues still open GitHub license GitHub contributors PipPerMonths Pip version fury.io

Report Bug Β· Request Feature

Loved the project? Please consider donating to help it improve!

Features 🌱

  • ✨ 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...)

Docker πŸ‹

You can also use the project in a docker container using docker-pythonpddl

Install πŸ’Ύ

  • 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

IPC Script βš”οΈ

  • 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.

Basic Usage πŸ“‘

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.

AutomatedPlanner Class πŸ—ΊοΈ

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)>]

DataAnalyst (more like Viz) Class πŸ“ˆ

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

Cite πŸ“°

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):

Contribute πŸ†˜

Please see docs/CONTRIBUTING.md for more details on contributing!

Maintainers Ⓜ️

  • Erwin Lejeune
  • Sampreet Sarkar

pythonpddl's People

Contributors

guilyx avatar mergify[bot] avatar renovate-bot avatar renovate[bot] avatar sampreets3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

pythonpddl's Issues

Add DFS

  • Respect case and PEP20/PEP8 (variables_names_like_this), no short vars names
  • Install the black formatter and run black .
  • Implement DFS

Increase performance by hashing states

As of now, every time we want to open a state we:

  • Check the available actions from the parent state
  • Apply an action on the parent state to get a child state

This is quite expensive computationally. A way to reduce those costs is to hash the actions available with the same hash as a state using __hash so that we only have to get it from a dict if we already did an action on the same state.

Same goes for the computation of a child state. If we do action x on parent y again, we should be able to retrieve the child state way faster than before.

Add Dijkstra

Will be implemented having A* in mind (A* with H=0)

Guidelines

Hey there and thank you for using Issue Tracker!

Do the checklist before filing an issue:

  • Is this something you can debug and fix? Send a pull request! Bug fixes and documentation fixes are welcome.
  • Have an idea for a feature? Post the feature request on Product Pains. It has a voting system to surface the important issues. GitHub issues should only be used for bugs.
  • Usage question ? The Issue Template will be available soon.

None of the above, create a bug report

Make sure to add all the information needed to understand the bug so that someone can help. If the info is missing we'll add the 'Needs more information' label and close the issue until there is enough information.

Increase performance

I think I figured out why the Julia API calls take time.
The first time they're called, they're initialized ! and when they're called again afterwards, they're ok !

I will try to run them at least once in the constructor and see if it improves the times on first execution

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v2
  • actions/setup-python v3
  • actions/checkout v2.4.0
  • julia-actions/setup-julia v1
  • snickerbockers/submodules-init v4
.github/workflows/format.yml
  • actions/checkout v2
  • actions/checkout v2
  • actions/setup-python v3
  • stefanzweifel/git-auto-commit-action v4.14.0
.github/workflows/tests.yml
  • actions/checkout v2
  • actions/setup-python v3
  • actions/checkout v2.4.0
  • julia-actions/setup-julia v1
  • snickerbockers/submodules-init v4
  • actions/checkout v2
  • actions/setup-python v3
  • actions/checkout v2.4.0
  • julia-actions/setup-julia v1
  • snickerbockers/submodules-init v4
  • codecov/codecov-action v2
pip_requirements
requirements.txt
  • julia ==0.5.7
  • coloredlogs ==15.0.1
  • matplotlib ==3.5.1

  • Check this box to trigger a request for Renovate to run again on this repository

Improve coverage

Every method implemented must be tested to reach 100% coverage.

Format Actions hides the actual CI

The CI shows it has passed with 2 checks when the format commit is applied. We will move formatting to a commit to main when a MR is merged

Package the output into a more readable format

The current output of the planning problem is difficult to interpret for someone who does not know what to look for. For example, the current solution provided is something like the following:

[(<PyCall.jlwrap flip_row(r1)>, 1), (<PyCall.jlwrap flip_row(r3)>, 1), (<PyCall.jlwrap flip_column(c2)>, 1)]
Computation time: 18.53

It would be more preferable to have the output in a much simpler fashion, something like :

flip_row(r1), 1
flip_row(r3), 1
flip_row(c2), 1

I think this might be easily achieved by storing the output and trimming off the unnecessary bits, but we'll see about that during implementation.

Relaxed Critical Path H^n for n > 1

Only computes single facts as of now (hardcoded in the julia utils we added)
Need to write Julia functions to compute costs to tuple/truple/etc..; of facts

Try catch when using DRH

Describe the bug
On some domains, delete relaxation either run indefinitely at a fixed point or breaks completely the code

To Reproduce
Run the DataAnalyst.plot_astar_comparison method

Expected behavior
It will hold on some domains, exit with failure on others

Integrate tests for planners

  • python3 -m pip install pytest
  • Add test_${NAME_OF_PLANNER}
  • Test different things on the methods/search results, whatever, even if it's as dumb as len(path) > 0
  • Run pytest and make them pass

Improve API

  • Make the projects more easy to use in REFL mode
  • Keep in mind this will be installed using pip
  • The main.py should not run everything automatically, add more arguments

In DFS, visited = path

In DFS, the visited list is the path
But we return the last node and then do a traceback from parent to child like with other planners
I'm not sure it works

Maybe we should return a path, computation_time, opened_nodes for DFS instead

Investigate if it breaks or not functions that call it (but it shouldn't since only AutomatedPlanner calls dfs.search() directly

We have:

if self.automated_planner.satisfies(self.automated_planner.problem.goal, current_node.state):
       computation_time = now() - time_start
       self.automated_planner.logger.debug( "Search finished at: " + str(timestamp.now()))
       return current_node, computation_time, opened_nodes
return None, computation_time, opened_nodes
def depth_first_search(self):
    dfs = DepthFirstSearch(self)
    last_node, total_time, opened_nodes = dfs.search()
    path = self.__retrace_path(last_node)
    return path, total_time, opened_nodes

We should have:

if self.automated_planner.satisfies(self.automated_planner.problem.goal, current_node.state):
       computation_time = now() - time_start
       self.automated_planner.logger.debug( "Search finished at: " + str(timestamp.now()))
       return self.visited, computation_time, opened_nodes
return [], computation_time, opened_nodes
def depth_first_search(self):
dfs = DepthFirstSearch(self)
path, total_time, opened_nodes = dfs.search()
return path, total_time, opened_nodes

Use logger instead of prints

import logging
logging.basicConfig(filename='app.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
logging.error('And non-ASCII stuff, too, like Øresund and Malmâ')
  • Add app.log to gitignore
  • Replace info prints by logging.info
  • Replace non critical failures by logging.debug (ex: when no path is found)
  • Add error logging on critical failures (not sure yet if there should be any)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.