Aula 1 · Verificação Formal de Software

Motivação e Lógica Proposicional

Conectivos, equivalências, dedução natural e provas em Lean

Baseada em How To Prove It with Lean (HTPIwL), capítulo 1.

§1.1 O teste mostra presença, não ausência

  • Software controla aeronaves, dispositivos médicos, sistemas financeiros e redes de comunicação. Erros custam dinheiro e vidas.

  • O teste examina finitas execuções de um programa que admite infinitas.

O teste de programas pode ser usado para mostrar a presença de erros, mas nunca para mostrar a sua ausência!

E. W. Dijkstra, Notes on Structured Programming, EWD249, 1970.

§1.1 O caminho complementar

  • Enunciamos uma propriedade de um programa como uma proposição matemática.

  • Provamos que toda execução a satisfaz; a prova cobre todas as entradas de uma vez.

  • Um assistente de prova verifica cada passo com respeito às regras de uma lógica formal e ajuda a construir a prova interativamente.

  • Em uso corrente: Lean, Rocq (antigo Coq), Isabelle/HOL, Agda. Marcos: o micronúcleo seL4 e o compilador CompCert.

§1.1 Código gerado

  • Modelos de linguagem escrevem hoje uma parcela crescente do código. Plausível não é o mesmo que correto; o modo de falha é a alucinação.

  • O assistente de prova verifica a prova independentemente de como o código surgiu, então código errado não passa.

  • O ônus da correção move-se de ler o código para escrever a especificação certa.

§1.2–1.3 Proposições e conectivos

  • Uma proposição é uma sentença declarativa que é verdadeira ou falsa. Em Lean o tipo Prop as classifica.

  • Conectivos constroem proposições compostas: ¬P, P ∧ Q, P ∨ Q, P → Q, P ↔ Q.

  • São funções de verdade, então o valor de uma proposição composta depende apenas dos valores das suas partes.

  • Uma implicação de antecedente falso é verdadeira, diga o que disser o consequente, porque uma implicação nada afirma sobre esses casos.

  • A disjunção é inclusiva, então P ∨ Q também vale quando P e Q valem juntas.

§1.4 Equivalência lógica

  • Uma valoração atribui um valor de verdade a cada variável. Uma tautologia é verdadeira sob toda valoração.

  • A ≡ B quando A ↔ B é uma tautologia, isto é, as duas coincidem sob toda valoração.

Nome

Equivalência

De Morgan

¬(P ∧ Q) ≡ ¬P ∨ ¬Q

De Morgan

¬(P ∨ Q) ≡ ¬P ∧ ¬Q

Dupla negação

¬¬P ≡ P

Contrapositiva

P → Q ≡ ¬Q → ¬P

Implicação material

P → Q ≡ ¬P ∨ Q

A implicação chama-se material porque a sua verdade depende apenas dos valores de verdade de P e Q, e não de alguma conexão de significado entre eles (Russell, 1903).

§1.4 Uma tabela-verdade verifica a equivalência

Segunda lei de De Morgan: as colunas de ¬(P ∨ Q) e ¬P ∧ ¬Q coincidem nas quatro valorações.

P

Q

P ∨ Q

¬(P ∨ Q)

¬P ∧ ¬Q

V

V

V

F

F

V

F

V

F

F

F

V

V

F

F

F

F

F

V

V

Tabelas-verdade decidem qualquer questão proposicional, mas crescem exponencialmente no número de variáveis e não se estendem aos quantificadores da Aula 2. Um cálculo deriva em vez de computar.

§1.4 Cálculos lógicos

  • Um cálculo fixa axiomas e regras de inferência. Uma derivação aplica as regras, nenhuma valoração aparece nela, e uma máquina pode verificá-la.

  • Ele é correto quando todo teorema é uma tautologia e completo quando toda tautologia é um teorema. Post provou as duas para o cálculo proposicional em 1921.

  • Um cálculo axiomático tem muitos axiomas e uma regra. Łukasiewicz e Tarski precisam de três esquemas sobre → e ¬, com o modus ponens.

   A → (B → A)
   (A → (B → C)) → ((A → B) → (A → C))
   (¬A → ¬B) → (B → A)
  • A resolução mantém uma única regra sobre cláusulas, e é com ela que provadores automáticos buscam (Robinson, 1965).

  • A dedução natural não tem axiomas e tem duas regras por conectivo, uma que o introduz e outra que o elimina. Esta disciplina a usa.

