Introdução à programação em NetLogo

Secções do NetLogo

O netlogo está dividido em várias secções:

Interfacesecção onde está disponível o aspecto gráfico e de interface da simulação
Informationsecção onde está disponível informação acerca do conteúdo do modelo e instruções de utilização
Proceduressecção onde está disponível o código fonte do modelo
Errorssecção onde surgem mensagens de erro durante o desenvolvimento dos modelos

Do ponto de vista do utilizador de um modelo, apenas interessam as secções "Interface" e "Information". Mas do ponto de vista de quem constrói o modelo, é indispensável utilizar as secções "Procedures" e os "Errors".

Em qualquer linguagem de programação os programas são constituídos por instruções que são executadas de forma sequencial.

No caso do netlogo, podem-se escrever instruções directamente na linha de comandos (command center) que são executados apenas quando introduzidas no momento. Ou podem-se escrever listas de instruções (funções) na secção "Procedures" que são executadas cada vez que se pressiona um botão da secção "Interface"

Vamos começar por ver as instruções mais simples.

Crie um modelo novo selecionando "New" no menu "File".

Linha de comandos e as instruções set e ask

Escreva a instrução seguinte na linha de comandos (caixa existente na secção "Interface" com o nome de "command center"):

ask patches [ set pcolor brown ]

Repare que a caixa de simulação se tornou castanha

Escreva agora a seguinte instrução:

ask patch 0 0 [ set pcolor red ]

Note que apareceu um quadrado (célula ou patch) pintado de vermelho no centro da caixa de simulação. Vejamos como se escrevem estas instruções.

Podemos separar a primeira instrução em duas partes:

ask patches que significa "pedir às células"

set pcolor brown alterar a propriedade pcolor para castanho

O comando ask tem a forma geral de:

ask objecto [ instruções ]

instruções é a lista de uma ou mais instruções

E o comando set a forma:

set variável/propriedade valor

Este último comando é bastante intuitivo, atribui o valor à variável ou propriedade.

Estamos agora em posição de compreender melhor a segunda instrucção usada anteriormente.

ask patch 0 0 "pedir à célula na posição 0 0" que execute a instrução set pcolor black

Experimente agora a seguinte instrução:

ask patches with [ pcolor = black ] [ set pcolor red ]

Esta é outra forma do comando ask que permite executar instruções apenas para as células que verificam a condição entre parentesis rectos a seguir à palavra with

O formato geral deste comando é:

ask objecto with [ condição ] [ instruções ]

Podem-se construir condições mais complexas com a ajuda dos operadores booleanos and,or,not (e,ou,não)

Objectos e propriedades

Escrevendo set pcolor green directamente na linha de comandos causa o seguinte erro:

ERROR: You can't use PCOLOR in an observer context, because PCOLOR is turtle/patch-only.

Isto acontece porque qualquer instrução é sempre executada do ponto de vista (contexto) de um objecto, e cada objecto possuí umas dadas propriedades.

Existem 3 tipos principais de objectos o Observer, as Turtles e as Patches. A instrução anterior dá erro porque é executada no contexto do Observer que não possuí nenhuma propriedade pcolor, apenas as Patches possuem essa propriedade.

Ao executar a instrução ask patches [ instruções ] as instruções são executadas do ponto de vista dos patches que, essas sim, possuem a propriedade pcolor.

Tambem algumas instruções existem apenas em determinados contextos, como o forward que existe apenas no contexto das turtles ou o sprout que existe apenas no contexto dos patches.

para mais informações acerca das propriedades e instruções existentes para cada contexto, veja o manual de referência do netlogo que se encontra aqui

Clicando onde aparece "O >" na linha de comandos, pode-se escolher o contexto em que se executam as instruções. A utilização da tecla "Tab" é outra forma de trocar de contexto na linha de comandos.

Quando se está a programar o modelo (secção "Procedures") a única forma de trocar de contexto é através da instrução ask

Sabendo que pxcor e pycor são as propriedades dos patches que correspondem às coordenadas x e y da célula, escreva uma instrução que pinte de branco todas as células com coordenada y negativa. resposta

ask patches with [ pycor < 0 ] [ set pcolor white ]

Síntaxe da instrução if

A forma geral da instrução if é:

if condição [ instruções ]

