Algoritmo de Pensamento e Consciência

Este artigo descreve um algoritmo para pensamento e consciência. Ofereço minha resposta à pergunta de como o pensamento e a consciência funcionam. E eu demonstro um algoritmo que pode realmente, criativamente pensar e possuir consciência real. O artigo é destinado a programadores e consiste em duas partes principais. A primeira parte é puramente técnica, contém uma descrição do algoritmo, uma lista de suas propriedades e um exemplo de aplicação prática. A segunda parte contém teses explicativas e uma solução para a questão da axiomatização construtiva da consciência. Um algoritmo é um texto significativo que fala por si e, portanto, haverá apenas comentários mínimos praticamente necessários.

Descrição do algoritmo


A descrição do algoritmo é realizada em um formalismo matemático caseiro, sob o princípio de "de cima para baixo", ou seja, o registro abstrato final é fornecido primeiro e, em seguida, o algoritmo é analisado em busca de partes na ordem em que as chamadas são feitas e os comentários são feitos. Portanto, o algoritmo "montado" é uma função recursiva da seguinte forma:

tn + 1 = composição [ abstração [ dedução [t n ]]]; t 0 = s; t n , s ∈ S ; n ∈ N

O cálculo desta função está pensando. Como você pode ver, três operadores aparecem no registro:
composição [] , abstração [] , dedução [] ; existem também: a variável de semente s ∈ S , o conjunto de linhas de uma forma especial S e o número da etapa n ∈ N. A seguir, consideramos em detalhes cada peça de reposição. Começamos com o conjunto S e seus elementos.

Para especificar o conjunto S, é necessário determinar a sintaxe na qual os elementos deste conjunto serão gravados. Os elementos do conjunto S serão chamados de cadeias. Qualquer linha em S consiste em uma hierarquia de colchetes “(“, ”)” e identificadores arbitrários de caracteres são gravados dentro dos colchetes. Para evitar o uso do termo "identificador", uma vez que pode ser necessário para outros fins, identificadores simbólicos dentro de colchetes serão chamados "mnemônicos". Cada mnemônica é escrita em caracteres latinos "A - z". Os mnemônicos entre parênteses podem ser separados por vírgula “,”. Se o comprimento dos mnemônicos for fixo, especificado separadamente, o separador não será definido. Os mnemônicos são escritos apenas entre parênteses. Uma linha pode conter colchetes aninhados. A hierarquia de colchetes na sequência é arbitrária, mas deve haver um colchete de fechamento para cada colchete de abertura. Neste artigo, usarei apenas letras minúsculas do alfabeto latino para escrever mnemônicos, e o comprimento dos mnemônicos será fixo, uma letra corresponde a um mnemônico, não coloquei um caractere separador. Exemplos de linhas:

() ≡ ∅ é uma string vazia.
(a) - uma string contendo um mnemônico " a ".
(aa) - uma string contendo duas instâncias dos mnemônicos “ a ”.
(ab) é uma string contendo dois mnemônicos " a " e " b ".
((a) (a)) - a linha contém duas cópias dos níveis mnemônicos “ a ” e aninhados de colchetes.

Os colchetes, juntamente com seu conteúdo, bem como os mnemônicos individuais, às vezes serão chamados de "componentes de string", nos casos em que é necessária uma generalização apropriada. Por exemplo, a linha ((a) ab) contém quatro componentes, entre eles: dois componentes “ a ”, um componente “ (a) ” e um componente “ b ”.

Registros de cadeias que correspondem a um rearranjo dos componentes dentro da cadeia são considerados idênticos. Exemplos de linhas idênticas:

aB) b)
(a) (b)) ≡ ((b) (a)) .
(abc) ≡ (bac) ≡ (cba) ≡ (acb) ≡ (bca) ≡ (cabina) .
(a) (ab)) ≡ ((a) (ba)) ≡ ((ab) (a)) ≡ ((ba) (a)) .

As linhas podem conter qualquer número de componentes idênticos e repetitivos e, nesse caso, um registro mais curto é possível usando o índice de repetição, que é colocado na frente do componente à esquerda, sem um separador. Exemplos:

aa) ≡ (2a)
(aabb) ≡ (2a2b) .
((a) (a)) ≡ (2 (a)) .
((aa) (aa)) ≡ (2 (2a)) .
(aa (bb) (bb) (ccc) (ccc) (ccc)) ≡ (2a2 (2b) 3 (3c)) .

Nos casos em que a sequência contém componentes vazios, por exemplo, (a ()) , (a () () (b)), as identidades são válidas: (a ()) ≡ (a) , (a () () (b) )) ≡ (a (b)) , ou seja, componentes vazios são jogados fora.

Definição de O conjunto S consiste em todas as sequências possíveis que atendem aos critérios de sintaxe acima, incluindo uma sequência vazia.

Os operadores de dedução, abstração e composição são definidos no conjunto S. Os argumentos do operador são indicados entre colchetes [] , porque os parênteses são reservados para a sintaxe da string. O termo "operador" é sinônimo de "função".