§1.5 Dedução natural: as regras do jogo

  • Cada regra tem premissas acima de uma linha e uma conclusão abaixo, aplicadas um passo por vez (Gentzen, 1935).

  • Regras de introdução provam um conectivo; regras de eliminação o usam. Algumas regras descartam uma suposição, marcada [P].

   [P]
    ⋮
    Q                   P → Q    P
  ───────  →I          ─────────────  →E
   P → Q                     Q

§1.5 Conjunção e disjunção

   P    Q              P ∧ Q            P ∧ Q
  ───────  ∧I         ───────  ∧E₁     ───────  ∧E₂
   P ∧ Q                 P                Q
     P                 Q                              [P]     [Q]
  ───────  ∨I₁      ───────  ∨I₂          P ∨ Q         ⋮       ⋮
   P ∨ Q             P ∨ Q                              R       R
                                        ──────────────────────────  ∨E
                                                     R

§1.5 Negação e a regra clássica

A constante ⊥ é o absurdo, e ¬P abrevia P → ⊥.

   [P]
    ⋮
    ⊥                  P    ¬P               ⊥
  ───────  ¬I         ─────────  ¬E        ─────  ⊥E
    ¬P                    ⊥                   C

As regras acima são construtivas. A lógica clássica acrescenta mais uma regra, equivalentemente RAA ou o terceiro excluído.

   [¬P]
     ⋮
     ⊥
  ─────────  RAA               ───────────  EM
     P                          P ∨ ¬P

§1.6 A sintaxe de Lean

  • Uma declaração dá nome a um enunciado e apresenta a sua prova. A palavra-chave vem primeiro, depois o nome, depois as hipóteses entre parênteses, depois o enunciado após os dois-pontos, e por fim a prova após :=.

Prova por termo

theorem and_swap (P Q : Prop) (h : P Q) : Q P := h.right, h.left
  • fun h => e constrói uma função, e f a aplica uma.

  • ⟨a, b⟩ é o construtor anônimo; h.left e h.right desmontam uma conjunção.

Prova por táticas

example (P Q : Prop) (h : P Q) : Q P := P:PropQ:Proph:P QQ P All goals completed! 🐙
  • by entra no modo de táticas, · foca um objetivo, e sorry marca uma prova ausente.

  • #check imprime o tipo de um termo, e -- inicia um comentário.

  • Os símbolos lógicos são unicode, digitados com uma abreviação de contrabarra: \to para →, \and para ∧, \or para ∨, \not para ¬, \iff para ↔, \bot para ⊥, \langle e \rangle para ⟨ ⟩, e \. para ·.

§1.7 Dedução natural em Lean

Uma prova de uma proposição é um termo cujo tipo é aquela proposição; uma suposição é uma variável daquele tipo. Cada regra constrói ou desmonta um termo.

Regra

Termo em Lean

Exemplo

suposição

um nome de hipótese

h

→I

fun h => e

fun h => h

→E

aplicação

f a

∧I

⟨_, _⟩

⟨ha, hb⟩

∧E₁, ∧E₂

.left, .right

h.left, h.right

∨I₁, ∨I₂

Or.inl, Or.inr

Or.inl h

∨E

Or.elim ou match

h.elim f g

¬I

fun h => e em False

fun hnP => hnP hP

¬E

aplicação em False

hnP hP

⊥E

False.elim ou absurd

False.elim h

§1.7 Termos de prova a partir da derivação

1. P ∧ Q → Q ∧ P

   [P ∧ Q]        [P ∧ Q]
  ─────────∧E₂   ─────────∧E₁
      Q              P
    ────────────────────── ∧I
          Q ∧ P
  ────────────────────────── →I
       P ∧ Q → Q ∧ P
example (P Q : Prop) : P Q Q P := fun h => h.right, h.left
  • fun h => é o →I que descarta P ∧ Q

  • h.right e h.left são ∧E₂ e ∧E₁

  • ⟨_, _⟩ é o ∧I

2. P → P ∨ Q

     [P]
   ───────  ∨I₁
    P ∨ Q
  ───────────  →I
   P → P ∨ Q
example (P Q : Prop) : P P Q := fun h => Or.inl h
  • fun h => é o →I que descarta P

  • Or.inl é o ∨I₁, escolhendo o disjunto esquerdo

§1.7 O exemplo P → ¬¬P em detalhe

  • ¬A é A → False. Duas vezes: ¬¬P é (P → False) → False, e o enunciado é P → ((P → False) → False).

  • Os parênteses são obrigatórios. Como → associa à direita, P → P → P → False é outra proposição, e falsa.

