Preámbulo · Lean desde cero

Demostrar es programar

La página anterior dejó una pregunta abierta. Si un enunciado como pqp \to q es un tipo, ¿qué es entonces una función de tipo p → q? Esta página da la respuesta, que es la idea más hermosa de todo el edificio: esa función es una demostración. Y no hará falta aprender nada nuevo: las expresiones son las mismas fun de la página 2.

El primer teorema

En Lean, un teorema se declara con su enunciado como tipo y su demostración como expresión:

example (p : Prop) : p → p :=
fun h => h

Léase con calma, porque aquí está todo:

  • (p : Prop) introduce una proposición arbitraria pp: «sea pp una proposición».
  • El enunciado es el tipo p → p: «pp implica pp».
  • La demostración, tras el :=, es la expresión fun h => h: la función identidad.

¿Por qué funciona? Una prueba de p → p debe ser una función que reciba una prueba de pp y devuelva una prueba de pp. La identidad hace exactamente eso: recibe h (léase «la hipótesis») y la devuelve intacta. Es palabra por palabra la prueba del cuaderno: «supóngase pp; entonces pp». La suposición es el binder fun h =>; el «entonces» es el cuerpo.

Nota (La misma expresión, dos lecturas)

fun h => h es literalmente la expresión de la página 2, fun (x : Nat) => x, con otro tipo. Sobre Nat es la función identidad de los números; sobre p es la prueba de que pp implica pp. No hay dos mundos: el mismo lenguaje de expresiones sirve para calcular y para demostrar. Ese es el contenido práctico de la correspondencia de Curry–Howard , que la ruta teórica demuestra con precisión en el nivel 4.

Modus ponens: aplicar es deducir

El segundo teorema del repertorio clásico: de pqp \to q y pp se deduce qq.

example (p q : Prop) : (p → q) → p → q :=
fun hpq hp => hpq hp

La demostración es fun hpq hp => hpq hp, y su cuerpo es una aplicación de función, la operación de la página 2. Si hpq es una prueba de pqp \to q (una función de pruebas de pp a pruebas de qq) y hp es una prueba de pp, entonces hpq hp es una prueba de qq. El modus ponens, la regla de inferencia más antigua de la lógica, es la aplicación de funciones. La flecha se consume igual que cuando (fun (x : Nat) => x + 1) 41 consumía Nat → Nat para dar Nat.

Ejemplo (theorem con nombre)

example demuestra y descarta. Para citar el resultado después, se usa theorem con nombre:

theorem modus_ponens (p q : Prop) (hpq : p → q) (hp : p) : q :=
hpq hp

Obsérvese el movimiento: las hipótesis pueden pasarse al lado izquierdo de los dos puntos como argumentos con nombre, y entonces la demostración ya no necesita el fun, es directamente el cuerpo. Ambas formas declaran el mismo término; es cuestión de estilo.

La conjunción: pruebas que son pares

¿Y pqp \wedge q? Una prueba de una conjunción es un par de pruebas: una de pp y una de qq. Lean lo escribe con And.intro, o con la notación de par anónimo ⟨·, ·⟩, y las dos componentes se extraen con .1 y .2:

example (p q : Prop) : p ∧ q → q ∧ p :=
fun h => ⟨h.2, h.1

La conmutatividad de la conjunción, uno de los primeros teoremas de cualquier curso de lógica, es intercambiar las componentes de un par. Nada más. La demostración recibe el par h, y devuelve el par con h.2 (la prueba de qq) primero y h.1 (la de pp) después.

Qué verifica Lean exactamente

Cuando Lean acepta example (p : Prop) : p → p := fun h => h, lo que hace es comprobar un tipo: verifica que la expresión fun h => h tiene el tipo p → p, con las mismas reglas de derivación que el laboratorio mostraba para fun (x : Nat) => x + 1 : Nat → Nat. No hay un «módulo de lógica» aparte: demostrar un teorema y tipar una expresión son la misma operación del mismo núcleo. Por eso una prueba aceptada no depende de la buena fe de nadie: o el término tiene el tipo, o no lo tiene.

Lo que ya sabes

  • Un teorema se declara theorem nombre : Enunciado := demostración, donde el enunciado es un tipo y la demostración una expresión.
  • fun h => h demuestra ppp \to p; la aplicación hpq hp es el modus ponens; el par ⟨h.2, h.1⟩ conmuta la conjunción.
  • Verificar una demostración = comprobar el tipo de una expresión. Ni más ni menos.

Escribir estas expresiones a mano se vuelve tedioso en cuanto las pruebas crecen. La página siguiente presenta el modo interactivo de Lean: las tácticas, órdenes que construyen estas mismas expresiones paso a paso mientras Lean muestra qué falta por demostrar.