Você está na página 1de 24

CAP 6 -Procedimentos

6- Procedimentos
Agora temos uma compreensão mais clara das propriedades dos símbolos

físicos. No sistema representado, 𝐷 , as entidades podem ser qualquer coisa,
reais ou imaginárias, mas no sistema de representação, Ĝ, os símbolos devem ser
fisicamente instanciados e ter formas distinguíveis. Precisamos agora
compreender as propriedades das funções em P̂ que desempenham um papel
nos sistemas representacionais fisicamente realizados.
Assim como a nossa compreensão dos símbolos em Ŝ mudou quando
consideramos as propriedades físicas desejáveis, o mesmo deve acontecer com a
nossa compreensão das funções em Ŝ. P̂. Neste capítulo exploramos as
propriedades de funções computáveis ​e fisicamente realizáveis ​em um sistema
representacional. As funções computacionais são o que permite que as funções
sejam colocadas em uso produtivo, assim como distinguir símbolos e estabelecer
referentes para eles é o que permite que os símbolos sejam colocados em uso
produtivo.

Algoritmos
Conforme discutido no Capítulo 3, as definições de função podem estabelecer
que existe um mapeamento de membros do domínio para membros do
contradomínio sem necessariamente fornecer um método ou processo para
determinar a saída para uma determinada entrada.
Um método ou processo claro e inequívoco que permite determinar
roboticamente os mapeamentos de entrada/saída de uma função é chamado de
algoritmo. Por exemplo, o método de multiplicação longa que as crianças do
ensino fundamental aprendem é um algoritmo para determinar o símbolo do
produto de dois números. Vimos alguns algoritmos geométricos no Capítulo 4,
como o algoritmo para determinar um segmento de linha que é 1/n de outro
segmento de linha, onde n é qualquer número inteiro (Figura 4.1).
Para dar um exemplo comum, digamos que você tenha um suprimento
infinito de moedas, denominadas 25 centavos, 10 centavos, 5 centavos e 1
centavo. Vamos definir uma função de “troco” que mapeia uma quantia de
dinheiro de 99 centavos ou menos para o grupo mínimo de moedas que iguala a
quantia dada. Quarenta e três centavos seriam mapeados para uma das moedas
de 25 centavos, duas das moedas de 10 centavos, uma das moedas de 5 centavos
e três das moedas de 1 centavo. Quarenta e três moedas de 1 centavo dariam a
quantidade certa de troco, mas não o número mínimo de moedas. Essa função é

1
CAP 6 -Procedimentos

o que os caixas devem determinar rotineiramente (se não quiserem


sobrecarregá-lo com pilhas de centavos) ao devolver o troco de uma compra.
Hoje em dia, a função é geralmente implementada por um computador na caixa
registradora, que então distribui o troco de um porta-moedas. Embora bem
definida, a definição desta função não nos fornece um método para
determiná-la. Aqui está um algoritmo que determina esta função para um valor
devido:

1. Pegue a maior moeda de n centavos onde n ≤ o valor devido.


2. Reduza o valor devido em n centavos.
3. Se o valor devido for 0 centavos, devolva todas as moedas retiradas e pare.
4. Volte para o estado (linha) 1.

O princípio operacional básico é começar no Estado 1 (linha 1) e executar


cada estado em ordem (a menos que seja indicado o contrário). Estado é um
termo geral que se refere a um estágio/etapa discernível em que um processo
(procedimento) se encontra, durante o qual atuará de alguma maneira específica.
Cada linha numerada acima descreve um estado. O leitor é convidado a
experimentar alguns exemplos de aplicação deste algoritmo. Em geral,
sugerimos passar pelo processo de tentar qualquer algoritmo mostrado para se
convencer de que eles determinam a função que deveriam. Isto também lhe dará
uma ideia da natureza mecânica e estúpida dos processos – o que, em última
análise, permite que eles sejam instanciados por processos biomoleculares e
biofísicos.
Neste algoritmo que proporciona mudanças, vemos uma série de temas
que veremos novamente em várias encarnações: Há uma série de estados
distintos pelos quais o algoritmo prossegue. O estado determina o que fazemos
em um determinado momento. Existe a composição de funções, porque as
etapas posteriores dependem dos resultados das etapas anteriores. Há uma série
de funções incorporadas ao algoritmo maior, como subtração (redução) e a
relação ≤. O algoritmo retorna a um estado visitado anteriormente (volta ao
Estado 1). O algoritmo eventualmente para e retorna uma resposta. O algoritmo
toma “decisões” (se) com base na situação atual.
O facto deste algoritmo depender de outras funções para as quais não
existe nenhum algoritmo apresentado deve fazer-nos pensar. Como
determinamos “se o valor devido é 0 centavos” ou “a maior moeda de n centavos
onde n ≤ valor devido?” Em última análise, se quisermos desenvolver algoritmos
com os detalhes necessários para compreender como o cérebro pode
determinar tais funções, teremos de desenvolver todas as peças desses

2
CAP 6 -Procedimentos

algoritmos com processos que não deixam espaço para interpretação, e não
exigem necessidade de compreensão da língua inglesa. No próximo capítulo,
mostraremos um formalismo, a máquina de Turing, que pode ser usada para
expressar algoritmos de uma forma que não deixe nada aberto à interpretação.
Qualquer algoritmo específico determina uma função; entretanto,
qualquer função específica pode ser determinada por muitos algoritmos
possíveis. Outro algoritmo que determina a função de dar troco é uma tabela de
consulta. Possui 99 entradas. A Tabela 6.1 mostra alguns deles. Para determinar a
função, basta procurar a resposta (saída) na tabela. Se utilizasse esse algoritmo, o
caixa teria um pequeno cartão no qual estavam escritas as moedas que deveriam
ser devolvidas para cada valor de troco possível. O caixa então simplesmente
encontra o troco necessário no cartão e devolve as moedas associadas a ele.
Tabela 6.1 Tabela de consulta parcial para fazer alterações
Alteração devida (em centavos) Grupo mínimo de moedas (em centavos)
3 (1,1,1)
26 (25,1)
37 (25,10,1,1)
66 (25, 25, 10, 5, 1)
80 (25, 25, 25, 5)

Procedimentos, computação e símbolos


Os algoritmos nos quais estamos interessados ​descreverão o processo pelo qual
a saída de uma função em P̂ é determinado dados os argumentos da função.
Todas as funções em P̂ devem ter algoritmos para eles, pois não se pode fazer
uso produtivo de uma função a menos que se possa determinar a saída para
qualquer entrada permitida. Como toda função em P̂ mapeia símbolos físicos
para símbolos físicos, os algoritmos serão aplicados a símbolos físicos como
entrada e produzirão símbolos físicos para sua saída. Em última análise, os
algoritmos serão instanciados como um sistema/processo físico que atua sobre
os símbolos e produz outros símbolos. Chamaremos os algoritmos de
processamento de símbolos de procedimentos eficazes, ou apenas
procedimentos, para abreviar. Podemos pensar nos procedimentos em P̂ como
sendo um conjunto de funções realizadas fisicamente e continuar a usar a
terminologia funcional.
Chamamos o processo de colocar em ação um procedimento de
computação. Dizemos também que o procedimento calcula a saída das entradas
fornecidas e calcula a função. Assim como aconteceu com a definição de
funções, não existe uma maneira universalmente sancionada de descrever um
procedimento que possa calcular uma função. Dito isto, um pequeno conjunto
de primitivas procedurais usadas composicionalmente parece ser suficiente para

3
CAP 6 -Procedimentos

