Em poucas palavras : Um algoritmo é a parte construtiva de uma prova construtiva de que um determinado problema tem uma solução. A motivação para essa definição é o isomorfismo de Curry-Howard entre programas e prova, considerando que um programa só tem interesse se resolver um problema, mas é provável. Essa definição permite mais abstração e deixa algumas portas abertas com relação ao tipo de domínios que podem estar envolvidos, por exemplo, com propriedades de finitude.
Atenção . Estou tentando encontrar uma abordagem formal adequada para responder à pergunta. Eu acho que é necessário, mas parece que nenhum dos usuários que responderam até agora (inclusive eu, e alguns foram mais ou menos explícitos sobre isso em outras postagens) tem o background certo para desenvolver adequadamente os problemas relacionados a matemática construtiva, teoria das provas, teoria dos tipos e resultados como o isomorfismo de Curry-Howard entre provas e programas. Estou fazendo o meu melhor aqui, com quaisquer trechos de conhecimento que possuo (acredito) que possuo, e estou ciente das limitações desta resposta. Só espero dar algumas dicas de como acho que a resposta deve ser. Se você vir algum ponto que esteja claramente errado formalmente (provavelmente), deixe-me agora em um comentário - ou por e-mail.
Identificando alguns problemas
Uma maneira padrão de considerar um algoritmo é declarar que um algoritmo é um programa arbitrariamente especificado finitamente para algum dispositivo de computação , incluindo aqueles que não têm limitações na memória. O idioma também pode ser a linguagem da máquina do computador. Na verdade, basta considerar todos os programas para um dispositivo de computação completo Turing (o que implica não ter limitações de memória). Pode não fornecer todas as apresentações de algoritmos, no sentido de que os algoritmos devem ser expressos de uma forma que depende em seus detalhes do contexto de interpretação, mesmo teórico, pois tudo é definido até alguma codificação. Mas, como computará tudo o que há para ser computado, incluirá de alguma forma todos os algoritmos, até a codificação.
π
O problema é que π, possivelmente no sentido matemático de quase todos. Mas isso exigiria mais precisão nas definições.
Portanto, a verdadeira questão é saber quais são os algoritmos significativos. A resposta é que os algoritmos significativos são aqueles que resolvem um problema, calculando passo a passo a "solução", a "resposta", para esse problema. Um algoritmo é interessante se estiver associado a um problema que resolve.
Portanto, dado um problema formal, como obtemos um algoritmo que resolve o problema. De maneira explícita ou implícita, os algoritmos estão associados à idéia de que existe uma solução para o problema, que pode ser provada correta. Se nossas técnicas de prova são precisas é outra questão, mas tentamos pelo menos nos convencer. Se você se restringe à matemática construtiva, que é realmente o que temos que fazer (e é uma restrição axiomática muito aceitável para a maioria da matemática), a maneira de provar a existência de uma solução é passar por etapas de prova que realmente exibem uma construção que representa a solução, incluindo possivelmente outras etapas que a estabelecem.
Todos os programadores pensam algo como: se eu mexer com os dados de tal maneira, então eu obtenho esse widget que tem as propriedades certas por causa do teorema do gergelim e, ao executar essa transformação de preservação, obtenho a resposta desejada . Mas a prova é geralmente informal, e não trabalhamos todos os detalhes, o que explica por que um satélite tentou orbitar Marte no subsolo (entre outras coisas). Fazemos grande parte do raciocínio, mas na verdade mantemos apenas a parte construtiva que constrói a solução, e a descrevemos em uma linguagem de computador como o algoritmo que resolve o problema.
Algoritmos (ou programas) interessantes
Tudo isso foi para introduzir as seguintes idéias, que são objeto de muitas pesquisas atuais (das quais eu não sou especialista). A noção de " algoritmo interessante " usada aqui é minha, introduzida como um espaço reservado informal para definições mais precisas.
Um algoritmo interessante é a parte construtiva de uma prova construtiva de que um determinado problema tem uma solução . Isso significa que a prova deve realmente exibir a solução em vez de simplesmente provar sua existência, por exemplo, por contradição. Para mais detalhes, veja Lógica Intuicionista e Construtivismo em Matemática.
É claro que esta é uma definição muito restritiva, que considera apenas o que chamei de algoritmos interessantes. Por isso, ignora quase todos eles. Mas o mesmo acontece com todos os nossos livros sobre algoritmo. Eles tentam ensinar apenas alguns dos interessantes.
Dados todos os parâmetros do problema (dados de entrada), ele mostra como obter um resultado especificado passo a passo. Um exemplo típico é a resolução de equações (o algoritmo de nome é realmente derivado do nome de um matemático persa, Muḥammad ibn Mūsā al-Khwārizmī , que estudou a resolução de algumas equações). Partes da prova são usadas para estabelecer que alguns valores calculados no algoritmo têm algumas propriedades, mas essas partes não precisam ser mantidas no próprio algoritmo.
Obviamente, isso deve ocorrer dentro de uma estrutura lógica formalizada que estabeleça com que dados os dados são computados, quais são as etapas computacionais elementares permitidas e quais são os axiomas usados.
Voltando ao seu exemplo fatorial, ele pode ser interpretado como um algoritmo, embora trivial. A função fatorial normal corresponde a uma prova de que, dada alguma estrutura aritmética e dado um número inteiro n, existe um número que é o produto dos primeiros n números inteiros. Isso é bem direto, assim como a computação fatorial. Pode ser mais complexo para outras funções.
Agora, se você decidir tabular o fatorial, assumindo que pode, o que não é verdadeiro para todos os números inteiros (mas pode ser verdadeiro para algum domínio finito de valores), tudo o que você está fazendo é incluir em seus axiomas a existência do fatorial, definindo com um novo axioma seu valor para cada número inteiro, para que você não precise mais provar (portanto, calcular) qualquer coisa.
Mas um sistema de axiomas deve ser finito (ou pelo menos definido finitamente). E há uma infinidade de valores para fatorial, um por inteiro. Então você está com problemas para o seu sistema finito de axiomas se axiomatizar uma função infinita, ou seja, definida em um domínio infinito. Isso se traduz computacionalmente no fato de que sua possível pesquisa de tabela não pode ser implementada para todos os números inteiros. Isso mataria o requisito de finitude usual para algoritmos (mas deve ser tão rigoroso quanto frequentemente apresentado?).
Você pode optar por ter um gerador de axiomas finitamente definido para lidar com todos os casos. Isso equivaleria, mais ou menos, a incluir o programa fatorial padrão em seu algoritmo para inicializar a matriz conforme necessário. Isso é chamado de memorização pelos programadores. Na verdade, esse é o valor mais próximo possível do equivalente a uma tabela pré-computada. Pode-se entender que possui uma tabela pré-computada, exceto pelo fato de a tabela ser realmente criada no modo de avaliação lenta , sempre que necessário. Essa discussão provavelmente precisaria de cuidados um pouco mais formais.
Você pode definir suas operações primitivas como desejar (dentro de consistência com seu sistema formal) e atribuir a elas o custo que escolherem quando usados em um algoritmo, para fazer análises de complexidade ou desempenho. Porém, se os sistemas concretos que realmente implementam seu algoritmo (um computador ou um cérebro, por exemplo) não podem respeitar essas especificações de custo, sua análise pode ser intelectualmente interessante, mas é inútil para o uso real no mundo real.
21000
Quais programas são interessantes
Essa discussão deve estar mais adequadamente vinculada a resultados como o
isomorfismo de Curry-Howard entre programas e provas. Se algum programa é realmente uma prova de algo, qualquer programa pode ser interpretado como um programa interessante no sentido da definição acima.
No entanto, para meu entendimento (limitado), esse isomorfismo é limitado a programas que podem ser bem digitados em algum sistema de digitação apropriado, em que tipos corresponde a proposições da teoria axiomática. Portanto, nem todos os programas podem se qualificar como programas interessantes. Meu palpite é que é nesse sentido que um algoritmo deve resolver um problema.
Isso provavelmente exclui a maioria dos programas "gerados aleatoriamente".
É também uma definição um tanto aberta do que é um "algoritmo interessante". Qualquer programa que possa ser visto como interessante é definitivamente assim, pois existe um sistema de tipos identificado que o torna interessante. Mas um programa que não era tipável até o momento, poderia se tornar tipificado com um sistema de tipo mais avançado e, assim, se tornar interessante. Mais precisamente, sempre foi interessante, mas por falta de conhecimento do sistema de tipos adequado, não podíamos conhecê-lo.
No entanto, sabe-se que nem todos os programas são tipificáveis, pois é sabido que algumas expressões lambda, como a implementação do combinador Y , não podem ser digitadas em um sistema de tipos de som .
Essa visão se aplica apenas a formalismos de programação que podem ser diretamente associados a algum sistema de provas axiomático. Não sei como isso pode ser estendido a formalismos computacionais de baixo nível, como a Máquina de Turing. No entanto, como algoritmos e computabilidade geralmente são um jogo de codificação de problemas e soluções (pense em aritmética codificada no cálculo lambda ), pode-se considerar que qualquer computação formalmente definida que possa ser mostrada como uma codificação de um algoritmo também é um algoritmo. Tais codificações provavelmente usam apenas uma parte muito pequena do que pode ser expresso em um formalismo de baixo nível, como as Máquinas de Turing.
Um interesse dessa abordagem é que ela fornece uma noção de algoritmo mais abstrata e independente de questões de codificação real, de "representabilidade física" do domínio de computação. Assim, pode-se, por exemplo, considerar domínios com objetos infinitos, desde que haja uma maneira computacionalmente sólida de usá-los.