You are here

Tutorial 9 - Memória Episódica

 

Memória episódica é um mecanismo do SOAR que AUTOMATICAMENTE captura, indexa e armazena os ESTADOS do agente, provendo uma interface que permite o acesso a essa informação AUTOBIOGRÁFICA do agente.
 
Igualmente à memória semântica, o acesso à memória episódica é feito a partir de uma interface onde comandos são enviados pelo agente e os resultados são fornecidos pela arquitetura; neste caso, as extensões são as seguintes:
 
  • ^epmem.command: interface onde o agente cria comandos para serem tratados pela memória episódica
  • ^epmem.result: interface onde a arquitetura cria as respostas aos comandos enviados
 
 
De forma diferente da memória semântica, as informações da memória episódica são automaticamente criadas e esse processo é governado pelo seguinte comando:
 
epmem --set trigger <dc | output | input>
 
 
Esse comando indica em qual ponto um SNAPSHOT do estado atual deve ser capturado: dc - "decision cycle" ou output - "output cycle". Por default SOAR utiliza output.
 
 
Para que seja utilizada, a memória semântica precisa ser habilitada, através do comando:
 
epmem --set learning on
 
 
 
É possível criar uma representação gráfica dos elementos na memória episódica, também com o uso do pacote Graphviz; o seguinte episódio:
 
epmem --print 1
(<id0> ^io <id1> ^reward-link <id2> ^superstate nil ^type state)
(<id1> ^input-link <id4> ^output-link <id3>)
 
 
Pode ser gravado para ser representado pelo Graphviz com o seguinte comando:
 
command-to-file <output-filename> epmem --viz 1
 
 
E transformado em gráfico da seguinte forma:
 
dot -Tpng <output-filename> -o <image-filename>.png
 
 
 
 
 
 
 
Durante o processo de captura de um episódio - ou seja, de um SNAPSHOT do estado atual - é possível indicar ao SOAR extensões que devem ser ignorada e NÃO devem fazer parte do episódio capturado. Isso é feito com o uso do comando:
 
epmem --set exclusions <attribute>
 
 
A lista de exclusões configurada pode ser obtida com o comando:
 
epmem --get exclusions
 
 
Por fim, para que se possa observar o processo de criação de episódios, pode ser utilizado o comando:
 
watch --epmem
 
 
 
 

INTERAÇÃO DO AGENTE COM A MEMÓRIA EPISÓDICA

 
Por default os comandos que o agente envia para a memória episódica são tratados durante a fase de OUTPUT; esse parâmetro pode ser alterado pelo seguinte comando:
 
epmem --set phase <selection | output>
 
 
Apenas 1 comando pode ser enviado por vez.
 
 
O tutorial segue o exemplo "epmem-tutorial.soar" para discutir os comandos suportados para a interação com a memória episódica.
 
 
Os comandos surportados são os seguintes:
 
  • "^query <cue>": permite buscar na memória episódica um episódio que MELHOR satisfaça a condição de busca, ou seja, tenha maior semelhança com a estrutura descrita com "<cue>", comparando apenas os NÓS FOLHA. No limite, se houver mais de um episódio que contenha uma estrutura IDÊNTICA com a especificada, o episódio mais recente (ou seja, de maior "^id") é retornado.
  • "^previous <id>": busca o episódio anterior ao ÚLTIMO episódio que foi recuperado da memória episódica.
  • "^next <id>": busca o episódio posterior ao ÚLTIMO episódio que foi recuperado da memória episódica.
 
 
 
Seguindo o programa exemplo, logo de início é criada a seguinte estrutura no estado atual:
 
p s1 -d 2
(S1 ^epmem E1 ^feature value3 ^feature2 value ^id E2 ^id E3 ^io I1 ^name epmem
       ^operator O2 + ^other-id E4 ^reward-link R1 ^smem S2 ^superstate nil
       ^type state)
  (E1 ^command C1 ^present-id 1 ^result R2)
  (E2 ^sub-feature value2)
  (E3 ^sub-id E5)
  (I1 ^input-link I2 ^output-link I3)
  (O2 ^name cbr)
  (E4 ^sub-feature value2 ^sub-id E6)
  (S2 ^command C2 ^result R3)
 
 
Ao se atingir a etapa de OUTPUT, é criado o episódio 1 com as seguintes informações:
 