determinar qualquer função. Vimos um vislumbre desta possibilidade nos temas


do nosso exemplo de mudança.
Como vimos no capítulo anterior, se quisermos criar numerosos símbolos
em Ĝ que possam ser utilizados de forma produtiva por meio de procedimentos,
teremos que construí-los a partir de peças componentes (dados). Além disso,
vimos que usando a concatenação com uma sintaxe combinatória, poderíamos
obter muito mais retorno em termos de quantos símbolos poderiam ser
construídos por unidade física. Este raciocínio se aplica tanto aos símbolos
nominais quanto aos compactos. Usando sintaxe combinatória, pode-se produzir
𝑛
𝑑 símbolos de d símbolos atômicos e strings de comprimento n.
Os símbolos de entrada devem ser diferenciados detectando sua sintaxe,
ou seja, sua forma e seu contexto espacial ou temporal. Os seus referentes não
podem entrar em jogo, porque a maquinaria que implementa uma função
(procedimento) apenas encontra os próprios símbolos, não os seus referentes.
Isto dá aos símbolos uma propriedade importante que não é compartilhada pelas
entidades que representam: os símbolos compartilham uma estrutura atômica
comum (uma moeda representacional comum), que é usada para calcular
funções desses símbolos. Isso torna a descrição dos procedimentos em P̂
potencialmente muito mais uniformes e passíveis de formalização do que as
funções das entidades que os procedimentos representam. As funções e
entidades no sistema representado assumem uma variedade desconcertante de
formas físicas e não físicas, mas a maquinaria no sistema de representação que
implementa as funções correspondentes nos símbolos dessas entidades é muitas
vezes construída a partir de um conjunto modesto de componentes básicos.
Uma manifestação neurobiológica elementar deste importante princípio é
vista no fato de que os trens de picos são a moeda universal pela qual a
informação é transmitida de um lugar para outro dentro do tecido neural. Um
pico é um pico, seja ele transmitindo informações visuais, auditivas ou táteis, etc.
Essa moeda de sinal comum permite que sinais visuais que transportam
informações sobre a localização sejam combinados com sinais auditivos que
transportam informações sobre a localização. Essa combinação determina a
atividade dos neurônios nas camadas profundas do colículo superior. Da mesma
forma, imaginamos que deve haver uma moeda comum para transmitir
informações no tempo, independentemente da natureza dessa informação.
Voltamos a esta questão no Capítulo 16.
Da mesma forma, o fato de o sistema de números reais poder ser usado
para representar tanto quantidades discretas, como o número de terremotos em
Los Angeles em um determinado período de tempo, quanto quantidades
contínuas, como um determinado período de tempo, torna possível para obter

4
CAP 6 -Procedimentos

um símbolo que represente a taxa de ocorrência do terremoto. O símbolo é o


número real obtido pela divisão do número inteiro que representa o número de
terremotos pelo número real que representa a quantidade de tempo. Se os
inteiros não fizessem parte do sistema de números reais (sistema de símbolos no
qual são definidas as funções aritméticas), isso não seria possível (Leslie, Gelman,
& Gallistel, 2008). Na verdade, o surgimento da representação algébrica da
geometria criou uma crise monetária comum nos fundamentos da matemática,
porque havia proporções geométricas simples, como a proporção entre o lado de
um quadrado e a sua diagonal ou a proporção entre a circunferência de um
quadrado e seu diâmetro, que não poderiam ser representados pelos chamados
números racionais. Como o próprio nome sugere, esses são os números que se
sugerem à razão inculta. A representação algébrica da geometria, entretanto,
requer os chamados números irracionais. Os gregos já sabiam disso. Foi uma das
principais razões para traçarem uma forte fronteira entre a geometria e a
aritmética, uma fronteira que foi violada quando Descartes e Fermat mostraram
como representar a geometria algebricamente. Seguindo o que Descartes e
Fermat iniciaram, os matemáticos do século XIX procuraram definir
rigorosamente os números irracionais e provar que eles se comportavam como
números racionais. Eles poderiam então ser adicionados à moeda
representacional da aritmética (as entidades sobre as quais operam as funções
aritméticas), criando os chamados números reais.
Nem sempre é fácil encontrar procedimentos para uma determinada
função. Existem funções bem definidas para as quais ninguém desenvolveu um
procedimento que as calcule. Dada uma noção bem definida do que significa ser
capaz de calcular uma função (discutiremos isso no próximo capítulo), existem
funções onde foi provado que tais procedimentos não existem. Funções que não
podem ser computadas sob esta noção são chamadas de incomputáveis. Outras
funções possuem procedimentos que em teoria as computam, mas os recursos
físicos necessários tornam os procedimentos impraticáveis. Outros
procedimentos tornam-se impraticáveis ​pela quantidade de tempo que o
procedimento levaria para calcular a função. Funções para as quais todos os
procedimentos possíveis que as computam têm tais problemas de recursos
espaciais ou temporais são chamadas de funções intratáveis.1* Há um grande
conjunto de funções computacionalmente importantes para as quais os únicos

1* Normalmente, a linha entre funções tratáveis ​e intratáveis ​é traçada quando os procedimentos


necessários para implementá-las precisam de uma quantidade de recursos espaciais ou
temporais que cresce exponencialmente no número de bits necessários para codificar
compactamente a entrada.
5
CAP 6 -Procedimentos

procedimentos conhecidos para resolvê-las não são práticos, e ainda assim não é
sabemos se essas funções são intratáveis.2*
A falta de procedimentos eficientes para encontrar os fatores primos de
grandes números é a base para muitos dos sistemas de criptografia que
protegem suas informações à medida que elas se movem pela Internet. Esses
esquemas aproveitam o fato de que, embora seja trivial calcular o produto de
quaisquer dois números primos, não importa quão grandes eles sejam, os
procedimentos conhecidos para calcular a função inversa, que especifica para
cada número não primo seus fatores primos , tornam-se inutilizáveis ​à medida
que os insumos se tornam grandes. Dado um número grande que não é primo,
sabemos que existe um conjunto único de fatores primos e conhecemos
procedimentos que garantem encontrar esse conjunto se for permitido correr
por tempo suficiente, mas para números muito grandes “longo o suficiente” é
maior do que a idade do universo, mesmo quando implementado em um
supercomputador. Funções cujos inversos não podem ser calculados de forma
eficiente são chamadas de funções de alçapão, porque permitem que uma siga
um caminho, mas não o outro.
Resumindo, há uma desconexão entre a definição de uma função e a
capacidade de determinar a saída quando dada a entrada. A desconexão ocorre
nos dois sentidos. Podemos ter um sistema que nos fornece pares de
entrada/saída e ainda assim não temos uma definição/compreensão da função.
A ciência está frequentemente nesta posição. Os cientistas realizam experiências
em sistemas naturais que podem ser considerados entradas e o sistema natural
reage com o que pode ser chamado de saídas. Contudo, os cientistas podem não
ter meios independentes de determinar e, assim, prever a relação entre entradas
e saídas. Os cientistas dizem, nesses casos, que não possuem um modelo do
sistema. Diríamos que não temos um sistema representacional para o sistema
natural.

Codificação e Procedimentos
Como mencionamos anteriormente, o uso de símbolos concatenados que
compartilham um conjunto de elementos de dados (por exemplo, ‘0’ e ‘1’) como
base construtiva sugere que os procedimentos em P̂ poderá tirar vantagem desta
moeda comum de construção de símbolos. Isto não implica, contudo, que a
codificação específica utilizada para os símbolos seja irrelevante no que diz