Operador de dedução . Definição de ∀s ∈ S , dedução k [s] ∈ S , k ∈ N , k> 1, dedução [s] ≝ dedução 2 [s] . Retorna a string s de S como argumento. Como resultado, retorna uma string de S. Ação. O operador k vezes duplica cada componente da cadeia e a cadeia inteira. A estrutura resultante é enquadrada por colchetes externos comuns. A duplicação começa com os componentes mais profundos, em termos de aninhamento. A linha inteira é duplicada por último. Para propósitos práticos imediatos, basta que k = 2 , então eu defini um caso especial de dedução [s] - dedução 2 [s] . O uso de dedução [] implica que k = 2 , ou seja, como resultado do operador dedução [s] , todos os componentes da string s são duplicados. Exemplos:

dedução [(a)] = ((aa) (aa)).
dedução [(aa)] = ((aaaa) (aaaa))
dedução [(ab)] = ((aabb) (aabb)).
dedução [(a (b))] = ((aa (bb) (bb)) (aa (bb) (bb))).
dedução [((a) (b))] = (((aa) (aa) (bb) (bb)) ((aa) (aa) (bb) (bb))).
dedução [((a) (b (cc)))] = (((aa) (aa) (bb (cccc) (cccc)) (bb (cccc) (cccc))) ((aa) (aa) ( bb (cccc) (cccc)) (bb (cccc) (cccc)))) .

Operador de abstração . Definição de ∈s ∈ S , abstração [s] ⊂ S. Retorna a string s de S como argumento. Como resultado, ele retorna muitas linhas. Princípio de ação. Um operador de abstração cria muitas linhas a partir de uma linha de origem usando uma operação especial - parênteses de componentes idênticos. A operação de bracketing se aplica apenas a colchetes aninhados que estão no mesmo nível de aninhamento. O princípio geral do bracketing. Se, em qualquer combinação de colchetes localizados no mesmo nível, os mesmos componentes estiverem dentro dos colchetes, qualquer conjunto dos mesmos componentes poderá ser retirado dos colchetes, e os componentes que permanecerem intactos deverão ser combinados nos mesmos colchetes gerais do mesmo nível. Considere um exemplo. String ((ab) (ac)) . Nesta linha, existem duas substrings no mesmo nível: (ab) e (ac) , dentro das quais há os mesmos mnemônicos " a ", esses mnemônicos podem ser colocados entre colchetes e o resultado é (a (bc)) . Como você pode ver, os mnemônicos restantes " b " e " c " são combinados entre colchetes. Considere um exemplo menos óbvio. A sequência ((aa) (aa)) contém as subseqüências (aa) e (aa) ; nesse caso, existem duas opções diferentes para colocar os colchetes. Na primeira variante, apenas um mnemônico " a " pode ser retirado de colchetes de cada substring e, na segunda variante, um grupo de mnemônico " aa " pode ser retirado. Vamos considerar as duas opções em mais detalhes.

Primeira opção, demonstração passo a passo:

  1. Etapa 1, escolha ( vermelho ) o que levar ((a) (a)) .
  2. Etapa dois, faça o selecionado ( a (... a) (... a)) .
  3. Etapa três, combine o restante entre colchetes ( a (... a ... a)) .
  4. Resultado (a (aa)) .

A segunda opção, nas etapas:

  1. Etapa um, escolha o que levar (( aa ) ( aa )) .
  2. Etapa dois, faça o selecionado ( aa (...) (...)) .
  3. Etapa três, combine o restante entre colchetes ( aa (...)) .
  4. Quarto passo, jogue fora os componentes vazios ( aa ) .
  5. Resultado (aa) .

Vamos complicar o exemplo. Seja dada a sequência ((aa) (aab) (aab)) , ela possui três substrings localizados no mesmo nível: (aa) , (aab) , (aab) , todos os três têm o mesmo conteúdo. A regra de parênteses não nos obriga a executar a operação para as três substrings de uma só vez. Para a operação de piquetagem, você pode selecionar qualquer grupo de substrings.

Nesse caso, existem três opções não idênticas para agrupar substrings:

  1. aa), aab)
  2. (aab), (aab) .
  3. aa), (aab), (aab) .

Realizamos todas as declarações possíveis para cada uma das opções de agrupamento, passo a passo.

Agrupamento (aa) , (aab) . String ((aa) (aab) (aab)) .

A primeira opção:

  1. Selecione o conteúdo (( a a) ( a ab) (aab)) .
  2. Nós tiramos ( a (... a) (... ab) (aab)) .
  3. Combinar ( a (... a ... ab) (aab)) .
  4. Resultado nº 1 (a (aab) (aab)) .

A segunda opção:

  1. Selecione o conteúdo (( aa ) ( aa b) (aab)) .
  2. A gente tira ( aa (...) (... b) (aab)) .
  3. Combinar ( aa (... b) (aab)) .
  4. Resultado No. 2 (a (b) (aab)) .

Agrupamento (aab) , (aab) . String ((aa) (aab) (aab)) .

A primeira opção:

  1. Selecione o conteúdo ((aa) ( a ab) ( a ab)) .
  2. Tiramos ((aa) a (... ab) (... ab)) .
  3. Combine ((aa) a (... ab ... ab)) .
  4. Resultado nº 3 (a (aa) (aabb)) .

A segunda opção:

  1. Selecione o conteúdo ((aa) ( aa b) ( aa b)) .
  2. Nós tiramos ((aa) aa (... b) (... b)) .
  3. Combine ((aa) aa (... b ... b)) .
  4. Resultado n ° 4 (aa (aa) (bb)) .

