SymbolicPlanners.jl
A library of symbolic planners for problems and domains specified in the Planning Domain Definition Language (PDDL) and its variants. Built on top of the PDDL.jl interface for automated planning.
Features
- Forward state-space planning (A*, BFS, etc.)
- Backward (i.e. regression) planning
- Policy-based planning (RTDP, RTHS, MCTS, etc.)
- Relaxed-distance heuristics (Manhattan, $h_\text{max}$, $h_\text{add}$, FF, etc.)
- Policy and plan simulation
- Modular framework for goal, reward and cost specifications
- Support for PDDL domains with numeric fluents and custom datatypes
Installation
Make sure PDDL.jl is installed. (See here for more instructions.)
For the stable version of SymbolicPlanners.jl, press ]
to enter the Julia package manager REPL, then run:
add SymbolicPlanners
For the latest development version, run:
add https://github.com/JuliaPlanners/SymbolicPlanners.jl
Usage
First, load a planning domain and problem using PDDL.jl. These can be loaded from local files, or from the PlanningDomains.jl online repository:
using PDDL, PlanningDomains, SymbolicPlanners
# Load Blocksworld domain and problem
domain = load_domain(:blocksworld)
problem = load_problem(:blocksworld, "problem-4")
Next, construct a Planner
, including a search Heuristic
if supported, and call it on the domain and problem:
# Construct A* planner with h_add heuristic
planner = AStarPlanner(HAdd())
# Solve the problem using the planner
sol = planner(domain, problem)
Alternatively, we can provide planners with the initial state, and a Specification
defining the goal predicates, action costs, and other desired criteria for the planning solution:
# Construct initial state from domain and problem
state = initstate(domain, problem)
# Construct goal specification that requires minimizing plan length
spec = MinStepsGoal(PDDL.get_goal(problem))
# Produce a solution given the initial state and specification
sol = planner(domain, state, spec)
A* search produces an ordered plan as a Solution
, which we can inspect and validate:
julia> sol
PathSearchSolution{GenericState, Nothing}
status: success
plan: 10-element Vector{Term}
(unstack b a)
(put-down b)
(unstack a d)
(stack a e)
(pick-up b)
(stack b a)
(pick-up c)
(stack c b)
(pick-up d)
(stack d c)
trajectory: 11-element Vector{GenericState}
julia> PDDL.satisfy(domain, sol.trajectory[end], PDDL.get_goal(problem))
true
We can also validate the solution by using a Simulator
to determine the final state:
julia> sim = EndStateSimulator(max_steps=100);
julia> end_state = sim(sol, domain, state, spec);
julia> PDDL.satisfy(domain, end_state, PDDL.get_goal(problem))
true