Skip to content

PDDL other types of planning

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

PDDL -- other types of Planning

🔗 more info here

Non standard classical PDDL features

⚠️ Not widely supported. It depends on the planner.

Object Types

🔗 see planning.wiki

In classical PDDL you cannot give specifications about the objects in the worlds, since they are given in the problem statement. You can perform checks about the "type of the objects" (the "trivial checkings" to check before the main checks in each action precondition), but you cannot give objects neither characteristics of objects except by means of predicates.

some PDDL extension includes types: simply give a type to a parameter. Take into account only these small changes on the syntax of parameters and instances:

  • the requirement to use to apply the typing is :typing

  • the domain contains a new tag (types ...list of objects...). Each type could have a subtype; the most general (subsumed) type is object.

    for example,

     ;; all the types here are objects
     (:types
     	site material
     )
     
     ;; also this works
     (:types
     	site - object
     	material
     )
     ;; and other variations upon the same leitmotiv ...
     
     ;; a bit cumbersome... you can sub-typing, but better to
     ;;    not use this functionality
     (:types
     	site material - object
     	bricks cables windows - material
     )
  • in order to specify the type of a generic parameter, write ?param - param_type.

  • in case of many params, simply list them before spcifying the type, or give a type for each of them. ?p1 ?p2 ?p3 - tp or ?p1 - tp ?p2 - tp ?p3 - tp. This syntax is required each time you have to declare a parameter: actions, predicates, ...

  • do the same thing when you declare the object instances, for example my-obj - tp, or also with the listing, o1 o2 o3 - tp. Take into account that PDDL is tabulation-free, hence you can do everything you want with this syntax.

  • if a type has not been specified, the type object is assumed, which is the uppermost class of objects.

PDDL 2.1 -- temporal and numerical planning

🔗 see PDDL2.1 on planning.wiki

Domain File

Requirements

🔗 see the requirements of PDDL2.1

Here's an example of requirements for PDDL2.1:

(:requirements :durative-actions :fluents :duration-inequalities)

In particular,

  • :fluents -- it adds numerical quantities, the so-called fluents or also functions. The planner can change the value of a fluent during the planning, and use it as a predicate.
  • :durative-actions -- it adds another type of action called (:durative-action ...) which takes into account also the duration of the action.
  • :durative-inequalities

functions -- fluents

🔗 see also :continuous-effect requirement on planning.wiki

(:functions
    (predicate ?obj1 ?obj2 ...)
    ;; ...
)

Here are the operations allowed on the fluents. You can use them both in actions or in durative actions.

;; simple operations
(+ (sample-capacity) (battery-capacity))
(- (sample-capacity) (battery-capacity))
(/ (sample-capacity) (battery-capacity))
(* (sample-capacity) (battery-capacity))

;; comparison
;; > , >= , < , <= , =

;; particular operations -- increase and decrease
(increase (battery-level ?r) 10)
(decrease (battery-level ?r) 10)
;; a more complicated form
(increase (battery-level ?r) (charge-available - ?solarpanel))
(decrease (battery-level ?r) (power-needed-for-work - ?task))
;; used a lot -- continuous effect (#t is the frame time)
(increase (fuel ?tank) #t)
(decrease (battery ?battery) (* 5 #t))

;; assignment
(assign (battery-level ?r) 10)
(assign (battery-level ?r) (max-charge ?r))

Durative Actions

🔗 see durative actions

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

Condition is interesting. You can specify the conditions at the beginning of the action, at the end of the action, and at the end of the action. In particular, here are the syntaxes:

;; condition before starting the action
(at start (at ?rover ?from-waypoint))

;; condition relative to the end of the action
(at end (>= (battery-amount ?rover) 0))

;; the conditon holds for the entire action
(over all (can-move ?from-waypoint ?to-waypoint))

These statements can be employed even in the :effect section.

Here below is an example of durative action, just to understand how it works:

(: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
			(decrease (fuel-level ?t) (* 2 #t))
			(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))
			)
)

Problem file

init numerical fluents

just use the syntax (= (<predicate> <args>) <value>)

(:init
    (= (battery-amount r1) 100)
    (= (recharge-rate r1) 2.5)
    ...
)

Metrics

We could ask the planner to maximize or minimize a fluent or a list of fluents during the search of a plan.

☝️ This is NOT a replacement of the (:goal ...) statement, but just a constraint, which could be applied or not. The planner will do (presumably) the best to satisfy this constraint.

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

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

PDDL+

It contains many features:

  • numerical flows
  • types
  • processes : they are "durative actions" with a unspecified duration, meaning that the process keeps going as long as the preconditions are met. Each frame, the process applies its effect on the state.
  • Events : an event is something "triggered" when the precondition becomes satisfied, and it is applied every time the precondition holds.

☝️ PDDL+ applies processes and events in background, meaning that a process or an event can be triggered every time a precondition becomes satisfied, regardless of the actions the planner could decide to apply. Hence, there are two levels in the planning: the actions (immediate) and the modelled dynamics of the world (the effects of an action and/or external actions by other actors).

☝️ a clever combination of processes and events lets to implement durative actions.

⚠️ the way PDDL+ works under the hood depends on the quality of the planner you're using for your project. be careful.

Requirements

🔗 see requirements for PDDL+

The typical configuration for a PDDL+ domain:

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

In particular, :time includes processes and events in your code.

Processes

🔗 see processes on planning.wiki

A process starts when the preconditions are met, and goes on until the precondition is satisfied. The syntax is the same as the actions, but with another statement.

The symbol #t indicates the frame time, useful for continuous updates of the fluents.

(: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)))
    )
)

Events

🔗 see Events on Planning.wiki

An event is triggered when the precondition is met. It could be triggered at each frame if the precondition keeps holding.

(: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)))
    )
)