Tipo dependiente - Dependent type

En informática y lógica , un tipo dependiente es un tipo cuya definición depende de un valor. Es una característica superpuesta de la teoría de tipos y los sistemas de tipos . En la teoría de tipos intuicionista , los tipos dependientes se utilizan para codificar cuantificadores lógicos como "para todos" y "existe". En lenguajes de programación funcional como Agda , ATS , Clojure , Coq , F * , Epigram e Idris , los tipos dependientes ayudan a reducir los errores al permitir que el programador asigne tipos que restringen aún más el conjunto de posibles implementaciones.

Dos ejemplos comunes de tipos dependientes son funciones dependientes y pares dependientes. El tipo de retorno de una función dependiente puede depender del valor (no solo del tipo) de uno de sus argumentos. Por ejemplo, una función que toma un número entero positivo puede devolver una matriz de longitud , donde la longitud de la matriz es parte del tipo de la matriz. (Tenga en cuenta que esto es diferente del polimorfismo y la programación genérica , los cuales incluyen el tipo como argumento). Un par dependiente puede tener un segundo valor del cual el tipo depende del primer valor. Siguiendo el ejemplo de la matriz, se puede usar un par dependiente para emparejar una matriz con su longitud de forma segura.

Los tipos dependientes agregan complejidad a un sistema de tipos. Decidir la igualdad de los tipos dependientes en un programa puede requerir cálculos. Si se permiten valores arbitrarios en tipos dependientes, entonces decidir la igualdad de tipos puede implicar decidir si dos programas arbitrarios producen el mismo resultado; por lo tanto, la verificación de tipos puede volverse indecidible .

Historia

En 1934, Haskell Curry notó que los tipos usados ​​en el cálculo lambda tipificado , y en su contraparte lógica combinatoria , seguían el mismo patrón que los axiomas en la lógica proposicional . Yendo más allá, para cada prueba en la lógica, había una función coincidente (término) en el lenguaje de programación. Uno de los ejemplos de Curry fue la correspondencia entre el cálculo lambda simplemente mecanografiado y la lógica intuicionista .

La lógica de predicados es una extensión de la lógica proposicional, agregando cuantificadores. Howard y de Bruijn ampliaron el cálculo lambda para igualar esta lógica más poderosa creando tipos para funciones dependientes, que corresponden a "para todos", y pares dependientes, que corresponden a "existe".

(Debido a este y otros trabajos de Howard, las proposiciones como tipos se conocen como correspondencia Curry-Howard ).

Definicion formal

Π tipo

Hablando libremente, los tipos dependientes son similares al tipo de una familia de conjuntos indexados. Más formalmente, dado un tipo en un universo de tipos , uno puede tener una familia de tipos , que asigna a cada término un tipo . Decimos que el tipo B (a) varía con a .

Una función cuyo tipo de valor de retorno varía con su argumento (es decir, hay no se fija codomain ) es una función dependiente y el tipo de esta función se llama dependiente de tipo de producto , de tipo pi o tipo de función dependiente . A partir de una familia de tipos, podemos construir el tipo de funciones dependientes , cuyos términos son funciones que toman un término y devuelven un término en . Para este ejemplo, el tipo de función dependiente generalmente se escribe como o

Si es una función constante, el tipo de producto dependiente correspondiente es equivalente a un tipo de función ordinaria . Es decir, es juzgadamente igual a cuando B no depende de x .

El nombre 'tipo pi' proviene de la idea de que estos pueden verse como un producto cartesiano de tipos. Los tipos Pi también pueden entenderse como modelos de cuantificadores universales .

Por ejemplo, si escribimos para n tuplas de números reales , entonces sería el tipo de función que, dado un número natural n , devuelve una tupla de números reales de tamaño n . El espacio de funciones habitual surge como un caso especial cuando el tipo de rango no depende realmente de la entrada. Por ejemplo, es el tipo de funciones desde números naturales hasta números reales, que se escribe como en el cálculo lambda escrito.

Para un ejemplo más concreto, teniendo A sea igual a la familia de enteros sin signo de 0 a 255, (las que pueden encajar en 8 bits o 1 byte) y B (a) = X una para 256 arbitraria X un 's , luego se convierte en el producto de X 0 × X 1 × X 2 × ... × X 253 × X 254 × X 255 precisamente porque el conjunto finito de enteros de 0 a 255 finalmente se detendría en los límites que se acaban de mencionar, lo que da como resultado un codominio finito de la función dependiente.

Σ tipo

El doble del tipo de producto dependiente es el tipo de par dependiente , dependiente de tipo suma , de tipo sigma , o (confusamente) dependiente de tipo de producto . Los tipos sigma también pueden entenderse como cuantificadores existenciales . Continuando con el ejemplo anterior, si, en el universo de tipos , hay un tipo y una familia de tipos , entonces hay un tipo de par dependiente . (Las notaciones alternativas son similares a las de los tipos Π).

El tipo de par dependiente captura la idea de un par ordenado donde el tipo del segundo término depende del valor del primero. Si entonces y . Si B es una función constante, entonces el tipo de par dependiente se convierte en (es juzgablemente igual a) el tipo de producto , es decir, un producto cartesiano ordinario .

Para un ejemplo más concreto, teniendo A a de nuevo sea igual a la familia de enteros sin signo de 0 a 255, y B (a) a de nuevo sea igual a X una para 256 más arbitraria X un 's, a continuación, se convirtiera en la suma X 0 + X 1 + X 2 + ... + X 253 + X 254 + X 255 por las mismas razones que sucedió con el codominio de la función dependiente.

