Back to Lecture 9

PDDL: Planning Domain Definition Language

The modern standard for representing planning problems

What is PDDL?

PDDL: Planning Domain Definition Language

PDDL is a standardized language for representing planning problems. It extends STRIPS with modern features like types, variables, and structured syntax.

Think of PDDL as the "programming language" for planning - it provides a common format that any planning system can read and solve.

Historical Context & Evolution
  • Created: 1998 for the International Planning Competition (IPC)
  • Purpose: Standardize planning problem representation
  • Based on: STRIPS (1971) + ADL extensions
  • Current Version: PDDL 3.1 (supports preferences, constraints)
📋

Why PDDL?
Before PDDL, every planner used its own format. PDDL unified the field!

PDDL vs STRIPS
STRIPS (1971)
  • Ground actions only
  • No types
  • Simple preconditions
  • Add/Delete lists
PDDL (1998+)
  • Variables in actions
  • Types for objects
  • Complex formulas
  • Structured syntax

PDDL Syntax Reference

Quick reference guide for PDDL syntax elements

Element Syntax Example File
Domain Header (define (domain <name>) ...) (define (domain blocks) ...) Domain
Requirements (:requirements <feature>...) (:requirements :strips :typing) Domain
Types (:types <type>...) (:types robot location cargo) Domain
Predicates (:predicates (<name> ?var - type)...) (at ?robot - robot ?loc - location) Domain
Action (:action <name> ...) (:action move ...) Domain
Parameters :parameters (?var - type...) :parameters (?r - robot ?from ?to - location) Domain
Precondition :precondition <formula> :precondition (at ?r ?from) Domain
Effect :effect <formula> :effect (at ?r ?to) Domain
Conjunction (and <formula>...) (and (at ?r ?loc) (clear ?loc)) Domain
Negation (not <formula>) (not (at ?r ?from)) Domain
Problem Header (define (problem <name>) ...) (define (problem blocks-1) ...) Problem
Domain Link (:domain <name>) (:domain blocks) Problem
Objects (:objects <obj> - type...) (:objects robot1 - robot kitchen - location) Problem
Initial State (:init <fluent>...) (:init (at robot1 kitchen) (clear table)) Problem
Goal (:goal <formula>) (:goal (at robot1 bedroom)) Problem
Variables ?<name> ?robot ?from ?to Both
Constants <lowercase-name> robot1 kitchen block-a Both
Naming Rules
  • Use lowercase
  • Use hyphens not underscores
  • Variables start with ?
  • No special characters
Structure
  • Domain defines schema
  • Problem defines instance
  • Actions use variables
  • Init/Goal use constants
Tips
  • Always use types
  • Keep actions simple
  • Test with small problems first
  • Use meaningful names
Tip: Bookmark this page as your PDDL syntax cheat sheet! You can also print this reference table.

PDDL Structure: Domain + Problem

A PDDL planning task consists of TWO separate files:

Domain File

Defines the general planning domain

  • Types: Categories of objects
  • Predicates: Relations that can be true/false
  • Actions: What can be done (with parameters)
(define (domain blocks)
  (:types block)
  (:predicates
    (on ?x ?y - block)
    (clear ?x - block))
  (:action move
    :parameters (?x ?y - block)
    :precondition (clear ?x)
    :effect (on ?x ?y))
)
domain.pddl

Reusable across many problems

Problem File

Defines a specific problem instance

  • Objects: Specific things in this problem
  • Init: Initial state facts
  • Goal: What we want to achieve
(define (problem blocks-1)
  (:domain blocks)
  (:objects a b c - block)
  (:init
    (on a b)
    (clear a)
    (clear c))
  (:goal
    (on a c))
)
problem.pddl

Specific instance to solve