2* Esta é a classe de funções (muitas vezes bastante úteis) agrupadas sob o título NP Completa.
Se alguma dessas funções tiver um procedimento viável, então todas elas terão. A natureza
tentadora disso faz com que a questão de saber se existe tal procedimento seja viável uma das
questões em aberto mais famosas da ciência da computação, chamada de problema P = NP. O
consenso geral é que estas funções são intratáveis, mas ninguém foi capaz de provar isso
6
CAP 6 -Procedimentos

respeito aos procedimentos. Na verdade, existe uma ligação muito estreita entre
os procedimentos em P̂ e a codificação dos símbolos em Ŝ.
Se o código utilizado for nominal, os símbolos nominais não podem ser
utilizados de forma produtiva aproveitando aspectos da sua forma. Eles só
podem ser usados ​de forma produtiva em um mapeamento, distinguindo toda a
cadeia de dados (sequência de elementos atômicos) que constitui o símbolo e,
em seguida, usando uma tabela de consulta para retornar o resultado. Isso
ocorre porque a cadeia usada para formar um símbolo nominal é arbitrária –
qualquer cadeia pode ser substituída por qualquer outra sem perda ou ganho de
eficácia referencial. Quando um grande número de símbolos nominais é
utilizado, torna-se impraticável distingui-los. Os símbolos de codificação,
entretanto, podem ser distinguidos eficientemente usando o que chamaremos
de procedimentos compactos.
Para ver a força desta consideração, examinamos sistemas
30
representacionais potenciais envolvendo os inteiros, N = {1, 2,. . . ,10 }, usando
sistemas nominais e de codificação, e duas funções aritméticas, a função de
paridade fé_par: N → {falso, verdadeiro}, e a função de adição f+: N × N → N. Cada
dado (elemento em uma sequência de símbolos) virá do conjunto {'0', '1'}, e
chamamos cada dado de pedaço. Os símbolos para verdadeiro e falso serão ‘1’ e

‘0’, respectivamente. Nossos procedimentos então serão da forma festá_par :𝐷 →

{0, 1}, onde𝐷 , a entrada, é uma sequência de bits e a saída é um único bit, e f+ :
⊗ ⊗ ⊗
𝐷 ×𝐷 →𝐷 , onde as entradas são duas sequências de bits e a saída é uma
sequência de bits.

Procedimentos usando símbolos não compactos


Preparatório para considerar procedimentos para festá_par e f+ que utilizam
símbolos compactos, consideramos brevemente a possibilidade de utilizar
codificações não compactas. Uma maneira simples de representar números
inteiros é a marca hash ou código unário em que o número de bits '1' é igual em
numerosidade ao número que ele codifica. Podemos rejeitar isto imediatamente,
30
porque temos de ser capazes de operar num número tão grande quanto10 e
25
existem apenas na ordem de10 átomos no cérebro humano. Mesmo que
dedicássemos cada átomo do cérebro à construção de um símbolo unário para
30
10 , não teríamos os recursos físicos. Os símbolos unários não são compactos.
Um símbolo analógico teria o mesmo problema. Os símbolos analógicos
compartilham uma propriedade com o sistema digital não combinatório na
medida em que ambos produzem um aumento na massa física dos símbolos que

7
CAP 6 -Procedimentos

é linearmente proporcional à sua capacidade representacional. Assim como os


símbolos unários, o uso mais eficiente de recursos físicos para símbolos
analógicos seria aquele em que cada símbolo fosse diferenciado pelo número de
átomos que o compõem. Poderíamos então usar o peso para distinguir o símbolo
de um número inteiro do símbolo de outro número inteiro (assumindo que todos
os átomos eram átomos da mesma substância). O problema de usar símbolos
analógicos para representar nossos números inteiros é duplo. Primeiro, tais
símbolos não são compactos, portanto não há átomos suficientes no cérebro
para representar o que precisa ser representado. Em segundo lugar, nenhum
29
procedimento de pesagem poderia distinguir o peso de10 átomos do peso de
29
10 + 1 átomos. Em suma, símbolos não compactos (digitais ou analógicos) não
são práticos como base para um sistema representacional cujos símbolos devem,
cada um, ser capazes de representar um grande número de diferentes estados
possíveis do sistema representado; sua demanda por recursos para a realização
de símbolos é muito alta e os símbolos logo se tornam indistinguíveis uns dos
outros.
Tabela 6.2 A função de paridade fé_par com um código binário nominal para os inteiros 0–7
Inteiro (base 10) Código binário nominal Paridade
0 001 1
1 100 0
2 110 1
3 010 0
4 011 1
5 111 0
6 000 1
7 101 0

Com uma sintaxe combinatória para formação de símbolos (compactos), a


forma do símbolo é variada variando a sequência de dados atômicos (por
exemplo, '0's e '1's), com cada sequência diferente representando um número
inteiro diferente. Se formarmos nossos símbolos para os inteiros dessa maneira,
precisaremos de uma cadeia de símbolos consistindo de apenas 100 bits para
representar qualquer número em nosso grande conjunto de inteiros (porque
2100 > 1030). As demandas de recursos físicos necessários para compor o
símbolo de um único número vão do absurdo ao trivial.

Procedimentos para festá_par usando símbolos nominais


compactos
Antes de discutir procedimentos para festá_par, devemos considerar como
30
codificaremos nosso grande (10 ) conjunto de números inteiros, porque os
procedimentos são específicos do código. A decisão de usar símbolos compactos
não aborda a questão de como codificamos números nesses símbolos – como

8
CAP 6 -Procedimentos

mapeamos os diferentes números para os diferentes padrões de bits que se


referem a eles. Consideramos primeiro as opções procedimentais quando
usamos um mapeamento nominal para os inteiros, no qual não existem
princípios de codificação que governem quais padrões de bits representam quais
números. A Tabela 6.2 mostra festá_par definido para um mapeamento nominal
possível para os inteiros 0–7. Os padrões de bits mostrados na segunda coluna
(os símbolos de entrada) podem ser embaralhados à vontade. A única restrição é
que o mapeamento seja um para um: cada número inteiro deve mapear apenas
um padrão de bits e cada padrão de bits deve representar apenas um número
inteiro. A questão é: o que um procedimento festá_par como seria se usássemos
esse tipo de codificação nominal dos inteiros? Parte do que dá força a esta
questão é que as codificações assumidas pelos neurobiólogos são comumente
codificações nominais: o disparo de “este” neurônio representa “aquele” estado
do mundo.
Qualquer que seja o procedimento que usemos para determinar festá_par,
terá que distinguir cada um dos 100 elementos de dados que compõem o
símbolo de entrada. Além disso, como não existe uma maneira baseada em
princípios de determinar a saída correta a partir da entrada, não temos escolha a
não ser usar uma tabela de consulta. Ou seja, devemos implementar diretamente
a Tabela 6.2.

Figura 6.1 Árvore de pesquisa binária para determinar a paridade dos primeiros oito inteiros usando a codificação binária
nominal da Tabela 6.2.
Primeiro consideramos um procedimento que distingue os elementos
sequencialmente, movendo-se pela cadeia de entrada da direita para a esquerda.
À medida que avançamos na entrada, mudaremos de estado para estado dentro
do procedimento. Cada estado fornecerá então uma memória do que vimos até
agora. Quando chegarmos ao último símbolo, saberemos qual deve ser a saída
com base no estado em que pousamos. Na verdade, estaremos nos movendo
através de uma árvore de estados (uma árvore de pesquisa binária) que se
ramifica após cada símbolo encontrado. A Figura 6.1 mostra a árvore que
corresponde ao mapeamento nominal dado. Diferentes strings de entrada nos

