Semântica do transformador de predicado - Predicate transformer semantics

A semântica do transformador de predicado foi introduzida por Edsger Dijkstra em seu artigo seminal " Comandos protegidos, não-determinação e derivação formal de programas ". Eles definem a semântica de um paradigma de programação imperativo , atribuindo a cada instrução nesta linguagem um transformador de predicado correspondente : uma função total entre dois predicados no espaço de estado da instrução. Nesse sentido, a semântica do transformador de predicado é uma espécie de semântica denotacional . Na verdade, em comandos protegidos , Dijkstra usa apenas um tipo de transformador de predicado: as pré - condições mais fracas conhecidas (veja abaixo).

Além disso, a semântica do transformador de predicado é uma reformulação da lógica de Floyd-Hoare . Enquanto a lógica de Hoare é apresentada como um sistema dedutivo , a semântica do transformador de predicado (seja pelas pré-condições mais fracas ou pelas pós-condições mais fortes, veja abaixo) são estratégias completas para construir deduções válidas da lógica de Hoare. Em outras palavras, eles fornecem um algoritmo eficaz para reduzir o problema de verificar um triplo de Hoare ao problema de provar uma fórmula de primeira ordem . Tecnicamente, a semântica do transformador de predicado executa um tipo de execução simbólica de declarações em predicados: a execução é executada para trás no caso das pré-condições mais fracas ou para frente no caso das pós-condições mais fortes.

Condições prévias mais fracas

Definição

Para uma declaração S e uma pós - condição R , uma pré - condição mais fraca é um predicado Q tal que para qualquer pré-condição , se e somente se . Em outras palavras, é o "mais frouxo" ou menos exigência restritiva necessária para garantia de que R mantém após S . Singularidade segue facilmente a partir da definição: Se ambos Q e Q' são mais fracas condições prévias, em seguida, pela definição de modo e assim , e assim . Denote pela pré-condição mais fraca para a declaração S e pós-condição R .

Pular

Abortar

Atribuição

Damos a seguir duas precondições mais fracas equivalentes para a instrução de atribuição. Nestas fórmulas, é uma cópia de R onde ocorrências livres de x são substituídos por E . Portanto, aqui, a expressão E é implicitamente coagida em um termo válido da lógica subjacente: é, portanto, uma expressão pura , totalmente definida, encerrando e sem efeito colateral.

  • versão 1:

onde y é uma variável nova (representando o valor final da variável x )

  • versão 2:

A primeira versão evita uma duplicação potencial de x em R , ao passo que a segunda versão é mais simples quando há, no máximo, uma única ocorrência de x em R . A primeira versão também revela uma profunda dualidade entre a pré-condição mais fraca e a pós-condição mais forte (veja abaixo).

Um exemplo de cálculo válido de wp (usando a versão 2) para atribuições com variável de valor inteiro x é:

Isso significa que para que a pós-condição x> 10 seja verdadeira após a atribuição, a pré-condição x> 15 deve ser verdadeira antes da atribuição. Esta também é a "pré-condição mais fraca", pois é a restrição "mais fraca" no valor de x que torna x> 10 verdadeiro após a atribuição.

Seqüência

Por exemplo,

Condicional

Por exemplo:

Loop while

Correção Parcial

Ignorando a terminação por um momento, podemos definir a regra para a pré-condição liberal mais fraca , denotada wlp , usando um predicado I , chamado de invariante de loop , normalmente fornecido pelo programador:

Isso simplesmente afirma que (1) o invariante deve ser mantido no início do loop; (2) adicionalmente, para qualquer estado inicial y , o invariante e o guarda tomados juntos são fortes o suficiente para estabelecer a pré-condição mais fraca necessária para que o corpo do laço seja capaz de restabelecer o invariante; (3) finalmente, se e quando o loop termina em um determinado estado y , o fato de o protetor de loop ser falso junto com a invariante deve ser capaz de estabelecer a pós-condição necessária.

Correção Total

Para mostrar correção total, também temos que mostrar que o loop termina. Para isso, definimos uma relação bem fundamentada no espaço de estados denotada "<" e chamada de variante de loop . Portanto, temos:

onde y é uma nova tupla de variáveis

