> ## Documentation Index
> Fetch the complete documentation index at: https://aegean.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Logistics Planning in PDDL

> Planning for package transport using trucks and airplanes.

We will use the Logistics domain to illustrate how to represent a planning task in PDDL.

In logistics, there are trucks and airplanes that can move packages between different airports and cities. We assume that in the initial state there is a truck in Paris airport. An airplane and two packages are in London airport. Paris has two places: south and north. The goal is to have one package in the north location and the other one in the south location.

## Defining the Domain

Let's start by defining in the file `logistics.pddl` the domain and its components:

* The requirements
* The types
* The predicates
* The actions or operators

First, we define the name of the domain:

```lisp logistics.pddl theme={null}
(define (domain logistics)
```

### Requirements

The requirements for this logistics example are:

* **strips**: The actions will only use positive preconditions (predicates that must be true in the current state to trigger actions) and deterministic effects (effects that necessarily follow action triggering).
* **typing**: We will use "types" like in OO programming to represent sets of objects in the world.

```lisp logistics.pddl theme={null}
(:requirements :strips :typing)
```

### Types

We will use the following types:

* Places, cities and physical objects are considered as objects
* Packages and vehicles are physical objects
* Trucks and airplanes are vehicles
* Airports and locations are places

```lisp logistics.pddl theme={null}
(:types city place physobj - object
        package vehicle - physobj
        truck airplane - vehicle
        airport location - place
)
```

### Predicates

We will use the following predicates:

* `in-city(loc, city)` - true iff a place `loc` is in the city `city`
* `at(obj, loc)` - true iff a physical object `obj` is at place `loc`
* `in(pkg, veh)` - true iff a package `pkg` is in a vehicle `veh`

In PDDL, question marks are used for variables:

```lisp logistics.pddl theme={null}
(:predicates
    (in-city ?loc - place ?city - city)
    (at ?obj - physobj ?loc - place)
    (in ?pkg - package ?veh - vehicle)
)
```

### Operators

We define the operators (actions) of the logistics domain. The domain has 6 operators: `load-truck`, `load-airplane`, `unload-truck`, `unload-airplane`, `drive-truck` and `fly-airplane`.

#### Load Truck

To load a truck, we need a package and a truck at the same place. The effect is that the package is now in the truck and no longer at the location.

```lisp logistics.pddl theme={null}
(:action load-truck
    :parameters (?pkg - package ?truck - truck ?loc - place)
    :precondition (and (at ?truck ?loc) (at ?pkg ?loc))
    :effect (and (not (at ?pkg ?loc)) (in ?pkg ?truck))
)
```

#### Load Airplane

```lisp logistics.pddl theme={null}
(:action load-airplane
    :parameters (?pkg - package ?airplane - airplane ?loc - place)
    :precondition (and (at ?pkg ?loc) (at ?airplane ?loc))
    :effect (and (not (at ?pkg ?loc)) (in ?pkg ?airplane))
)
```

#### Unload Truck

```lisp logistics.pddl theme={null}
(:action unload-truck
    :parameters (?pkg - package ?truck - truck ?loc - place)
    :precondition (and (at ?truck ?loc) (in ?pkg ?truck))
    :effect (and (not (in ?pkg ?truck)) (at ?pkg ?loc))
)
```

#### Unload Airplane

```lisp logistics.pddl theme={null}
(:action unload-airplane
    :parameters (?pkg - package ?airplane - airplane ?loc - place)
    :precondition (and (in ?pkg ?airplane) (at ?airplane ?loc))
    :effect (and (not (in ?pkg ?airplane)) (at ?pkg ?loc))
)
```

#### Fly Airplane

```lisp logistics.pddl theme={null}
(:action fly-airplane
    :parameters (?airplane - airplane ?loc-from - airport ?loc-to - airport)
    :precondition (at ?airplane ?loc-from)
    :effect (and (not (at ?airplane ?loc-from)) (at ?airplane ?loc-to))
)
```

#### Drive Truck

```lisp logistics.pddl theme={null}
(:action drive-truck
    :parameters (?truck - truck ?loc-from - place ?loc-to - place ?city - city)
    :precondition (and (at ?truck ?loc-from)
                       (in-city ?loc-from ?city)
                       (in-city ?loc-to ?city))
    :effect (and (not (at ?truck ?loc-from)) (at ?truck ?loc-to))
)
```

<Note>
  Action preconditions and effects can be more complex:

  * **Quantified**: `(forall (?v1 ... ?vn) <effect>)` requires the `:adl` requirement
  * **Conditional**: `(when <condition> <effect>)`
  * Actions can also have costs, duration, and time constraints
</Note>

## Defining the Problem

Now let's define in the file `problem.pddl` the problem instance:

```lisp problem.pddl theme={null}
(define (problem p01)
    (:domain logistics)
```

### Objects

```lisp problem.pddl theme={null}
(:objects
    plane - airplane
    truck - truck
    cdg lhr - airport
    south north - location
    paris london - city
    p1 p2 - package
)
```

### Initial State

The initial state is a set of ground predicates (all variables bound to objects). Facts not listed are assumed false:

```lisp problem.pddl theme={null}
(:init
    (in-city cdg paris)
    (in-city lhr london)
    (in-city north paris)
    (in-city south paris)
    (at plane lhr)
    (at truck cdg)
    (at p1 lhr)
    (at p2 lhr)
)
```

### Goal Description

The goal is to have package p1 at north and package p2 at south:

```lisp problem.pddl theme={null}
(:goal (and (at p1 north)
            (at p2 south))
)
```

## Solution

Running a PDDL planner produces the following plan:

```text Plan Output theme={null}
00: (load-airplane p1 plane lhr) [1]
01: (load-airplane p2 plane lhr) [1]
02: (fly-airplane plane lhr cdg) [1]
03: (unload-airplane p1 plane cdg) [1]
04: (unload-airplane p2 plane cdg) [1]
05: (load-truck p1 truck cdg) [1]
06: (load-truck p2 truck cdg) [1]
07: (drive-truck truck cdg south paris) [1]
08: (unload-truck p2 truck south) [1]
09: (drive-truck truck south north paris) [1]
10: (unload-truck p1 truck north) [1]

Plan total cost: 11.00
```

***

<Callout icon="pen-to-square" iconType="regular">
  [Edit this page on GitHub](https://github.com/aegean-ai/eaia/edit/main/src/aiml-common/lectures/planning/task-planning/pddl/logistics/index.mdx) or [file an issue](https://github.com/aegean-ai/eaia/issues/new/choose).
</Callout>