9
CAP 6 -Procedimentos

direcionarão ao longo de diferentes caminhos da árvore, gerando no final a saída


pré-especificada para a entrada dada (o símbolo '1' ou o símbolo '0', dependendo
se o inteiro codificado é par ou ímpar ). Aqui está o procedimento que
implementa a árvore de busca mostrada na Figura 6.1:

1 Leia o bit 1. Se for ‘0’, vá para o estado 2. Se for ‘1’, vá para o estado 3.
2 Leia o bit 2. Se for ‘0’, vá para o estado 4. Se for ‘1’, vá para o estado 5.
3 Leia o bit 2. Se for ‘0’, vá para o estado 6. Se for ‘1’, vá para o estado 7.
4 Leia o bit 3. Se for ‘0’, produza ‘1’. Se for '1', produza '0'. Pare.
5 Leia o bit 3. Se for ‘0’, produza ‘0’. Se for '1', produza '1'. Pare.
6 Leia o bit 3. Se for ‘0’, produza ‘1’. Se for '1', produza '0'. Pare.
7 Leia o bit 3. Se for ‘0’, produza ‘1’. Se for '1', produza '0'. Pare.

Vemos aqui vários dos mesmos temas que vimos no algoritmo de


mudança. Existem duas propriedades e problemas relacionados aos
procedimentos da tabela de consulta que são de grande importância.
Explosão combinatória. O procedimento da árvore de busca tem a infeliz
propriedade de que o tamanho da árvore cresce exponencialmente com o
comprimento das cadeias binárias a serem processadas e, portanto, linearmente
com o número de diferentes entradas possíveis. Como podemos ver
graficamente na Figura 6.1, cada nó da árvore é representado por um estado
diferente que deve ser fisicamente distinto um do outro estado. Portanto, o
número de estados necessários cresce exponencialmente com o comprimento
dos símbolos a serem processados. Usamos sintaxe combinatória para evitar o
problema de crescimento linear do tamanho do símbolo necessário. No entanto,
como utilizámos uma codificação nominal dos números, o problema voltou a
assombrar-nos nas nossas tentativas de criar um procedimento que opere
produtivamente nos símbolos.

10
CAP 6 -Procedimentos

Figura 6.2 Uma memória endereçável por conteúdo torna possível a pesquisa paralela. A string a ser processada é
alimentada na parte superior. Todos os três bits vão simultaneamente para os três nós de entrada em cada local de
memória. Cada nó de entrada é ativado somente se o bit de entrada que ele vê corresponder a ele. Se todos os nós em um
determinado local forem ativados, eles geram o bit de saída armazenado naquele local, o bit que especifica a paridade do
número representado por esse local na memória endereçável por conteúdo. (A ordem dos números binários nesta
ilustração não desempenha nenhum papel no procedimento.)

Pré-especificação. Intimamente relacionado, mas distinto do problema da


explosão combinatória, está o problema da pré-especificação em procedimentos
baseados em uma abordagem de tabela de consulta. O que isto significa é que no
procedimento, para cada entrada possível (que corresponde ao número de
símbolos potenciais utilizados para a entrada) foi necessário incorporar na
estrutura de um estado o símbolo de saída correspondente que será retornado.
Isto implica que todos os possíveis pares de entrada/saída são determinados a
priori no sistema de representação. Embora seja certamente possível descobrir
se qualquer número de cem bits é par, não é razoável exigir que o criador do
procedimento determine isso antecipadamente para todos os números de 2.100.
O problema com procedimentos baseados em tabelas de consulta é que eles não
são produtivos; eles apenas devolvem o que já foi investido.
Pode-se perguntar se o problema de processar um grande número de
símbolos nominais desaparece se usarmos um procedimento de busca paralela
em vez de um procedimento sequencial. Levantamos esta questão em parte
porque, em primeiro lugar, argumenta-se frequentemente que o cérebro é tão

11
CAP 6 -Procedimentos

poderoso porque se envolve num processamento paralelo massivo e, em segundo


lugar, muitos modelos de redes neurais para implementar funções são baseados
em redes de memória endereçáveis ​por conteúdo aprendidas. As memórias
endereçáveis ​por conteúdo são tabelas de consulta nas quais os diferentes
resultados possíveis são acessados ​através de busca paralela (ver Figura 6.2).
Como fica evidente na Figura 6.2, um procedimento de busca paralela,
usando uma tabela de memória endereçável por conteúdo em vez de uma árvore
de busca binária, não evita nem o problema da explosão combinatória nem o
problema da pré-especificação. Na verdade, piora a situação. A memória
endereçável por conteúdo requer um local de memória fisicamente distinto para
cada sequência de entrada possível (levando a uma explosão combinatória). O
hardware necessário para implementar uma comparação entre um bit de entrada
e um bit armazenado em cada local também deve ser replicado tantas vezes
quanto o comprimento da entrada. Além disso, temos que armazenar nesse local
o bit de saída especificando a paridade do número inteiro para o qual esse local
está “sintonizado” (o problema de pré-especificação).

Memória de estado
O procedimento sequencial ilustra um conceito de importância central na nossa
compreensão das possíveis arquiteturas de máquinas computacionais, o
conceito de memória de estado. O estado de um dispositivo de computação é
uma capacidade instalada para executar uma função específica em um
determinado contexto. Cada estado implementa essencialmente uma mini tabela
de consulta própria e, ao passar de um estado para outro, uma máquina pode
mapear um conjunto pré-especificado de entradas para um conjunto
pré-especificado de saídas (implementando uma tabela de consulta maior). . A
qualquer momento, ele está em um e apenas um dos seus estados possíveis. O
estado em que se encontra em determinado momento depende do histórico de
entrada, porque diferentes entradas levam a diferentes transições de estado.
Tomemos, por exemplo, uma máquina de escrever (ou, hoje em dia, um teclado,
que não é tão favorável para os nossos propósitos, porque a base física para as
suas mudanças de estado não é aparente). Quando a tecla Shift não foi
pressionada (entrada anterior), ela está em um estado. Nesse estado, ele mapeia
os pressionamentos das teclas para seus símbolos em minúsculas. Quando a
tecla Shift é pressionada, ela mapeia as mesmas entradas para suas saídas em
maiúsculas, porque pressionar a tecla Shift mudou a máquina para um estado
diferente. Em uma máquina de escrever antiga, pressionar a tecla Shift levantava
todo o conjunto de alavancas de percussão, de modo que a parte inferior da
extremidade de cada alavanca atingisse o papel, em vez da parte superior. O fato

12
CAP 6 -Procedimentos

de a máquina estar em um estado diferente quando a tecla Shift foi pressionada


