La teoría homotópica de tipos (HoTT) se define como:
HoTT=MLTT+UA+tipos inductivos superiores
donde MLTT es la teoría de tipos de Martin-Löf (con los formadores de tipos vistos hasta ahora), UA es el axioma de univalencia, y los tipos inductivos superiores (HITs) son una extensión de los tipos inductivos que permite constructores no solo para términos, sino también para igualdades y igualdades entre igualdades.
De tipos inductivos a tipos inductivos superiores
Recordemos que los tipos inductivos ordinarios son generados por sus constructores (términos canónicos). Ahora, dado que consideramos los tipos como teniendo:
Términos
Igualdades
Igualdades entre igualdades
...
podemos considerar tipos inductivos superiores, cuyos constructores pueden ser términos, igualdades, igualdades entre igualdades, etc.
Ejemplo 1 — S0≅bool
S0:≡bool tiene dos constructores de términos:
true:bool
false:bool
El intervalo
Definición 1 — Intervalo D1
El intervalo D1 es el tipo inductivo superior con tres constructores:
true:D1 (punto)
false:D1 (punto)
p:true=D1false (camino)
Reglas:
Eliminación: Dado d:D1, un tipo E(d), términos t:E(true), f:E(false) y un camino π:p∗t=f:E(false), existe:
indD1,t,f,π(d):E(d)
Computación:
indD1,t,f,π(true)≐t:E(true)
indD1,t,f,π(false)≐f:E(false)
indD1,t,f,π(p)≐π:p∗t=f:E(false)
El círculo
Definición 2 — Círculo S1
El círculo S1 es el tipo inductivo superior con dos constructores:
base:S1 (un punto)
loop:base=base (un camino del punto base a sí mismo)
Teorema 2 — π1(S1)=Z
El grupo fundamental del círculo es Z.
Truncaciones
A veces queremos que un tipo sea un conjunto, o una proposición. Las truncaciones son HITs que "colapsan" la estructura superior de un tipo.
Truncación proposicional
Definición 3 — Truncación proposicional ∥T∥1
Dado un tipo T, su truncación proposicional∥T∥1 es el HIT con constructores:
∣−∣1:T→∥T∥1
∏x,y:∥T∥1∣x∣1=∣y∣1
La segunda condición fuerza que ∥T∥1 sea una proposición.
Ejemplo 3 — ∥T∥1 es una proposición
Para cualquier tipo T, ∥T∥1 es una proposición (h-level 1).
Lógica proposicional con HITs:
Teorema 4 — Proposiciones cerradas bajo ∧, →, ∀
Si P,Q:Prop, entonces P×Q:Prop (análogo a P∧Q).
Si P:Prop y E:P→Prop, entonces ∑p:PE(p) y ∏p:PE(p) están en Prop.
Sin embargo, P+Qno es una proposición en general (tiene dos constructores distinguibles). Para obtener la disyunción proposicional usamos la truncación:
Definición 4 — Disyunción proposicional
Para P,Q:Prop:
P∨Q:≡∥P+Q∥1
Ejemplo 5 — Factorización por truncación
Para cualquier tipo T y proposición P, las funciones (T→P)≃(∥T∥1→P).
Truncación como conjunto
Definición 5 — Truncación como conjunto ∥T∥2
Dado un tipo T, su truncación como conjunto∥T∥2 es el HIT con constructores:
∣−∣2:T→∥T∥2
∏x,y:∥T∥2∏p,q:x=y∣p∣2=∣q∣2
Ejemplo 6 — ∥T∥2 es un conjunto
Para cualquier tipo T, ∥T∥2 es un conjunto (h-level 2).
Definición 6 — Grupo fundamental π1
π1:U→Setπ1(T):≡λT.∥S1→T∥2
π1(S1)=Z.
Interfaces y la completación de Rezk
El resultado de Coquand-Danielsson dice que, para tipos con estructura algebraica, la univalencia implica que la igualdad coincide con el isomorfismo:
(A=algB)≃(A≅B)
Por lo tanto, no se puede decir nada que distinga estructuras isomorfas.
Supongamos que especificamos un lenguaje/interfaz limitada para hablar sobre una estructura algebraica.
Por ejemplo, para una estructura U: pU:≡∑T:UT→Prop.
Dados (T,p):pU, pensamos en p como el lenguaje o interfaz que usamos para razonar sobre T. Solo podemos distinguir s,t:T si podemos distinguir p(s) y p(t).
Decimos que s,t son indiscernibles si:
(s≍t):≡(p(s)=p(t))
Podemos tomar el cocienteT/≍, que es un HIT con constructores:
Ejemplo 7 — Independencia de representación para colas
Consideremos la interfaz de colas:
Queues(A):≡∑Q:UQ×(A→Q→Q)×(Q→Maybe(Q×A))
Es decir, un record con: un tipo Q, una constante empty:Q, una función enqueue:A→Q→Q y una función dequeue:Q→Maybe(Q×A).
La implementación simple usa List(A):
(List(A),empty,enqueue,dequeue):Queues(A)
Pero hay implementaciones más eficientes, como BatchedList:
BatchedList(A):≡List(A)×List(A)
con enqueue en O(1) (agrega al final de la segunda lista).
Existe una surección s:BatchedList(A)→List(A) que respeta las operaciones de la interfaz. Podemos tomar el cociente:
(b∼c):≡(s(b)=s(c))
Entonces, al nivel del computador (≐), nada cambia — seguimos usando la representación eficiente. Al nivel humano (=), tenemos BatchedList(A)/∼=List(A).
Así, las pruebas de correctitud sobre programas que usan List(A) se pueden aplicar a BatchedList(A).
Nota importante: Cuando tomamos cocientes de tipos así, estamos agregando cosas a los tipos (caminos nuevos). Esto contrasta con los cocientes en la teoría de conjuntos, que resultan en menos cosas (clases de equivalencia). Los cocientes en la teoría de tipos son mucho más fáciles de manejar formalmente. Esta idea ha sido importada exitosamente a lenguajes funcionales como Haskell.
Podemos entonces definir Q como un cociente de N×N, R como un cociente de sucesiones de Q, etc. Los lenguajes de programación también son cocientes (complicados) de tipos inductivos, por lo que mucha investigación actual se enfoca en entender y justificar estos cocientes para poder razonar formalmente sobre lenguajes de programación.