A terceira opção:

  1. Selecione o conteúdo ((aa) (a ab ) (a ab )) .
  2. A gente tira ((aa) ab (... a) (... a)) .
  3. Combine ((aa) ab (... a ... a)) .
  4. Resultado n ° 5 (ab (aa) (aa)) .

Quarta opção:

  1. Selecione o conteúdo ((aa) (aa b ) (aa b )) .
  2. Nós tiramos ((aa) b (... aa) (... aa)) .
  3. Combine ((aa) b (... aa ... aa)) .
  4. Resultado n ° 6 (b (aa) (aaaa)) .

Quinta opção:

  1. Selecione o conteúdo ((aa) ( aab ) ( aab )) .
  2. A gente tira ((aa) aab (...) (...)) .
  3. Combine ((aa) aab (...)) .
  4. Resultado nº 7 (aab (aa)) .

Agrupamento (aa) , (aab) , (aab) . String ((aa) (aab) (aab)) .

A primeira opção:

  1. Selecione o conteúdo (( a a) ( a ab) ( a ab)) .
  2. Nós tiramos ( a (... a) (... ab) (... ab)) .
  3. Combinar ( a (... a ... ab ... ab)) .
  4. Resultado nº 8 (a (aaabb)) .

A segunda opção:

  1. Selecione o conteúdo (( aa ) ( aa b) ( aa b)) .
  2. A gente tira ( aa (...) (... b) (... b)) .
  3. Combinar ( aa (... b ... b)) .
  4. Resultado n ° 9 (aa (bb)) .

A ação do operador de abstração . Como você pode ver no exemplo, para a linha original ((aa) (aab) (aab)), existem nove opções diferentes para colocar algo fora dos colchetes, e nove linhas resultantes correspondem a essas opções. É assim que o operador de abstração age - repete todas as opções possíveis para colocar colchetes e cria o conjunto correspondente de linhas resultantes. Além disso, o operador de abstração está procurando opções para criar não apenas na linha de origem, mas também em todas as linhas de resultado resultantes. Em outras palavras, o operador de abstração é aplicado recursivamente aos seus resultados, e assim por diante até que todas as opções possíveis sejam esgotadas. Por razões óbvias, para qualquer linha final, o número de opções de remoção possíveis também é finito.

Vamos voltar ao exemplo anterior. No exemplo considerado, não escrevi todas as opções possíveis, mas apenas nove partes do primeiro nível. Para ilustrar o efeito total do operador de abstração, é necessário construir todas as opções para colocar colchetes para cada um dos nove resultados obtidos anteriormente. Vamos escrever todas as opções, mas de uma maneira mais concisa.

Resultado nº 1 (a (aab) (aab)) :

1.1 (a ( a ab) ( a ab)) => (a a (aabb)) .
1.2 (a ( aa b) ( aa b)) => (a aa (bb)) .
1.3 (a (a ab ) (a ab )) => (a ab (aa)) . * No. 7
1.4 (a ( aab ) ( aab )) => ( aab ) .
1.5 (a (aa b ) (aa b )) => (a b (aaaa)) .
Resultado nº 2 (a (b) (aab)) :
2.1 (a ( b ) (aa b )) => (a b (aa)) .
Resultado nº 3 (a (aa) (aabb)) :
3.1 (a ( a a) ( a abb)) => (a a (aabb)) . * No. 1.1
3.2 (a ( aa ) ( aa bb)) => (a aa (bb)) . * No. 1.2
Resultado n ° 4 (aa (aa) (bb)) .
Resultado no. 5 (ab (aa) (aa)) :
5.1 (ab ( a ) ( a )) => ( a (aa)) . * No. 7, * No. 1.3
5.2 (ab ( aa ) ( aa )) => ( aa ab) . * No. 1.4
Resultado no 6 (b (aa) (aaaa)) :
6.1 (b ( a a) ( a aaa)) => ( a b (aaaa)) . * No. 1.5
6.2 (b ( aa ) ( aa aa)) => ( aa b (aa)) . * No. 7, * No. 1.3, * No. 5.1
Resultado nº 7 (aab (aa)) .
Resultado nº 8 (a (aaabb)) .
Resultado n ° 9 (aa (bb)) .

Um asterisco indica opções que são repetidas. Somente variações exclusivas são incluídas no resultado da abstração. No exemplo analisado, existem catorze linhas de resultados exclusivas. Total:

abstração [((aa) (aab) (aab))] =
{
(a (aab) (aab)), (aa (aabb)), (aaa (bb)), (aaab), (a (b) (aab)), (ab (aa)), (a (aa)) (aabb)), (aa (aa) (bb)), (ab (aa) (aa)), (b (aa) (aaaa)), (ab (aaaa)), (aab (aa)), ( a (aaabb)), (aa (bb))
}

Para maior clareza, considere mais alguns exemplos.

String ((a (b)) (a (b))) . Opções de parênteses. Primeira iteração:

(( a (b)) ( a (b))) => ( a ((b) (b))) , resultado Nº 1.
((a (b) ) (a (b) )) => ( (b) (aa)) , resultado n ° 2.
(( a (b) ) ( a (b) )) => ( a (b) ) , resultado n ° 3.
No primeiro resultado, mais uma decisão pode ser tomada. Segunda iteração:
(a (( b ) ( b ))) => (a ( b )) , o resultado nº 1.2 coincide com o resultado nº 3.