A derivação e o objetivo a cada passo

   [¬P]   [P]
  ────────────  ¬E
       ⊥
    ────────  ¬I
       ¬¬P
   ─────────────  →I
     P → ¬¬P
⊢ P → ¬¬P

hP : P
⊢ ¬¬P

hP : P, hnP : ¬P
⊢ False

Uma função por seta

example (P : Prop) : P ¬¬P := fun (hP : P) => fun (hnP : ¬P) => hnP hP
  • o primeiro fun é o →I que descarta P

  • o segundo é o ¬I que descarta ¬P; o seu parâmetro tem tipo ¬P, e não P

  • hnP hP é o ¬E: uma hipótese negativa é uma função em False, e aplicá-la a hP dá ⊥

§1.8 Provando com táticas

  • Uma tática transforma o estado de prova, o objetivo junto com as hipóteses em escopo, um passo por vez.

  • by entra no modo de táticas, e a sequência elabora para um termo de prova, então prova por táticas e prova por termos produzem o mesmo objeto.

  • exact e fecha o objetivo quando o tipo de e é o objetivo, e have h : A := e é o passo progressivo, que acrescenta h : A ao contexto sem mexer no objetivo.

  • apply f é o passo regressivo. Ela aplica f a argumentos em aberto, unifica a conclusão do tipo de f com o objetivo e deixa cada premissa não resolvida como novo objetivo. Com objetivo Q e f : P → Q, o objetivo passa a P, e o termo em construção é hPQ ?p, que exact hP completa em hPQ hP.

example (P Q : Prop) (hPQ : P Q) (hP : P) : Q := P:PropQ:ProphPQ:P QhP:PQ P:PropQ:ProphPQ:P QhP:PP All goals completed! 🐙
⊢ Q       apply hPQ
⊢ P       exact hP

§1.8 Táticas por conectivo

Conectivo

Introduzir

Eliminar

intro

apply, aplicação

constructor

.left, .right, cases

Or.inl, Or.inr

cases

¬

intro

apply para chegar a False

(nenhum)

exact False.elim

example (P Q : Prop) : P Q Q P := P:PropQ:PropP Q Q P P:PropQ:Proph:P QQ P cases h with P:PropQ:ProphP:PQ P All goals completed! 🐙 P:PropQ:ProphQ:QQ P All goals completed! 🐙
example (P : Prop) : ¬¬P P := P:Prop¬¬P P P:Proph:¬¬PP P:Proph:¬¬P¬P False P:Proph:¬¬PhnP:¬PFalse All goals completed! 🐙

Táticas de introdução constroem o objetivo; táticas de eliminação usam uma hipótese. O raciocínio clássico acrescenta Classical.byContradiction e Classical.em, necessários para a eliminação da dupla negação.

§1.8 Provando com táticas, como um jogo de tabuleiro

Uma prova por táticas se desenrola como um jogo de tabuleiro. Cada elemento do jogo nomeia uma parte precisa da prova.

Jogo de tabuleiro

Prova por táticas

O tabuleiro

o estado de prova, o objetivo junto com as hipóteses em escopo

Suas peças

as hipóteses que você pode usar

Uma jogada

uma tática (intro, apply, exact, cases, constructor, have)

Dividir o tabuleiro

uma tática que abre vários objetivos; cada um precisa ser vencido

Duas direções

apply joga regressivamente a partir do objetivo, have joga progressivamente a partir das suas peças

O livro de regras

as regras de introdução e eliminação da dedução natural

Vencer

todo objetivo fechado, e o kernel de Lean verifica o termo de prova final

§1.9 Exemplo resolvido: P ∧ Q → P

Derivação

   [P ∧ Q]
  ──────────  ∧E₁
      P
  ────────────  →I
   P ∧ Q → P

Modo de termos

example (P Q : Prop) : P Q P := fun h => h.left
  • fun h => é o →I que descarta P ∧ Q

  • h.left é o ∧E₁, a projeção esquerda

Modo de táticas

example (P Q : Prop) : P Q P := P:PropQ:PropP Q P P:PropQ:Proph:P QP All goals completed! 🐙
  • intro h é o →I que descarta P ∧ Q

  • exact h.left fecha o objetivo por ∧E₁

§1.9 Exemplo resolvido: ⊥ → P

Derivação

   [⊥]
  ──────  ⊥E
    P
  ────────  →I
   ⊥ → P

Modo de termos