Como o nome indica esta instrução apenas executa a lista de instruções se a condição for verificada.

Síntaxe da instrução ifelse

ifelse condição [ instruções1 ] [ instruções2 ]

Esta instrução executa a primeira lista de instruções se a condição for verdadeira e executa a segunda lista de instruções se a condição for falsa.

Modelo simples de percolação

Sabendo os comandos essenciais podemos construir o nosso primeiro modelo.

Para isso começamos por construir o interface de utilizador.

Crie um botão "preparar", clicando no icone "button" e fazendo clique de novo numa zona livre da janela.

Escreva no campo "code" a palavra "preparar" e confirme a criação do botão premindo "ok"

Note que as letras "preparar" do botão acabado de criar e das secções "Interface" e "Errors" tornaram-se vermelhas.

Isto é um aviso do programa NetLogo que encontrou alguma falha no seu modelo.

Para obter mais informações acerca dos erros pode clicar na secção "Errors".

Neste caso existe um erro porque a função "preparar" ainda não foi definida.

Quando um utilizador clica no botão "preparar" a função com o mesmo nome é executada. Vamos agora definir essa função. Para isso mude para a secção "Procedures" e escreva:

 to preparar
   ca
   ask patches [
     set pcolor brown
   ]
 end

ca é uma abreviatura de clear-all e serve não só para limpar e inicializar a janela do NetLogo como tambem todas as variáveis internas

Funções

Funções são instruções definidas pelo utilizador

A forma geral de definição de funções é:

to função [ argumento1 argumento2 ... ]
  instruções
end

Para chamar esta função basta escrever: função valor1 valor2 ...

O exemplo a seguir define uma função que pinta um quadrado de células de lado L na posição X,Y

to quadrado [ X Y L ]
  ask patches with [ X - L / 2 < pxcor and pxcor < X + L / 2 and Y - L / 2 < pycor and pycor < Y + L / 2 ]
    [ set pcolor blue ]
end

Um exemplo da utilização desta instrução é: quadrado 0 0 10 que pinta um quadrado de lado 10 no centro da caixa de simulação.

Existe ainda outro tipo de funções que devolvem um valor. Um exemplo de uma função deste tipo é a que calcula o quadrado de um número.

to-report q [ x ]
  report x * x
end

Neste caso a função em vez de começar pela palavra to começa por to-report e algures na função deve existir uma chamada à instrução report que define o resultado que deve ser devolvido.

Pode-se usar esta função numa instrução como: set abc q 3. A função q é executada com a variavel "x" igual a 3. No final a função devolve 9. Por fim é atribuido à variavel "abc" o valor 9.

Voltando ao nosso modelo, repare que pressionando o botão criado, limpa-se e inicializa-se o NetLogo e todas as células da caixa de simulação ficam pintadas de castanho.

Adicione agora outro botão que corra a função "executar" quando pressionado. Mas desta vez clique na opção "forever". Esta opção faz com que o botão fique pressionado "para sempre" ou seja, a função é chamada repetidamente até a simulação parar ou o utilizador carregar no botão de novo.

Na secção "Procedures" escreva a função executar da seguinte forma:

 to executar
   ask patches with [pcolor = red] [
     ask patches at-points [[0 -1]] [
       set pcolor red
     ]
     set pcolor black
   ]
 end

Esta função procura todos os pontos com cor vermelha e para cada um encontrado pinta de vermelho a célula imediatamente abaixo (de coordenadas relativas x=0 y=-1), no fim pinta a própria célula de preto.

Nada acontece clicando em "executar" visto que não existem células vermelhas na janela do NetLogo. Experimente escrever na linha de comandos do NetLogo o seguinte comando:

ask patches at-points [[0 8]] [ set pcolor red ]

O que vai acontecer quando executar esta função pressionando o respectivo botão?

Clique em "executar". Os resultados estão de acordo com o que esperava observar?

Pintando de vermelho, continuamente, as células que se encontram abaixo de células vermelhas, faz com que apareça uma linha preta. Repare no entanto que a célula abaixo da última célula vertical é a primeira célula no topo e por isso quando a linha chega ao fundo, continua a ser traçada a partir de cima.

Acrescente agora o comando que usou para pintar uma célula de vermelho no fim da função "preparar"