Informalmente, na conjunção acima de três fórmulas:

  • o primeiro significa aquele invariante que devo inicialmente manter;
  • o segundo significa que o corpo do loop (por exemplo, instrução S ) deve preservar o invariante e diminuir a variante: aqui, a variável y representa o estado inicial da execução do corpo;
  • o último significa que R deve ser estabelecido no final do loop: aqui, a variável y representa o estado final do loop.

Na semântica dos transformadores de predicado, invariante e variante são construídos imitando o teorema de ponto fixo de Kleene . Abaixo, esta construção é esboçada na teoria dos conjuntos . Assumimos que U é um conjunto que denota o espaço de estados. Primeiro, definimos uma família de subconjuntos de U denotados por indução sobre o número natural k . Informalmente representa o conjunto de estados iniciais que tornam R satisfeito após menos de k iterações do loop:

Então, definimos:

  • invariante I como o predicado .
  • variante como a proposição

Com essas definições, reduz-se à fórmula .

No entanto, na prática, tal construção abstrata não pode ser tratada de forma eficiente por provadores de teoremas. Conseqüentemente, invariantes e variantes de loop são fornecidos por usuários humanos ou inferidos por algum procedimento de interpretação abstrato .

Comandos protegidos não determinísticos

Na verdade, a Guarded Command Language (GCL) de Dijkstra é uma extensão da linguagem imperativa simples fornecida até aqui com declarações não determinísticas. Na verdade, GCL pretende ser uma notação formal para definir algoritmos. Declarações não determinísticas representam escolhas deixadas para a implementação real (em uma linguagem de programação eficaz): propriedades provadas em declarações não determinísticas são garantidas para todas as escolhas possíveis de implementação. Em outras palavras, as pré-condições mais fracas de declarações não determinísticas garantem

  • que existe uma execução final (por exemplo, existe uma implementação),
  • e, que o estado final de toda execução de término satisfaz a pós-condição.

Observe que as definições da pré-condição mais fraca fornecidas acima (em particular para o loop while ) preservam essa propriedade.

Seleção

A seleção é uma generalização da instrução if :

Aqui, quando dois guardas e são simultaneamente verdadeiros, a execução desta instrução pode executar qualquer uma das instruções associadas ou .

Repetição

A repetição é uma generalização da instrução while de maneira semelhante.

Declaração de especificação (ou pré-condição mais fraca de chamada de procedimento)

O cálculo de refinamento estende declarações não determinísticas com a noção de declaração de especificação . Informalmente, esta instrução representa uma chamada de procedimento em caixa preta, onde o corpo do procedimento não é conhecido. Normalmente, usando uma sintaxe próxima ao Método B , uma instrução de especificação é escrita

 @

Onde

  • x é a variável global modificada pela declaração,
  • P é um predicado que representa a pré-condição,
  • y é uma nova variável lógica, limitada em Q , que representa o novo valor de x não deterministicamente escolhido pela declaração,
  • Q é um predicado que representa uma pós-condição, ou mais exatamente um guarda: em Q , a variável x representa o estado inicial ey denota o estado final.

A pré-condição mais fraca da declaração de especificação é dada por:

 @

onde z é um novo nome

Além disso, uma declaração S implementa tal declaração de especificação se e somente se o seguinte predicado for uma tautologia:

onde é um novo nome (denotando o estado inicial)

De fato, em tal caso, a seguinte propriedade é assegurada para toda a pós-condição R (esta é uma consequência direta da monotonicidade wp , veja abaixo):

 @

Informalmente, esta última propriedade garante que qualquer prova sobre alguma declaração envolvendo uma especificação permaneça válida ao substituir esta especificação por qualquer uma de suas implementações.

Outros transformadores de predicado

Pré-condição liberal mais fraca

Uma variante importante da condição prévia mais fraco é o mais fraco condição prévia liberal , que origina o estado mais fraco em que S seja não terminar ou estabelece R . Portanto, difere do wp por não garantir o encerramento. Conseqüentemente, corresponde à lógica de Hoare em correção parcial: para a linguagem de instrução fornecida acima, wlp difere de wp apenas no laço while , por não exigir uma variante (veja acima).