Total: abstração [((a (b)) (a (b)))] = {(a ((b) (b))), ((b) (aa)), (a (b))}

Ótimo exemplo:
abstração [ dedução [(a (b))]] = abstração [((aa (bb) (bb)) (aa (bb) (bb)))] =>
1. ((aa ( b b) ( b b)) (aa (bb) (bb))) => ((aa b (b)) (aa (bb) (bb))) .
1.1 ( a ab (b)) ( a a (bb) (bb))) => ( a (aab (b) (bb) (bb)))) .
1.1.1 (a (aab ( b ) (bb) (bb))) => (a (aab b (b) (bb))) .
1.1.1.1 (a (aabb ( b ) ( b b))) => (a (aabb b (b))) .
1.1.2 (a (aab ( b ) ( b b) ( b b))) => (a (aab b (bb))) .
1.1.3 (a (aab (b) ( b b) ( b b))) => (a (aab b (b) (bb))) .
1.1.3.1 (a (aabb ( b ) ( b b))) => (a (aabb b (b))) .
1.1.4 (a (aab (b) ( bb ) ( bb ))) => (a (aab bb (b))) .
1.2 (( aa b (b)) ( aa (bb) (bb))) => ( aa (b (b) (bb) (bb))) .
1.2.1 (aa (b ( b ) ( b b) (bb))) => (aa (b b (b) (bb))) .
1.2.1.1 (aa (bb ( b ) ( b b))) => (aa (bb b (b))) .
1.2.2 (aa (b ( b ) ( b b) ( b b))) => (aa (b b (bb))) .
1.2.3 (aa (b (b) ( b b) ( b b))) => (aa (b b (b) (bb))) .
1.2.3.1 (aa (bb ( b ) ( b b))) => (aa (bb b (b))) .
1.2.4 (aa (b (b) ( bb ) ( bb ))) => (aa (b bb (b))) .
1.3 (aab (b)) (aa ( b b) ( b b))) => ((aab (b)) (aa b (bb))) .
1.3.1 (( a ab (b)) ( a ab (bb))) => ( a (aabb (b) (bb))) .
1.3.1.1 (a (aabb ( b ) ( b b))) => (a (aabb b (b))) .
1.3.2 (( aa b (b)) ( aa b (bb))) => ( aa (bb (b) (bb))) .
1.3.2.1 (aa (bb ( b ) ( b b))) => (aa (bb b (b))) .
1.3.3 ( aab (b)) ( aab (bb))) => ( aab ((b) (bb))) .
1.3.3.1 (aab (( b ) ( b b))) => (aab ( b (b))) .
1.3.4 ((a ab (b)) (a ab (bb))) => ( ab (aa (b) (bb))) .
1.3.4.1 (ab (aa ( b ) ( b b))) => (ab (aa b (b))) .
1.3.5 ((aa b (b)) (aa b (bb))) => ( b (aaaa (b) (bb))) .
1.3.5.1 (b (aaaa ( b ) ( b b))) => (b (aaaa b (b))) .
1.4 (aab (b)) (aa ( bb ) ( bb ))) => ((aab (b)) (aa bb )) .
1.4.1 ( a ab (b)) ( a abb)) => ( a (aabbb (b))) .
1.4.2 (( aa b (b)) ( aa bb)) => ( aa (bbb (b))) .
1.4.3 (( aab (b)) ( aab b)) => ( aab (b (b))) .
1.4.4 ((a ab (b)) (a ab b)) => ( ab (aab (b))) .
1.4.5 ((aa b (b)) (aa b b)) => ( b (aaaab (b))) .
2. ((aa ( bb ) ( bb )) (aa (bb) (bb))) => ((aa bb ) (aa (bb) (bb))) .
2.1 (aabb) (aa ( b b) ( b b))) => ((aabb) (aa b (bb))) .
2.1.1 ( a abb) ( a ab (bb))) => ( a (aabbb (bb))) .
2.1.2 (( aa bb) ( aa b (bb))) => ( aa (bbb (bb))) .
2.1.3 ( aab b) ( aab (bb))) => ( aab (b (bb))) .
2.1.4 (a ab b) (a ab (bb))) => ( ab (aab (bb))) .
2.1.5 (aaa b b) (aa b (bb))) => ( b (aaaab (bb))) .
2.2 (aabb) (aa ( bb ) ( bb ))) => ((aabb) (aa bb )) .
2.2.1 ( a abb) ( a abb)) => ( a (aabbbb)) .
2.2.2 (( aa bb) ( aa bb)) => ( aa (bbbb)) .
2.2.3 ( aab b) ( aab b)) => ( aab (bb)) .
2.2.4 (a abb ) (a abb )) => ( abb (aa)) .
2.2.5 ( aabb ) ( aabb )) => ( aabb ) .
2.2.6 ((a ab b) (a ab b)) => ( ab (aabb)) .
2.2.7 ((aa b b) (aa b b)) => ( b (aaaabb)) .
2.2.8 ((aa bb ) (aa bb )) => ( bb (aaaa)) .
2.3 ( a abb) ( a a (bb) (bb))) => ( a (aabb (bb) (bb))) .
2.3.1 (a (aabb ( b b) ( b b))) => (a (aabb b (bb))) .
2.3.2 (a (aabb ( bb ) ( bb ))) => (a (aabb bb )) .
2.4 (( aa bb) ( aa (bb) (bb))) => ( aa (bb (bb) (bb))) .
2.4.1 (aa (bb ( b b) ( b b))) => (aa (bb b (bb))) .
2.4.2 (aa (bb ( bb ) ( bb ))) => (aa (bb bb )) .
3. (( a a (bb) (bb)) ( a a (bb) (bb))) => ( a (aa (bb) (bb) (bb) (bb))) .
3.1 (a (aa ( b b) ( b b) (bb) (bb))) => (a (aa b (bb) (bb) (bb))) .
3.1.1 (a (aab (bb) (bb) (bb))) => (a (aab b (bb) (bb))) .
3.1.1.1 (a (aabb ( b b) ( b b))) => (a (aabb b (bb))) .
3.1.1.2 (a (aabb ( bb ) ( bb ))) => (a (aabb bb )) .
3.1.2 (a (aab ( b b) ( b b) ( b b))) => (a (aab b (bbb))) .
3.1.3 (a (aab ( bb ) ( bb ) (bb))) => (a (aab bb (bb))) .
3.1.4 (a (aab ( bb ) ( bb ) ( bb ))) => (a (aab bb )) .
3.2 (a (aa ( bb ) ( bb ) (bb) (bb))) => (a (aa bb (bb) (bb))) .
3.2.1 (a (aabb ( b b) ( b b))) => (a (aabb b (bb))) .
3.2.2 (a (aabb ( bb ) ( bb ))) => (a (aabb bb )) .
3.3 (a (aa ( b b) ( b b) ( b b) (bb))) => (a (aa b (bbb) (bb))) .
3.3.1 (a (aab ( b bb) ( b b))) => (a (aab b (bbb))) .
3.3.2 (a (aab ( bb b) ( bb ))) => (a (aab bb (b))) .
3.4 (a (aa ( b b) ( b b) ( b b) ( b b))) >> (a (aa b (bbbb))) .
3.5 (a (aa ( bb ) ( bb ) ( bb ) (bb))) => (a (aa bb (bb))) .
3.6 (a (aa ( bb ) ( bb ) ( bb ) ( bb ))) => (a (aa bb )) .
4. (( aa (bb) (bb)) ( aa (bb) (bb))) >> ( aa ((bb) (bb) (bb) (bb))) .
4.1 (aa (( b b) ( b b) (bb) (bb))) => (aa ( b (bb) (bb) (bb)))) .
4.1.1 (aa (b ( b b) ( b b) (bb))) => (aa (b b (bb) (bb))) .
4.1.1.1 (aa (bb ( b b) ( b b))) => (aa (bb b (bb))) .
4.1.1.2 (aa (bb ( bb ) ( bb ))) => (aa (bb bb )) .
4.1.2 (aa (b ( b b) ( b b) ( b b))) => (aa (b b (bbb))) .
4.1.3 (aa (b ( bb ) ( bb ) (bb))) => (aa (b bb (bb))) .
4.1.4 (aa (b ( bb ) ( bb ) ( bb ))) => (aa (b bb )) .
4.2 (aa (( bb ) ( bb ) (bb) (bb))) => (aa ( bb (bb) (bb))) .
4.2.1 (aa (bb ( b b) ( b b))) => (aa (bb b (bb))) .
4.2.2 (aa (bb ( bb ) ( bb ))) => (aa (bb bb )) .
4.3 (aa (( b b) ( b b) ( b b) (bb))) => (aa ( b (bbb) (bb))) .
4.3.1 (aa (b ( b bb) ( b b))) => (aa (b b (bbb))) .
4.3.2 (aa (b ( bb b) ( bb ))) => (aa (b bb (b))) .
4.4 (aa (( b b) ( b b) ( b b) ( b b))) >> (aa ( b (bbbb))) .
4.5 (aa (( bb ) ( bb ) ( bb ) (bb))) => (aa ( bb (bb))) .
4.6 (aa (( bb ) ( bb ) ( bb ) ( bb ))) => (aa ( bb )) .
5. ((aa (bb) (bb)) (aa (bb) (bb))) => ( (bb) (aaaa (bb) (bb))) .
5.1 (bb) (aaaa ( b b) ( b b))) => ((bb) (aaaa b (bb))) .
5.1.1 ( b b) (aaaa b (bb))) => ( b (aaaab (bb))) .
5.2 (bb) (aaaa ( bb ) ( bb ))) => ((bb) (aaaa bb )) .
5.2.1 (bb) (aaaa b b)) => ( b (aaaabb)) .
5.2.2 ( bb ) (aaaa bb )) => ( bb (aaaa)) .
6. ((aa (bb) (bb) ) (aa (bb) (bb) )) => ( (bb) (bb) (aaaa)) .
6.1 ( b b) ( b b) (aaaa)) => ( b (bb) (aaaa)) .
6.2 ( bb ) ( bb ) (aaaa)) => ( bb (aaaa)) .
7. ((a a (bb) (bb)) (a a (bb) (bb))) => ( a (bb) (aa (bb) (bb))) .
7.1 (a (bb) (aa ( b b) ( b b))) => (a (bb) (aa b (bb))) .
7.1.1 (a ( b b) (aa b (bb))) => (a b (aab (bb))) .
7.2 (a (bb) (aa ( bb ) ( bb ))) => (a (bb) (aa bb )) .
7.2.1 (a ( b b) (aa b b)) => (a b (aabb)) .
7.2.2 (a ( bb ) (aa bb )) => (a bb (aa)) .
8. (( aa (bb) (bb)) ( aa (bb) (bb))) => ( aa (bb) ((bb) (bb))) .
8.1 (aa (bb) (( b b) ( b b))) => (aa (bb) ( b (bb))) .
8.1.1 (aa ( b b) ( b (bb))) => (aa b (b (bb))) .
8.2 (aa (bb) (( bb ) ( bb ))) => (aa (bb) ( bb )) .
8.2.1 (aa ( b b) ( b b)) => (aa b (bb)) .
8.2.2 (aa ( bb ) ( bb )) => (aa bb ) .
9. ((a a (bb) (bb) ) (a a (bb) (bb) )) => ( a (bb) (bb) (aa)) .
9.1 (a (aa) ( b b) ( b b)) => (a b (aa) (bb)) .
9.2 (a (aa) ( bb ) ( bb )) => (a bb (aa)) .
10. (( aa (bb) (bb) ) ( aa (bb) (bb) )) => ( a (bb) (bb) ) .
10.1 (a ( b b) ( b b)) => (a b (bb)) .
10.2 (a ( bb ) ( bb )) => (a bb ) .

