class: center, middle # Artificial Intelligence: Planning ### PDDL --- class: center, middle # Planning --- # Reminder: The Planning Problem A planning problem consists of three parts: * A definition of the current state of the world * A definition of a desired state of the world * A definition of the actions the agent can take All of these definitions are done in "some" formal language. --- class: medium # The Planning Domain Definition Language (PDDL) * In The Olden Days every planner used their own input format * The formats not only differed in syntax, but also in capabilities * In 1998 Drew McDermott and colleagues developed a standardized language for planning problems: PDDL * This made comparisons between different planners easier and lead to the creating of the International Planning Competition --- class: medium # PDDL Influences * STRIPS, as we have heard, represented operators as preconditions, additions and deletions * Other languages, such as ADL, supported a wider variety of formulas as preconditions and effects * The idea of actions having "preconditions", that describe when they are applicable, and "effects" that describe what is changed, was common to many of them * The "core" of PDDL is therefore the definition of actions --- class: medium # PDDL Layout * PDDL separates a planning problem into two files - The domain, which defines how the actions operate - The problem, which defines the initial state and the goal * The idea is that the domain can be reused for many different problems * Since historically many planners were written in LISP, PDDL uses the same basic syntax: S-Expressions --- # S-Expressions * Simply put, an S-Expression consists of parenthesized list, where each element can be either a literal string or another S-Expression * (Classically S-Expressions are defined as having two elements, which are concatenated with a period `.`, but this is not commonly explicitly used anymore) * For example, these are all valid S-Expression: ``` () (and (or (not a) b (and (not x) c d e) e)) (defun fib (n) (if (lt n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) ``` --- # S-Expressions * Why are S-Expressions useful? * They are very simple to parse, and we can use them to represent syntax trees * That's exactly what you will do in task 3 of the project * Let's look into how we'd parse them --- class: medium # Parsing S-Expressions * Tokenize the input * Consume tokens one at a time, and push them onto a stack, until you encounter a closing parenthesis * When you encounter a closing parenthesis, pop items from the stack until you find the *first* opening parenthesis on the stack * Push a list containing all popped items onto the stack * Continue consuming tokens * When the last token has been consumed, the stack will contain a single item: The list representing the S-Expression --- # Parsing S-Expressions: An Example ``` (and (or (not a) b) e) ``` Push tokens until we encounter the first closing parenthesis: ``` a not ( or ( and ( ``` Pop `a`, `not` and `(`, and push the list containing them: ``` [not, a] or ( and ( ``` --- # Parsing S-Expressions: An Example ``` (and (or (not a) b) e) ^ ``` Push tokens until we encounter the next closing parenthesis ``` b [not, a] or ( and ( ``` Pop `b`, `[not, a]`, `or`, and `(` and push the list containing them: ``` [or, [not, a], b] and ( ``` --- # Parsing S-Expressions: An Example ``` (and (or (not a) b) e) ^ ``` Push tokens until we encounter the next closing parenthesis ``` e [or, [not, a], b] and ( ``` Pop `and`, `[or, [not, a], b]`, `and`, and `(` and push the list containing them: ``` [and, [or, [not, a], b], e] ``` We have reached the end of the tokens, and the only item on our stack is the list representing the S-Expression --- # Practical considerations * We need to tokenize our input: The list elements are separated by spaces, but we have to ensure the parentheses are too * If we ever try to pop from an empty stack, or if there is more than one element on the stack at the end, there was a syntax error * The literal strings can contain pretty much any character except for parenthesis and spaces (we saw `-` earlier as a literal string) --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * Now we have our PDDL domain file as a parse-tree * Let's extract the individual parts * For each part we have to do some processing * After all processing, we have our domain ] --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * Now we have our PDDL domain file as a parse-tree * Let's extract the individual parts * For each part we have to do some processing * After all processing, we have our domain ] --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * **Requirements** * Types/Objects * Predicates * Actions ] --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * Requirements * **Types/Objects** * Predicates * Actions ] --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * Requirements * Types/Objects * **Predicates** * Actions ] --- # Structure of a PDDL Domain File .left-column[
] .right-column[ * Requirements * Types/Objects * Predicates * **Actions** ] --- class: medium # Extensions: "Requirements" * PDDL is a standard, but it allows for several extensions * The planner you implement in the project will support - `:strips` - `:typing` - `:adl`, which is an abbreviation for `:disjunctive-preconditions`, `:equality`, `:existential-preconditions`, `:universal-preconditions`, and `:conditional-effects` * There are many other extensions, related to numbers, temporal planning, probabilistic effects, etc. --- # Types * Objects and variables in PDDL can have types * Types form a hierarchy, with a root type containing *all* objects * We need to store these types so we can expand variables in e.g. forall expressions --- # Types * Types are written *after* objects * A type can be applied to multiple objects at the same time ``` p3 p6 - going_up p5 p3 p6 p2 p9 p1 - attendant p7 - never_alone p2 p7 - conflict_A p0 p9 p3 p6 p1 p8 p5 p4 - conflict_B f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 - floor ``` --- # Type Hierarchy * Similar to giving types to objects, types can also be "applied" to other types * This is used to create a type hierarchy, by saying "everything that has type X or Y also has type Z" by writing `X Y - Z` ``` passenger - object going_up going_down vip going_nonstop attendant never_alone conflict_A conflict_B - passenger floor - object ``` --- class: medium # Parsing Types * As usual, tokenize the input * Store types as a dictionary of sets * Process token by token, collecting items in a accumulator set * When you encounter a `-`, interpret the next token as a type * Add all objects from the accumulator set to that type's set in the dictionary --- # Type Hierarchy * You can use the same approach to process the type hierarchy * Then you need to perform a post-processing step * For each type, add all objects of each of its subtypes * Either do this from the bottom up, or just repeat it n times --- # Actions * "Actions" in PDDL are actually *operators* * That means they contain free variables (often with types) * Each operator may represent multiple actions * Additionally, each operator contains a precondition and an effect --- # Action Example ``` (:action up :parameters (?f1 - floor ?f2 - floor) :precondition (and (lift-at ?f1) (above ?f1 ?f2)) :effect (and (lift-at ?f2) (not (lift-at ?f1))) ) ``` --- # Structure of a PDDL Problem File .left-column[
] .right-column[ * The *domain* defines the available operators of the world * The *problem* defines the initial state and the goal condition * Objects may be spread out over both files ] --- # Structure of a PDDL Problem File .left-column[
] .right-column[ * **Domain Reference** * Additional Objects * Initial State * Goal Condition ] --- # Structure of a PDDL Problem File .left-column[
] .right-column[ * Domain Reference * **Additional Objects** * Initial State * Goal Condition ] --- # Structure of a PDDL Problem File .left-column[
] .right-column[ * Domain Reference * Additional Objects * **Initial State** * Goal Condition ] --- # Structure of a PDDL Problem File .left-column[
] .right-column[ * Domain Reference * Additional Objects * Initial State * **Goal Condition** ] --- class: center, middle # PDDL Example: Elevator --- # Domain: Types and Predicates ``` (:types passenger - object floor - object ) (:predicates (origin ?person - passenger ?floor - floor) (destin ?person - passenger ?floor - floor) (above ?floor1 - floor ?floor2 - floor) (boarded ?person - passenger) (served ?person - passenger) (lift-at ?floor - floor) ) ``` --- # Domain: Drive Up and Down ``` ;;drive up (:action up :parameters (?f1 - floor ?f2 - floor) :precondition (and (lift-at ?f1) (above ?f1 ?f2)) :effect (and (lift-at ?f2) (not (lift-at ?f1))) ) ;;drive down (:action down :parameters (?f1 - floor ?f2 - floor) :precondition (and (lift-at ?f1) (above ?f2 ?f1)) :effect (and (lift-at ?f2) (not (lift-at ?f1))) ) ``` --- # Domain: Stop at Floor (Homework) ``` (:action stop :parameters (?f - floor) :precondition (lift-at ?f) :effect (and (forall (?p - passenger) (when (and (boarded ?p) (destin ?p ?f)) (and (not (boarded ?p)) (served ?p)))) (forall (?p - passenger) (when (and (origin ?p ?f) (not (served ?p))) (boarded ?p))) ) ) ``` --- # Problem ``` (:objects p0 - passenger f0 f1 - floor) (:init (above f0 f1) (origin p0 f1) (destin p0 f0) (lift-at f0) ) (:goal (forall (?p - passenger) (served ?p))) ``` --- class: center, middle # Planners --- class: small # Running a Planner * Most planners will provide you with some executable that expects two parameters: a domain file, and a problem file * Some will then perform some preprocessing step and translate the problem into some internal representation, and you may have to run a second executable on that * Then you wait ... -- * And wait ... -- * And wait ... -- * And then you get a solution (or not)! --- # Some Planners * [FastForward](https://fai.cs.uni-saarland.de/hoffmann/ff.html) * [FastDownward](http://www.fast-downward.org/) * [Glaive](http://nil.cs.uno.edu/projects/glaive/) --- # Plans * So you run your planner and it finishes * The output will be a "plan" * However, unlike for the input, there is no real standard for the output * Some/most planners will print the required actions in a PDDL/LISP-like syntax --- # planning.domains * Since planning is a very active field of research, there are many planning domains out there * [planning.domains](http://planning.domains) actually contains a collection of known domains, drawing from planning competitions and other sources * All of the files in that repository are PDDL files * However, they may require various extensions --- # Some Advice For the Project * For the project, testing your planner on the classical domains is a good idea * On the project page, you will find information on which domains should work with your planner * There are also other sources for domains, some of which are linked on the project page * If you find anything else, please let me know, and I'll test them with my solution --- class: medium # Some Advice For the Project * You may assume that the domain/problem you are given "make sense" * That means you don't have to check if the `:requirements` section matches what is used in the files, if all used predicates exist and the types match, etc. * You also don't need to worry about emitting "good" error messages for syntax errors * But make sure that the files listed on the project page work with your planner, and come up with your own (reasonable) tests --- # Performance * With task 3, your planner will be quite slow * There will still be a decent amount of problems you should be able to solve * Check the project page for performance metrics of my solution for comparison * In task 4 we will improve this performance (and we will talk next week about how) --- # Homework * [Homework 4](/PF-3335/assets/pdf/homework4.pdf) has been posted on the class website * There are 6 problems using the planning domains from the repository of http://planning.domains * No bonus problem this week * You will see a lot of PDDL in task 3, so take the time to understand the format --- class: small # Resources * [International Planning Competition](http://icaps-conference.org/index.php/Main/Competitions)