Parser and Writer

PDDL.jl supports both parsing and writing of PDDL files and strings. In addition, the parser is designed to be extensible, allowing variants or extensions of PDDL to be easily supported.

General Parsing

The PDDL.Parser submodule contains all functionality related to parsing PDDL strings and loading of PDDL files. To parse a string in PDDL, use the macro @pddl or the function parse_pddl. Both of these return a list of parsed results if multiple strings are provided.

PDDL.Parser.@pddlMacro
@pddl(strs...)

Parse string(s) to PDDL construct(s).

When parsing PDDL formulae, the variable x can be interpolated into the string using the syntax \$x. For example, @pddl("(on \$x \$y)") will parse to Compound(:on, Term[x, y]) if x and y are Terms.

Julia expressions can be interpolated by surrounding the expression with curly braces, i.e. \${...}.

source

Below we use @pddl to parse a sequence of predicates, and use parse_pddl to parse a PDDL axiom (a.k.a. derived predicate):

julia> @pddl("(on a b)", "(on b c)")
2-element Vector{Compound}:
 on(a, b)
 on(b, c)
julia> parse_pddl("(:derived (handempty) (forall (?x) (not (holding ?x))))")
handempty <<= forall(object(X), not(holding(X)))

In addition, there exists a string macro pddl"...", which is useful for parsing single string literals:

julia> pddl"(on a b)"
on(a, b)
PDDL.Parser.@pddl_strMacro
pddl"..."

Parse string "..." to PDDL construct.

When parsing PDDL formulae, the variable x can be interpolated into the string using the syntax $x. For example, pddl"(on $x $y)" will parse to Compound(:on, Term[x, y]) if x and y are Terms.

Julia expressions can be interpolated by surrounding the expression with curly braces, i.e. ${...}.

source

Interpolation

The string macro pddl"... (as well as the @pddl macro) supports the interpolation of Julia variables using the $ operator when parsing PDDL formulae. This makes it easier to construct predicates or expressions with a fixed structure but variable contents:

obj = Const(:a)
sym = :b
pddl"(on $obj $sym)"
# Parses to the same value as pddl"(on a b)"

fname = :on
pddl"($fname a b)"
# Also parses to pddl"(on a b)"

var = pddl"(?x)"
type = :block
pddl"(forall ($var - $type) (on-table $var))"
# Parses to pddl"(forall (?x - block) (on-table ?x))"

It is also possible to interpolate entire Julia expressions by surrounding the expression in curly braces (note that the expression itself must not contain any curly braces):

pddl"(= cost ${1 + 2})"     # Parses to pddl"(= cost 3)"
pddl"(= cost ${zero(Int)})" # Parses to pddl"(= cost 0)"

Interpolation is not supported when parsing larger PDDL constructs, such as actions, domains, and problems.

Parsing Domains and Problems

To parse domains and problems specified as PDDL strings, use parse_domain and parse_problem.

To load domains or problems from a file, use load_domain and load_problem.

PDDL.Parser.load_domainFunction
load_domain(path::AbstractString)
load_domain(io::IO)

Load PDDL domain from specified path or IO object.

source

Extending the Parser

The parser can be extended to handle new PDDL constructs using the following macros:

General Writing

The PDDL.Writer submodule contains all functionality related to writing PDDL strings and saving of PDDL files. To write a string in PDDL syntax, use the function write_pddl.

Below we use write_pddl to write out an Action from the Blocksworld domain.

julia> write_pddl(PDDL.get_action(domain, :stack)) |> print
(:action stack
 :parameters (?x ?y - block)
 :precondition (and (holding ?x) (clear ?y) (not (= ?x ?y)))
 :effect (and (not (holding ?x)) (not (clear ?y)) (clear ?x) (handempty) (on ?x ?y)))

Writing Domains and Problems

To write domains and problem as PDDL strings, use write_domain and write_problem.

To save domains or problems as text files to a path, use save_domain and save_problem.