epmem --print 1
(<id0> ^feature value3 ^feature2 value ^id <id2> <id3> ^io <id1> ^name epmem ^operator* <id5> ^other-id <id4> ^reward-link <id6> ^superstate nil ^type state)
(<id1> ^input-link <id8> ^output-link <id7>)
(<id2> ^sub-feature value2)
(<id3> ^sub-id <id9>)
(<id4> ^sub-feature value2 ^sub-id <id10>)
(<id5> ^name cbr)
 
 
 
 
 
 

O comando QUERY

 
O programa exemplo ilustra o uso do comando "^query" com as seguintes regras:
 
sp {epmem*apply*cbr-clean
   (state <s> ^operator <op>
              ^feature2 <f2>
              ^feature <f>
              ^id <e2>
              ^id <e3>
              ^other-id <e4>)
   (<e2> ^sub-feature value2)
   (<e3> ^sub-id)
   (<op> ^name cbr)
-->
   (<s> ^feature2 <f2> -
        ^feature <f> -
        ^id <e2> -
        ^id <e3> -
        ^other-id <e4> -)
}
 
sp {epmem*apply*cbr-query
   (state <s> ^operator <op>
              ^epmem.command <cmd>)
   (<op> ^name cbr)
-->
   (<cmd> ^query <n1>)
   (<n1> ^feature value
        ^id <n2>)
   (<n2> ^sub-feature value2
         ^sub-id <n3>)
}
 
 
 
A primeira regra, "epmem*apply*cbr-clean", aplica o operador "cbr" para remover algumas das estruturas inicializadas no estado e que foram capturadas no episódio 1; a segunda regra, "epmem*apply*cbr-query", aplica o mesmo operador "cbr" para criar o comando de QUERY, buscando justamente por algumas das estruturas removidas.
 
 
Representação da consulta realizada no comando "^query"
 
 
Até que o comando QUERY seja executado, SOAR captura ainda um segundo episódio - uma vez que atinge novamente a fase de OUTPUT:
 
NEW EPISODE: 2
CONSIDERING EPISODE (time, cardinality, score): (1, 2, 2.000000)
NEW KING (perfect, graph-match): (false, false)
 
 
Apenas o primeiro episódio é retornado, com uma pontuação de 2, que não representa um "perfect match", uma vez que havia 3 nós na consulta. De fato, os nós que pontuaram foram os seguintes:
 
 
 
 
 
Os valores retornados como resultado do comando são os seguintes:
 
p e1 -d 10
(E1 ^command C1 ^present-id 3 ^result R2)
  (C1 ^query N1)
    (N1 ^feature value ^id N2)
      (N2 ^sub-feature value2 ^sub-id N3)
  (R2 ^cue-size 3 ^graph-match 0 ^match-cardinality 2 ^match-score 2.
         ^memory-id 1 ^normalized-match-score 0.6666666666666666 ^present-id 3
         ^retrieved R4 ^success N1)
    (R4 ^feature value3 ^feature2 value ^id I5 ^id I6 ^io I4 ^name epmem
           ^operator* O5 ^other-id O4 ^reward-link R5 ^superstate nil
           ^type state)
      (I5 ^sub-feature value2)
      (I6 ^sub-id S3)
      (I4 ^input-link I7 ^output-link O6)
      (O5 ^name cbr)
      (O4 ^sub-feature value2 ^sub-id S4)
 
O episódio 1 está a partir da extensão R4.
 
 
 

O comando NEXT

 
Na sequência do programa exemplo, é aplicado o comando NEXT a partir da seguinte regra:
 
sp {epmem*apply*next
   (state <s> ^operator <op>
              ^epmem.command <cmd>)
   (<op> ^name next)
   (<cmd> ^query <q>)
-->
   (<cmd> ^query <q> -
          ^next <next>)
}
 
 
Uma vez executado esse comando, além da criação de um novo episódio (novo ciclo OUTPUT) é retornado o episódio 2:
 
NEW EPISODE: 3
p e1 -d 10
(E1 ^command C1 ^present-id 4 ^result R2)
  (C1 ^next N4)
  (R2 ^memory-id 2 ^present-id 4 ^retrieved R6 ^success N4)
    (R6 ^io I8 ^name epmem ^operator* O7 ^reward-link R7 ^superstate nil
           ^type state)
      (I8 ^input-link I9 ^output-link O8)
      (O7 ^name next)
 
 
 
 
 
 

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer