Q1 Quando podemos dizer que dois programas (escritos em alguma linguagem de programação como C ++) são diferentes?
O primeiro extremo é dizer que dois programas são equivalentes se forem idênticos. O outro extremo é dizer que dois programas são equivalentes se eles computarem a mesma função (ou mostrarem o mesmo comportamento observável em ambientes semelhantes). Mas isso não é bom: nem todos os programas que verificam a primalidade são iguais. Podemos adicionar uma linha de código sem afetar o resultado e ainda a consideraríamos o mesmo programa.
Q2 Programas e algoritmos são o mesmo tipo de objeto? Caso contrário, qual é a definição de um algoritmo e como ela difere da definição de um programa? Quando podemos dizer que dois algoritmos são equivalentes?
Respostas:
Q1: Existem muitas noções de equivalência de programas (equivalência de rastreio, equivalência contextual, equivalência observacional, bisimilaridade) que podem ou não levar em consideração itens como tempo, uso de recursos, não-determinismo e rescisão. Muito trabalho foi feito para encontrar noções utilizáveis de equivalência de programas. Por exemplo: Teorias de equivalência de programas com base operacional de Andy Pitts . Mas isso mal arranha a superfície. Isso deve ser útil mesmo se você estiver interessado quando dois programas não são equivalentes. Pode-se até raciocinar sobre programas sem interrupção (usando bisimulação e coindução).
P2: Uma resposta possível para parte dessa pergunta é que os programas interativos não são algoritmos (supondo que se considere um algoritmo receber todas as suas entradas de uma só vez, mas essa definição restrita exclui os algoritmos online). Um programa pode ser uma coleção de processos de interação que também interagem com seu ambiente. Isso certamente não corresponde à noção de algoritmo da máquina de Turing / Recursão.
fonte
Isso não é extremo: a equivalência do programa deve ser definida em relação a uma noção de observação.
A definição mais comum na pesquisa em PL é equivalência contextual. Na equivalência contextual, a ideia é que observemos programas usando-os como componentes de programas maiores (o contexto). Portanto, se dois programas calculam o mesmo valor final para todos os contextos, eles são considerados iguais. Como essa definição quantifica todos os contextos possíveis do programa, é difícil trabalhar diretamente. Portanto, um programa de pesquisa típico em PL é encontrar princípios de raciocínio composicional que impliquem equivalência contextual.
No entanto, essa não é a única noção possível de observação. Por exemplo, podemos dizer facilmente que o comportamento da memória, hora ou potência de um programa é observável. Nesse caso, menos equivalências de programas são válidas, pois podemos distinguir mais programas (por exemplo, mergesort agora é distinguível de quicksort). Se você deseja (digamos) projetar linguagens imunes a ataques de canal de temporização ou projetar linguagens de programação com espaço limitado, esse é o tipo de ação que você deve fazer.
Além disso, podemos optar por julgar alguns dos estados intermediários de uma computação como observáveis. Isso sempre acontece para idiomas concorrentes, devido à possibilidade de interferência. Mas você pode considerar essa visão mesmo em idiomas seqüenciais - por exemplo, se quiser garantir que nenhum cálculo armazene dados não criptografados na memória principal, você deve considerar as gravações na memória principal como observáveis.
Basicamente, não existe uma noção única de equivalência de programa; é sempre relativo à noção de observação que você escolhe, e isso depende da aplicação que você tem em mente.
fonte
P2: Eu acho que as definições teóricas usuais não distinguem realmente algoritmos e programas, mas o "algoritmo", como comumente usado, é mais como uma classe de programas. Para mim, um algoritmo é como um programa com algumas sub-rotinas deixadas não totalmente especificadas (ou seja, seu comportamento desejado é definido, mas não sua implementação). Por exemplo, o algoritmo de eliminação gaussiano não especifica realmente como a multiplicação de números inteiros deve ser realizada.
Sinto muito se isso é ingênuo. Eu não faço pesquisa PL.
fonte