Na lista acima, de linhas resultantes (à direita da seta), é necessário selecionar todas as linhas exclusivas, e esse conjunto de linhas exclusivas será o resultado da abstração [((aa (bb) (bb)) (aa (bb) (bb))]] . Não escreverei linhas únicas, pois isso não acrescentará nada à explicação. Abaixo, ao considerar a otimização e o uso prático do algoritmo, vou me referir a este exemplo.


Operador de composição . Definição de ⊂U ⊂ S , U ∅ ∅, composição [U] ∅ ∅, composição [U] ∈ S. Ele aceita muitas linhas de entrada e retorna uma linha. Ação. O operador prepara o conteúdo para a próxima iteração do algoritmo. Após a ação do operador de abstração, muitas linhas aparecem e, no estágio de composição, ocorre a seleção e concatenação de linhas para a próxima iteração do algoritmo. Mais detalhadamente, considerarei essa questão nas seções de otimização e uso prático. No caso mais simples, o operador de composição executa uma concatenação simples de todos os resultados da abstração. Então, nós o definimos. Exemplo: composição [ abstração [((a (b)) (a (b)))]] = composição [{(a ((b) (b))), ((b) (aa)), (a ( b))}] = ((a ((b) (b))) ((b) (aa)) (a (b))) .

Propriedades do algoritmo


