Matemáticas, lógica e informática

Formal Math logo

60 años de la carrera de matemáticas
Celebración en honor a Xavier Caicedo
Universidad de Los Andes, Diciembre 2024

Florent Schaffhauser
Universidad de Heidelberg

Matemáticas, lógica e informática - Clase 3

Cronograma

  • Clase 1: Introducción a Lean.
  • Clase 2: Tácticas básicas.
  • Clase 3: Tipos dependientes.
  • Clase 4: Estructuras algebraicas.
Matemáticas, lógica e informática - Clase 3

Resumen de la Clase 2

  • Las proposiciones se definen como tipos. Podemos formar proposiciones nuevas a partir de otras más antiguas usando los conectores , , y . La regla del modus ponens corresponde a evaluar una función.
  • La lógica no es externa a nuestro sistema de tipos. No hay valores lógicos ni tablas de verdad. Las reglas de inferencia se deducen de las reglas sintácticas, no son axiomas.
  • Para probar un teorema, se escribe un programa. Si el programa pasa la verificación de tipos, el teorema está probado.
  • Para escribir pruebas en Lean, podemos ser asistidos por el compilador entrando al modo táctico de Lean.
  • En esta clase, veremos cómo codificar los cuantificadores y , para poder enunciar y probar declaraciones matemáticas más sofisticadas.
Matemáticas, lógica e informática - Clase 3

Clase 3 - Tipos dependientes

  1. Familias de tipos y funciones dependientemente tipadas.
  2. Cuantificadores existencial y universal.
  3. Formalización de las matemáticas.
Matemáticas, lógica e informática - Clase 3

Archivo para practicar

Si prefieren usar este tiempo para trabajar en tácticas avanzadas, aquí les va un archivo para practicar:

Practice File QR Code Tácticas avanzadas

Matemáticas, lógica e informática - Clase 3

Familias de tipos, funciones dependientes y universos

  • Familias de tipos.
  • Funciones dependientemente tipadas.
  • Universos.
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Varios tipos de funciones

  • Hasta ahora, hemos trabajado principalmente con funciones básicas, como square : Nat → Nat o fact : Nat → Nat. Estas son funciones simplemente tipadas, de un tipo a otro tipo.
  • Pero de hecho, también hemos visto formadores de tipos, como Prod : Type → Type → Type o Sum, que toman tipos como entradas y devuelven un tipo. Otro ejemplo común sería List : Type → Type.
  • Para un tipo fijo X, el tipo List X se define inductivamente: se comienza con la lista vacía y luego se anteponen términos de tipo X.
inductive List (X : Type) : Type
  | nil  : List X
  | cons : XList XList X
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Términos que dependen de tipos, tipos que dependen de términos

Hasta el momento, hemos visto:

  • Términos que dependen de términos (funciones simplemente tipadas).
  • Tipos que dependen de tipos (formadores de tipos).

Debería haber:

  • Términos que dependen de tipos (funciones polimorfas).
  • Tipos que dependen de términos (familias de tipos).
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Funciones polimorfas

Una función polimorfa es una función que toma un tipo como argumento. La función polimorfa más simple es la función identidad:

def id {X : Type} : XX := fun x ↦ x