era, portanto, fisicamente transparente.
No procedimento de busca em árvore para determinar a paridade, o
procedimento percorre um galho da árvore, e depois outro e outro. O galho que
ele percorrerá em seguida depende do estado que alcançou, ou seja, de onde ele
está na árvore. A árvore deve ser fisicamente realizada para que este
procedimento funcione porque é a árvore que controla onde o procedimento
chegou. Cada vez que o procedimento avança para um novo nó, o estado do
maquinário de processamento muda.
O estado em que se encontra o componente processual de uma máquina
de computação reflete o histórico das entradas e determina qual será sua
resposta a qualquer entrada. É, portanto, tentador usar o estado da maquinaria
de processamento como memória da máquina. Na verdade, uma ideia que
dominou a teoria da aprendizagem durante um século – e, portanto, a tentativa
de compreender a aprendizagem e a memória neurobiologicamente – é que toda
a aprendizagem é, em essência, processual e baseada no estado. A experiência
coloca as máquinas neurais em estados permanentemente diferentes
(reconecta-as para implementar uma nova tabela de consulta), e é por isso que
elas respondem de maneira diferente às entradas depois de terem tido
experiências de mudança de estado (religação). A maior parte da modelagem
conexionista contemporânea é dedicada ao desenvolvimento desta ideia. Um
problema recorrente com esta abordagem é que, tal como as tabelas de consulta
em que resultam, estas redes carecem de produtividade: neste caso, só se
recupera o que a experiência investiu. 14.)
Embora o uso de tabelas de consulta seja, em muitos casos, absurdamente
ineficiente ou (como no presente caso) fisicamente impossível, as tabelas de
consulta são, no entanto, um componente importante de muitos procedimentos
de computação. Como sugere o exemplo de conteúdo endereçável (Figura 6.2),
um procedimento de consulta de tabela pode envolver o acesso à memória
apenas uma vez, enquanto um procedimento implementado pela composição de
muitas funções elementares, com cada composição exigindo leitura e gravação
na memória, pode levar muito tempo. mais longo.
Tomemos, por exemplo, o uso de tabelas de senos e cossenos em um
videogame, onde a velocidade dos procedimentos é uma prioridade. Calcular o
seno e o cosseno de um ângulo consome muito tempo. Por exemplo, uma
fórmula para sin(x) onde x está em radianos é dada por
3 5 7
𝑥 𝑥 𝑥
𝑝𝑒𝑐𝑎𝑑𝑜(𝑥) = 𝑥 − 3!
+ 5!
− 7!
+ . . . .Embora seja possível limitar o número de
termos usados, ainda pode levar um bom tempo para calcular e os
denominadores se tornam números inteiros muito grandes muito rapidamente.

13
CAP 6 -Procedimentos

O que muitas vezes é feito para superar esse problema de velocidade é


criar uma tabela de consulta para ângulos suficientes para fornecer uma
resolução razoavelmente boa para o jogo. Por exemplo, pode-se ter um
procedimento de tabela de consulta que determina a função seno para cada grau
integral de 1 a 360. Então, basta encontrar o ângulo integral mais próximo da
entrada que está armazenada na tabela de consulta e usar isso. para uma
aproximação. Pode-se pegar os dois ângulos integrais mais próximos e então
usar a interpolação linear para obter uma estimativa melhor e ainda mais fácil de
calcular.

Procedimentos para festá_par usando símbolos de codificação


compactos
Quando os símbolos codificam seus referentes de alguma forma sistemática,
muitas vezes é possível implementar funções nesses símbolos usando o que
chamamos de procedimento compacto. Um procedimento compacto é aquele
em que o número de bits necessários para comunicar o procedimento que
implementa uma função (os bits necessários para codificar o próprio algoritmo) é
muitas ordens de grandeza menor que o número de bits necessários para
comunicar a tabela de consulta para a função. E normalmente, o número de bits
necessários para comunicar um procedimento compacto é independente do
tamanho do domínio e contradomínio utilizáveis, enquanto em um
procedimento de tabela de consulta, o número de bits necessários cresce
exponencialmente com o tamanho do contradomínio e domínio utilizáveis. .
Começamos a nossa análise de procedimentos com a função de paridade porque
é uma ilustração simples e surpreendente da diferença geralmente bastante
radical entre a informação necessária para especificar um procedimento
compacto e a informação necessária para especificar o procedimento da tabela
de consulta. Como a maioria dos leitores já deve ter percebido há muito tempo,
o procedimento de determinação de paridade para a codificação binária
convencional dos números inteiros é absurdamente simples:

Leia o bit 1. Se for ‘0’, produza ‘1’. Se for '1', produza '0'. Pare.

Esta função de inverter um bit (transformar 0 em 1 e 1 em 0) é a função fnão


em álgebra booleana (fnão(0) = 1,fnão(1) = 0). É uma das operações primitivas
incorporadas aos computadores.3* Ao se comunicar com um dispositivo que
possui algumas funções básicas incorporadas, o procedimento pode ser

3* Conjecturamos que é também um primitivo computacional no tecido neural, uma conjectura


que ecoa nas reflexões expressas no slogan da camiseta: “Que parte do não você não entende?”
14
CAP 6 -Procedimentos

comunicado como a composição desaída(fnão(fprimeiro_bit(x))). Esta expressão possui


apenas quatro símbolos, representando as três funções necessárias e a entrada.
Como todos estes seriam referentes de alta frequência (na representação que o
dispositivo faz de si mesmo), os símbolos para eles seriam todos compostos de
apenas alguns bits, num dispositivo construído racionalmente. Assim, o número
de bits necessários para comunicar o procedimento de cálculo da função de
paridade a um dispositivo (adequadamente equipado) é consideravelmente
2
menor do que10 . Por outro lado, para comunicar o procedimento da tabela de
30
consulta de paridade para os inteiros de 0 a10 , precisaríamos usar pelo menos
2 30 32
100 bits para cada número. Assim, precisaríamos de cerca de (10 )(10 ) =10 ,
bits para comunicar a tabela de consulta correspondente.
Isso é mais de 30 ordens de grandeza maior que o número de bits
necessários para comunicar o procedimento compacto. E esse número enorme –
30 ordens de grandeza – baseia-se na suposição completamente arbitrária de
que limitamos os números inteiros na nossa tabela de paridade àqueles menores
30
que10 . O procedimento compacto não para de funcionar quando os símbolos
de entrada representam números inteiros maiores que 1030. Como estamos
usando uma codificação compacta dos números inteiros, o tamanho dos
símbolos (os comprimentos das cadeias de dados) não apresenta problema e não
é mais difícil olhar para o primeiro bit de uma string com 1.000.000 bits de
comprimento do que olhar para o primeiro bit de uma string com 2 bits de
comprimento. Em resumo, não há comparação entre o número de bits
necessários para comunicar o procedimento compacto e o número de bits
necessários para comunicar o procedimento da tabela de consulta que o
procedimento compacto pode, em princípio, calcular. O último número pode se
10.000.000
tornar arbitrariamente grande (como, digamos10 ) sem colocar qualquer
pressão sobre a execução física do procedimento compacto. É claro que um
dispositivo equipado com este procedimento nunca computa qualquer parte
substancial da tabela. Não é necessário. Com o procedimento, ele pode
encontrar a saída para qualquer entrada, o que é tão bom (na verdade, muito
melhor, se você aceitar o trocadilho) do que incorporar alguma parte realizada
da tabela em sua estrutura.
A eficácia de um procedimento compacto depende do tipo de símbolo no
qual ele opera. Quando usamos símbolos nominais para representar inteiros, não
existe um procedimento compacto que implemente a função de paridade ou
qualquer outra função útil. A simbolização nominal não se baseia numa
decomposição analítica dos referentes. Uma simbolização de codificação sim.
Quando a forma de um símbolo deriva de uma decomposição analítica da

15
CAP 6 -Procedimentos

entidade codificada, então a decomposição é explicitamente representada pela