Ejemplo como cuantificación existencial

Sea algún tipo, y déjelo . Por la correspondencia Curry-Howard , B puede ser interpretado como una lógica de predicado en términos de A . Para un dado , si el tipo B (a) está habitado indica si a satisface este predicado. La correspondencia puede extenderse a la cuantificación existencial y los pares dependientes: la proposición es verdadera si y solo si el tipo está habitado.

Por ejemplo, es menor o igual que si y solo si existe otro número natural tal que m + k = n . En lógica, esta afirmación está codificada por cuantificación existencial:

Esta proposición corresponde al tipo de par dependiente:
Es decir, una prueba de la afirmación de que m es menor que o igual a n es un par que contiene un número no negativo k , que es la diferencia entre m y n , y una prueba de la igualdad m + k = n .

Sistemas del cubo lambda

Henk Barendregt desarrolló el cubo lambda como un medio para clasificar los sistemas de tipos a lo largo de tres ejes. Las ocho esquinas del diagrama en forma de cubo resultante corresponden cada una a un sistema de tipos, con cálculo lambda simplemente mecanografiado en la esquina menos expresiva y cálculo de construcciones en la más expresiva. Los tres ejes del cubo corresponden a tres aumentos diferentes del cálculo lambda simplemente tipado: la adición de tipos dependientes, la adición de polimorfismo y la adición de constructores de tipos de kinded superior (funciones de tipos a tipos, por ejemplo). El cubo lambda se generaliza aún más mediante sistemas de tipos puros .

Teoría de tipos dependientes de primer orden

El sistema de tipos dependientes puros de primer orden, correspondiente al marco lógico LF , se obtiene generalizando el tipo de espacio funcional del cálculo lambda simplemente tipado al tipo de producto dependiente.

Teoría de tipos dependientes de segundo orden

El sistema de tipos dependientes de segundo orden se obtiene al permitir la cuantificación sobre constructores de tipos. En esta teoría el operador producto dependiente subsume tanto el operador de cálculo lambda simplemente mecanografiado y el aglutinante de System F .

Cálculo lambda polimórfico de tipo dependiente de orden superior

El sistema de orden superior se extiende a las cuatro formas de abstracción del cubo lambda : funciones de términos a términos, tipos a tipos, términos a tipos y tipos a términos. El sistema corresponde al cálculo de construcciones cuya derivada, el cálculo de construcciones inductivas es el sistema subyacente del asistente de prueba de Coq .

Lenguaje y lógica de programación simultánea

La correspondencia Curry-Howard implica que se pueden construir tipos que expresen propiedades matemáticas arbitrariamente complejas. Si el usuario puede proporcionar una prueba constructiva de que un tipo está habitado (es decir, que existe un valor de ese tipo), entonces un compilador puede verificar la prueba y convertirla en un código de computadora ejecutable que calcule el valor realizando la construcción. La función de verificación de pruebas hace que los lenguajes de escritura dependiente estén estrechamente relacionados con los asistentes de prueba . El aspecto de generación de código proporciona un enfoque poderoso para la verificación formal del programa y el código de prueba , ya que el código se deriva directamente de una prueba matemática verificada mecánicamente.

Comparación de idiomas con tipos dependientes

Idioma Desarrollado activamente Paradigma Táctica Condiciones de prueba Comprobación de terminación Los tipos pueden depender de Universos Prueba de irrelevancia Extracción de programa La extracción borra términos irrelevantes
Ada 2012 Imperativo Si (opcional) ? Cualquier término ? ? Ada ?
Agda Puramente funcional Pocas / limitadas Si (opcional) Cualquier término Si (opcional) Argumentos irrelevantes para la prueba Proposiciones irrelevantes para la prueba Haskell , JavaScript
ATS Funcional / imperativo No Términos estáticos ?
pimentón No Puramente funcional No No Cualquier término No No ? ?
Gallina
( Coq )
Puramente funcional Cualquier término No Haskell , Scheme y OCaml
ML dependiente No ? ? ? Números naturales ? ? ? ?
F* Funcional e imperativo Si (opcional) Cualquier término puro OCaml , F # y C
Gurú No Puramente funcional hipunión Cualquier término No Carraway
Idris Puramente funcional Si (opcional) Cualquier término No Si, agresivamente
Inclinarse Puramente funcional Cualquier término
Matita Puramente funcional Cualquier término OCaml
NuPRL Puramente funcional Cualquier término ? ?
PVS ? ? ? ? ? ? ? ?
sabio No Puramente funcional No No No ? No ? ? ?
Duodécimo Programación lógica ? Si (opcional) Cualquier término (LF) No No ? ?

Ver también

Notas al pie

  1. ^ Esto se refiere allenguaje central , no a ninguna táctica ( procedimiento de demostración de teoremas) o sublenguaje de generación de código.
  2. ^ Sujeto a restricciones semánticas, como restricciones de universo
  3. ^ Static_Predicate para términos restringidos, Dynamic_Predicate para verificación similar a la afirmación de cualquier término en la conversión de tipos
  4. ^ Solucionador de anillos
  5. ^ Universos opcionales, polimorfismo de universos opcionales y universos opcionales especificados explícitamente
  6. ^ Universos, restricciones de universo inferidas automáticamente (no lo mismo que el polimorfismo de universo de Agda) e impresión explícita opcional de restricciones de universo
  7. ^ Ha sido reemplazado por ATS
  8. ^ El último artículo de Sage y la última instantánea del código tienen fecha de 2006

Referencias

Otras lecturas

enlaces externos