O algoritmo produz seqüências de caracteres. O conjunto de todas as linhas formadas como resultado da operação iterativa do algoritmo será chamado de "saída do algoritmo" ou simplesmente "saída". Definição de inferência. T s ≝ { tn | tn + 1 = composição [ abstração [ dedução [t n ]]]; t 0 = s; t n , s ∈ S ; n ∈ N }. T s é a saída para a semente s . Nos casos em que T está sem um parâmetro, estamos falando sobre a conclusão de qualquer semente. Propriedade de inferência: ∀s, e ∈ S , s ∅, e ≠ s, s ≠ e, T sT e = ∅ . Isso significa que cada elemento de saída corresponde exclusivamente à semente. Como resultado, a conclusão é única para cada semente.

Uma interpretação significativa de dedução e abstração . O significado físico do operador de dedução é o seguinte. A partir da linha original, de maneira universal, o operador de dedução cria um objeto construtivo fundamentalmente novo com propriedades internas fundamentalmente novas e mais complexas. Numa aproximação intuitiva, podemos dizer que a dedução adiciona informações qualitativamente novas. Por sua vez, o operador de abstração analisa o novo objeto em partes e, assim, expressa as informações adicionadas no estágio de dedução em um equivalente construtivo. Você pode perceber que, como resultado do procedimento de colocação entre colchetes, as informações são perdidas. Além disso, para essa sintaxe, colocar entre parênteses é uma maneira universal de perder informações de maneira significativa na ausência de dados a priori sobre o valor das strings. Ou seja, do ponto de vista do algoritmo, todas as opções possíveis para a perda de informações que são calculadas no estágio de abstração, de fato, são o valor das linhas. Assim, a cada etapa, o algoritmo cria uma heurística sintática nova e exclusiva. E cada heurística subsequente é fundamentalmente mais complexa e mais substancial que a anterior. A cada iteração do algoritmo, novos conhecimentos aparecem.

Aplicação prática


O algoritmo é uma "coisa em si".Ele pensa, mas esse é o pensamento de um "alienígena". Para obter benefícios práticos do pensamento alienígena, você precisa encontrar uma linguagem comum com ele. Por um lado, é necessário treinar um alienígena e, por outro lado, aprender a entendê-lo, no final, estabelecer uma comunicação significativa. Em geral, o paradigma de interação com o algoritmo é semelhante aos princípios bem conhecidos de interação com a "caixa preta". Além disso, para maior conveniência, chamarei o algoritmo de pensamento de Kohl alienígena.