subestrutura do próprio símbolo. A codificação binária dos inteiros baseia-se na
decomposição de um inteiro em uma soma de potências sucessivamente
3 2 1 0
maiores de 2 (por exemplo, 13 = 1(2 ) + 1(2 ) + 0(2 ) + 1(2 ) = 8 + 4 + 0 + 1). Nesta
decomposição, a paridade de um número inteiro é explicitamente representada
pelo bit mais à direita no símbolo dele. Isso torna possível o procedimento
altamente compacto para realizar a função de paridade.
Como este ponto é de fundamental importância, ilustraremos a seguir
com um exemplo biológico: se os símbolos da sequência de nucleotídeos para
proteínas no DNA de um cromossomo fossem símbolos nominais, então não
seríamos capazes de deduzir dessas sequências as estruturas lineares. das
proteínas que representam. Na verdade, porém, o código genético usa símbolos
codificados. A codificação de estruturas proteicas por sequências de
nucleotídeos baseia-se em uma decomposição analítica da proteína em uma
sequência linear de aminoácidos. Dentro das sequências de nucleotídeos da
molécula de DNA de dupla hélice de um cromossomo, diferentes tripletos de
nucleotídeos (códons) representam diferentes aminoácidos, e a sequência de
códons representa a sequência dos aminoácidos dentro da proteína. A
decomposição de proteínas em suas sequências de aminoácidos e a
representação explícita dessa sequência dentro do símbolo genético (gene) de
uma proteína torna possível um procedimento molecular relativamente simples
para montar a proteína, usando uma transcrição do símbolo para ela como
entrada para o procedimento. Uma pequena parte do projeto genético especifica
a estrutura de uma máquina (o ribossomo) que pode construir um número
arbitrariamente grande de proteínas diferentes a partir de símbolos codificados
compostos de apenas quatro dados atômicos (os nucleotídeos A, G, T e C). A
sintaxe combinatória destes símbolos – o facto de, tal como os bits, poderem ser
transformados em cadeias com sequências infinitamente diversas – torna-os
capazes de representar um número arbitrariamente grande de proteínas
diferentes. Qualquer que seja a sequência de códons, o procedimento de
transcrição pode mapeá-la para uma proteína real, assim como a função de
paridade e a função de adição a ser descrita podem mapear a codificação binária
de qualquer número inteiro ou de qualquer par de inteiros para o símbolo da
paridade ou do símbolo para a soma. Os mecanismos de codificação biológica e
os procedimentos neles baseados, assim como os mecanismos de codificação de
computador e os procedimentos neles baseados, são informados pela lógica da
codificação e pelos procedimentos compactos. Esta lógica é uma restrição tão
profunda à realização de processos moleculares eficazes quanto qualquer
restrição química.

16
CAP 6 -Procedimentos

Procedimentos para f+
Ao trabalhar com símbolos que se referem a uma quantidade, a função de adição
é extremamente útil porque, em muitas circunstâncias, as quantidades se
combinam aditivamente (ou linearmente, como a combinação aditiva é
frequentemente chamada). Como sempre, o procedimento depende da
codificação. Se usarmos um código unário (analógico) - símbolos que possuem
tantos '1's quanto o número inteiro que codificam - o procedimento de adição é
altamente compacto: você obtém o símbolo da soma simplesmente
concatenando (encadeando) os adendos (os símbolos para os inteiros a serem
adicionados). Ou, se pensarmos que os dois números estão contidos em dois
“sacos”, então obteremos a soma simplesmente colocando os dois sacos num
novo saco. O problema desta abordagem não está no procedimento – não
poderia ser mais compacto – mas sim na simbolização (a codificação). Como já
vimos, leva a um crescimento exponencial na utilização de recursos, pelo que é
fisicamente impraticável. Se tentarmos usar uma codificação nominal, os
símbolos serão compactos, mas seremos forçados a construir um procedimento
de tabela de consulta que sucumbirá à explosão combinatória.

0110 carregar
00011 para ser adicionado1 3
01011 para ser adicionado2 11
1110 soma 14

Figura 6.3 Os resultados do cálculo de f+ nas entradas 3 e 11 (representados em binário). Todos os dados criados durante
o cálculo são mostrados em itálico.

Assim como fizemos com a paridade, prosseguiremos com o uso de


símbolos de codificação empregando o sistema numérico binário para inteiros.
Então, qual seria um procedimento compacto para determinar f+? Uma
abordagem é essencialmente o método que aprendemos na escola primária. Os
números (como geralmente representados no sistema numérico decimal) são
colocados um em cima do outro, justificados à direita, de modo que os numerais
se alinhem nas colunas.4* Começando pela direita, cada coluna é adicionada
usando outro procedimento de adição, f++ , para produzir um número. Esta não é
uma regressão infinita, pois o subprocedimento é em si uma tabela de consulta.
Como haverá carregamentos, talvez tenhamos que adicionar três números em
cada coluna. Para tornar este processo uniforme (e assim simplificar o nosso

4* Observe que o posicionamento espacial relativo permite discernir o número superior como o
primeiro adendo e o número inferior como o segundo adendo. Sendo a adição comutativa, esta
distinção não é relevante; entretanto, para subtração, por exemplo, distinguir entre o minuendo
(o número superior) e o subtraendo (o número inferior) é fundamental.
17
CAP 6 -Procedimentos

procedimento), colocamos um '0' no topo da primeira coluna e, em seguida, para


cada coluna seguinte, um '0' se não houver transporte, ou um '1' se há um
transporte. Também adicionamos um ‘0’ à extremidade esquerda de ambas as
adendas para que possamos lidar com um último transporte de maneira
uniforme. Para somar os três números em cada coluna, usamos composição
funcional com f++ –f++(f++(carry_bit, adendo1_bit), adicionando2_bit) – para somar
os dois primeiros dígitos e depois adicionar esse resultado ao terceiro dígito.
Abaixo está um procedimento que calcula a função de adição (f+). A Figura
6.3 mostra os resultados deste cálculo nas entradas ‘0011’ (3) e ‘1011’ (11).

1 Coloque um ‘0’ no topo da primeira coluna (mais à direita) e na extremidade


esquerda de ambas as adendas1 e adendo2.
2 Comece com a coluna mais à direita.
3 Adicione os dois primeiros números da coluna atual usando f++.
4 Adicione o resultado do Estado 3 ao número inferior da coluna atual usando f++.
(Aqui estamos usando a composição funcional de f++ consigo mesmo.)
5 Coloque o primeiro bit (mais à direita) do resultado do Estado 4 na linha
inferior da coluna atual.
6 Coloque o segundo bit do resultado do Estado 4 no topo da coluna à esquerda
da coluna atual. Se não houver um segundo bit, coloque um ‘0’ ali.
7 Mova uma coluna para a esquerda.
8 Se houver números na coluna atual, volte ao estado 3.
9 Produza a linha inferior. Pare.

Tabela 6.3 Tabela de consulta para f++


a b f++(a,b)
0 0 0
0 1 1
1 0 1
1 1 10
10 0 10
10 1 11

O procedimento para f++, que é usado dentro de f+, pode ser implementado
como uma tabela de consulta (Tabela 6.3). Observe que isso não significa que f+
não compacto. A tabela de consulta incorporada não cresce em função da
entrada; f++ só precisa lidar com a adição de três bits. Nossos acréscimos podem
aumentar sem limites, sem alterar a forma como lidamos com cada coluna. Aqui,
a memória de estado não é apenas útil, é necessária. Todos os procedimentos

4* Observe que o posicionamento espacial relativo permite discernir o número superior como o
primeiro adendo e o número inferior como o segundo adendo. Sendo a adição comutativa, esta
distinção não é relevante; entretanto, para subtração, por exemplo, distinguir entre o minuendo
(o número superior) e o subtraendo (o número inferior) é fundamental.
18
CAP 6 -Procedimentos

requerem alguma memória de estado, assim como requerem alguma estrutura


