Celem laboratorium jest zapoznanie się z językiem PDDL, czyli ustandaryzowaną notacją używaną do reprezentacji problemów planowania.
Przed podejściem do tego laboratorium polecane jest wykonaniu zadań z laboratorium wprowadzającego problematykę planowania. W szczególności należy zapoznać się i wykonać ćwiczenia z sekcji 'Program planujący'. Poniższe laboratorium stanowi niejako rozwinięcie przedstawionej tam problematyki i będzie nawiązywać do rozwiązywania problemu świata klocków przy użyciu planera STRIPS.
PDDL jest próbą wprowadzenie jednolitej reprezentacji wiedzy dla szczególnej klasy problemów dotyczących automatycznego planowania. Dziedzina problemu oraz jego poszczególne instancje są oddzielone od solverów, których zadaniem jest znalezienie ciągu akcji, który doprowadziłby w danej dziedzinie z zadanego stanu początkowego do stanu końcowego. Na reprezentację problemu w PDDL składają się dwa pliki:
PDDL korzysta z notacji prefiksowej inspirowanej językiem LISP (tzw. S-wyrażenia. W uproszczeniu: każde wyrażenie o postaci (f a1 a2 a3)
należy interpretować jako f(a1, a2, a3)
, np. (= ?x (+ 3 2))
należy interpretować jako równoważne 5 = 3 + 2
. Element S-wyrażenia poprzedzony pytajnikiem, np. ?x
reprezentuje zmienną, same nawiasy natomiast jedynie grupują symbol funkcyjnego z jego argumentami. W szczególności cały program LISP-owy jest S-wyrażeniem, co przekłada się na łatwe parsowanie pliku i przetwarzanie kodu (metaprogramowanie).
Na plik PDDL opisujący dziedzinę problemu składają się z następujące elementy:
(define (domain <name>) … )
(:requirements <wymaganie1> <wymaganie2>)
. Takimi konstrukcjami mogą być na przykład::typing
pozwalające na grupowanie obiektów modelu w kategoriach typów:equality
pozwalające na sprawdzanie czy dwie nazwy wskazują na ten sam obiekt:strips
zapewnia wsparcie dla opisywania problemów na wzór reprezentacji STRIPS:adl
oznacza, że dana dziedzina wykracza poza STRIPS i korzysta z reprezentacji ADLtyping
)(:predicate (sa_polaczone ?x ?y) <predykat2> …)
(:action …)
. Każda akcja opisana jest przy użyciu::parameters (?x ?y)
- listy wymagań, które muszą być spełnione, aby dana akcja mogła być wykonana:
:preconditions (<warunek>):effects (?efekt1, ?efekt2)
Bazując na definicji problemu świata klocków, zapisanej przy użyciu Prologu (patrz: preliminaria), proszę uzupełnić poniższy model o trzy brakujące akcje:
(define (domain blocksworld) (:requirements :strips) ; wymagany STRIPS (:predicates (on ?x ?y) ; klocek ?x na klocku ?y (ontable ?x) ; klocek ?x na stole (clear ?x) ; na klocku ?x nic nie lezy (handempty) ; ramie robota jest puste (holding ?x) ; ramie robota trzyma ?x ) (:action pick-up ; akcja "podnies ze stolu" :parameters (?block) :precondition (and (clear ?block) (ontable ?block) (handempty)) :effect (and (not (ontable ?block)) (not (clear ?block)) (not (handempty)) (holding ?block))) ; akcja "postaw na stole" ; akcja "postaw klocek A na klocku B" ; akcja "zdejmij klocek A z klocka B" )
Drugi plik PDDL opisuje konkretną instancję problemu, składają się na niego:
(define (problem <name>) … )
(:domain <dziedzina>)
(:objects a1 a2 a3 …)
(:init (predykat argument) …)
(:goal (predykat argument))
Na podstawie poniższego przykładu:
(define (problem easy) (:domain blocksworld) (:objects a b c) (:init (ontable a) (ontable b) (ontable c) (clear a) (clear b) (clear c) (handempty)) (:goal (and (on b c) (on a b))) )
Proszę przepisać na PDDL dwa trudniejsze przykłady z Prologowej implementacji STRIPS - patrz: preliminaria.
Jeżeli używasz laptopa w sali C2 316, solver Fast Forward powinien już być zainstalowany i dodany do ścieżki PATH. Zatem wpisanie ff
w konsoli powinno wystarczyć.
FF.zip
zawiera katalog z plikami źródłowymi oraz plik binarny skompilowany na Ubuntu 64bit (powinno działać na serwerze uczelnianym). W razie potrzeby kompilacja wymaga zainstalowania narzędzi ''flex'' oraz ''bison'' i przebiega poprzez wykonanie kolejno: make veryclean
make
./ff -o <sciezka do pliku z domena> -f <sciezka do pliku z instancja problemu>
Poprzez dopisanie :typing
w sekcji :requirements
można rozszerzyć możliwości języka PDDL o dodanie typów do istniejących obiektów, czy też parametrów akcji. Można w ten sposób małym kosztem wyeliminować dużą liczbę nielegalnych akcji.
Typy definiowane są po sekcji :requirements
poprzez dopisanie: (:types nazwa1 nazwa2 …)
dla typów o nazwach nazwa1
, nazwa2
, etc. Następnie każdy parametr predykatu i akcji musi zostać opatrzony odpowiednią adnotacją określającą jego typ, np. ?x - typ
oznacza, że parametr ?x
musi być typu typ
w danej akcji lub predykacie.
Podobnie w definicji instancji problemu należy wszystkie obiekty opatrzyć odpowiednimi adnotacjami (- typ
określającymi ich typ.
Proszę uzupełnić pliki świata klocków o adnotacje i przetestować, czy nadal wszystko działa.
Czy jesteś w stanie zasymulować typowanie bez dodawania konstrukcji :typing
? Jak można byłoby tego dokonać w Prologu?
Mając już przetestowaną reprezentację problemu świata klocków, proszę zgeneralizować problem dodając do niego dwa dodatkowe elementy:
Uwagi:
Reprezentacja STRIPS jest bardzo ograniczona i, aby rozszerzyć warunki akcji o nowe konstrukcje, należy dopisać w sekcji :requirements
dopisać dodatkowe wymaganie :adl
. ADL różni się od STRIPS w kilku zasadniczych względach, m.in.:
(forall (?x1 ?x1 …) <warunek>) (exists (?x1 ?x2 …) <warunek>)
(not <warunek>)
(or <warunek1> <warunek2>)
clear
.