Skip to content

PDDL Cheatsheet

Francesco Ganci edited this page Jun 26, 2022 · 11 revisions

Some general remarks

  • Closed World Assumption : any predicate not explicitly stated as true is false. This means that each predicate is false when "instanced" at the beginning of the program.

PDDL domain file template

🔗 see planning.wiki, a awesome resource for learning what is needed to deal with PDDL.

classical PDDL

(define (domain ???)

(:requirements :strips :adl :typing)

(:types
;; o1 o2 o3 - type/object
)

(:predicates 
;; (predicate-name ... ?pi1 ?pi2 ?pi3 - type ...)
)

;; === ACTIONS === ;;

(:action ???action_name???
	:parameters ( ???list_of_the_params??? )
	:precondition (and 
		;; trivial checkings
		
		;; other checkings
	)
	:effect (and 
		;; NEGATIVE EFFECTS -- make them false
		;; (not (predicate ...))

		;; AFFERMATIVE -- make them true
		;; (predicate ...)
	)
)

)

PDDL+ domain file

(define (domain ???)

(:requirements :strips :adl :typing :time)

(:types
;; o1 o2 o3 - type/object
)

(:predicates 
;; (predicate-name ... ?pi1 ?pi2 ?pi3 - type ...)
)

(:functions
;; (fluent-name ?p1 ?p2 ...)
;; even with typing
)

;; === ACTIONS === ;;

(:action ???action_name???
	:parameters ( ???list_of_the_params??? )
	:precondition (and 
		;; trivial checkings
		
		;; other checkings
	)
	:effect (and 
		;; NEGATIVE EFFECTS -- make them false
		;; (not (predicate ...))

		;; AFFERMATIVE -- make them true
		;; (predicate ...)
	)
)

;; === PROCESSES === ;;

(:process ???process name???
    :parameters (<params>)
    :precondition (and
        <predicates -- activation conditions>
    )
    :effect (and
        <updates frame by frame (remember #t)>
    )
)

;; === EVENTS === ;;

(:process ???process name???
    :parameters (<params>)
    :precondition (and
        <predicates -- trigger conditions>
    )
    :effect (and
        <predicates -- effect>
    )
)

)

PDDL Requirements

Classical requirements

🔗 see also planning.wiki requirements for classical PDDL

(:requirements :strips :adl :typing)

PDDL2.1 requirements

🔗 see also planning.wiki requirements for PDDL2.1

;; the complete set
(:requirements strips :adl :typing :durative-actions :fluents :duration-inequalities)

;; the minimal set
(:requirements :durative-actions :fluents :duration-inequalities)

PDDL+ requirements

🔗 see also planning.wiki PDDL+, in partiular the examples.

;; complete 
(:requirements :strips :adl :typing :time)

;; minimal
(:requirements :time :typing)

PDDL types

🔗 see also Object Types on planning.wiki

;; === DOMAIN FILE ===

;; types declaration
(:types
    site material - object
    bricks cables windows - material
)

;; using types in predicates (see also listing and other syntactic variants)
;;    valid also with fluents
(material-used ?m - material)

;; using types in actions, processes and events
(:action MOVE-MATERIAL
    :parameters (?s1 - site ?s2 - site ?m -material)
    ...
)

;; === PROBLEM FILE ===

;; using types in objects instances (with variants)
(:objects
	s1 - site
	b - bricks
	w - windows
	c - cables
)

PDDL predicates

☝️ Closed World Assumption : any predicate not explicitly stated as true is false. This means that each predicate is false when "instanced" at the beginning of the program.

how to define predicates

In domain file:

;; syntax
(:predicates
    (<predicate_name> <argument_1> ... <argument_n>)
)

;; a simple example
(:objects
obj1 obj2
obj3 ob3a - object
obj4 - type-my

obj5
)

;; an example
(:predicates
    (walls-built ?s - site)
    (windows-fitted ?s - site)
    (foundations-set ?s - site)
    (cables-installed ?s - site)
    (site-built ?s - site)
    (on-site ?m - material ?s - site)
    (material-used ?m - material)
)

logical expressions

;; and
(and (...) (...) (...))

;; or
(or (...) (...) (...))

;; not (your planner could not support it)
(not (...))

PDDL2.1 fluents

Define fluents

(:functions
    (<variable_name> <parameter_name> - <object_type>)
    ...
    (<variable_name> <parameter_name> - <object_type>)
)

;; some example
(:functions
    (distance ?wp1 - waypoint ?wp2 - waypoint)
)
(:functions
    (battery-level ?r - rover)
)

operations and expressions using Fluents

;; MAIN SYNTAX with <f1> <f2> fluents
(<op> <f1> <f2>)

;; simple operations (in actions)
(+ <f1> <f2>)
(- <f1> <f2>)
(* <f1> <f2>)
(/ <f1> <f2>)
;; increase decrease (in actions)
(increase <f1> <f2>)
(decrease <f1> <f2>)

;; comparisons (in preconditions and goals)
(< <f1> <f2>)
(<= <f1> <f2>)
(> <f1> <f2>)
(>= <f1> <f2>)
(= <f1> <f2>)

;; continuous effects
;;    use the symbol #t which is the frame time
;; for instance, (use them in actions)
(increase (fuel ?tank) #t)
(decrease (battery ?battery) (* 5 #t))

assigning fluents and init fluents

;; assignment (in actions, processes, events)
(assign <f1> <f2>)

;; init fluents (in (init ...) statement)
(= <f1> <f2>)

PDDL typing

How to define types

In the domain file:

;; syntax
(:types
    mytype1 
    mytype2
    ...
)

;; example
(:types
    site material - object
    bricks cables windows - material
)

How to use types in params and instances

;; in predicates, see the example
    (:predicates
        (walls-built ?s - site)
        (windows-fitted ?s - site)
        (foundations-set ?s - site)
        (cables-installed ?s - site)
        (site-built ?s - site)
        (on-site ?m - material ?s - site)
        (material-used ?m - material)
    )

;; in action definitions, see the example
    (:action BUILD-WALL
        :parameters (?s - site ?b - bricks)
        :precondition (and
            (on-site ?b ?s)
            (foundations-set ?s)
            (not (walls-built ?s))
            (not (material-used ?b))
        )
        :effect (and
            (walls-built ?s)
            (material-used ?b)
        )
        ; :expansion ;deprecated
    )

;; in fluents, see the example
    (:functions
        (battery-amount ?r - rover)
        (sample-amount ?r - rover)
        (recharge-rate ?r - rover)
        (battery-capacity)
        (sample-capacity)
        (distance-travelled)
    )

;; in objects, see the example
    (:objects
        s1 - site
        b - bricks
        w - windows
        c - cables
    )

PDDL actions

;; === SYNTAX
(:action <action_name>
    :parameters (<argument_1> ... <argument_n>)
    :precondition (<logical_expression>)
    :effect (<logical_expression>)
    ; :expansion
)

;; === classical PDDL example
    (:action BUILD-WALL
        :parameters (?s - site ?b - bricks)
        :precondition (and
            (on-site ?b ?s)
            (foundations-set ?s)
            (not (walls-built ?s))
            (not (material-used ?b))
        )
        :effect (and
            (walls-built ?s)
            (material-used ?b)
        )
        ; :expansion ;deprecated
    )

;; === PDDL+ and PDDL2.1 example
    ;; action to serve the cookie to the client OOG
    (:action serve-cookie-OOG
        :parameters (?who - client ?w - waiter ?p - position)
        :precondition (and
            (waiter-OOG-mode ?w)
            (waiter-gripper-carry ?w)
            (cookie-to ?who)
            (waiter-client ?w ?who)
            (pos-is-table ?p)
            (waiter-at ?w ?p)
            (client-at-table ?who ?p)
        )
        :effect (and
            (not(cookie-to ?who))
            (not (waiter-gripper-carry ?w)) (waiter-gripper-empty ?w)
            (not (waiter-client ?w ?who))
            (client-served ?who)
            (assign (client-drinking-progress ?who) 4)
        )
    )

PDDL2.1 durative actions

Overall structure

(:durative-action <action_name>
    :parameters (<arguments>)
    :duration (= ?duration <duration_number>)
    :condition (logical_expression)
    :effect (logical_expression)
)

New statements and expressions

🔗 see also :condition from planning.wiki

;; === :duration statement === ;;
;; action duration (<f> for a fluent or an expression involving fluents)
:duration (= ?duration <f>)

;; for example (also a numeric literal works well)
:duration (= ?duration 10)


;; === :condition statement === ;;
;; START -- the condition must be true at the start of the 
;;    action in order for the action to be applied
(at start (at ?rover ?from-waypoint))

;; END -- the condition must be true at the end of the action 
;;    in order for the action to be applied
(at end (>= (battery-amount ?rover) 0))

;; OVER ALL -- the condition must be true throughout the action, 
;;    including at the start and end
(over all (can-move ?from-waypoint ?to-waypoint))


;; === :effect statement === ;;
;; the durative action can specify when to apply the effect
;; for example,
:effect
    (and
        (at start (not (at ?rover ?from-waypoint)))
        (at start (decrease (battery-amount ?rover) 8))
        (at end (at ?rover ?to-waypoint))
        (at end (been-at ?rover ?to-waypoint)))

PDDL+ processes

🔗 see processes on planning.wiki

syntax identical to the one seen for the actions:

(:process FALLING
    :parameters (?b - ball)
    :precondition (and
        (not (held ?b))
        (< (velocity ?b) 100)
    )
    :effect (and
        (increase (velocity ?b) (* #t 9.8))
        (decrease (distance-to-floor ?b) (* #t (velocity ?b)))
    )
)

PDDL+ events

🔗 see Events on Planning.wiki

syntax identical to the one seen for the actions:

(:event HIT-GROUND
    :parameters (?b - ball)
    :precondition (and
        (not (held ?b))
        (<= (distance-to-floor ?b) 0)
        (> (velocity ?b) 0)
    )
    :effect (
        (assign (velocity ?b) (* -0.8 (velocity ?b)))
    )
)

PDDL -- problem statement

PDDL problem file template

☝️ delete (:metric ...) if you're not dealing with PDDL2.1

☝️ remember to replace ???

(define
(problem ???)
(:domain ???)

(:objects
;; simple: obj (subsumed type object)
;; simple with type: obj - type 
;; list: o1 o2 o3
;; list with type: o1 o2 o3 - type
)

(:init
;; fluents:    (= (battery-amount r1) 100)
;; predicates: (on-site building site1)
)

(:goal (and
;; fluents:    (= (battery-amount r1) 100) or other comparisons
;; predicates: (on-site building site1)
))

;; metrics available: maximize, minimze
(:metric maximize 
;; an expression involving fluents: +, -, *, /, one fluent fluent
)

)

PDDL2.1 -- optimization metrics

☝️ this is not a goal, but a optimization instead: the planner will do the best to keep the given quantity minimized or maximized depending on the metric.

☝️ only one statement (metric ...) for each problem file! If you want to optimize two fluents, you should create a measure involving both to minimize or maximize. Not possible to optimize both separately.

;; try to minimize something
(:metric minimize (<numeric_operation> ...))

;; try to maximize something
(:metric maximize (<numeric_operation> ...))

Examples

⚠️ examples provided just to taste the flavour of PDDL; probably they won't work. Use then just for a practical syntax "memo".

classical PDDL -- construction

Domain file

(define
    (domain construction)
    (:extends building)
    (:requirements :strips :typing)
    (:types
        site material - object
        bricks cables windows - material
    )
    (:constants mainsite - site)

    ;(:domain-variables ) ;deprecated

    (:predicates
        (walls-built ?s - site)
        (windows-fitted ?s - site)
        (foundations-set ?s - site)
        (cables-installed ?s - site)
        (site-built ?s - site)
        (on-site ?m - material ?s - site)
        (material-used ?m - material)
    )

    (:timeless (foundations-set mainsite))

    ;(:safety
        ;(forall
        ;    (?s - site) (walls-built ?s)))
        ;deprecated

    (:action BUILD-WALL
        :parameters (?s - site ?b - bricks)
        :precondition (and
            (on-site ?b ?s)
            (foundations-set ?s)
            (not (walls-built ?s))
            (not (material-used ?b))
        )
        :effect (and
            (walls-built ?s)
            (material-used ?b)
        )
        ; :expansion ;deprecated
    )

    (:axiom
        :vars (?s - site)
        :context (and
            (walls-built ?s)
            (windows-fitted ?s)
            (cables-installed ?s)
        )
        :implies (site-built ?s)
    )

    ;Actions omitted for brevity
)

Problem File

(define
    (problem buildingahouse)
    (:domain construction)
    ;(:situation <situation_name>) ;deprecated
    (:objects
        s1 - site
        b - bricks
        w - windows
        c - cables
    )
    (:init
        (on-site b s1)
        (on-site c s1)
        (on-site w s1)
    )
    (:goal (and
            (walls-built ?s1)
            (cables-installed ?s1)
            (windows-fitted ?s1)
        )
    )
)

PDDL+ -- ballphysics

Domain file

(define
    (domain ballphysics)
    (:requirements :time :typing)
    (:types
        ball - object
    )
    (:predicates
        (held ?b - ball)
    )
    (:functions
        (velocity ?b - ball)
        (distance-to-floor ?b - ball)
    )
    (:process FALLING
        :parameters (?b - ball)
        :precondition (and
            (not (held ?b))
            (< (velocity ?b) 100)
        )
        :effect (and
            (increase (velocity ?b) (* #t 9.8))
            (decrease (distance-to-floor ?b) (* #t (velocity ?b)))
        )
    )
    (:event HIT-GROUND
        :parameters (?b - ball)
        :precondition (and
            (not (held ?b))
            (<= (distance-to-floor ?b) 0)
            (> (velocity ?b) 0)
        )
        :effect (
            (assign (velocity ?b) (* -0.8 (velocity ?b)))
        )
    )

    ; Actions omitted
)

Problem File

same as PDDL2.1 ; what distinguishes PDDL+ from the other versions is the domain.

PDDL2.1 -- rover-domain

Domain file

(define (domain rover-domain)
    (:requirements :durative-actions :fluents :duration-inequalities)
    (:types rover waypoint)
    (:functions
        (battery-amount ?r - rover)
        (sample-amount ?r - rover)
        (recharge-rate ?r - rover)
        (battery-capacity)
        (sample-capacity)
        (distance-travelled)
    )
    (:predicates
        ... ; Predicates omitted
	)

    (:durative-action move
        :parameters
            (?r - rover
             ?fromwp - waypoint
             ?towp - waypoint)

        :duration
            (= ?duration 5)

        :condition
	        (and
	            (at start (rover ?rover))
	            (at start (waypoint ?from-waypoint))
	            (at start (waypoint ?to-waypoint))
	            (over all (can-move ?from-waypoint ?to-waypoint))
	            (at start (at ?rover ?from-waypoint))
	            (at start (> (battery-amount ?rover) 8)))

        :effect
	        (and
	            (at end (at ?rover ?to-waypoint))
	            (at end (been-at ?rover ?to-waypoint))
	            (at start (not (at ?rover ?from-waypoint)))
	            (at start (decrease (battery-amount ?rover) 8))
                (at end (increase (distance-travelled) 5))
                )
	)
    ... ; Additional actions omitted
)

Problem File

(define
    (problem rover1)
    (:domain rover-domain)
    (:objects
        r1 r2 - rover
        wp1 wp2 - waypoint
    )
    (:init
        (= (battery-amount r1) 100)
        (= (recharge-rate r1) 2.5)
        ...
    )
    (:goal (and
            ...
        )
    )
    (:metric maximize (+
            (battery-amount r1)
            (battery-amount r2)
        )
    )
)