que não é resultado da experiência. Isto é um reflexo direto do fato de que, para
que qualquer dispositivo receba informações, ele deve ter uma representação a
priori das possíveis mensagens que poderá receber.
O procedimento compacto f+ permite a adição eficiente de números
inteiros arbitrariamente grandes. Como o procedimento compacto parafparidade,
faz isso usando símbolos compactos e aproveitando a decomposição analítica
dos referentes. Enquanto as abordagens de tabela de consulta são agnósticas no
que diz respeito à codificação, os procedimentos compactos só funcionam
adequadamente com símbolos codificados de forma adequada. Existe um vínculo
estreito entre o procedimento de codificação que gera os símbolos e os
procedimentos que atuam sobre eles.
Quando você analisa os detalhes dos procedimentos necessários para
implementar até mesmo algo tão simples como a operação de adição em
símbolos compactos, é um tanto surpreendente o quão complexos eles são. Não
há dúvida de que o cérebro possui um procedimento (ou possivelmente
procedimentos) para adicionar símbolos para quantidades simples, como
distância e duração. Revisamos uma pequena parte das evidências
comportamentais relevantes nos Capítulos 11 a 13. Os animais – até mesmo os
insetos – podem inferir a distância e a direção de um local conhecido a partir de
outro local conhecido (Gallistel, 1990; 1998; Menzel et al., 2005). Não há como
fazer isso sem realizar operações em símbolos semelhantes a vetores,
formalmente equivalentes à subtração vetorial (ou seja, adição com inteiros
assinados). Ou, de forma um pouco mais cautelosa, se o cérebro do inseto puder
calcular o alcance e o rumo de um local conhecido a partir de outro local
conhecido sem fazer algo homomórfico à adição de vetores, a descoberta de
como isso acontece terá profundas implicações matemáticas.
Não se pode enfatizar demais que o procedimento pelo qual o cérebro do
inseto faz a adição de vetores dependerá da forma dos símbolos neurobiológicos
nos quais o procedimento opera e da função de codificação que mapeia
distâncias e direções para as formas desses símbolos. Se a forma for unária – ou,
o que é quase a mesma coisa, se a adição for feita em símbolos analógicos –
então o procedimento pode ser muito simples. Entretanto, então devemos
entender como o cérebro pode representar distâncias que variam de milímetros
a quilômetros usando esses símbolos unários. Para ver o problema, basta
ponderar por que nenhuma simbolização de quantidade que tenha qualquer
poder apreciável usa símbolos unários (símbolos). O sistema romano começa
assim (I, II, III), mas desiste após apenas três símbolos. Adicionar (concatenar)
marcas de hash é extremamente simples, mas não atrai quando se considera

19
CAP 6 -Procedimentos

adicionar o símbolo de hash de 511 ao símbolo de hash de 10.324. Assim, a questão


de como o cérebro simboliza quantidades simples e os seus
procedimentos/mecanismos para realizar operações aritméticas sobre essas
quantidades é uma questão profundamente importante e interessante, para a
qual neste momento a neurociência não tem resposta.

Dois Sentidos de Saber


Ao traçar nosso caminho através dos detalhes dos procedimentos tanto para
festá_par e f++, deparamo-nos com uma distinção entre conhecer no sentido
simbólico e o “conhecer” que está implícito numa fase (estado) de um
procedimento. Esta é, em essência, a distinção entre o conhecimento simbólico
direto e transparente e o “conhecimento” indireto e opaco que é característico
das máquinas de estado finito, que carecem de uma memória simbólica de
leitura/gravação. O conhecimento simbólico é transparente porque os símbolos
transportam informações coletadas da experiência no tempo de uma maneira
que as torna acessíveis à computação. A informação necessária para informar o
comportamento é explícita nos símbolos que o transportam ou pode ser
explicitada por cálculos que tomam esses símbolos como entradas. Compare isso
com o “conhecimento” processual que ocorre, por exemplo, na implementação
da árvore de busca de festá_par. O estado 5 “sabe” que o primeiro bit na entrada
era '0' e o segundo bit era '1', não porque possui símbolos que transportam esta
informação, mas porque o procedimento nunca teria entrado nesse estado se
não fosse o caso. Nós, que somos deuses fora do procedimento, podemos
deduzir isso examinando o procedimento, mas o procedimento não simboliza
esses fatos. Isso não os torna acessíveis a algum outro procedimento.
Vemos em nosso procedimento compacto para f+ ambas as formas de
conhecimento. O subprocedimento da tabela de consulta para f++, implementado
como memória de estado, só “saberia” qual foi o primeiro bit recebido em
virtude do fato de estar em um determinado estado. Por outro lado, considere o
conhecimento que ocorre no procedimento principal quando ele começa a
adicionar uma nova coluna. Ele sabe o que é o bit de transporte porque essa
informação é transportada por um símbolo (o bit) colocado no topo da coluna
atual durante o cálculo. f+ pode estar no estado 3 com um ‘0’ na posição de
transporte ou um ‘1’ na posição de transporte. Esta informação é conhecida
explicitamente.
Colocamos a forma de conhecimento baseada no estado entre aspas,
porque ela não corresponde ao que normalmente se entende por conhecimento.
Não colocamos a forma simbólica do conhecimento entre aspas, tanto porque
corresponde ao sentido comum, como porque acreditamos que este sentido

20
CAP 6 -Procedimentos

simbólico do conhecimento é o sentido correto quando dizemos coisas como “o


rato sabe onde está”. ou “a abelha sabe a localização da fonte de néctar” ou “o
gaio sabe quando e onde armazenou o quê” (ver capítulos posteriores).
É importante ser claro sobre estes diferentes sentidos de conhecimento,
porque estão intimamente relacionados com uma controvérsia de longa data
dentro da ciência cognitiva e campos relacionados. A tradição
anti-representacional, que é vista essencialmente em todas as formas de
behaviorismo, seja na psicologia, na filosofia, na linguística ou na neurociência,
considera todas as formas de aprendizagem como a aprendizagem de
procedimentos. Para expressões puras e antigas desta linha de pensamento, ver
Hull (1930) e Skinner (1938, 1957). Pelo menos na sua forma mais forte (Skinner,
1990), esta linha de pensamento sobre os processos subjacentes ao
comportamento rejeita explícita e enfaticamente a suposição de que existem
símbolos no cérebro que codificam fatos experienciados sobre o mundo (tais
como onde as coisas estão e quanto tempo duram). é preciso que um
determinado tipo de alimento apodreça). Por outro lado, a suposição de que
existem tais símbolos e de que eles são atores centrais na causalidade do
comportamento é central para o que poderia ser chamado de ciência cognitiva
de linha principal (Chomsky, 1975; Fodor, 1975; Fodor & Pylyshyn, 1988; Marcus,
2001). ; Marr, 1982; Newell, 1980).
O behaviorismo anti-representacional de uma era anterior encontra eco
no trabalho conexionista contemporâneo e de sistemas dinâmicos (P. M.
Churchland, 1989; Edelman & Gally, 2001; Hoeffner, McClelland, & Seidenberg,
1996; Rumelhart & McClelland, 1986; Smolensky, 1991 ). Grosso modo, quanto
mais comprometidos os teóricos estão em construir uma teoria psicológica
sobre fundamentos neurobiológicos, mais céticos eles são sobre a hipótese de
que existem símbolos e operações de processamento de símbolos no cérebro.
Exploraremos as razões para isso nos capítulos seguintes, mas a razão básica é
simples: a linguagem e a estrutura conceitual para o processamento simbólico
são estranhas à neurociência contemporânea. Os neurocientistas não
conseguem identificar claramente a base material dos símbolos – isto é, não há
consenso sobre qual poderia ser a base – nem podem especificar a maquinaria
que implementa qualquer uma das operações de processamento de informação
que agiriam plausivelmente sobre esses símbolos (operações como adição de
vetores). Assim, há um abismo conceitual entre a ciência cognitiva tradicional e a
neurociência. Nosso livro é dedicado a explorar esse abismo e construir as bases
para superá-lo.

