AgentSpeak - Úvod
Na přednášce jste si povídali o agentech s BDI architekturou. Na tomto cvičení budeme mluvit o AgentSpeaku a Jasonu. AgentSpeak je programovací jazyk pro implementaci BDI agentů, Jason je jeho interpret. Jason navíc také umožňuje snadno definovat jednoduchá prostředí, kde se agenti mohou pohybovat, a proto je možné vytvořit poměrně jednoduše i komplikovanější simulace.
AgentSpeak je interpretovaný jazyk se syntaxí a funkčností podobnou Prologu. Jeho interpret se jmenuje Jason a lze jej stáhnout z http://jason.sourceforge.net/wp/. Instalace je jednoduchá - stačí rozbalit archiv do libovolného adresáře.
Abyste mohli pracovat s Jasonem, potřebujete IDE. Distribuce Jasonu obsahuje verzi jEdit, která podporuje projekty AgentSpeak a Jason. Existuje také modul do Eclipse, který přidává podporu Jasonu, ale zdá se, že už není vyvíjen. Instrukce k instalaci modulu jsou dostupné na http://jason.sourceforge.net/mini-tutorial/eclipse-plugin/, nicméně doporučuji použít jEdit.
Příklad “cleaning-robots”
Jason je distribuován s několika příklady (v adresáři examples
). Základy si ukážeme na příkladu cleaning-robots
.
Tento příklad obsahuje dva roboty. Jeden z nich se pohybuje prostředím a sbírá odpadky, druhý sedí uprostřed a ničí všechny odpadky, které do něj zanesou ostatní roboti (přesněji řečeno, všechny odpadky, které jsou na stejném místě jako on). Prostředí je reprezentováno mřížkou 7x7 a poskytuje agentům několik základních akcí.
next(slot)
- přesune agenta na další pozicimoveTowards(x,y)
- posune agenta o jednu pozici blíže k daným souřadnicímpick(garb)
- sebere odpad (může selhat)drop(garb)
- položí odpadburn(garb)
- spálí odpad na místě agentar2
(to je ten, který odpadky spaluje)
Prostředí také poskytuje následující informace
pos(R,X,Y)
- robotR
je na pozici(X,Y)
garbage(R)
- na pozici robotaR
je odpad
Otevřete příklad v jEdit - hlavní soubor příkladu se nazývá mars.mas2j
a popisuje celý multiagentní systém. Základní syntaxe souborů .mas2j
je poměrně jednoduchá, neměli byste mít problémy ji pochopit - pouze určuje název systému, jakou infrastrukturu používat pro komunikaci (vždy budeme používat Centralised
, ale Jason podporuje také jade
), třídu hlavního prostředí a seznam agentů. Později také uvidíme, že můžeme upřesnit parametry agentů a další věci.
Abyste mohli spustit příklady v jEdit, musíte nastavit cestu k souboru jason.jar
a k ant-libs. Tato nastavení najdete v části Plugins -> Plugin Options -> Jason. Nakonec musíte kliknout na zelenou šipku v pravém dolním rohu.
Implementace prostředí
Z hlediska implementace je prostředí pro agenta vytvořeno jako implementace třídy Environment
. Je potřéba napsat metody init(String [])
a executeAction(String ag, Structure action)
. Prostředí obvykle používá model, v tomto případě GridWorldModel
, který lze použít pro prostředí implementovaná jako mřížky. V metodě executeAction
vidíte, jak můžeme provádět akce v prostředí a jak zpracovat parametry takových akcí. Metoda také volá metodu updatePercepts
, která aktualizuje vjemy agentů.
Jason může spolupracovat i s dalšími frameworky pro implementaci složitějších prostředí, jako je Cartago. Tyto frameworky ale nebudeme potřebovat a nebudeme se jim ani dále věnovat.
Implementace agenta
Každý program v AgentSpeaku se skládá z několika částí - pravidel, počátečních beliefs a plánů a cílů.
Počáteční beliefs a pravidla
Pravidla v AgentSpeaku vyjadřují vztah mezi beliefs nebo jiné obecné informace o světě. Chceme-li například napsat pravidlo, které platí, že pokud se robot r1
nachází na stejném místě jako robot P
(a umístění robotů je v beliefs reprezentováno jako pos(R, X, Y)
), můžeme definovat predikát at(P)
jako
at(P) :- pos(P,X,Y) & pos(r1,X,Y).
Všimněte si, že syntaxe pravidel je podobná syntaxi Prologu. Jediný rozdíl je v tom, že místo čárky jsou atomy odděleny znakem &
. Interpret AgentSpeaku dokonce při použití pravidla provádí unifikace a odvození je také podobné Prologu.
Jak pravidla, tak další atomy, které dáte agentovi hned na začátku tvoří množinu počátečních beliefs, které se později během samotné simulace mohou měnit. A na základě toho může agent uvažovat a chovat se.
Beliefs se automaticky aktualizují vždy, když se agent něco dozví od prostředí, nebo od jiného agenta. Každá belief může mít navíc anotaci (psanou v hranaté závorce za ní), která říká, odkud se agent o této věci dozvěděl, např. likes(peter, music)[source(martin)]
, říká, že agent věří, že agent petr
má rád hudbu, protože mu to řekl agent martin
. Anotace se dají unifikovat stejně, jako samotné beliefs.
Plány
Chování agenta je dáno především jeho plány. Popis plánu v Jasonu je opět velmi jednoduchý. Každý plán se skládá ze třech částí – triggeru, kontextu a vlastního těla.
Trigger určuje, kdy se má plán spustit. Z pohledu syntaxe je velmi podobný hlavě predikátu v Prologu s tím, že před samotnou hlavou je pár dalších znaků, které určují, jestli se plán má spustit při přidání (+
) nebo odebrání (-
) belief (nic), cíle (!
, případně ?
pro dotazovací cíle). Pokud se podíváte na vzorového agenta, můžete například najít plán, který se spustí při přidání belief garbage(r1)
, ten má trigger tvaru +garbage(r1)
. Také si můžete všimnout triggeru pro přidání počátečního plánu check(slots)
, který má tvar +!check(slots)
. U triggerů funguje, stejně jako u hlav pravidel, unifikace v Prologovském významu. Unifikované proměnné jsou potom vázané i v kontextu a těle plánu.
Další část plánu (je od triggeru oddělená dvojtečkou) určuje kontext tohoto plánu. Je to jakási podmínka, která musí platit, aby plán bylo možné spustit. Syntaxe samotné podmínky je stejná, jako syntaxe těla nějakého pravidla. Zase se můžete podívat na vzorového agenta a najdete plán
+!ensure_pick(S) : garbage(r1)
[...]
Část za dvojtečkou je právě kontext – na místě, kde je agent r1
musí být nějaký odpad.
Když se na vzorového agenta podíváte pořádně, najdete i kontexty, které obsahují klíčové slovo not
. To znamená, že agent o podmínce za ním nevěří, že je pravda. Ještě existuje operátor ~
, který naopak znamená, že agent věří, že podmínka za ním není pravda.
Poslední část každého plánu je jeho samotné tělo. To se od kontextu odděluje pomocí symbolu <-
a obsahuje posloupnost akcí, které má agent provést. Akce mohou být různých druhů. Akce, které poskytuje prostředí, se píšou jen tak, bez čehokoliv před nimi (např. pick(garb)
), naproti tomu interní akce agenta (.print(“Hello world”)
) mají před samotnou akcí tečku.
Speciální druh akcí potom tvoří akce pro přidání plánu (je před nimi !
, nebo ?
pro dotazovací plány), přidání (+
) a odebrání (-
) belief. Jako zkratka, pro update belief slouží operátor (-+
). Pokud se chcete dotázat svojí belief base použijete operátor ?
(v zásadě jde o přidání dotazovacího cíle).
Speciální typ plánu je dotazovací plán. Ten se může hodit, pokud chceme zjistit nějakou věc, které není přímo v beliefs (např. agent, který je v obýváku a chce vědět, jestli je v ledničce pivo se k ní musí napřed přesunout).
Úkoly
Hlavním cílem tohoto cvičení je, abyste porozuměli základům AgentSpeaku, takže postupujte podle výše uvedeného textu, stáhněte si Jason a zkontrolujte zdrojové kódy příkladu cleaning-robots
. Poté se můžete pokusit upravit kód některým z následujících způsobů:
- Přidejte do prostředí dalšího spalovacího robota.
- Aktualizujte uklízecího robota tak, aby nosil odpadky k nejbližšímu spalovacímu robotovi.
- Přidejte další uklízecí roboty.
V Jasonu jsou další zajímavé jednoduché příklady, jeden z nich se jmenuje blocks-world
, kde je cílem, aby agent stavěl věže z bloků. Zdrojový kód agentů je pěkně okomentován, doporučuji se na něj podívat.