**IAIC** Práctica 4 Planificación !!!def: Objetivo El objetivo de esta práctica es representar y resolver diversos problemas representándolos como **Problemas de Planificación**. !!!warn Antes de ponerte a resolver ejercicios o ver cómo funciona la librería específica de Julia, lee el ejemplo completo que está desarrollado en la [sección siguiente](#unejemplodecreaci%C3%B3ndepdd:log%C3%ADstica) de esta misma página. # Contenido de esta práctica El contenido de esta práctica se puede descargar por medio del siguiente fichero: [Practica4.zip](practica4.zip) Consta de un cuaderno de Pluto: * [`Plan1.jl`](Plan1.html): Cuaderno con ejemplos resueltos que demuestra el uso de las librerías de planificación que hacen uso del estándar PDDL. * [`Plan2.jl`](Plan2.html): Cuaderno con una demostración de uso de repertorios de dominios y problemas de planificación. * `wgc-domain.pddl`: Fichero PDDL con el dominio del puzzle del granjero. * `wgc-domain.pddl`: Fichero PDDL con el problema del puzzle del granjero. Descarga el fichero ZIP y abre los cuadernos en Pluto. Se recomienda abrir los ficheros PDDL en un editor de texto para explorar su contenido. # Un ejemplo de creación de PDD: Logística Utilizaremos el dominio `logistics` para ilustrar cómo representar una tarea de planificación en PDDL. En este dominio, hay camiones y aviones que pueden mover paquetes entre diferentes aeropuertos y ciudades. Suponemos que en el estado inicial hay un camión en el aeropuerto de París. Un avión y dos paquetes se encuentran en el aeropuerto de Londres. París tiene dos lugares: el sur y el norte. El objetivo es tener un paquete en el lugar norte y el otro en el lugar sur. En primer lugar, crea dos archivos de texto llamados respectivamente `logistics.pddl` y `problem.pddl` y copia y pega el fragmento de código PDDL dado paso a paso en estos archivos. !!!note Recuerda que PDDL requiere dos archivos: 1. Un *archivo de dominio* para requisitos, tipos, predicados y acciones, 2. Un *archivo de problema* para objetos, estado inicial y especificación de objetivos. ## Definición del dominio Empecemos definiendo en el fichero `logistics.pddl` el dominio y sus componentes: * los requisitos, * los tipos, * los predicados, * las acciones o los operadores. En primer lugar, tenemos que definir el nombre del dominio. En PDDL, escribimos : ~~~~none (define (domain logistics) ~~~~ ### Requerimientos Los requisitos para este ejemplo de logística son: * `strips` : las acciones solo utilizarán precondiciones positivas (predicados que deben ser ciertos en el estado actual para desencadenar acciones) y efectos deterministas (efectos que siguen necesariamente al desencadenamiento de la acción). No se permite nada más. * `typing`: utilizaremos tipos para representar conjuntos de objetos en el mundo. ~~~~none (:requirements :strips :typing) ~~~~ ### Tipos Usaremos los siguientes tipos: * Lugares, ciudades y objetos físicos * Los paquetes y los vehículos son objetos físicos, * Los camiones y aviones son vehículos, * Los aeropuertos y localizaciones son lugares. ~~~~none (:types city place physobj - object package vehicle - physobj truck airplane - vehicle airport location - place ) ~~~~ ### Predicados Usaremos los siguientes predicados: * `in-city(loc,city)` - `true` si el lugar *loc* está en la ciudad *city* * `at(obj,loc)` - `true` si el objeto físico *obj* está en el lugar *loc* * `in(pkg,veh)` - `true` si el paquete *pkg* está en el vehículo *veh* En PDDL, se usa `?` para las variables: ~~~~none (:predicates (in-city ?loc - place ?city - city) (at ?obj - physobj ?loc - place) (in ?pkg - package ?veh - vehicle) ) ~~~~ ### Operadores/Acciones Vamos a definir las acciones del dominio de logística, que son quienes pueden cambiar el estado del mundo. Tenemos 5 operadores/acciones: `load-truck`, `load-airplaine`, `unload-truck`, `unload-airplane`, `drive-truck` y `fly-aiplane`. ~~~~none (: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)) ) (: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)) ) (: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)) ) (: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)) ) (: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)) ) (: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 Debemos tener en cuenta que: * Las precondiciones y los efectos de las acciones pueden ser más complicados de lo que se ha visto hasta ahora. Pueden cuantificarse universal o existencialmente mediante una sentencia PDDL de la forma `(forall (?v1 ... ?vn) )`. En ese caso, deben utilizarse requisitos específicos, por ejemplo `:adl`. * Pueden usarse condicionales: `(when )`. * Las acciones pueden tener costes, duración, restricciones de tiempo, etc. Ya puedes cerrar el fichero de dominio... ## Definición del Problema Ahora vamos a definir el fichero `problem.pddl`, que consta de: * los objetos, * el stado inicial, * el objetivo a alcanzar. En primer lugar, hay que definir el nombre del problema e indicar el dominio asociado a este problema: ~~~~none (define (problem p01) (:domain logistics) ~~~~ ### Objetos En este ejemplo vamos a usar los siguientes objetos (con los tipos): * Un camión: *truck* * Un avión: *airplane* * Dos aeropuertos: *cdg*, *lhr* * Dos lugares: *north*, *south* * Dos ciudades: *london*, *paris* * Dos paquetes: *p1*, *p2* ~~~~none (:objects plane - airplane truck - truck cdg lhr - airport south north - location paris london - city p1 p2 - package ) ~~~~ !!!note Los tipos de los objetos sólo pueden ser los tipos definidos en el dominio o el tipo `object`. ### Estado inicial El estado inicial es un conjunto de **predicados fundamentados** (todas las variables están ligadas a objetos). Los predicados básicos en el estado inicial representan hechos verdaderos en este estado. Cualquier hecho que no esté representado en un estado es falso. En nuestro caso: ~~~~none (: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) ) ~~~~ ### Descripción del Objetivo El objetivo es tener *at(p1, north)* y *at(p2, south)* en el estado final (sin importar el valor de verdad de los otros predicados). En PDDL, escribimos: ~~~~none (:goal (and (at p1 north) (at p2 south)) ) ~~~~ # Encontrando un Plan Haciendo uso de un planificador (como el que vemos en la asignatura hecho en Julia) podríamos encontrar un plan que resuelva el problema propuesto: ~~~~none 00: (load-airplane p1 plane lhr) 01: (load-airplane p2 plane lhr) 02: (fly-airplane plane lhr cdg) 03: (unload-airplane p1 plane cdg) 04: (unload-airplane p2 plane cdg) 05: (load-truck p1 truck cdg) 06: (load-truck p2 truck cdg) 07: (drive-truck truck cdg south paris) 08: (unload-truck p2 truck south) 09: (drive-truck truck south north paris) 10: (unload-truck p1 truck north) plan total cost: 11,00 ~~~~