/!\ This page unfortunately never made it beyond preliminary stage. Some details of the temporal semantics of object fluents still need to be worked out, and the use of "unknown" values below needs further thought.

Changes in PDDL 3.1

Executive summary: PDDL 3.1 introduces state variables which are neither binary (true/false) nor numeric (real-valued), but instead map to a finite domain. This is achieved by adding object fluents to the language, which are analogous to the numeric fluents introduced in PDDL 2.1. Where numeric fluents map a tuple of objects to a number, object fluents map a tuple of objects to an object of the problem.

In addition to what is described here, PDDL 3.1 also introduces a new requirement for specifying numeric action costs in language fragments that don't normally permit numerical features of the language. This new requirement is described on a separate page on action costs.

Illustrative example

/!\ If someone could provide an illustrative example here, that would be nice... :-)

Examples for download

The PDDL 3.1 examples (ZIP) archive contains examples for the following planning domains:

For each domain, four files are included:

The Functional STRIPS in PDDL 3.1 examples (tar.gz) archive contains PDDL3.1 encodings of four of the reformulations of standard planning domains in Hector Geffner's "Functional Strips" paper (see the PDDL resources page). Note: Each example has the domain and problems (and in some cases even a plan) in one file.


Grammar changes

Here, we describe the changes to the PDDL grammar in some technical detail. We do not provide formal semantics for the changed language yet, and hope that the discussion on this page is sufficiently clear. If anything is unclear, please ask!

We describe the changes relative to the "BNF Description of PDDL3.0" by Gerevini and Long, which can be found on the PDDL resources page.

Changes to prerequisites

PDDL 3.1 introduces two new "requirements" for the :requirements stanza of PDDL domain files and modifies the meaning of one existing requirement. In detail:

Note that the changed meaning of :fluents do not make old PDDL specifications invalid, since the features activated by :fluents in PDDL 3.1 subsume those activated in PDDL 3.0. We feel that with the introduction of non-numeric fluents, it is no longer appropriate to use a requirement spelled :fluents to refer to numeric fluents exclusively.

For similar reasons, we ask domain designers to no longer rely on the fact that fluents specified in a :functions stanza are numeric by default. Omitting the type of a fluent in a :functions declaration is now deprecated. Under the old semantics, the stanzas


are equivalent. This remains true, but the second form is now strongly preferred to allow distinguishing object and numeric fluents more easily. (Of course, as everywhere within PDDL, it is sufficient to provide the type once, at the end of the :functions list. Repeating the type for each fluent may be clearer, though.)

Due to the overlap in syntax between numeric fluents and object fluents, some of the productions in the PDDL 3.0 grammar that used to be available under the :fluents requirement are now available under either of the :numeric-fluents or :object-fluents requirements. Others are only available under the :numeric-fluents requirement (for example, the number type or the productions for f-exp). These should all be intuitively clear, so we do not discuss these changes here in detail.

Declaring object fluents

If the :object-fluents requirement is used (either directly or implied by the :fluents requirement), the domain and problem specification may make use of object fluents. These are introduced in the :functions stanza along with numeric fluents. Formally, this is achieved by changing the definitions of the <function typed list (x)> and <function type> grammar symbols. In PDDL 3.0, these are defined as follows:

<function typed list (x)> ::= x*
<function typed list (x)> ::= x+ - <function type> <function typed list (x)>
<function type> ::= number

where the second production is only available with the :typing requirement. We change this in three ways:

  1. Fluents can now be of an object type, i.e. have the type object. If :typing is available, any legal PDDL <type> may be used instead of object (for example location or (either location vehicle)).

  2. The grammar now allows basic type annotation (number or object) unconditionally, even without the :typing requirement. (This is necessary to distinguish numeric from object fluents.)

  3. Declaring fluents to implicitly be of type number is now deprecated.

This is achieved by replacing the above productions with the following ones:

<function typed list (x)> ::= x+ - <function type> <function typed list (x)>
<function typed list (x)> ::=
<function typed list (x)> ::= x+
<function type> ::= number
<function type> ::= object
<function type> ::= <type>

The first and second productions are available under either the :numeric-fluents or :object-fluents requirements. The third and fourth are only available under the :numeric-fluents requirement, and moreover the third is deprecated. The fifth and sixth are only available under the :object-fluents requirement, and the sixth additionally requires :typing.

Using object fluents in conditions

Object fluents are incorporated into the parts of the PDDL grammar that deal with conditions (e.g. preconditions or goal conditions) by introducing a new grammar symbol <function-term> and adding the following production rules:

<term> ::= <function-term>
<function-term> ::= (<function-symbol> <term>*)

In the second production, the function symbol must be one of those declared in the :functions stanza and be of an object type (i.e., not of type number). The number of terms provided must match the arity of the object fluent.

Note that function terms can be nested, and that by the first production they may be used wherever other terms (constants and variables) may be used. In particular, if the :equality requirement is specified, they may be used in conditions of the form (= <term> <term>).

Effects on object fluents

To allow operator effects to change the value of an object fluent, the following productions are added for the <p-effect> grammar symbol:

<p-effect> ::= (assign <function-term> <term>)
<p-effect> ::= (assign <function-term> undefined)

These are analogous to assignments to numeric fluents in PDDL 3.0 and should require no further explanation. Just like numeric fluents, object fluents can have an undefined value. Unlike numeric fluents, which may start being undefined but never become undefined again once a value has been assigned, the value undefined may be explicitly assigned to function terms. This is mostly useful for temporal planning. A durative action that moves object o from location from-loc to location to-loc may set location(o) to undefined at the start and to to-loc at the end. This ensures that other actions requiring o to be at from-loc or to-loc cannot be used during the movement. Note that undefined is not a term, so it cannot be referred to in conditions.

Initial values for object fluents

Like numeric fluents, object fluents are initially undefined unless explicitly initialized. To allow their initialization, a new grammar symbol <basic-function-term> and three productions are added to the grammar:

<basic-function-term> ::= (<function-symbol> <name>*)
<basic-function-term> ::= <function-symbol>
<init-el> ::= (= <basic-function-term> <name>)

A <basic-function-term> is analogous to a <function-term> as defined above, and the same comments apply: the function symbol must be properly defined, and arities must match. Unlike general function terms, a basic function term does not include variable symbols or allow nesting. The production added to <init-el> is similar to that for numerical fluents and should require no further explanation.


Drew McDermott was the first to suggest that "multi-valued state variables", as they were called at that time, could be added to the language by extending the existing mechanism for numeric state variables.

The original design goal for PDDL 3.1 was to enrich the language with SAS+-like problem representations, which have become very popular in the years leading up to IPC-2008. However, SAS+ only allows using functional fluents in very limited ways (no nesting; only comparison to constants and assignments to constants). The much more elegant solution of allowing functional fluents wherever the PDDL grammar calls for a term is largely inspired by the "Functional Strips" formalism introduced by H├ęctor Geffner (see the PDDL resources page).

Maria Fox and Derek Long explicitly designed the :functions stanza in PDDL 2.1 with future extensions to non-numeric fluents in mind, which greatly helped with integrating object fluents into the grammar in a clean fashion.

PddlExtension (last edited 2011-09-12 15:24:49 by PatrikHaslum)