Considere o caso ideal. Suponha que tenhamos um poder computacional ilimitado à nossa disposição e que possamos calcular qualquer número de iterações do pensamento de Kolya sem nos preocupar com problemas de otimização. Nesse caso, os seguintes ingredientes serão necessários para interagir com Kolya:

  1. Um modelo digital de um ambiente interativo cujo significado da atividade é conhecido.
  2. Um modelo digital de uma ferramenta que pode afetar o meio ambiente.
  3. Que codifica algoritmo para sinais codificam a partir do ambiente de cordas S .
  4. Um algoritmo de decodificação que será de alguma forma confuso, mas racionalmente justificado para decodificar linhas previamente desconhecidas de S e convertê-las em sinais para o instrumento.

Com esses componentes, é possível organizar um esquema de aprendizado universal com motivação desconhecida, o que permitirá adaptar o pensamento de Kolya ao meio ambiente. Abaixo está o pseudo-código.

S NextThought(S prevThought, S ExternalSignal, int exposure = 1) { S t = composition[prevThought, ExternalSignal]; for (int i = 0; i < exposure; i++) t = composition[abstraction[deduction[t]]]; return t; } EnvironmentModel e; S s = encode(e.GetState()); S o = ∅; while (0) { S o = NextThought(o, s); e.ImpactTool.perform(decode(o)); s = encode(e.GetState()); } 

Circuito de realimentação . No começo, Kolya não pensa. O primeiro pensamento de Kolya é o estado inicial codificado do meio. A cada iteração, um sinal externo é derramado no pensamento de Kolya. Após o que Kolya pensa durante o tempo de exposição. Os resultados do pensamento são decodificados e enviados para a ferramenta. Por sua vez, a ação da ferramenta altera de alguma forma o estado do ambiente. E tudo se repete novamente. Com o tempo, o pensamento de Kolya se adaptará ao ambiente e ele começará a mostrar sinais de comportamento altamente organizado e motivado subjetivamente. No entanto, a motivação de Kolya permanecerá desconhecida. Para entender sua motivação, no próximo estágio do treinamento, é necessário montar experimentos, ou seja, mudar propositadamente o ambiente e estudar as reações de Kolya às mudanças. Se for possível descrever o comportamento externo desejado de Kolya em termos de alguma função objetiva, o processo de aprendizado pode ser automatizado, por exemplo, usando um algoritmo genético.

Problema de decodificação . É necessário decodificar os pensamentos de Kolya para sintetizar um sinal para o instrumento. A dificuldade é que todo pensamento, como observei na seção anterior, é um design fundamentalmente novo. Ou seja, um pesquisador hipotético nunca pode entender completamente o conteúdo dos pensamentos de Kolya. Parte do conteúdo produzido pelo pensamento de Kolya, por mais que seja estudado, permanecerá para sempre algo completamente obscuro. Apenas alguns dos fragmentos de pensamento mais altamente organizados podem ser reconhecidos de maneira significativa, e essa é uma restrição fundamental e intransponível na comunicação com Kolya. Mas, em termos práticos, essa restrição não é fundamental. Como, em primeiro lugar, é possível especificar infinitamente o lado significativo dos pensamentos de Kolya e, em segundo lugar, não há necessidade de entender Kolya de maneira abrangente. Basta desenvolver uma linguagem comum na qual você possa explicar questões práticas. Do ponto de vista técnico, a situação é a seguinte. O sinal de entrada que descreve o estado do meio é codificado em algum idioma. Palavras e declarações de idioma são seqüências de caracteres de S. A linguagem tem seu próprio vocabulário, sintaxe e semântica. O conteúdo de cada iteração do pensamento de acordo com critérios gramaticais será dividido em várias categorias:

1. Fragmentos com vocabulário desconhecido.
2. Sintaxe desconhecida.
3. Semântica desconhecida.
4. Fragmentos gramaticalmente e semanticamente corretos.

O conteúdo de todas essas categorias é arbitrário de acordo com o método de ocorrência. Ou seja, mesmo no caso de fragmentos gramaticalmente corretos - isso é um acidente e não se sabe qual o significado que Kolya coloca neles, pois seu significado interno é acessível apenas a si mesmo. A priori, não há critérios para conectar corretamente os pensamentos de Kolya e as ações correspondentes do instrumento. E, nesse assunto, resta confiar apenas no próprio Kolya. Seu comportamento é arbitrário e somente ele pode compreender sua motivação à medida que o grau de organização de seu pensamento aumentará. Nesse caso, qualquer esquema racional para responder aos pensamentos de Kolya será aceitável e produtivo, a única questão é a relativa eficácia dos vários esquemas. A opção básica é responder a todos os fragmentos gramaticalmente corretos, mesmo que tenham um conteúdo absurdo. Em geral, tudo o que pode ser convertido em termos da codificação original deve ser transformado e reagido. E assim por diante, até que Kohl “percebeu” reações significativas. E, claro, o modelo mais plástico do ambiente, com um grande número de graus de liberdade, será útil. O meio, de alguma forma, se tornará o corpo de Kolya.

O problema do poder de computação limitado . Em termos de quantidade de computação, o algoritmo é pesado. Claramente, várias dezenas de iterações esgotarão todo o poder computacional do planeta. Podemos confiar em dispositivos quânticos e no fato de haver um análogo quântico do algoritmo, mas até agora houve apenas uma saída: em vez de um pensamento enormemente complexo, pense em muitos pensamentos pequenos e simples em paralelo. Existem vários truques técnicos para isso:

