Skip to content

Rewrite jupyddl as a pure-Python PDDL planning framework (remove Julia)#148

Draft
guilyx wants to merge 5 commits into
mainfrom
cursor/native-pddl-framework-1f2e
Draft

Rewrite jupyddl as a pure-Python PDDL planning framework (remove Julia)#148
guilyx wants to merge 5 commits into
mainfrom
cursor/native-pddl-framework-1f2e

Conversation

@guilyx

@guilyx guilyx commented Jul 1, 2026

Copy link
Copy Markdown
Member

Overview

Removes the Julia / PDDL.jl / PyCall / pyjulia dependency entirely and rewrites jupyddl from scratch as a pure-Python, zero-runtime-dependency planning framework: a hand-written PDDL parser + grounder, a suite of planners (classical → SOTA), a family of heuristics, a benchmarking harness, and a CLI — with a comprehensive test suite.

What's included

Parser (jupyddl/parser/) — tokenizer, AST and recursive-descent parser for STRIPS, :typing (with hierarchy), :negative-preconditions, :equality, :action-costs ((increase (total-cost) k)), universally-quantified goals, and forall/when conditional effects. Numeric fluents beyond total-cost are rejected with a clear UnsupportedFeatureError.

Grounding (jupyddl/grounding.py, task.py) — type-aware instantiation, static-predicate pruning, positive-normal-form compilation of negative preconditions/goals, object harvesting for undeclared constants, and conditional/quantified effect expansion into an integer-encoded grounded Task.

Planners (jupyddl/search/)bfs, dfs, iddfs, dijkstra, gbfs, astar, wastar, idastar, ehc (enforced hill climbing), on a shared best-first engine, behind a registry.

Heuristics (jupyddl/heuristics/)blind, goalcount, hmax, hadd, hff (FF relaxed plan), critical-path h^m (h1/h2), and LM-cut, behind a registry.

Framework glue — high-level API (solve, build_task, solve_task, validate_plan), a benchmarking harness (jupyddl/benchmark.py, CSV + plots) and a CLI (jupyddl solve / jupyddl benchmark).

Packaging — migrated to pyproject.toml (hatchling, uv); core has no runtime dependencies (matplotlib is an optional viz extra). CI reworked to a pure-Python matrix (3.9–3.12), no Julia.

Correctness highlights

  • Optimal planners (bfs, dijkstra, astar/idastar with an admissible heuristic) agree on optimal cost on every solvable example; every planner returns a validated plan.
  • Admissible heuristics (blind, hmax, h1, h2, lmcut) never overestimate on STRIPS instances; h1 == hmax; lmcut >= hmax.
  • dinner (op2(a,a,c)) and flip (3 flips) reproduce the previous Julia implementation's plans.

Known scope notes

  • On conditional-effect domains (flip), the delete-relaxation heuristics (hadd/hff/lmcut/h^m) are satisficing only (not guaranteed admissible), since each conditional effect is relaxed into its own operator. Use bfs/dijkstra or astar/idastar with blind for guaranteed-optimal plans there. This matches how tools like Fast Downward restrict LM-cut to STRIPS.
  • Example-data quirks (external submodule, unchanged): grid is numeric (unsupported); vehicle has typos (struck/truck, acessible) making its goal unreachable. Both are handled gracefully.

Testing

  • pytest --cov=jupyddl — 92 passed, ~92% coverage
  • flake8 jupyddl tests — clean (config in .flake8)
  • jupyddl solve and jupyddl benchmark CLIs

Demos

CLI solve (optimal A*+LM-cut on tsp, and A*+blind on the conditional-effect flip):
cli_solve_demo.txt

Comparative benchmark across planners (node expansions; informed search expands far fewer nodes):
Planner comparison (expanded nodes)

Full per-run benchmark CSV:
benchmark_results.csv

Notes

AGENTS.md documents the new pure-Python environment and the non-obvious scope notes above.

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 5 commits July 1, 2026 21:53
…nts.txt

Co-authored-by: Erwin L. <guilyx@users.noreply.github.com>
Remove the Julia/PDDL.jl/PyCall integration and reimplement from scratch:
- parser/: hand-written tokenizer, AST and recursive-descent PDDL parser
- grounding.py + task.py: grounder (typing, static pruning, positive normal
  form for negative preconditions, forall/when conditional effects) and a
  grounded STRIPS task representation
- search/: BFS, DFS, iterative deepening, Dijkstra, greedy best-first, A*,
  weighted A*, IDA*, enforced hill climbing + shared best-first engine
- heuristics/: blind, goal-count, h_max, h_add, FF, critical-path h^m, LM-cut
- api.py, cli.py, benchmark.py: high-level API, CLI and benchmarking harness

Co-authored-by: Erwin L. <guilyx@users.noreply.github.com>
Covers parsing, grounding, search optimality/completeness, heuristic
admissibility and dominance, the high-level API, the benchmark harness and the
CLI (92 tests, ~92% coverage).

Co-authored-by: Erwin L. <guilyx@users.noreply.github.com>
…amework

Co-authored-by: Erwin L. <guilyx@users.noreply.github.com>
Co-authored-by: Erwin L. <guilyx@users.noreply.github.com>
@mergify

mergify Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

This pull request is now in conflicts. Could you fix it @guilyx? 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants