You are here

Aula 03: SOAR Tutorial 2

A seguinte imagem apresenta o programa iniciando de Eaters

Ilistração 1

Apos carregar o arquivo move-to-food.soar é rodado o programa e a saída dele e apresentada na Ilustração 2

Nesta parte o eater começo a comer algumas bolinhas até ele chegar no canto inferior esquerdo, ali ele ficou presso e o Soar Debugger apresento a seguinte mensagem:

          Goal stack depth exceeded on a no-change impasse. Soar appears to be in an infinite loop.

Ilustração 2

Quando é feita um segundo teste o resultado é o apresentado na Ilustração 3. O eater fica quieto quando não tem comida nos quadros ao redor dele.

Ilustração 3

A saída do SoarDebugger apresentada na Ilustração 4, mostra que quando o eater está numa posição que não tem comida nos quadros do lado ele apresenta a massagem:

      ==>S: S13 (state no-change)

Essa mensagem significa que não existe nenhuma regra que possa ser utilizada nesse estado, é dizer, quando o eater fica sem comida ao redor dele, ele não sabe o que fazer e o programa entra num loop infinito onde o estado não muda.

Ilustração 4

Na ilustração 5 é apresentado o código em SOAR do arquivo move-to-food.soar. Neste arquivo é definido um operador chamado  

Ilustação 5

P1: Como o estado atual da criatura é considerado nas regras ?. 

R: Na primeira regra a condição pergunta se a criatura tem alimento em algum quadro perto dele.

P2: Como a decisão de ação escolhida é aplicada de fato ao jogo ?

R: A ação de decisão é proposta como aleatória por meio dos caracteres “+” e “=”.

P3: Como esse conjunto de regras escolhe a direção para a qual a criatura deve se mover ?

R: O conjunto de regras neste arquivo escolhe a direção perguntando somente se ela tem comida ou não. Se ele tem comida então propõe o operador de movimentação, se não tem comida não faz nada.

P4: Para que serve a regra apply*move-to-food*remove-move ?

R: A regra apply*move-to-food-remove-move serve para eliminar o comando de saída quando ele este completo.

P5: O que aconteceria se ela não existisse ?

R: Se a regra apply*move-to-food-remove-move não existisse a criatura se movimentaria só na direção proposta na primeira aplicação da regra já que para cada aplicação da regra vai ter a mesma saía, a primeira delas.

P6: Quais são as limitações desse programa ? 

R: As limitações desse programa é o fato de não considerar a opção da criatura quedar sem comida nos quadros adjacentes, porque ela só é verdadeira quando a criatura tem comida em algum quadro perto.

P7: O que seria necessário fazer para que ele não ficasse paralizado, depois de um tempo ?

R: Seria necessária a implementação de um operador que contemple a possibilidade da criatura se movimentar quando não tivesse comida nos quadros adjacentes.

 

Building a Simple Eater Using Rules

O primeiro que será feito é um operador que permita à criatura se movimentar para o norte.

Todo estado tem um atributo chamado io que a sua vez tem outro atributo chamado output-link.

Em Soar, todas as ações externas são realizadas por elementos na working memory que são agregados ao elemento output-link

Em Eaters o comado de movimentação (move) é emitido criando o agregado no objeto output-link. O elemento move também tem um atributo chamado direction com o valor da direção a se movimentar.

Os valores validos para direction são: “north”, “south”, “east”, ou “west”. A estrutura do comando de saída é apresentada na Ilustração 6.

 

 

Ilustração 6

Por cada tarefa em Soar, é definido um conjunto de comandos, e neste casso tem-se duas tarefas: movimentar (move) e pular (jump)

 

Move-north operator

O primeiro operador a ser realizado é o move-north operator o operador simplesmente vai gerar um comando de movimentação na direção norte. A proposta da regra em inglês é:

# Propose*move-north:
# If I exist, then propose the move-north operator.
# Apply*move-north:
# If the move-north operator is selected, then generate an output command to
# move north.


A Proposta em soar ele é:

sp {propose*move-north
   (state <s> ^type state)
-->
   (<s> ^operator <o> +)
   (<o> ^name move-north)}

E a aplicação é:

sp {apply*move-north
    (state <s> ^operator <o>
               ^io <io>)
    (<io> ^output-link <out>)
    (<o> ^name move-north)
-->
    (<out> ^move <move>)
    (<move> ^direction north)}

A saída no Soar é apresentada na Ilustração 7. Aqui se pode ver como o operador move-north é aplicado e depois o estado não muda mais. Neste ponto a criatura só se pode movimentar uma umica vez para o norte.

Ilustração 7

A saída do jogo é apresentada na Ilustração 8

Ilustração 8

 

Para lograr que a criatura se movimente mais de uma vez é necessário criar uma instancia do operador e aplicá-lo cada vez que se tenha uma mudança no estado. Para obter essa mudança se pode utilizar a entrada do estado. Ao movimentar a criatura ela cambia de posição, e sua entrada também cambia, então o ciclo ficaria assim:

 

Ilustração 9

A estrutura do objeto de entrada para o programa eater é apresentada na Ilustração 10.

Ilustração 10

É modificada a proposta do operador para que ele fique assim:

sp {propose*move-north
     (state <s> ^io.input-link.eater <e>)
     (<e> ^x <x> ^y <y>)
-->
     (<s> ^operator <o> +)
     (<o> ^name move-north)}

A ilustração 11 apresentada a saída do programa com a codificação na regra.

Ilustração 11

Agora serão escritas as regras para que a criatura se movimente a qualquer espaço perto dele que tenha comida, as regras em inglês são:

# Propose*move-to-food*normalfood
# If there is normalfood in an adjacent cell,
# propose move-to-food in the direction of that cell
# and indicate that this operator can be selected randomly.
 

# Propose*move-to-food*bonusfood
# If there is bonusfood in an adjacent cell,
# propose move-to-food in the direction of that cell
# and indicate that this operator can be selected randomly.

# Apply*move-to-food
# If the move-to-food operator for a direction is selected,
# generate an output command to move in that direction.
 
# Apply*move-to-food*remove-move:
# If the move-to-food operator is selected,
# and there is a completed move command on the output link,
# then remove that command.

A Ilustração 12 apresenta a saída do jogo e do SoarDebugger

Ilustração 12

 

Debugging Soar Programs

Os programas de Soar podem ter dois tipos de erros, os erros de sintaxe e os erros semânticos. Os erros de sintaxe são facilmente detectáveis usando a ferramente VisualSoar. Os error semânticos são erros da lógica do programa e são as vesses mais difíceis de achar, para isso o Soar tem muitos comandos para ajudar na localização de esse tipo de erros

 

Generalized Move Operator

A regra de proposta do operador para o movimento da criatura, em inglês é:

# Propose*move:
# If there is no wall
# propose move in the direction of that cell
# and indicate that this operator can be selected randomly.

A Ilustração 13 apresenta o final do jogo. A criatura consegui acabar toda a comida, mas demora muito, 2238 movimentos.

 Ilustração 13

Para melhorar esse tempo se podem propor regras de preferência, para que Soar pegue um operador mas adequado.

A primeira dessas regras que é a criatura prefira ir onde esta a comida com bonus, do que a comida normal ou que o espaço vazio ou onde esta outra criatura.

# Select*move*bonusfood-better-than-normalfood
# If there is a proposed operator to move to a cell with bonusfood and
# there is a second proposed operator to move to a cell that is empty or
# has normalfood or another eater
# prefer the first operator.

Para colocar um operador em melhor posição do que outro é possível utilizar a preferência de melhor (better) utilizando o símbolo “>”. O caso contrário também é valido, quando se quer colocar um operador em uma posição inferior se usa o operador de (worse) utilizando o símbolo “<”

Assim a regra para propor o operador que coma comida com bonus sobre as demais possibilidades é:

A regra para que a criatura prefira ir para um espaço vazio ou com outra criatura pode ser colocada como menor adequada usando o operador de (worse)

A Ilustração 14 apresenta o jogo completado, com as novas regras de preferência o número de movimentos diminuiu até 764.

Ilustração 14

 

Advanced Move Operator Proposal

Nesta seção são criadas as regras necessária para que o a criatura não faça o movimento anterior ao feito, evitanto assim que perca energia indo por exemplo de esquerda a direita e de nodo de direita a esquerda. Para evitar esse tipo de comportamento é necessária a criação de estruturas que sejam permanentes e não sejam eliminadas após aplicar o operador.

Na Ilustração 15 é possível ver que a última direção tomada foi o norte, assim nas regras propostas não esta contemplada a possibilidade dê-se movimentar para o sul.

 

Ilustração 15

Na Ilustração 16 pode-se ver como o jogo termina com menos passos (477) do que na etapa anterior da Ilustração 14 (764)

Ilustração 16

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer