Jason: Componentes personalizados
-
Upload
necio-de-lima-veras -
Category
Documents
-
view
282 -
download
3
Transcript of Jason: Componentes personalizados
Notas de estudo sobre User-Defined Components
por
Nécio de Lima Veras
ObjetivoEstes slides objetivam documentar um estudo sobre a programação de agentes em sistemas multi-agentes, especificamente, o capítulo 7 (componentes definidos pelo usuário) do livro Programming Multi-Agent Systems in AgentSpeak Using Jason. A ideia é investigar as formas de implementar arquiteturas (diferentes à BDI) de agentes no Jason.
Introdução do capítulo
● Jason é distribuído com um conjunto de funcionalidade para desenvolvimento de Agentes;
● No entanto, desenvolvedores sempre necessitam de requisitos específicos em seus sistemas, tais como:– Acesso à base de dados;– Integração com sistemas legados;– Interfaces gráficas;– Capacidades e percepções personalizadas de agentes;– Manipulação de intenções especiais;– Muitos outros.....
Introdução do capítulo
● Para atender a essas especificidades uma abordagem baseada em extensibilidade foi adotada no projeto Jason;
● Como o próprio Jason é escrito em Java, então essas extensões envolvem também a linguagem Java;
● É possível desenvolver agentes com uma linguagem totalmente declarativa (AgentSpeak) e também estender a linguagem com bibliotecas e componentes criados usando o paradigma tradicional da OO;
● Novos comandos podem ser adicionados à linguagem por meio de ações internas e diversos componentes (ambos escritos em Java) do interpretador podem ser personalizados;
– Para isso, existe uma API disponível;
Introdução do capítulo
● Há dois motivos para a criação de ação interna:
– Ampliar as capacidades internas do Agentes (quando a OO for mais cabível do que o paradigma do AgentSpeak);
– Permitir que seja usado código legado já programado em Java ou em outras linguagens (acessíveis por meio do JNI – Java Native Interface);
● Existem algumas ações (padrão) internas no Jason, tais como:
– .send
– .my_name
– Uma lista completa está no apêndice A.3 do livro.● Além disso é possível também personalizar e estender diferentes
componentes do interpretador;
Definindo uma nova ação interna
● Ações internas definidas pelo usuário podem ser organizadas em bibliotecas específicas;
● Em AgentSpeak, uma AI é acessada pelo nome da biblioteca seguido por um “.” e pelo nome da ação;
● Exemplo:– Uma nova AI chamada de distance dentro de uma
biblioteca chamada math pode ser usada tanto no contexto ou no corpo de um plano do código AgentSpeak;
Definindo uma nova ação interna
● Bibliotecas são definidas como packages em Java e cada AI é uma classe Java dentro do pacote;
● Lembre-se que em AgentSpeak identificadores que iniciam com letras maiúsculas indicam variáveis;– Por isso nomes de bibliotecas e de ações internas
em Java devem iniciar com letras minúsculas já que serão usadas no AgentSpeak;
Mesmo sendo um antipadrão OO
Definindo uma nova ação interna● Todas as classes que definem uma AI deve implementar a
interface InternalAction;
● Existe uma implementação padrão desta interface que simplifica a criação de novas AI chamada de DefaultInternalAction;
Definindo uma nova ação interna
● Exemplo:
Definindo uma nova ação interna
● Entendendo o exemplo:– O método sobrescrito execute é chamado pelo interpretador
AgentSpeak para executar a AI;
– O argumento ts contém todas as informações sobre o estado atual do agente;
– O segundo (un) é uma função unificadora que é determinado pela execução do plano onde a AI apareceu (ou a checagem se o plano é aplicável);
● Isso depende se a AI surgiu no contexto ou em um plano;● Essa função unificadora é importante para o caso do valor ligado a
variáveis AgentSpeak for necessário para a implementação da AI;
– O terceiro é um array de termos e contém os argumentos passados para a AI pelo usuário no código AgentSpeak que chama a AI;
Definindo uma nova ação interna
● O segundo método de DefaultInternalAction– Chamado de suspendIntention
● Deve retornar true quando a AI causar uma suspensão do estado da intenção, assim como
– .at e também .send com askOne como performativa;● Por padrão o método retorna false;
– O usuário precisa garantir que a intenção será retomada quando for o caso (se o método suspendIntention for sobrescrito);
– O código Java para execução da ação interna math.distance possui três etapas:
Passo 1: ● obter as referências dos parâmetros
Passo 2: ● Realizar os cálculos
Passo 3: ● Organizar, unificar e retornar os
resultados
Definindo uma nova ação interna
● Para o caso da AI ter sido usada no contexto do plano retornar falso significa que o plano não é aplicável;
● Quando usado em um corpo de um plano, retornar falso irá causar uma falha no plano;
Exemplo alternativo (um bingo!)
● Existe um ambiente (Cartago) será um “bingo” onde números serão sorteados depois de X cartelas “vendidas”;
● Existem dois agentes: um proprietário (owner) e um jogador (player);
– O owner cria o artefato “Bingo” e monitora-o a fim de perceber se as X cartelas foram vendidas. Feito isso, ele realiza uma operação no ambiente para iniciar o sorteio;
– O player fica “vagando” até encontrar o artefato “bingo”. Ao encontrar realiza uma operação de “compra” para participar do sorteio. Após isso sua função é monitorar o ambiente esperando por números sorteados (informados por meio de sinais) e pelo final do sorteio.
● Este possui uma internal action chamada de buildCard que fica no pacote ias. Ela gera aleatoriamente uma cartela de N números com um um teto T para o sorteio dos números.
Ação interna buildCardpackage ias;public class buildCard extends DefaultInternalAction{private Set <Integer> box = new HashSet <Integer>();
@Overridepublic Object execute (TransitionSystem ts, Unifier un, Term[] args) throws Exception{
NumberTerm size = (NumberTerm) args[0]; //tamanho da cartelaNumberTerm max= (NumberTerm) args[1]; // TETO para um numero sorteado
Random r = new Random();while (box.size() < size.solve())
box.add(r.nextInt((int)max.solve()) + 1); //garantir a não repetição dos números da cartela
ListTerm result = new ListTermImpl();for (Integer i : box){
Term t = new NumberTermImpl(i);result.add(t); //converter a cartela em um feedback para o
agente}return un.unifies(result, args[2]);
}}
Estrutura e planos do agente Player/* Initial beliefs and rules */
/* Initial goals */
!participate.
/* Plans */
+!participate: true<- ?myArtifact (ID);focus(ID);sell; //buy - adquire uma cartelaprintln("Comprei uma cartela ...no bingo:", ID);ias.buildCard(5, 40, Card); .concat("Cartela:", Card,S); println(S); +myCard(Card); Hit = 0; +myHits(Hit).
+?myArtifact(C) : true <-lookupArtifact("b0", C).
-?myArtifact(Art) : true <-.wait(1000);println("Esperando por um bingo.");!participate.
Chamada para a ação interna
Registrando a cartela na base de crença
Registrando o número de acertos na base de crença
Percepções do agente Player//Perceptions of the signals
+status(S) : S == "sorted" & myCard(Card) & myHits(Hit) <-?numSorted(V);println("Opa, percebi um numero sorteado ... ", V);if (.member(V, Card) ) {+myHits(Hit+1);println("acertei:", V, " Ate agora acertei ", Hit+1, " numero(s) em um total de ", .length(Card));}.
+myHits(Hit) : myCard(Card) <-if (Hit == .length(Card)){ print("Gaaaaaaaaaaaaaaaaaaaannnnnnnnnnnnhhhhhhhhhhheeeeeeeeiiiiiii!!"); winner;}.
+status(S) : S == "started" <-println("Legal! Bingo inciado!").
+status(S) : S == "stoped" <- println("Ahhhh .. já acabou.").
//Percepctions of the Observable Properties+numSorted(V).
Personalizando a classe Agente
● Partindo do ponto de vista do interpretador AgentSpeak um agente é:– Um conjunto de crenças; – Um conjunto de planos;
– Algumas funções de seleção definidas pelo usuário;
– Funções de confiança (uma relação socialmente aceitável para mensagens recebidas);
– A função de atualização de crença;
– A função de revisão de crenças;
– Elementos circunstanciais (eventos pendentes, intenções e outras estruturas necessárias durante a interpretação de um agente em AgentSpeak);
Personalizando a classe Agente
● A implementação padrão destas funções está na classe Agent que pode ser customizada por desenvolvedores a fim de estender funcionalidades básicas;
● Alguns dos métodos da classe pode ser enxergado no diagrama a seguir;
Personalizando a classe Agente
Personalizando a classe Agente● Métodos da classe Agent que
normalmente são sobrescritos:– selectMessage
(Queue<Message> mailbox)● Seleciona a mensagem que será
manipulada no atual ciclo de raciocínio;
● Na implementação padrão o método retorna e remove a primeira mensagem na caixa do agente;
● Implementa a função SM
Recorte do ciclo de raciocínio Jason
Personalizando a classe Agente● Métodos da classe Agent
que normalmente são sobrescritos:– selectEvent
(Queue<Event> events);
– Seleciona o evento que será manipulado no atual ciclo de raciocínio;
– A implementação padrão remove e retorna o primeiro evento na fila;
– Implementa a função SE
Recorte do ciclo de raciocínio Jason
Personalizando a classe Agente
● Métodos da classe Agent que normalmente são sobrescritos:– selectOption
(List<Option> options)– É usado para selecionar um
dentre várias opções para manipular um evento;
– A implementação padrão remove e retorna a primeira opção de acordo com a ordem de escrita dos planos do código do agente;
– Implementa a função S0
Recorte do ciclo de raciocínio Jason
Personalizando a classe Agente
● Métodos da classe Agent que normalmente são sobrescritos:
– selectIntention
(Queue<Intention> intentions)
– Seleciona uma intenção para continuar a ser executada no atual ciclo do raciocínio;
– A implementação padrão remove e retorna a primeira intenção da fila e após a execução da intenção é inserida no final da fila (como em um round robin)
– Implementa a função SI
Recorte do ciclo de raciocínio Jason
Personalizando a classe Agente
● Métodos da classe Agent que normalmente são sobrescritos:
– socAcc(Message m)
● Retorna true se a mensagem m é socialmente aceitável;● A implementação padrão retorna true para todas as mensagens;● Se segurança for um problema, então este método deve
sobrescrito;
– Caso contrário, o agente ficará suscetível a simples ataques de DoS;
– buf(List<Literal> percepts)
● Atualiza a base de crenças com as percepções dadas;● Adiciona todas as alterações efetivadas como novos eventos em
um conjunto de eventos;
Personalizando a classe Agente
● Métodos da classe Agent que normalmente são sobrescritos:
– brf(Literal add, Literal rem, Intention i)
● Revisa a base de crença com um literal a ser adicionado (se houver), outra a ser removido (se houver) e a estrutura da intenção é requerida para alterar a crença
● A implementação padrão não faz nada e o método deve ser sobrescrito ( ou seja, não há um revisor padrão de crenças em Jason);
● Retorna duas listas em uma matriz (uma com os acréscimos na base de crença e outra com as exclusões);
– As listas podem ser úteis para gerar eventos relevantes;● É importante enfatizar que a função de atualização de crença em
Jason apenas atualiza a base de crenças e gera eventos externos de acordo com as percepções atuais;
– Ela NÃO garante consistência de crença;
Personalizando a classe Agente
● A implementação padrão da função de atualização da base de crença funciona da seguinte forma:
Conjunto de todos os literais atualmente na base de crença
Lista das percepções atuais recebidas
Conjunto de eventos
Um primeiro exemplo de personalização da classe Agent
● Vamos mudar a função de seleção de eventos do robô aspirador de pó (descrito no cap. 5);
– Agora, ela priorizará eventos criados quando a sujeira é percebida;
● A fila de eventos possui eventos criados a partir das percepções (sujo; pos(r); pos(l)) e ações internas criadas por intenções;
● O método passa por todos os eventos da fila e verifica se o gatilho é igual a sujo (dirty)
– Se for, a função remove da fila e retorna esse como único a ser tratado no atual ciclo de raciocínio;
– Se não, ele invoca a implementação padrão (que retorna o evento no início da fila);
● A seguir a implementação …....
Gatilho de uma percepção de sujeira
Retorna o comportamento padrão
Um primeiro exemplo de personalização da classe Agent
● Lembrando que o arquivo de configuração deve associar os agentes oriundos dessa nova classe da seguinte forma:
Nossa classe
Um segundo exemplo...
● Suponha que queremos indicar no código AgentSpeak de um agente que uma intenção deve ser selecionada apenas quando não há mais nada a fazer; – Vamos chamar essa intenção de “the idle intention”;
● Assim, o agente deve:– Selecionar a intenção ociosa somente se for a única intenção do agente;– Ou seja, enquanto o agente possui muitos focos simultâneos então a
intenção ociosa jamais deve ser selecionada;
● Para marcar uma intenção como ociosa, um programador deve adicionar uma anotação “idle” em um rótulo de plano que irá formar a intenção;– Quando este plano se torna a intenção significa que toda a intenção torna-
se “idle”;
● O código a seguir mostra a implementação da função Si
Considere o seguinte agente:
A saída seria:
Perceba que as duas intenções são executadas concorrentemente.
Se adicionarmos uma anotação rotulando o “idle” no último plano da seguinte forma:
Teremos então a seguinte saída:
Conclusões sobre a personalização da classe Agent
● Percebemos que é possível estender o Jason com novas funcionalidades (como a intenção ociosa);
● No entanto, vale enfatizar que ajustes nas funções de seleção são perigosos, pois emergem problemas típicos da programação concorrente como o starvation de intenções ou eventos;– Estes devem ser feitos com muito cuidado;
● Por outro lado, de qualquer maneira, na prática os agentes podem precisar morrer por inanição de eventos se o ambiente for bastante dinâmico;
Referência
● Bordini, R. H., Hübner, J. F., and Wooldridge, M. 2007. Programming Multi-Agent Systems in AgentSpeak Using Jason. John Wiley & Sons, Ltd.