{"id":21204188,"url":"https://github.com/fareskalaboud/learnpddl","last_synced_at":"2026-01-02T14:05:54.140Z","repository":{"id":75489592,"uuid":"111390110","full_name":"fareskalaboud/LearnPDDL","owner":"fareskalaboud","description":"A beginner's guide to learning, implementing and using PDDL.","archived":false,"fork":false,"pushed_at":"2024-07-25T12:02:20.000Z","size":132,"stargazers_count":55,"open_issues_count":0,"forks_count":11,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-21T15:16:26.301Z","etag":null,"topics":["beginner","guide","learn","pddl","teaching"],"latest_commit_sha":null,"homepage":"http://fareskalaboud.github.io/LearnPDDL","language":"PDDL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fareskalaboud.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-20T09:38:10.000Z","updated_at":"2025-01-03T09:28:39.000Z","dependencies_parsed_at":"2024-11-20T20:32:57.357Z","dependency_job_id":"d480b34a-8683-41b9-a35c-295aeda66cee","html_url":"https://github.com/fareskalaboud/LearnPDDL","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fareskalaboud%2FLearnPDDL","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fareskalaboud%2FLearnPDDL/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fareskalaboud%2FLearnPDDL/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fareskalaboud%2FLearnPDDL/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fareskalaboud","download_url":"https://codeload.github.com/fareskalaboud/LearnPDDL/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243658195,"owners_count":20326464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beginner","guide","learn","pddl","teaching"],"created_at":"2024-11-20T20:30:48.844Z","updated_at":"2026-01-02T14:05:54.127Z","avatar_url":"https://github.com/fareskalaboud.png","language":"PDDL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Getting Started with PDDL\n\nWelcome to LearnPDDL, a short guide to getting started with using PDDL.\n\nThis guide is designed for first-time readers, people who need refreshers and others, like myself, who sometimes need some syntax sanity-checking.\n\nIf you read anything here that you believe needs improvement, [contribute to it on GitHub](https://github.com/fareskalaboud/LearnPDDL). \n\n## Introduction\n\nPDDL one of the few languages designed for the purpose of creating a standard for Artificial Intelligence (AI) planning. It was developed in 1998 and was introduced at ICAPS, with improvements and extensions being built into it over the years [[1]](https://en.wikipedia.org/wiki/Planning_Domain_Definition_Language#De_facto_official_versions_of_PDDL). \n\nThe most popular of PDDL used today are PDDL2.1, which is an extension to PDDL for expressing temporal domains [[2]](http://www.jair.org/papers/paper1129.html); PDDL 3 [[3]](http://www.cs.yale.edu/homes/dvm/papers/pddl-ipc5.pdf) which adds trajectory constraints and preferences to PDDL 2.1, and PDDL+ [[4]](http://www.jair.org/papers/paper2044.html) which allows modelling mixed discrete-continuous domains in PDDL.\n\n## Environment Setup\n\nYou can use your own text editor, the online editor at [planning.domains](http://editor.planning.domains), but I would recommend using [Visual Studio Code](https://code.visualstudio.com/#alt-downloads) with the [PDDL](https://marketplace.visualstudio.com/items?itemName=jan-dolejsi.pddl) extension built by the amazing [Jan Dolejsi](https://github.com/jan-dolejsi), which will give you syntax higlighting, hover-over information, auto-completion, plan visualization and validation and more. It also automatically downloads the VAL binaries and.\n\n## Components of PDDL\n\nBefore we start writing PDDL, we need to understand what how to model a \"world\" in PDDL. \n\nA world is described by a set of states, each containing a list of **facts** and/or **objects**. A world begins with an **initial state**, and is governed by a set of rules and constraints that limit which **actions** can be taken in each state, and each action generally represents a transition to a different state. \n\nThere are certain things we need to keep track of in the \"world\". \n\n- **Objects**: Things in the world that interest us.\n- **Predicates**: Facts that we are interested in (e.g. properties of objects), which can be true or false.\n- **An initial state**: The state of the world that we start in, i.e. things that are true at the start.\n- **Goal specification**: The state of the world we want to end at, i.e. things that we want to be true at the end.\n- **Actions/Operators**: Ways of changing the state of the world, i.e. things that happen that change the facts.\n\n## PDDL Syntax\n\nFirst thing you need to know, PDDL files usually have the extension `.pddl`. \n\nThere are two PDDL files you need to learn the syntax of:\n\n### The Domain File\n\nThe domain file establishes the context of the world. It determines what sorts of details the states can include (predicates), and what can we do to move between states in the world (actions). \n\nThe basic syntax of a domain file is:\n```\n(define (domain \u003cdomain name\u003e)\n  (:predicates\n    \u003cpredicate-list\u003e\n  )\n  \n  (:action\n    \u003caction-details\u003e\n  )\n)\n```\n\nwhere `\u003cdomain-name\u003e` is the name of the world.\n\nBoth **predicates** and **actions** will become clearer in examples below.\n\n### The Problem File\n\nThe problem file represents an instance of the world we established in the domain. It determines what is true at the start of the plan (initial state), and what we want to be true at the end of the plan (goal state). \n\nThe basic syntax of a problem file is:\n\n```\n(define (problem \u003ctitle\u003e)\n\t(:domain \u003cdomain-name\u003e)\n\t(:objects\n    \t\u003cobject-list\u003e\n\t)\n\n\t(:init\n\t\t\u003cpredicates\u003e\n\t)\n\t(:goal \n\t\t\u003cpredicates\u003e\n\t)\n)\n```\n\nwhere `\u003ctitle\u003e` is the title of the problem file and `\u003cdomain-name\u003e` refers to the name of the corresponding domain file.\n\n## Simple Example: Let's Eat!\n\n![Gripper](img/arm-cupcake.png)\n\nLet's imagine we have a robot gripper arm, a cupcake and a plate. The gripper is empty, the cupcake is on the table and we want to put the cupcake on the plate. \n\nBefore we model this in PDDL, let's look at the components of the PDDL problem:\n\nFirst we define the domain.\n\n```\n(define (domain letseat)\n```\n\nThen we define the **objects**: plate, gripper, cupcake. We will also mark the cupcake and the arm as locatable, a little hack to help us query the locations of these objects using a predicate we'll create later.\n```  \n(:requirements :typing) \n\n(:types         \n    location locatable - object\n\tbot cupcake - locatable\n    robot - bot\n)\n```\nWe also need to define some **predicates**. Is the gripper arm empty? Where is the cupcake?\n\n```\n(:predicates\n\t(on ?obj - locatable ?loc - location)\n\t(holding ?arm - locatable ?cupcake - locatable)\n    (arm-empty)\n    (path ?location1 - location ?location2 - location)\n)\n```\n\nWe'll also have to define **actions/operators**. We need to be able to pick up and drop the cupcake, as well as move the arm between the table and the plate.\n```\n(:action pick-up\n  :parameters\n   (?arm - bot\n    ?cupcake - locatable\n    ?loc - location)\n  :precondition\n   (and \n      ; Note how we use the same variable loc\n      ; in both lines below. This is to make\n      ; sure it's looking at the same location.\n      (on ?arm ?loc) \n      (on ?cupcake ?loc) \n      (arm-empty)\n    )\n  :effect\n   (and \n      (not (on ?cupcake ?loc))\n      (holding ?arm ?cupcake)\n      (not (arm-empty))\n   )\n)\n\n(:action drop\n  :parameters\n   (?arm - bot\n    ?cupcake - locatable\n    ?loc - location)\n  :precondition\n   (and \n      (on ?arm ?loc)\n      (holding ?arm ?cupcake)\n    )\n  :effect\n   (and \n      (on ?cupcake ?loc)\n      (arm-empty)\n      (not (holding ?arm ?cupcake))\n   )\n)\n\n(:action move\n  :parameters\n   (?arm - bot\n    ?from - location\n    ?to - location)\n  :precondition\n   (and \n    (on ?arm ?from) \n    (path ?from ?to)\n   )\n  :effect\n   (and \n    (not (on ?arm ?from))\n    (on ?arm ?to)\n   )\n)\n```\n \nPut all the above into a file, and you have [a domain file](https://github.com/fareskalaboud/LearnPDDL/blob/master/files/letseat/domain.pddl)!\n\nNow we'll look at the problem file. We'll start by letting it know which domain it's associated to, and define the objects that exist in the world.\n```\n(define (problem letseat-simple)\n\t(:domain letseat)\n\t(:objects\n    \tarm - robot\n    \tcupcake - cupcake\n    \ttable - location\n    \tplate - location\n\t)\n```\nThen, we'll define the **initial state**: the gripper is empty, the cupcake is on the table, and the arm can move between both.\n```\n(:init\n\t(on arm table)\n\t(on cupcake table)\n\t(arm-empty)\n\t(path table plate)\n)\n```\nFinally, we define the **goal specification**: the cupcake on in the plate.\n```\n(:goal \n\t(on cupcake plate)\n)\n```\nPut that all together and you'll have [the problem file](https://github.com/fareskalaboud/LearnPDDL/blob/master/files/letseat/pfile.pddl)!\n\nIf you run this using [OPTIC](https://nms.kcl.ac.uk/planning/software/optic.html), you'll get this solution:\n\n```\nInitial heuristic = 3\nInitial stats: t=0s, 4299060kb\nb (2 @ n=3, t=0s, 4300084kb)b (1 @ n=6, t=0s, 4308276kb)\n;;;; Solution Found\n; Time 0.00\n; Peak memory 4308276kb\n; Nodes Generated: 5\n; Nodes Expanded:  3\n; Nodes Evaluated: 6\n; Nodes Tunneled:  1\n; Nodes memoised with open actions: 0\n; Nodes memoised without open actions: 6\n; Nodes pruned by memoisation: 0\n0: (pick-up arm cupcake table) [1]\n1: (move arm table plate) [1]\n2: (drop arm cupcake plate) [1]\n```\n\n#### Exercises:\nHere are a few tasks to make it more complex and enforce your understanding.\n- Add a second cupcake on the table, and add it to the goal spec to make sure it's put on the plate as well.\n- Add a unicorn object to the domain, and make the goal for the unicorn to eat the cupcake. The unicorn can only eat the cupcake if it's on the plate.\n\n## Not-as-Simple Example\n\nIf you want to check out something a bit more complex, check out the [driverlog domain](https://github.com/fareskalaboud/LearnPDDL/tree/master/files/driverlog).\n\n## Past the Basics\n\nIf you're a first timer, don't venture into this part until after you've fully understood the basics. \n\n### Durative Actions\n\nYou can actually give actions durations to work in temporal domains.\n\nEach condition and effect is given the time at which it's supposed to happen.\n\nThere are a few types of temporal constraints:\n\n`(at start (\u003ccondition/effect\u003e))`, which means this must be true or happen at the start of the action.\n`(at end (\u003ccondition/effect\u003e))` , which means this must be true or happen at the end of the action.\n`(over all (\u003ccondition\u003e))`, which means this must be true for the full duration of the action.\n\nBelow is an example of the `(move)` action from our previous example transformed into a durative action. \n```\n(:durative-action move\n  :duration (= ?duration 10) ; Duration goes here.\n  :parameters\n   (?arm - bot\n    ?from - location\n    ?to - location)\n  :condition ; Note how this is \"condition\" not \"pre-condition\"\n   (and \n    (at start (on ?arm ?from))\n    (over all (path ?from ?to))\n   )\n  :effect\n   (and \n    (at start (not (on ?arm ?from)))\n    (at end (on ?arm ?to))\n   )\n)\n```\n\n### Functions\n\nFunctions in PDDL are used to represent numeric values that can change over time as actions are executed. These functions are useful for more complex planning problems where simple predicates (true/false) are not enough. Functions allow planners to handle quantities like resources, distances, or costs. They're perfect for calculating variables like temperature, speed, energy, etc. \n\nFunctions in PDDL are defined using the :functions keyword within the domain file. They can be used within action definitions to update values dynamically.\n\nIn the below example, the `distance` function defines the distance between two locations, and the `fuel` function keeps track of the fuel level in a vehicle. The `drive` action decreases the fuel level based on the distance traveled.\n\n```\n(define (domain logistics)\n  (:requirements :typing :fluents)\n\n  (:types\n    package location vehicle - object)\n\n  (:predicates\n    (at ?pkg - package ?loc - location)\n    (in ?pkg - package ?veh - vehicle)\n    (at ?veh - vehicle ?loc - location))\n\n  (:functions\n    (distance ?loc1 - location ?loc2 - location)\n    (fuel ?veh - vehicle))\n\n  (:action drive\n    :parameters (?veh - vehicle ?loc1 - location ?loc2 - location)\n    :precondition (and (at ?veh ?loc1) (\u003e (fuel ?veh) (distance ?loc1 ?loc2)))\n    :effect (and (not (at ?veh ?loc1)) (at ?veh ?loc2) (decrease (fuel ?veh) (distance ?loc1 ?loc2))))\n\n  (:action load\n    :parameters (?pkg - package ?loc - location ?veh - vehicle)\n    :precondition (and (at ?pkg ?loc) (at ?veh ?loc))\n    :effect (and (not (at ?pkg ?loc)) (in ?pkg ?veh)))\n\n  (:action unload\n    :parameters (?pkg - package ?loc - location ?veh - vehicle)\n    :precondition (and (in ?pkg ?veh) (at ?veh ?loc))\n    :effect (and (at ?pkg ?loc) (not (in ?pkg ?veh))))\n)\n```\n\n### Processes \u0026 Events\n\nPDDL+ introduces processes and events, which are crucial for modeling continuous change and exogenous events in dynamic systems. These elements allow for more realistic and flexible planning in environments where the state can change independently of the actions taken by the planner.\n\n#### Processes\n\nProcesses represent continuous activities that change the state over time as long as certain conditions remain true. They are defined using the `:process` keyword. A process has conditions that need to be true for it to be active and effects that continuously change the state. If these conditions are true, the process is **always running**.\n\nIn the below snippet, the `fuel-consumption` process continuously decreases the fuel level of a vehicle as long as it is moving, with the rate of consumption dependent on the vehicle's speed and the duration of movement.\n\n```\n(:process fuel-consumption\n  :parameters (?veh - vehicle)\n  :condition (at start (moving ?veh))\n  :effect (decrease (fuel ?veh) (* (speed ?veh) ?duration)))\n```\n\nOf course, you can set numeric constants in the effect of a process, not only variables.\n\n#### Events\n\nEvents represent instantaneous occurrences that can change the state of the world. They are defined using the `:event` keyword. An event has a condition that triggers it and effects that change the state. Once the condition is true, it immediately activates.\n```\n(:event low-fuel\n  :parameters (?veh - vehicle)\n  :precondition (\u003c= (fuel ?veh) 10)\n  :effect (not (moving ?veh)))\n```\n\nProcesses and events add a layer of complexity and realism to PDDL models, allowing planners to handle continuous and unpredictable changes in the environment. \n\n#### What's the difference between processes and events?\n\nThink of processes and events in PDDL as the AI planning world's equivalent of while loops and if statements in coding. \n\nImagine processes as the diligent while loops, tirelessly working in the background, constantly checking if certain conditions are met and then continuously performing their magic as long as those conditions hold true. They're like a robot that keeps vacuuming the floor as long as it detects dirt. \n\nOn the other hand, events are the snappy if statements, springing into action only when a specific condition is met, just once, and then they move on. They're like a toaster that pops up when your bread is perfectly toasted.\n\nProcesses are the steady workers maintaining ongoing tasks, events are the quick responders, handling sudden changes with swift precision.\n\n# But wait, there's more?\n\nOf course there is. This is a very small guide, but can be improved greatly with your contribution. Feel free to submit a [pull request](https://github.com/fareskalaboud/LearnPDDL/pulls).\n\n# Contributions\n\n- **[Fares Alaboud](http://faresalaboud.me)** (Author)\n- **[Dr. Andrew Coles](http://nms.kcl.ac.uk/andrew.coles)** (Editor)\n- **[Jan Dolejsi](https://github.com/jan-dolejsi)** (Contributor)\n- **[Daniel Kröni](https://github.com/danielkroeni)** (Contributor)\n\n# References\n\n[1] [PDDL's Wikipedia Page](https://en.wikipedia.org/wiki/Planning_Domain_Definition_Language#De_facto_official_versions_of_PDDL)\n\n[2] Fox, M. and Long, D. (2003). PDDL2.1: An Extension to PDDL for Expressing Temporal Planning Domains. [online] Available at: [http://www.jair.org/papers/paper1129.html](http://www.jair.org/papers/paper1129.html) [Accessed 20 Nov. 2017]. \n\n[3] Gerevini, A. and Long, D. (2005) Plan Constraints and Preferences in PDDL3. Volume 27, pages 235-297. [online] Available at [http://www.cs.yale.edu/homes/dvm/papers/pddl-ipc5.pdf](http://www.cs.yale.edu/homes/dvm/papers/pddl-ipc5.pdf)\n\n\n[4] Fox, M. and Long, D. (2006) Modelling Mixed Discrete-Continuous Domains for Planning. Volume 27, pages 235-297. [online] Available at [http://www.jair.org/papers/paper2044.html](http://www.jair.org/papers/paper2044.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffareskalaboud%2Flearnpddl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffareskalaboud%2Flearnpddl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffareskalaboud%2Flearnpddl/lists"}