Analogy: Think of the domain as a "class" in programming (defines what's possible), and the problem as an "instance" of that class (specific scenario to solve).

Domain File Structure

Let's build a complete domain file for the Spare Tire problem:

domain-tire.pddl
;; Spare Tire Domain
(define (domain spare-tire)
  
  ;; 1. Requirements (optional features)
  (:requirements :strips :typing)
  
  ;; 2. Types - Categories of objects
  (:types 
    tire location
  )
  
  ;; 3. Predicates - Relations that can be true/false
  (:predicates
    (tire-at ?t - tire ?loc - location)  ;; tire ?t is at location ?loc
  )
  
  ;; 4. Actions - What can be done
  (:action remove
    :parameters (?tire - tire ?from - location)
    :precondition (tire-at ?tire ?from)
    :effect (and
      (not (tire-at ?tire ?from))
      (tire-at ?tire ground)
    )
  )
  
  (:action put-on
    :parameters (?tire - tire)
    :precondition (tire-at ?tire ground)
    :effect (and
      (not (tire-at ?tire ground))
      (tire-at ?tire axle)
    )
  )
)
Component Breakdown:
1. Domain Header
(define (domain spare-tire) ...)

Names the domain. This name will be referenced by problem files.

2. Types Declaration
(:types tire location)

Defines categories of objects. Like classes in OOP!

Example: tire type includes: flat-tire, spare-tire
location type includes: axle, trunk, ground
3. Predicates Declaration
(:predicates (tire-at ?t - tire ?loc - location))

Defines relations. Variables start with ?

Example: (tire-at flat-tire axle) means "flat-tire is at axle"
4. Action Schemas
(:action remove
  :parameters (?tire - tire ?from - location)
  :precondition (tire-at ?tire ?from)
  :effect (and (not (tire-at ?tire ?from)) 
               (tire-at ?tire ground))
)

Parameterized actions! The ?tire and ?from are variables that get instantiated with actual objects.

Interactive: Build PDDL Domain Step-by-Step

Watch how we convert a plain text description into formal PDDL syntax!

Plain Text Description
Current Step: 1 of 6
PDDL Domain Code

Problem File Structure

Now let's define a specific problem instance using the domain:

problem-tire.pddl
;; Spare Tire Problem Instance
(define (problem tire-problem-1)
  
  ;; 1. Link to domain file
  (:domain spare-tire)
  
  ;; 2. Objects - Specific instances
  (:objects
    flat-tire spare-tire - tire
    axle trunk ground - location
  )
  
  ;; 3. Initial State - What's true at start
  (:init
    (tire-at flat-tire axle)
    (tire-at spare-tire trunk)
  )
  
  ;; 4. Goal - What we want to achieve
  (:goal
    (tire-at spare-tire axle)
  )
)
Component Breakdown:
1. Problem Header
(define (problem tire-problem-1) (:domain spare-tire) ...)

Names the problem and links to the domain.

2. Objects Declaration
(:objects flat-tire spare-tire - tire ...)

Lists specific objects with their types.

Note: These are the constants that will replace variables in actions!
3. Initial State
(:init (tire-at flat-tire axle) (tire-at spare-tire trunk))

Ground atomic fluents that are true initially.

Remember: Closed-World Assumption! Anything not listed is FALSE.
4. Goal Specification
(:goal (tire-at spare-tire axle))

What we want to achieve. Can be a conjunction of facts.

Example: (:goal (and (tire-at spare-tire axle) (tire-at flat-tire ground)))
Interactive: Build PDDL Problem Step-by-Step

Watch how we convert a problem description into formal PDDL syntax!

Plain Text Description
Current Step: 1 of 5
PDDL Problem Code

Action Schemas: The Power of PDDL

What Makes PDDL Powerful?

PDDL uses Action Schemas - parameterized templates that define families of actions using variables instead of specific objects.

From STRIPS to PDDL: STRIPS used ground actions (e.g., Move(Robot1, Kitchen, Bedroom)). PDDL generalizes with schemas: move(?r, ?from, ?to)

One Schema, Many Actions
PDDL Action Schema:
(:action move
  :parameters (?robot - robot ?from - location ?to - location)
  :precondition (and (at ?robot ?from) (connected ?from ?to))
  :effect (and (not (at ?robot ?from)) (at ?robot ?to))
)

Instantiates to...

move(robot1, kitchen, bedroom)
move(robot2, hallway, office)
move(robot1, bedroom, bathroom)
Result: With 2 robots, 4 locations, and connectivity constraints, this one schema generates dozens of ground actions automatically!
Components of Action Schema
Action Name move
:parameters Typed variables (?robot - robot)
:precondition Conditions using variables
:effect Changes using variables
Why Action Schemas?
  • Compact: One definition, many actions
  • Scalable: Works with any number of objects
  • Reusable: Same schema, different domains
  • Maintainable: Change once, affects all instances
Concrete Example: Delivery Domain
Action Schema
(:action pick-up
  :parameters (?pkg - package
               ?truck - truck
               ?loc - location)
  :precondition (and
    (at ?truck ?loc)
    (at ?pkg ?loc)
  )
  :effect (and
    (not (at ?pkg ?loc))
    (in ?pkg ?truck)
  )
)
Ground Actions Generated
pick-up(pkg1, truck1, warehouse) pick-up(pkg1, truck2, warehouse) pick-up(pkg2, truck1, depot) pick-up(pkg2, truck2, depot) ...and many more combinations!
Connection to Topic 3: In STRIPS, we introduced Action Schemas conceptually. PDDL provides the formal syntax with typed parameters (?x - type) and structured representation.

Parameters and Variables in PDDL

Understanding PDDL Variables

Variables in PDDL (marked with ?) are placeholders that get replaced with actual objects when creating ground actions. This is called instantiation or grounding.

From Action Schema to Ground Actions
Action Schema (with variables):
(:action remove
  :parameters (?tire - tire 
               ?from - location)
  ...
)

Instantiate

Ground Actions (no variables):
remove(flat-tire, axle)
remove(flat-tire, trunk)
remove(spare-tire, axle)
remove(spare-tire, trunk)
All possible combinations!
Important: The planner generates ground actions by substituting variables with all possible objects of the correct type. This can create many actions! (2 tires × 3 locations = 6 ground actions for remove)
Variable Binding Example: Robot Domain
;; Action Schema
(:action move
  :parameters (?robot - robot ?from - location ?to - location)
  :precondition (at ?robot ?from)
  :effect (and (not (at ?robot ?from)) (at ?robot ?to))
)

;; Objects
(:objects robot1 - robot  kitchen bedroom bathroom - location)

;; This generates ground actions like:
;;   move(robot1, kitchen, bedroom)
;;   move(robot1, kitchen, bathroom)
;;   move(robot1, bedroom, kitchen)
;;   ... etc (3×2 = 6 total moves)

Complete Example: Saudi Air Cargo

A more complex example with multiple types and actions:

domain-cargo.pddl
(define (domain air-cargo)
  (:requirements :strips :typing)
  
  (:types cargo plane city)
  
  (:predicates
    (at-cargo ?c - cargo ?city - city)
    (at-plane ?p - plane ?city - city)
    (in-cargo ?c - cargo ?p - plane)
  )
  
  (:action load
    :parameters (?c - cargo ?p - plane ?city - city)
    :precondition (and (at-cargo ?c ?city) (at-plane ?p ?city))
    :effect (and (not (at-cargo ?c ?city)) (in-cargo ?c ?p))
  )
  
  (:action unload
    :parameters (?c - cargo ?p - plane ?city - city)
    :precondition (and (in-cargo ?c ?p) (at-plane ?p ?city))
    :effect (and (not (in-cargo ?c ?p)) (at-cargo ?c ?city))
  )
  
  (:action fly
    :parameters (?p - plane ?from - city ?to - city)
    :precondition (at-plane ?p ?from)
    :effect (and (not (at-plane ?p ?from)) (at-plane ?p ?to))
  )
)
problem-cargo.pddl
(define (problem cargo-problem-riyadh-jeddah)
  (:domain air-cargo)
  
  (:objects
    cargo1 cargo2 - cargo
    plane1 - plane
    riyadh jeddah dammam - city
  )
  
  (:init
    ;; Initial locations
    (at-cargo cargo1 riyadh)
    (at-cargo cargo2 riyadh)
    (at-plane plane1 riyadh)
  )
  
  (:goal
    (and
      (at-cargo cargo1 jeddah)
      (at-cargo cargo2 dammam)
    )
  )
)
Sample Solution Plan:
  1. load(cargo1, plane1, riyadh)
  2. load(cargo2, plane1, riyadh)
  3. fly(plane1, riyadh, jeddah)
  4. unload(cargo1, plane1, jeddah)
  5. fly(plane1, jeddah, dammam)
  6. unload(cargo2, plane1, dammam)

Interactive Demo: Variable Instantiation

See how action schemas with variables expand into ground actions!

Action Schema Grounding
Action Schema (with variables)
Ground Actions (instantiated)
Total Ground Actions: 0
Notice: One action schema with N variables can generate many ground actions! This is the power of PDDL - compact representation.

Interactive Demo: PDDL Action Executor

Execute PDDL actions step-by-step and see state changes in real-time!

Interactive Spare Tire Problem
Current State
Goal
(tire-at spare-tire axle)
Available Actions (preconditions satisfied)
Execution History
No actions executed yet. Click an available action above to execute it!
Goal Achieved! 🎉

You've successfully solved the problem! The spare tire is now on the axle.

Interactive Demo: PDDL Syntax Validator

Test your PDDL syntax knowledge! Type predicates and actions to validate them.

PDDL Syntax Checker
Try these examples:
Try these examples:
PDDL Naming Conventions:
  • Predicates: Enclosed in parentheses, lowercase with hyphens: (at-robot ?r ?loc)
  • Variables: Start with ?: ?robot, ?from, ?to
  • Actions: Lowercase with hyphens: move, pick-up, put-down
  • Constants: Lowercase: robot1, kitchen, block-a

Common Mistakes & Troubleshooting

Learn from these common errors to avoid frustration!

Mistake #1: Forgetting Parentheses
❌ Wrong
(:predicates
  at-robot ?r - robot ?loc - location
  holding ?r - robot ?b - box
)

Problem: Predicates must be enclosed in parentheses!

✅ Correct
(:predicates
  (at-robot ?r - robot ?loc - location)
  (holding ?r - robot ?b - box)
)

Solution: Each predicate needs its own parentheses.

Mistake #2: Using Variables in Problem Files
❌ Wrong
(:init
  (at ?robot1 kitchen)
  (empty ?robot1)
)

Problem: Variables (?) only in domain, not problem!

✅ Correct
(:init
  (at robot1 kitchen)
  (empty robot1)
)

Solution: Use constants (no ?) in problem files.

Mistake #3: Missing Type Declarations
❌ Wrong
(:action move
  :parameters (?r ?from ?to)
  :precondition (at ?r ?from)
  ...
)

Problem: Parameters have no types! Planner won't know what they are.

✅ Correct
(:action move
  :parameters (?r - robot ?from - location ?to - location)
  :precondition (at ?r ?from)
  ...
)

Solution: Always specify types with - type syntax.

Mistake #4: Forgetting to Delete Old Facts
❌ Wrong
(:action move
  :parameters (?r - robot ?from - location ?to - location)
  :precondition (at ?r ?from)
  :effect (at ?r ?to)
)

Problem: Robot will be in BOTH locations!

✅ Correct
(:action move
  :parameters (?r - robot ?from - location ?to - location)
  :precondition (at ?r ?from)
  :effect (and (not (at ?r ?from)) (at ?r ?to))
)

Solution: Use not to remove old facts.

Mistake #5: Closed-World Assumption Confusion
⚠️ Remember: In PDDL, if something is NOT listed in :init, it's automatically FALSE!
❌ Wrong
(:init
  (at robot1 kitchen)
  (not (at robot1 bedroom))
  (not (at robot1 bathroom))
)

Problem: Don't explicitly state negative facts!

✅ Correct
(:init
  (at robot1 kitchen)
)

Solution: Only list TRUE facts. Everything else is false by CWA.

Pro Tips
  • ✅ Always check parentheses balance
  • ✅ Use meaningful names: at-robot not ar
  • ✅ Test with simple problems first
  • ✅ Use :typing requirement - it prevents many errors
  • ✅ When in doubt, look at working examples

Visual: Domain ↔ Problem Connection

See how Domain and Problem files work together!

How Domain & Problem Connect
DOMAIN FILE
General Rules
Types
(:types robot box room)
Predicates (with variables)
(at-robot ?r - robot ?loc - room)
Actions (schemas)
(:action move
  :parameters (?r ?from ?to)
  ...
)

Maps to

PROBLEM FILE
Specific Instance
Objects (specific instances)
(:objects robot1 - robot kitchen - room)
Init/Goal (with constants)
(at-robot robot1 kitchen)
Plan (ground actions)
move(robot1, kitchen, bedroom)
Types → Objects

Domain types define categories
robot box room

Problem objects are instances
robot1, box-a, kitchen

Variables → Constants

Domain uses variables
?r ?loc (with ?)

Problem uses constants
robot1 kitchen (no ?)

Actions → Plan

Domain defines action schemas
move(?r, ?from, ?to)

Problem produces ground actions
move(robot1, kitchen, bedroom)

Key Insight: The domain is like a template with placeholders (?variables). The problem fills in those placeholders with actual objects!

From Natural Language to PDDL

See how everyday descriptions become formal PDDL code!

Example: Delivery Robot
📝 Natural Language

Scenario:

"We have a delivery robot that needs to move packages between rooms."

What the robot can do:

  • The robot can move from one room to another
  • The robot can pick up a package if it's in the same room
  • The robot can drop a package in a room

Current situation:

  • Robot is in the warehouse
  • Package-A is in the warehouse
  • Robot's hand is empty

Goal:

Get Package-A to the office

💻 PDDL Code
Domain File:
(define (domain delivery)
  (:types robot package room)
  
  (:predicates
    (at-robot ?r - robot ?loc - room)
    (at-package ?p - package ?loc - room)
    (holding ?r - robot ?p - package)
    (empty ?r - robot)
  )
  
  (:action move
    :parameters (?r - robot ?from ?to - room)
    :precondition (at-robot ?r ?from)
    :effect (and (not (at-robot ?r ?from))
                 (at-robot ?r ?to))
  )
  
  (:action pick-up
    :parameters (?r - robot ?p - package ?loc - room)
    :precondition (and (at-robot ?r ?loc)
                       (at-package ?p ?loc)
                       (empty ?r))
    :effect (and (not (at-package ?p ?loc))
                 (not (empty ?r))
                 (holding ?r ?p))
  )
  
  (:action drop
    :parameters (?r - robot ?p - package ?loc - room)
    :precondition (and (at-robot ?r ?loc)
                       (holding ?r ?p))
    :effect (and (not (holding ?r ?p))
                 (at-package ?p ?loc)
                 (empty ?r))
  )
)
Problem File:
(define (problem delivery-task-1)
  (:domain delivery)
  
  (:objects
    robot1 - robot
    package-a - package
    warehouse office - room
  )
  
  (:init
    (at-robot robot1 warehouse)
    (at-package package-a warehouse)
    (empty robot1)
  )
  
  (:goal
    (at-package package-a office)
  )
)
Translation Map:
• "delivery robot" → robot type
• "packages" → package type
• "rooms" → room type
• "move from... to..." → move action
• "pick up" → pick-up action
• "drop" → drop action
• "Robot is in warehouse" → (at-robot robot1 warehouse)
• "Get Package-A to office" → (at-package package-a office)
Common Translation Patterns
Natural Language PDDL
"X can do Y" (:action Y ...)
"X is in Y" (at X Y)
"X is holding Y" (holding X Y)
"X must be true before..." :precondition
"After doing X, Y becomes true" :effect Y
"X is no longer true" (not X)
Tips for Translation
  1. Identify nouns → These become types and objects
  2. Identify verbs → These become actions
  3. Identify properties → These become predicates
  4. Identify requirements → These become preconditions
  5. Identify changes → These become effects
  6. Be specific: "in the warehouse" not just "there"
Feature STRIPS (1971) PDDL (1998+)
Variables ❌ No variables (only ground actions) ✅ Variables in action schemas
Types ❌ No type system ✅ Objects have types
Syntax Informal notation Structured Lisp-like syntax
Effects Add/Delete lists (and ... (not ...)) format
Files Single representation Separate domain + problem files
Standardization Informal standard Official standard for competitions
Example Action Remove(Flat, Axle)
Ground action
(:action remove :parameters (?t - tire ?from - location) ...)
Parameterized schema

Key Takeaways

✅ PDDL Essentials
  1. Two Files: Domain (general) + Problem (specific)
  2. Types: Categories of objects
  3. Predicates: Relations (with variables)
  4. Actions: Parameterized schemas
  5. Variables: Start with ?, get grounded to objects
🎯 Why PDDL Matters
  • Standard: Universal format for planners
  • Compact: Variables reduce redundancy
  • Reusable: One domain, many problems
  • Modern: Supports advanced features
Next: See how to solve these PDDL problems with planning algorithms! Continue to Planning Examples →