#check id  -- id {X : Type} :  X → X
  • id es, en efecto, un término que depende (implícitamente) de un tipo. Por ejemplo, id (X := Nat) (también denotado por @id Nat) es un término de tipo Nat → Nat, es decir, una función de Nat a Nat.
  • id es un ejemplo de un término sobrecargado: para cualquier tipo X, podemos denotar su función identidad simplemente como id, por lo que una expresión como id (3 : Nat) está bien tipada (y es de tipo Nat).
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Familias de tipos

  • Una familia de tipos parametrizada por X es una función F: X → Type, es decir, tipos que dependen de términos: para todo x : X, F x es un tipo.
  • A manera de ejemplo, pueden pensar en la familia de tipos Tuplas : Nat → Type tal que Tuplas n es el tipo de las listas de enteros de longitud n:
    Tuplas n := {L : List Int // List.length L = n}.
  • Si juntan estos, obtienen un llamado -tipo, por ejemplo List Int, que representa la suma de todos los Tuplas n.
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Pares dependientes

  • Dada una familia de tipos F: X → Type, podemos construir el -tipo asociado, a veces denotado por (x : X) × F x, cuyos términos se llaman pares dependientes y son de la forma ⟨x, t⟩ donde x : X y t : F x.
  • Por ejemplo, ⟨2, [1, -1]⟩ es un término del tipo (n : Nat) × Tuplas n. Otra notación posible sería Sigma Tup, donde Tuplas : Nat → Type. Y la notación clásica en teoría de tipos sería:

  • Los pares dependientes generalizan los pares usuales: si para todo x : X, tenemos F x = Y, entonces ((x : X) × F x) = (X × Y).
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Representación de un -tipo

Un Sigma-tipo

Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Definición formal de un -tipo

Dada una familia de tipos F: X → Type, el -tipo asociado es un tipo inductivo con un solo constructor. El tipo Sigma F así definido se puede denotar (x : X) × F x.

inductive Sigma {X : Type} (F : XType) 
  | mk (x : X) (t : F x) : Sigma F

Se puede definir una proyección al primer factor por pattern matching (lo cual hace uso del principio de inducción asociado al tipo inductivo Sigma F):

def pr₁ {X : Type} {F : XType} : Sigma FX
  | Sigma.mk x t => x
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Funciones dependientemente tipadas

  • También podemos usar familias de tipos F : X → Type para definir los llamados -tipos (también llamados tipos de funciones dependientes).
  • Una función dependiente es una función f : (x : X) → F x cuyo tipo de retorno depende del valor de entrada.
  • La notación clásica en teoría de tipos para el tipo de las funciones dependientes (x : X) → F x sería:

  • Esto generaliza los tipos de funciones: si para todo x : X, tenemos F x = Y, entonces ((x : X) → F x) = (X → Y).
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Un ejemplo: la función cero-tupla

  • Definamos una función cero-tupla : (n : Nat) → Tuplas n. Procederemos por inducción.
  • Para n = 0, se pone cero-tupla 0 := ([] : List Int) (la lista vacía). Si cero-tupla n : Tuplas n ya está definido, se pondrá cero-tupla (n + 1) := (0 :: cero-tupla n), que de hecho es de tipo Tuplas (n + 1).
  • ¿Podrían implementar esto en Lean? 😅 ¡Invito a un ☕ a quien termine primero!
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Relaciones entre -tipos y -tipos

  • Un -tipo viene dotado con una segunda proyección, que es una función dependiente, definida utilizando pattern matching.
def pr₂ {X : Type} {F : XType} : (p : Sigma F) → F (pr₁ p)
  | Sigma.mk x t => t
  • Podemos utilizar esta proyección para establecer una equivalencia entre funciones dependientes de signatura y secciones de .

  • Esta equivalencia viene inducida por la función que envía una función dependiente a la función definida por

Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Representación de un -tipo

Un Pi-tipo

Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

El -cubo de Barendregt

  • Hemos generalizado las funciones simplemente tipadas en tres direcciones: formadores de tipos, funciones polimorfas y familias de tipos. Cada combinación de estos enriquece el sistema de tipaje.
  • El vértice representa el cálculo de construcciones. Junto con los tipos inductivos, nos permite formalizar una cantidad sorprendente de matemáticas.

El lambda-cubo de Barendregt Por Tellofou - Trabajo propio, CC BY-SA 4.0

Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Universos

  • Si le hacen #check al tipo List que hemos definido, encontrarán que es de tipo Type → Type. Para poder escribir esto, necesitamos tratar Type como un término. ¿Pero cuál es su tipo?
  • En Lean, Type es un término de tipo Type 1. Como consecuencia, formadores de tipos con valores en Type también son términos de tipo Type 1.
  • Esta es una característica de la teoría: para controlar la formación de tipos, se requiere una jerarquía de tipos especiales llamados universos. Así es como se evitan en la teoría de tipos paradojas similares a la paradoja de Russell.
  • De manera informal, un universo es un tipo cuyos términos también son tipos. En Lean, Prop es un universo, de tipo Type (también denotado por Type 0). Pueden pensar en Type l como el universo de tipos de nivel l.
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Jerarquía de universos y coerciones

  • Ya vimos la necesidad de trabajar con universos para poder realizar ciertas operaciones polimorfas sobre tipos (tomar listas o marcar puntos, por ejemplo).
  • Un universo es un tipo cuyos términos son tipos y que es estable bajo las operaciones

  • Siguiendo a Grothendieck y Martin-Löf, se postula la existencia de una jerarquía de universos , donde es un entero natural (en un sentido intuitivo).
  • Esa jerarquía es cumulativa en el sentido que si , entonces . En la práctica, se implementan coerciones: si tenemos dos tipos y , podemos construir etc. y serán términos de tipo .
  • Un tipo pertenece a un universo pero no existe un universo de todos los tipos:eso conduciría a una paradoja de estilo Burali-Forti o Girard.
Matemáticas, lógica e informática - Clase 3
Familias de tipos, funciones dependientes, y universos

Teoría de tipos dependientes en pocas palabras

Teoría de tipos dependientes en pocas palabras

Matemáticas, lógica e informática - Clase 3

Enunciados existenciales y universales

  • El cuantificador existencial .
  • El cuantificador universal .
Matemáticas, lógica e informática - Clase 3
Enunciados existenciales y universales

El cuantificador existencial

  • De manera notable, podemos usar pares dependientes para definir proposiciones con un cuantificador existencial.
  • Tomemos un número complejo z : ℂ y consideremos la proposición z ^ 2 = -1. Ya que proposiciones son tipos, esto define una familia de tipos F : ℂ → Prop.
  • Entonces, podemos interpretar un par dependiente ⟨z, p⟩, donde p : z ^ 2 = -1 (así que p es una prueba de que z ^ 2 = -1), como una prueba de que -1 tiene una raíz cuadrada en .
Matemáticas, lógica e informática - Clase 3
Enunciados existenciales y universales

Enunciados existenciales

  • Dado un predicado P : X → Prop sobre un tipo X, la proposición ∃ x : X, P x es la proposición definida inductivamente de la siguiente manera.
inductive Exists {X : Type} (P : XProp) : Prop
  | intro (x : X) (p : P x) : Exists P
  • Esto significa que, para probar que ∃ x : X, P x, se necesita construir un término x : X (un testigo) y una demostración de la proposición P x (la prueba).
  • Vemos que esto representa el enfoque constructivo sobre enunciados existenciales: en general, decir que ¬(∀ x : X, ¬(P x)) es más débil que decir que ∃ x : X, P x.
Matemáticas, lógica e informática - Clase 3
Enunciados existenciales y universales

El cuantificador universal

  • Usemos ahora funciones dependientes para definir proposiciones con un cuantificador universal.
  • Tomemos un número real x : ℝ y consideremos la proposición x ^ 2 ≥ 0. Pensando en proposiciones-como-tipos, esto define una familia de tipos F : ℝ → Prop.
  • Entonces, una función dependiente f : (x : ℝ) → x ^ 2 ≥ 0 envía un número real x a una prueba de que x ^ 2 ≥ 0. Así que podemos interpretar tal función dependiente f como una prueba de la proposición ∀ x : ℝ, x ^ 2 ≥ 0.
Matemáticas, lógica e informática - Clase 3
Enunciados existenciales y universales

Enunciados universales

  • Dado un predicado P : X → Prop sobre un tipo X, la proposición ∀ x : X, P x es la proposición definida por el tipo de las funciones dependientes (x : X) → P x.
  • En particular, para probar tal enunciado universal, debemos definir una función, por lo que uno comienza el programa con fun x ↦ _ (si estamos en modo término) o intro x (si estamos en modo táctico).
  • Por ejemplo, si queremos probar que ∀ w : ℂ, ∃ z : ℂ, z ^ 2 = w, entonces intro w cambia el objetivo a ∃ z : ℂ, z ^ 2 = w, para un w que ahora está fijado. Luego tenemos que construir una raíz cuadrada de ese w para concluir.
  • Nótese que puede haber más de un testigo z : ℂ para la propiedad z ^ 2 = w, ¡pero esta información no se puede recuperar del enunciado existencial!
Matemáticas, lógica e informática - Clase 3

Matemáticas formales

  • Proposiciones y sub-tipos.
  • El tipo de las proposiciones.
Matemáticas, lógica e informática - Clase 3
Matemáticas formales

Proposiciones y sub-tipos

  • Una proposición puede definirse formalmente como un tipo A para el cual se cumple la siguiente propiedad: (a b : A) → a = b, es decir que a dos términos cualesquiera a y b de tipo A, podemos asociar una identificación a = b.
  • Las proposiciones permiten definir sub-tipos de un tipo : a partir de un predicado , se define un sub-tipo de como caso particular de un -tipo.

  • En Lean, los tipos de igualdad A := (x = y) para x, y en un tipo X cualquiera son todos proposiciones. El estudio detallado de los tipos de igualdad es un tema fundamental en teoría homotópica de tipos. Ahí se demuestra, por ejemplo, que para todo tipo A, el tipo IsProp A es una proposición 😅.
Matemáticas, lógica e informática - Clase 3
Matemáticas formales

Tipos de proposiciones

  • Viendo proposiciones como tipos y utilizando tipos inductivos, funciones dependientes y universos, podemos formalizar una gran cantidad de matemáticas.
theorem FLT {n : Nat} {x y z : Int} : (n > 2) → x ^ n + y ^ n = z ^ n → x * y * z = 0
  • La teoría homotópica de tipos de Voevodsky afina eso todavía, construyendo el tipo de las proposiciones en un universo como un sub-tipo de . Por ejemplo, el tipo FLT definido arriba es una proposición 👌.
  • Nótese que, si y son proposiciones, el tipo es una proposición pero el tipo no es una proposición. Para construir la proposición , debemos tomar un cociente para identificar pruebas de con pruebas de . Eso se conoce como proof irrelevance o truncación.
Matemáticas, lógica e informática - Clase 3
Matemáticas formales

Resumen y próximos pasos

  • Además de funciones simplemente tipadas, podemos definir formadores de tipos, funciones polimorfas y familias de tipos.
  • A partir de una familia de tipos F : X → Type, definimos un -tipo asociado (el tipo de los pares dependientes (x : X) × (F x)) y un -tipo asociado (el tipo de las funciones dependientes (x : X) → F x).
  • Dado un predicado P : X → Prop, la proposición ∃ x : X, P x es la proposición cuyas pruebas se construyen usando pares dependientes (x : X) × (P x). Y una prueba de la proposición ∀ x : X, P x es una función dependiente (x : X) → P x.
  • ¡Ahora podemos demostrar enunciar algunos teoremas 💻! De hecho, podemos formalizar una cantidad notable de matemáticas.
Matemáticas, lógica e informática - Clase 3
Matemáticas formales

Ejercicios sobre tácticas avanzadas

Practice File QR Code Tácticas avanzadas

Matemáticas, lógica e informática - Clase 3