Pós-condição mais forte

Dada S uma declaração e R uma pré - condição (um predicado no estado inicial), então é sua pós-condição mais forte : ela implica qualquer pós-condição satisfeita pelo estado final de qualquer execução de S, para qualquer estado inicial que satisfaça R. Em outras palavras, um triplo de Hoare pode ser demonstrado na lógica de Hoare se e somente se o predicado abaixo for válido:

Normalmente, as pós-condições mais fortes são usadas na correção parcial. Portanto, temos a seguinte relação entre as pré-condições liberais mais fracas e as pós-condições mais fortes:

Por exemplo, na atribuição, temos:

onde y é fresco

Acima, a variável lógica y representa o valor inicial da variável x . Portanto,

Na sequência, parece que sp corre para a frente (enquanto wp corre para trás):

Transformadores de predicado de vitória e pecado

Leslie Lamport sugeriu vitória e pecado como transformadores de predicado para programação simultânea .

Propriedades de transformadores de predicado

Esta seção apresenta algumas propriedades características dos transformadores de predicado. Abaixo, T denota um transformador de predicado (uma função entre dois predicados no espaço de estados) e P um predicado. Por exemplo, T (P) pode denotar wp (S, P) ou sp (S, P) . Mantemos x como a variável do espaço de estados.

Monotônico

Os transformadores predicados de interesse ( wp , wlp e sp ) são monotônicos . Um transformador de predicado T é monotônico se e somente se:

Esta propriedade está relacionada à regra de conseqüência da lógica de Hoare .

Rigoroso

Um transformador de predicado T é estrito iff:

Por exemplo, wp é estrito, enquanto wlp geralmente não é. Em particular, se a instrução S não pode terminar, então é satisfatória. Nós temos

Na verdade, true é um invariante válido desse loop.

Terminando

Um transformador de predicado T está encerrando iff:

Na verdade, esta terminologia faz sentido apenas para rigorosas transformadores predicado: de facto, é a mais fraca condição prévia garantindo-terminação de S .

Parece que nomear esta propriedade de não aborto seria mais apropriado: em correção total, não rescisão é aborto, enquanto em correção parcial, não é.

Conjuntivo

Um transformador de predicado T é conjuntivo iff:

Este é o caso de , mesmo se a afirmação S não for determinística como uma instrução de seleção ou uma instrução de especificação.

Disjuntivo

Um transformador de predicado T é disjuntivo se:

Geralmente, esse não é o caso quando S é não determinístico. De fato, considere uma afirmação não determinística S escolhendo um booleano arbitrário. Esta declaração é dada aqui como a seguinte declaração de seleção :

Então, reduz-se à fórmula .

Conseqüentemente, reduz-se à tautologia

Considerando que, a fórmula se reduz à proposição errada .

O mesmo contra-exemplo pode ser reproduzido usando uma declaração de especificação (veja acima) em vez disso:

 @

Formulários

Além dos transformadores de predicado

Pré-condições mais fracas e pós-condições mais fortes de expressões imperativas

Na semântica dos transformadores de predicado, as expressões são restritas aos termos da lógica (veja acima). No entanto, essa restrição parece muito forte para a maioria das linguagens de programação existentes, onde as expressões podem ter efeitos colaterais (chamada para uma função que tem um efeito colateral), não podem terminar ou abortar (como a divisão por zero ). Existem muitas propostas para estender as pré-condições mais fracas ou as pós-condições mais fortes para as linguagens de expressão imperativas e, em particular, para as mônadas .

Entre eles, a Teoria dos Tipos de Hoare combina a lógica de Hoare para uma linguagem semelhante a Haskell , lógica de separação e teoria dos tipos . Este sistema está atualmente implementado como uma biblioteca Coq chamada Ynot . Nessa linguagem, a avaliação de expressões corresponde a cálculos de pós-condições mais fortes .

Transformadores de predicado probabilístico

Transformadores de predicado probabilísticos são uma extensão dos transformadores de predicado para programas probabilísticos . Na verdade, tais programas têm muitas aplicações em criptografia (ocultação de informações usando algum ruído aleatório), sistemas distribuídos (quebra de simetria).

Veja também

Notas

Referências