example (P : Prop) : False P := fun h => False.elim h
  • fun h => é o →I que descarta ⊥

  • False.elim h é o ⊥E, dando qualquer P

Modo de táticas

example (P : Prop) : False P := P:PropFalse P P:Proph:FalseP All goals completed! 🐙
  • intro h é o →I que descarta ⊥

  • exact False.elim h fecha o objetivo por ⊥E

§1.9 Exemplo resolvido: (P → Q) ∧ P → Q

Derivação

   [(P→Q)∧P]           [(P→Q)∧P]
  ───────────── ∧E₁    ───────────── ∧E₂
      P → Q                  P
    ────────────────────────────── →E
                 Q
   ──────────────────────────────── →I
        (P → Q) ∧ P → Q

Modo de termos

example (P Q : Prop) : (P Q) P Q := fun h => h.left h.right
  • fun h => é o →I que descarta (P → Q) ∧ P

  • h.left e h.right são ∧E₁ e ∧E₂

  • a aplicação h.left h.right é o →E, modus ponens

Modo de táticas

example (P Q : Prop) : (P Q) P Q := P:PropQ:Prop(P Q) P Q P:PropQ:Proph:(P Q) PQ P:PropQ:Proph:(P Q) PP All goals completed! 🐙
  • intro h é o →I que descarta (P → Q) ∧ P

  • apply h.left reduz o objetivo a P por →E

  • exact h.right fornece P por ∧E₂

§1.9 Exemplo resolvido: P ∨ Q → Q ∨ P

Derivação

               [P]           [Q]
   [P ∨ Q]    ─────── ∨I₂   ─────── ∨I₁
              Q ∨ P         Q ∨ P
  ───────────────────────────────────── ∨E
             Q ∨ P
  ──────────────────────  →I
   P ∨ Q → Q ∨ P

Modo de termos

example (P Q : Prop) : P Q Q P := fun h => h.elim (fun hP => Or.inr hP) (fun hQ => Or.inl hQ)
  • fun h => é o →I que descarta P ∨ Q

  • h.elim é o ∨E, um ramo por disjunto

  • Or.inr e Or.inl são ∨I, trocando os disjuntos

Modo de táticas

example (P Q : Prop) : P Q Q P := P:PropQ:PropP Q Q P P:PropQ:Proph:P QQ P cases h with P:PropQ:ProphP:PQ P All goals completed! 🐙 P:PropQ:ProphQ:QQ P All goals completed! 🐙
  • intro h é o →I que descarta P ∨ Q

  • cases h é o ∨E, dividindo nos dois disjuntos

  • cada ramo fecha com Or.inr / Or.inl (∨I)

§1.9 Exemplo resolvido: ¬¬P → P (clássico)

Derivação

   [¬P]  [¬¬P]
  ──────────────  ¬E
        ⊥
    ──────────  RAA
        P
   ───────────────  →I
     ¬¬P → P

Modo de termos

example (P : Prop) : ¬¬P P := fun h => Classical.byContradiction (fun hnP => h hnP)
  • fun h => é o →I que descarta ¬¬P

  • Classical.byContradiction é a regra clássica (RAA)

  • fun hnP => h hnP deriva ⊥ de ¬P e ¬¬P por ¬E

Modo de táticas

example (P : Prop) : ¬¬P P := P:Prop¬¬P P P:Proph:¬¬PP P:Proph:¬¬P¬P False P:Proph:¬¬PhnP:¬PFalse All goals completed! 🐙
  • intro h é o →I que descarta ¬¬P

  • apply Classical.byContradiction invoca a RAA

  • intro hnP e então exact h hnP derivam ⊥ por ¬E

Resumo

  • Uma proposição é classificada por Prop; os conectivos ¬, ∧, ∨, →, ↔ constroem proposições compostas.

  • Tabelas-verdade decidem questões proposicionais, mas crescem exponencialmente; a dedução natural aplica regras um passo por vez e generaliza.

  • Cada conectivo tem regras de introdução e eliminação; algumas regras descartam suposições.

  • Uma prova é um termo cujo tipo é a proposição (Curry-Howard): fun h => e para →I, aplicação para →E, ⟨_, _⟩ para ∧I, Or.inl/Or.inr para ∨I.

  • Táticas transformam o estado de prova: intro, exact, apply, cases, constructor, have; by as elabora para o mesmo termo de prova.

  • O raciocínio clássico acrescenta Classical.byContradiction e Classical.em, necessários para ¬¬P → P e uma lei de De Morgan.

Exercícios: veja as notas de aula.