1. Na fase de composição, não é necessário incluir no resultado todas as muitas abstrações. Para que o algoritmo retenha suas propriedades fundamentais, basta selecionar do conjunto apenas duas linhas resultantes independentes. O critério de independência é a diferença diferente de zero dos primeiros dígitos na numeração hierárquica dos resultados da abstração. Voltamos ao grande exemplo, que é mais alto sob o spoiler. Todas as linhas são numeradas de acordo com o princípio de abcd. Um par de linhas com os índices a1.b1.c1.d1 ... , a2.b2.c2.d2 ... é chamado de independente se a1 ≠ a2 . E isso significa que é possível dividir o resultado inteiro da abstração em pares independentes e, para cada par, na próxima etapa, iniciar seu próprio ramo computacional. Além disso, não há necessidade de usar todos os resultados da abstração. No caso mínimo, você pode selecionar apenas um par de linhas e descartar todo o resto (perda irrevogavelmente) e todos os princípios de pensamento serão preservados. Dada a capacidade de perder resultados, é possível organizar uma etapa de seleção adicional, na qual, de maneira racional, por exemplo, de acordo com a significância estatística, para selecionar o conteúdo para cálculos adicionais.

2. O segundo truque é baseado no pressuposto de que quanto mais profundamente os colchetes estiverem na linha, menos organizado será o conteúdo que eles contêm. Consequentemente, o conteúdo "pop-up" como resultado do bracketing é mais organizado e abstrato do ponto de vista dos significados internos de Kolya, o que significa que níveis profundos de aninhamento podem ser removidos. Assim, a quantidade de computação na próxima iteração diminui exponencialmente. Em um sentido intuitivo, esse procedimento permite aproximar apenas a parte mais abstrata do pensamento.

3. Como resultado da paralelização com muitos ramos menores, os cálculos crescerão “em largura”. Essa largura pode ser absolutamente limitada pela seleção, não apenas no nível de ramificações de computação individuais, mas também em toda a matriz de ramificações paralelas. Isso pode ser feito por meio de um pool comum de tamanho fixo, de onde cada ramificação desenhará linhas para a próxima iteração e, consequentemente, de onde irá despejar os resultados. E para strings, você pode limitar absolutamente o nível permitido de parênteses. Essa abordagem combinada ajudará a restringir e regular o crescimento do volume de cálculos.

Interpretação e comentário


Evidência . Não há evidências e não pode ser. Qualquer teoria do pensamento é uma questão de definição. O algoritmo apresentado é uma teoria construtiva do pensamento. E, portanto, ele é um axioma. O algoritmo do pensamento é apodicticamente reconhecível para o sujeito do pensamento. O reconhecimento pode ser facilitado recorrendo primeiro a um axiomatics não construtivo que seja mais intuitivo e depois encontre a coincidência das propriedades de definições construtivas e não construtivas.

Definição não construtiva de pensamento . Pensar não é uma produção algorítmica de conteúdo. Em um entendimento intuitivo, os fenômenos não algorítmicos têm as seguintes características específicas: independência, espontaneidade, singularidade, auto-organização, arbitrariedade, subjetividade, complexidade, imprevisibilidade e incerteza fundamentais, ausência de barreiras conceituais e, no sentido mais amplo - uma possibilidade inerente e duradoura de novidade fundamental. Todos os recursos listados são de alguma forma inerentes ao algoritmo de pensamento descrito. Embora a combinação de um algoritmo e propriedades não-algorítmicas não seja intuitiva e, à primeira vista, contraditória, na verdade não há contradição. O algoritmo implanta conteúdo usando procedimentos algorítmicos bem definidos, mas no processo de implantação, o conteúdo possui uma organização não algorítmica. Dadas as especificidades de design do algoritmo, as propriedades não-algorítmicas na organização do conteúdo resultam das propriedades próprias, internas e não-algorítmicas do próprio conteúdo.

Pontos de vista adicionais sobre o algoritmo . O algoritmo de pensamento é, incluindo:

1. Implementação construtiva de uma metáfora. Pensar é essencialmente metafórico. Não há outros significados além do figurativo (possível). No entanto, em sentido figurado, são possíveis significados literais (algoritmos).
2. Modelo de auto-organização do caos absoluto. Um modelo de espontaneidade conceitual.
3. Um modelo de comportamento completamente independente e motivado subjetivamente. Modelo de criatividade.
4. Linguagem auto-organizada.
5. O modelo de aproximação construtiva, para semântica não construtiva, puramente possível.

Consciência A questão da consciência também é resolvida no nível da definição. Consciência é algo que está além de qualquer limitação conceitual. À luz dessa definição, só podemos envenenar histórias mais ou menos complicadas sobre a consciência, cada uma das quais refletirá algumas possibilidades da consciência, mas nenhuma delas será verdadeira. Ao mesmo tempo, histórias sobre consciência têm potenciais heurísticos diferentes. De todos os contos, aqueles que são mais difíceis são mais úteis. Do ponto de vista dos algoritmos, a consciência é um objeto trans-algorítmico, infinitamente complexo (ou simplesmente - complexo). Uma história de consciência pode ser gravada usando um algoritmo. Parece assim:

lim n → ∞ [t n + 1 = composição [ abstração [ dedução [t n ]]]]]; t 0 = s; t n , s ∈ S ; n ∈ N

Source: https://habr.com/ru/post/pt440424/


All Articles