21
CAP 6 -Procedimentos

Um exemplo geométrico
A estreita ligação entre os procedimentos e as codificações que geram os
símbolos sobre os quais operam é um ponto de extrema importância. Ilustramos
isso até agora com operações puramente numéricas nas quais os símbolos se
referiam a números inteiros. Isto pode parecer um referente muito abstrato. Os
cérebros dos animais representam números? Tradicionalmente, a resposta a esta
pergunta tem sido não, mas pesquisas sobre cognição animal nos últimos anos
mostraram que ratos, pombos, macacos e símios representam de fato números
per se (Biro & Matsuzawa, 1999; Boysen & Berntson, 1989 ; Brannon & Terrace,
2002; Cantlon & Brannon, 2005, 2006; Gallistel, 1990; Hauser, Carey, & Hauser,
2000; Matsuzawa & Biro, 2001; Rumbaugh & Washburn, 1993). No entanto, é
desejável uma ilustração não numérica envolvendo símbolos para algo
indiscutivelmente menos abstrato e cuja representação seja claramente uma
base do comportamento animal. Em nosso exemplo final, voltamo-nos para o
processamento de símbolos geométricos, símbolos de localizações. Há
evidências comportamentais esmagadoras de que os animais representam locais,
porque a representação de locais é uma condição sine qua non para uma
navegação eficaz, e animais de todos os tipos, incluindo mais particularmente
insetos, são navegadores talentosos (T. S. Collett, M. Collett, & Wehner, 2001 ;
Gallistel, 1998; Gould, 1986; Menzel et al., 2005; Tautz et al., 2004; J. Wehner &
Srinivasan, 2003; R. Wehner, Lehrer, & Harvey, 1996).

Figura 6.4 Duas maneiras diferentes de codificar locais e linhas em vetores. (a) A codificação cartesiana. (b) Codificação
polar.

Como qualquer outra coisa, os locais podem ser codificados de diferentes


maneiras. Qualquer que seja a forma como sejam codificados, a codificação

22
CAP 6 -Procedimentos

tornará alguns procedimentos simples e outros complexos. Quais procedimentos


são simples e quais complexos dependerão da codificação. A codificação
cartesiana de localizações (Figura 6.4a) decompõe uma localização em suas
distâncias sinalizadas (isto é, direcionadas) de dois eixos ortogonais escolhidos
arbitrariamente. Uma alternativa é decompor as localizações em uma distância
radial e uma distância angular (Figura 6.4b). Na navegação, essa decomposição é
chamada de alcance e rumo de um ponto a partir da origem. Para efetuar esta
codificação de localizações, fixamos um ponto no plano, denominado origem ou
pólo. O alcance é a distância do local a este ponto. Para poder especificar os
rumos das localizações, desenhamos um raio (segmento de linha delimitado em
uma extremidade) do pólo, estendendo-se arbitrariamente em alguma direção.
Esta direção é muitas vezes escolhida tendo em mente referentes direcionais
geralmente válidos, como, por exemplo, o norte, que é o ponto no céu em torno
do qual todos os corpos celestes giram, porque é o ponto em direção ao qual
uma extremidade do eixo dos pontos de rotação da Terra. Esta linha é chamada
de eixo polar. A segunda coordenada na codificação polar de localização (o rumo
de uma localização) é a distância angular através da qual devemos girar o eixo
polar para que ele passe por aquela localização. Por uma questão de
familiaridade, especificaremos as distâncias angulares em graus, embora os
radianos sejam preferidos para fins computacionais.
Um inconveniente neste mapeamento é que existe uma infinidade de
distâncias angulares para qualquer localização – portanto, um número infinito
de símbolos que mapeiam para o mesmo referente. Primeiro, podemos girar o
eixo polar no sentido anti-horário (como fazemos na Figura 6.4b) ou no sentido
horário. De qualquer forma, ele eventualmente passará por qualquer local que
estivermos codificando, mas o componente de distância angular do nosso
símbolo vetorial terá um valor absoluto diferente e um sinal diferente,
dependendo da maneira que escolhermos para girar o eixo polar. Para evitar isto,
podemos especificar que a rotação deve ser, digamos, no sentido anti-horário.
Isto não resolve o problema de símbolos múltiplos para o mesmo referente
porque o eixo polar passará novamente pelo ponto se o rodarmos 360° ou 720°
adicionais, e assim por diante. Para evitar isso, devemos estipular que apenas a
menor distância angular do conjunto infinito deve ser usada como segunda
componente do símbolo. Alternativamente, podemos usar o seno e o cosseno do
rolamento.
Outra estranheza desta codificação é que não existe uma distância
angular especificável para o próprio ponto polar. Assim, o símbolo deste ponto é
diferente do símbolo de todos os outros pontos. Para alguns propósitos, isso é
mais do que um pouco estranho. No entanto, para outros fins, esta codificação é

23
CAP 6 -Procedimentos

preferida porque torna extremamente simples os procedimentos para obter


alguns símbolos muito úteis. Algo que um navegador muitas vezes deseja saber é
a distância e a direção de um local (por exemplo, o ninho ou a colméia ou a fonte
mais rica de alimento ou o porto mais próximo quando uma tempestade
ameaça). Nem a distância nem a direção de uma localização desde a origem (ou
de qualquer outro ponto) estão explícitas na codificação cartesiana. Eles devem
ser determinados por meio de um procedimento razoavelmente complexo
aplicado ao vetor que simboliza a localização. Na codificação cartesiana, para
determinar a distância (alcance) de um ponto da origem <0, 0> ao ponto <x, y>,
2 2
devemos calcular 𝑥 + 𝑒 . Para determinar sua direção (rolamento), devemos
calcular o arco seno (y/x). Por outro lado, ambas as quantidades são explícitas na
codificação polar de localização. Como no caso de determinar a paridade a partir
da codificação binária de um inteiro, podemos ler o que precisamos diretamente
do próprio símbolo; o alcance (distância linear) da localização é representado
pelo primeiro elemento do símbolo vetorial, o rumo (distância angular) pelo
segundo elemento. Existem muitos outros procedimentos que são mais simples
com a codificação polar do que com a codificação cartesiana. Por outro lado,
existem muitos mais procedimentos que são mais simples com a codificação
cartesiana do que com a codificação polar, razão pela qual a codificação
cartesiana é a codificação padrão.
O ponto importante para o nosso propósito é que, se você alterar a
codificação, também deverá alterar os procedimentos usados ​para calcular a
distância e tudo o mais que se deseja calcular. Se não forem feitas alterações
adequadas no lado computacional, o homomorfismo será interrompido; fazer os
cálculos não produz mais resultados válidos. Quando você tenta mapear os
símbolos computados de volta às entidades às quais eles se referem, isso não
funciona. Este ponto é de fundamental importância quando se consideram
sistemas propostos para estabelecer referência entre a atividade nos neurônios
ou qualquer outro símbolo neural proposto e os aspectos do mundo que a
atividade supostamente representa. Deve-se sempre perguntar: se essa é a
forma que os símbolos assumem, como funciona o lado computacional do
sistema? Quais são os procedimentos que, quando aplicados a esses símbolos,
extrairiam informações comportamentais úteis?

24

Você também pode gostar