Sou iniciante trabalhando em métodos que provam equivalência de programa. Li alguns artigos sobre como definir relações lógicas ou simulações para provar que dois programas são equivalentes. Mas estou bastante confuso sobre essas duas técnicas.
Só sei que as relações lógicas são definidas indutivamente enquanto as simulações são baseadas na coindução. Por que eles são definidos dessa maneira? Quais são seus prós e contras, respectivamente? Qual devo escolher em diferentes situações?
lo.logic
pl.programming-languages
logical-relations
parametricity
Hongjin Liang
fonte
fonte
Respostas:
Eu tenho uma resposta para esta pergunta que é possivelmente nova. De fato, ainda estou pensando nos últimos 6 meses ou mais, e ainda não foi escrito em artigos.
A tese geral é que princípios de raciocínio relacional como "relações lógicas", "simulações" e até "invariantes" são manifestações de abstração de dados ou ocultação de informações. Onde quer que oculte informação, esses princípios surgem.
As primeiras pessoas a descobri-lo foram os teóricos dos autômatos. Os autômatos têm um estado oculto. Portanto, você precisa de um raciocínio relacional para falar sobre sua equivalência. Os teóricos dos autômatos lutaram com os homomorfismos por um tempo, desistiram e criaram uma noção chamada "cobertura relacional", que é uma forma de relações de simulação.
Milner pegou a idéia em um artigo pouco conhecido, mas muito fundamental, chamado " Uma noção algébrica de simulação entre programas " em 1971. Hoare sabia disso e a usou na criação de " Prova de correção de representações de dados " em 1972 (mas usada abstração funciona em vez de relações, porque ele pensava que eram "mais simples"). Mais tarde, ele retirou a reivindicação de simplicidade e voltou a usar as relações em " Refinamento de dados refinado ". Reynolds usou o raciocínio relacional em " Craft of Programming"", Capítulo 5 (1981). Ele achava que as relações eram mais naturais e gerais do que as funções de abstração. Se você voltar e ler este capítulo, encontrará idéias de parametridade relacional à espreita, à espera de serem descobertas. Com certeza, dois anos depois, Reynolds publicou "Tipos, abstração e polimorfismo paramétrico" (1983).
Parece que todas essas idéias não têm nada a ver com tipos, mas realmente têm. Linguagens e modelos com estado têm abstração de dados incorporada . Você não precisa definir um "tipo de dado abstrato" para ocultar as informações. Você apenas declara uma variável local e a oculta. Podemos ensiná-lo aos alunos do primeiro ano nas aulas de Java nas primeiras semanas. Sem suor.
Linguagens e modelos funcionais, por outro lado, precisam esconder suas informações por meio de tipos . Os modelos funcionais não possuem abstração de dados incorporada. Temos que adicioná-lo explicitamente, usando ou ∃ . Portanto, se você traduzir um idioma com estado para um idioma funcional, notará todo o estado local sendo traduzido em variáveis de tipo. Para uma descrição explícita de como isso funciona, consulte meu artigo " Objetos e classes em linguagens semelhantes a Algol ", mas as idéias realmente vêm de Reynolds 1981 ("A Essência de Algol"). Estamos apenas entendendo melhor essas idéias clássicas agora.∀ ∃
Pegue duas máquinas e M ' que você deseja provar equivalentes. Milner 1971 diz, define uma relação entre os estados de M e M ' e mostra que as duas máquinas preservam a relação. A parametridade de Reynolds diz: pense nos estados das máquinas como pertencendo aos tipos X e X ' . Defina uma relação R entre eles. Se as máquinas são do tipo F ( X ) e F ( X ′ ) , parametrizadas pelos tipos de seus estados, verifique se as duas máquinas estão relacionadas pela relação FM M′ M M′ X X′ R F(X) F(X′) . F(R)
Portanto, simulações e parametridade relacional são essencialmente a mesma idéia . Não é apenas uma semelhança superficial. O primeiro é feito para linguagens com estado onde há abstração de dados embutida. O último é feito para linguagens sem estado onde a abstração de dados é obtida por meio de variáveis de tipo.
E as relações lógicas, então? Aparentemente, as relações lógicas parecem ser uma ideia mais geral. Enquanto a parametridade fala sobre como relacionar variáveis de tipo dentro do mesmo modelo, relações lógicas parecem relacionar tipos entre modelos diferentes. (Dave Clarke escreveu uma exposição brilhante disso antes.) Mas meu sentimento é (e ainda precisa ser demonstrado) que esse é um exemplo de alguma forma de parametridade de tipo superior que ainda não foi formulada. Fique atento para mais progresso nessa frente.
[Nota adicionada] A conexão entre relações lógicas e simulações é discutida em nosso artigo recente Relações lógicas e parametria: Um programa de Reynolds para teoria de categorias e linguagens de programação .
fonte
functor
Uma das principais diferenças é que as relações lógicas são usadas como uma técnica para mostrar que uma classe de programas (por exemplo, entrada para um compilador) corresponde a outra classe de programas (por exemplo, a saída do compilador), enquanto as relações de simulação são usadas para mostrar a correspondência entre dois programas.
A semelhança entre as duas noções é que ambas definem uma relação usada para mostrar a correspondência entre duas entidades diferentes. Em certo sentido, pode-se pensar em uma relação lógica como uma relação de simulação definida indutivamente na sintaxe dos tipos. Mas existem diferentes tipos de relações de simulação.
As relações lógicas podem ser usadas para mostrar a correspondência entre um idioma como ML e sua tradução para o idioma assembly, como no artigo que você lê. Uma relação lógica é definida indutivamente na estrutura de tipos. Uma relação lógica fornece um meio de composição para mostrar, por exemplo, que uma tradução está correta, mostrando que a tradução está correta para cada tipo de construtor. Nos tipos de função, a condição de condição de correção diria algo como, a tradução dessa função leva entrada bem traduzida para saída bem traduzida.
As relações lógicas são uma técnica versátil para idiomas com base no cálculo lambda. Outras aplicações de relações lógicas incluem ( daqui ): caracterização da definibilidade lambda, relacionando definições semânticas denotacionais, caracterizando polimorfismo paramétrico, modelando a interpretação abstrata, verificando representações de dados, definindo semântica totalmente abstrata e modelando o estado local em linguagens de ordem superior.
As relações de simulação são geralmente usadas para mostrar a equivalência de dois programas. Normalmente, esses programas produzem algum tipo de observação, como o envio de mensagens nos canais. Um programa P simula outro Q se P pode fazer tudo o que Q pode fazer, embora talvez mais.
A bisimulação é, grosso modo, duas relações de simulação reunidas. Você mostra que o programa P e simula o programa Q e esse programa Q pode simular o programa P e você tem uma bimimulação, embora geralmente existam condições adicionais. A entrada da Wikipedia sobre bisimulação é um bom ponto de partida (mais preciso). Existem milhares de variantes da idéia, mas é uma idéia fundamental que foi reinventada de forma mais ou menos igual à da ciência da computação, lógica modal e teoria dos modelos. O artigo de Sangiorgi fornece uma história maravilhosa da idéia.
Um artigo que estabelece uma relação entre as duas noções é Uma Nota sobre Relações Lógicas entre Semântica e Sintaxe, de Andy Pitts, que usa relações lógicas, em última análise, uma noção semântica definida sintaticamente, para provar uma certa propriedade sobre a bisimulação aplicada , que é uma noção puramente sintática.
fonte
Os dois tipos de relações parecem ser usados em contextos diferentes. Simulações lógicas para linguagens digitadas e relações de simulação ao lidar com cálculos de processos ou lógicas modais interpretadas em sistemas de transição. Dave Clarke forneceu muitas explicações intuitivas, portanto, adicionarei algumas dicas que podem ajudar.
Tem havido trabalho para caracterizar as duas noções usando interpretação abstrata. Pode não ser o que você deseja, mas pelo menos as duas noções são tratadas na mesma estrutura matemática.
Samson Abramsky usou relações lógicas para provar a solidez e a análise de rigidez do cálculo preguiçoso de Lambda ( Interpretação abstrata, relações lógicas e extensões de Kan ). Ele também mostrou que as relações lógicas definem funções de abstração no sentido de conexão de Galois da interpretação abstrata. Mais recentemente, Backhouse e Backhouse mostraram como construir conexões de Galois para tipos de ordem superior a partir de conexões de Galois para tipos de base e que essas construções podem ser descritas de forma equivalente usando relações lógicas (relações lógicas e conexões de Galois ). Assim, no contexto específico das linguagens funcionais digitadas, as duas noções são equivalentes.
As relações de simulação caracterizam a preservação da propriedade entre as estruturas de Kripke para várias lógicas modais e temporais. Em vez de tipos, temos modalidades em uma lógica. As relações de simulação também definem conexões de Galois e, portanto, abstrações. Pode-se perguntar se essas abstrações têm propriedades especiais. A resposta é que as abstrações padrão são sólidas e as abstrações baseadas em relações de simulação estão completas. A noção de completude diz respeito às conexões de Galois, que podem não coincidir com a interpretação intuitiva. Esta linha de trabalho foi desenvolvida por David Schmidt ( relações binárias de preservação de estrutura para abstração de programa ) e Francesco Ranzato e Francesco Tapparo ( preservação forte generalizada por interpretação abstrata ).
fonte
Eu diria que os dois conceitos são um tanto vagos. Ambos são sobre relações binárias de mecanismos computacionais que de alguma forma incorporam uma noção de igualdade. As relações lógicas são definidas pela indução da estrutura do tipo, enquanto as simulações podem ser definidas da maneira que você desejar, mas o termo alude à coindução.
fonte