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.
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.