Este exemplo modela de uma forma extremamente simples a infiltração de um líquido num solo poroso.

Para o tornar mais realista alteremos o modelo para que pinte uma célula vermelha mediante uma dada probabilidade. A função "executar" é alterada para:

 to executar
   ask patches with [pcolor = red] [
     ask patches at-points [[0 -1]] [
       if (random-float 100 < 75) [
         set pcolor red
       ]
     ]
     set pcolor black
   ]
 end

random-float 100 é um comando que retorna um número aleatório entre 0 e 100 não inclusive. Desta forma apenas pintamos a célula abaixo quando o número aleatório devolvido for menor que 75.

Correndo a simulação não se notam diferenças excepto que o tempo de simulação aumenta.

Para tornar a infiltração mais realista em vez de pintarmos a célula abaixo das células vermelhas, alteremos o código para pintar as células em baixo à esquerda e à direita da célula inicial.

     ask patches at-points [[0 -1]] [

Fica então:

     ask patches at-points [[-1 -1] [1 -1]] [

No entanto continuamos com um problema que é o que fazer quando a mancha de óleo chega à última linha

Uma opção é em cada ciclo verificar se o óleo voltou ao topo, e nesse caso limpar o terreno contaminado pintando todas as células pretas de castanho

Assim criamos uma nova função "verificar":

 to verificar
   if (pycor-of one-of patches with [pcolor = red] = screen-edge-y) [
     display
     ask patches with [pcolor = black] [
       set pcolor brown
     ]
   ]
 end

De modo a organizar melhor o código devemos mudar o nome da função "executar" para "percolar" e criar outra função "executar" que por sua vez chama a função "percolar"

 to executar
   percolar

  if not any? patches with [pcolor = red]
    [ stop ]

   verificar
 end

 to percolar
   ask patches with [pcolor = red] [
     ask patches at-points [[-1 -1] [1 -1]] [
       if (random-float 100 < 62) [
         set pcolor red
       ]
     ]
     set pcolor black
   ]
 end

Para podermos visualizar melhor a simulação é conveniente aumentar o tamanho da caixa de simulação. Para isso, clique com o botão direito do rato na caixa e escolha a opção "edit". Altere os valores do tamanho da caixa de acordo com a imagem abaixo e confirme as alterações premindo o botão "ok".

Execute agora a simulação e observe o resultado

Barra de ajuste de parametros

Vamos acrescentar uma barra que nos permita variar a probabilidade de infiltração de uma gotícula de óleo. Carregue no botão "Slider" e clique numa zona vazia da janela de modo a acrescentar esse componente.

No código (secção "Procedures") é necessário alterar apenas a linha:

  if (random-float 100 < 62) [

substituindo-a por

  if (random-float 100 < porosidade) [

Desta forma permite-se que o utilizador possa experimentar vários valores do parâmetro e estudar diferentes comportamentos do modelo.

Traçar gráficos

Podemos ainda acrescentar um gráfico onde será traçada a contaminação total do solo ao longo da simulação. Para isso cria-se uma variável global que é incrementada à medida que o solo é contaminado.

Para criar uma variável global acrescenta-se o código seguinte no início do texto da secção "Procedures".

 globals [
   contaminacao
 ]

Na função "preparar" acrescenta-se:

  set contaminação 0

E na função percolar, acrescenta-se a seguir à linha:

   set pcolor black

a linha:

   set contaminacao (contaminacao + 1)

Adicione agora o gráfico clicando no botão respectivo da barra de ferramentas e em seguida numa zona vazia da janela.

Para o nome do gráfico, introduza:"Terra Contaminada".Tenha em atenção que é necessário escrever o nome exactamente da mesma forma, incluíndo, espaços maiusculas/minusculas, que vai escrever no código.

Acrescente agora uma função "desenhar-grafico" com o seguinte código:

 to desenhar-grafico
   set-current-plot "Terra Contaminada"
   plot contaminacao
 end

set-current-plot é o comando que define em que gráfico se quer marcar o novo ponto

plot marca um ponto no gráfico escolhido previamente.

Finalmente é necessário que esta função seja chamada após cada iteração. Para isso, a seguir à linha onde se chama a função "percolar" acrescente:

 desenhar-grafico 

Assim concluímos esta introdução à programação em netlogo.