Nivel 6 · El CIC y Lean
Recursores y eliminación
La consecuencia más profunda de definir un tipo por sus constructores es que el sistema puede generar automáticamente su principio de eliminación, también conocido como recursor . Esta página lo presenta primero en el caso familiar de , luego en su forma esquemática general, y cierra con la regla de cómputo que lo hace efectivo: la -reducción.
El recursor de los naturales
Para los números naturales, el recursor permite definir funciones por recursión primitiva. El artículo de Paulin-Mohring (Paulin-Mohring, 1993) lo denota , con las siguientes reglas de cómputo:
- se comporta como ;
- se comporta como ;
donde es el tipo de retorno, el valor devuelto en el caso base, la función del paso inductivo (que calcula el resultado para a partir de y de la llamada recursiva) y el argumento sobre el cual se elimina.
Este recursor se generaliza a un principio de inducción completo, la eliminación dependiente. El eliminador unificado es una función cuyo tipo es el principio de inducción matemática:
Leído componente a componente: para cualquier propiedad sobre los naturales, si se proporciona una prueba del caso base y una prueba del paso inductivo (una función que, para cualquier , transforma una prueba de en una de ), se obtiene una función que, para cualquier , construye una prueba de . La inducción ya no es un principio inalcanzable sobre una codificación: es un principio de razonamiento generado automáticamente por la propia definición del tipo.
Vale la pena traducir el recursor a un lenguaje familiar, porque no introduce nada ajeno a la matemática ordinaria; solo lo vuelve primitivo. Las dos reglas de cómputo del recursor sobre , a saber, y , son exactamente las ecuaciones del teorema de recursión: dado un valor inicial y una regla de paso , existe una única función con y . Por ejemplo, el factorial es la instancia . Y el tipo de la versión dependiente, , es, leído palabra por palabra, el principio de inducción de Peano. La diferencia con la matemática usual no es de contenido sino de estatus: donde Peano postula la inducción como axioma y la codificación impredicativa ni siquiera permite demostrarla (solo proporciona la recursión; la inducción dependiente no es derivable en el CoC puro (Geuvers, 2001) ), el CIC la genera junto con el tipo. Definir un tipo inductivo equivale, pues, a obtener de una vez su definición por constructores, su teorema de recursión y su principio de inducción.
Las reglas generales de eliminación
La regla de eliminación es la pieza central que dota de poder computacional y lógico a las definiciones inductivas. Se introduce un pseudo-término que generaliza la recursión sobre los naturales a cualquier estructura inductiva. Se distinguen dos casos: eliminación no dependiente (para definir funciones) y dependiente (para pruebas por inducción).
Antes de la regla general conviene fijar el caso de , con constructores y . El eliminador no dependiente recibe un valor para el caso y un manejador para , y es la recursión primitiva:
La notación que aparece en las reglas no es más que el tipo de cada manejador tras reemplazar la ocurrencia recursiva por un resultado de tipo : para es ; para es (el predecesor y el resultado de la llamada recursiva). En la versión dependiente, donde depende del valor, el caso se vuelve , que es exactamente el paso inductivo de Peano. Las reglas generales que siguen solo expresan esto mismo para un tipo inductivo cualquiera.
Eliminación no dependiente. Se usa para definir funciones cuyo tipo de retorno no depende del valor de entrada. Sea con (el denota aquí descomposición estructural: se analiza como una secuencia de productos que termina en la sort ). La regla de tipado es
Aquí es el tipo de retorno y cada maneja el caso del constructor -ésimo; es la transformación del tipo del constructor para incluir las llamadas recursivas, que ahora devuelven un resultado de tipo .
Eliminación dependiente. Es la forma más general y corresponde al principio de inducción estructural: el tipo de retorno puede depender no solo de los parámetros del tipo inductivo, sino también del valor inductivo mismo.
La notación representa el tipo del caso -ésimo, donde las hipótesis inductivas tienen ahora el tipo dependiente aplicado a los subtérminos recursivos.
Las reglas anteriores no valen para pares arbitrarios. La eliminación fuerte (hacia ) se restringe a tipos inductivos pequeños, y un inductivo que habita solo puede eliminarse hacia , salvo en los casos vacío y unitario (eliminación singleton). Sin estas restricciones el sistema sería inconsistente (eliminación fuerte sobre una sort impredicativa) y las pruebas en dejarían de ser borrables, contra la irrelevancia de pruebas que la página sobre universos explica en detalle (Paulin-Mohring, 1993) .
La reducción iota
El comportamiento computacional del eliminador se define mediante una nueva regla de reducción, la reducción-, que estipula cómo se reduce una aplicación de a un término construido con :
La expresión del lado derecho es compleja, pero su intuición es simple: se selecciona la función correspondiente al constructor y se le aplican los argumentos del constructor ; la parte se encarga de sustituir las llamadas recursivas por aplicaciones del propio término de eliminación, encapsulado en
que actúa como el manejador de las llamadas recursivas dentro de la estructura del término. Para los naturales, esto instancia las conocidas reglas de reducción de la recursión:
En Lean, la igualdad por definición incluye la regla (un recursor aplicado a un constructor se reduce por definición) y todo inductive trae su recursor T.rec. De ahí que, para Nat.rec, las igualdades siguientes se cierren con rfl:
example (Q : Nat → Sort u) (z : Q 0) (s : (n : Nat) → Q n → Q (n+1)) : Nat.rec z s 0 = z := rfl
example (Q : Nat → Sort u) (z : Q 0) (s : (n : Nat) → Q n → Q (n+1)) (n : Nat) : Nat.rec z s (Nat.succ n) = s n (Nat.rec z s n) := rflLa regla computa el recursor: en devuelve la base y en aplica el paso al resultado recursivo; como ambas son reducciones por definición, se cierran con rfl.
Las reglas de -reducción se generan para el tipo inductivo: gobiernan a Nat.rec aplicado a constructores. Las ecuaciones de una definición recursiva como Nat.add (la suma, notación +, definida internamente mediante Nat.rec) no son reglas primitivas nuevas: el núcleo las valida desplegando la definición (reducción ) y aplicando e sobre Nat.rec. Así, que Nat.add m 0 sea definicionalmente igual a m es un teorema del cómputo , no un axioma adicional.
Conviene reunir las piezas vistas, que son siempre las mismas cuatro y aparecen generadas por una sola declaración:
- Formación (Ind): se declara el tipo enumerando sus constructores (por ejemplo,
Natconzeroysucc). - Introducción (Constr): los constructores son las únicas maneras de construir un habitante del tipo.
- Eliminación (Elim/recursor): la única manera de usar un habitante; en su forma no dependiente define funciones por recursión, y en la dependiente es el principio de inducción.
- Cómputo (-reducción): fija cómo se reduce el eliminador frente a cada constructor, haciendo el cálculo efectivo y la verificación de tipos decidible.
Todo tipo inductivo de Lean (incluidas la sintaxis de fórmulas y la relación de derivabilidad del módulo 07) se entiende con este mismo molde.