stringtranslate.com

Cálculo lambda

El cálculo lambda (también escrito como λ -cálculo ) es un sistema formal de lógica matemática para expresar cálculos basados ​​en la abstracción y aplicación de funciones mediante la vinculación y sustitución de variables . El cálculo lambda no tipificado, el tema de este artículo, es un modelo universal de computación que se puede utilizar para simular cualquier máquina de Turing (y viceversa). Fue introducido por el matemático Alonzo Church en la década de 1930 como parte de su investigación sobre los fundamentos de las matemáticas . En 1936, Church encontró una formulación que era lógicamente consistente y la documentó en 1940.

El cálculo lambda consiste en construir términos lambda y realizar operaciones de reducción sobre ellos. En la forma más simple del cálculo lambda, los términos se construyen utilizando únicamente las siguientes reglas: [a]

  1. :Una variable es un carácter o cadena que representa un parámetro.
  2. :Una abstracción lambda es una definición de función, que toma como entrada la variable enlazada (entre λ y el punctum/punto ) y devuelve el cuerpo .
  3. : Una aplicación que aplica una función a un argumento . Tanto y son términos lambda.

Las operaciones de reducción incluyen:

Si se utiliza la indexación de De Bruijn , ya no se requiere la conversión α, ya que no habrá colisiones de nombres. Si la aplicación repetida de los pasos de reducción finalmente termina, entonces, según el teorema de Church-Rosser, se producirá una forma β-normal .

Los nombres de variables no son necesarios si se utiliza una función lambda universal, como Iota y Jot , que puede crear cualquier comportamiento de función llamándola a sí misma en varias combinaciones.

Explicación y aplicaciones

El cálculo lambda es Turing completo , es decir, es un modelo universal de computación que puede utilizarse para simular cualquier máquina de Turing . [3] Su homónimo, la letra griega lambda (λ), se utiliza en expresiones lambda y términos lambda para denotar la vinculación de una variable en una función .

El cálculo lambda puede ser tipado o no tipado . En el cálculo lambda tipado, las funciones solo se pueden aplicar si son capaces de aceptar el "tipo" de datos de entrada dado. Los cálculos lambda tipados son más débiles que el cálculo lambda no tipado, que es el tema principal de este artículo, en el sentido de que los cálculos lambda tipados pueden expresar menos que el cálculo no tipado. Por otro lado, los cálculos lambda tipados permiten demostrar más cosas. Por ejemplo, en el cálculo lambda simplemente tipado , es un teorema que cada estrategia de evaluación termina para cada término lambda simplemente tipado, mientras que la evaluación de términos lambda no tipados no necesita terminar (ver más abajo). Una razón por la que hay muchos cálculos lambda tipados diferentes ha sido el deseo de hacer más (de lo que el cálculo no tipado puede hacer) sin renunciar a ser capaz de demostrar teoremas fuertes sobre el cálculo.

El cálculo lambda tiene aplicaciones en muchas áreas diferentes de las matemáticas , la filosofía , [4] la lingüística , [5] [6] y la informática . [7] [8] El cálculo lambda ha desempeñado un papel importante en el desarrollo de la teoría de los lenguajes de programación . Los lenguajes de programación funcional implementan el cálculo lambda. El cálculo lambda también es un tema de investigación actual en la teoría de categorías . [9]

Historia

El cálculo lambda fue introducido por el matemático Alonzo Church en la década de 1930 como parte de una investigación sobre los fundamentos de las matemáticas . [10] [c] El sistema original demostró ser lógicamente inconsistente en 1935 cuando Stephen Kleene y JB Rosser desarrollaron la paradoja de Kleene-Rosser . [11] [12]

Posteriormente, en 1936, Church aisló y publicó sólo la parte relevante para el cálculo, lo que ahora se llama cálculo lambda no tipificado. [13] En 1940, también introdujo un sistema computacionalmente más débil, pero lógicamente consistente, conocido como cálculo lambda simplemente tipificado . [14]

Hasta la década de 1960, cuando se aclaró su relación con los lenguajes de programación, el cálculo lambda era sólo un formalismo. Gracias a las aplicaciones de Richard Montague y otros lingüistas en la semántica del lenguaje natural, el cálculo lambda ha comenzado a disfrutar de un lugar respetable tanto en la lingüística [15] como en la informática. [16]

Origen de lalasímbolo

Existe cierta incertidumbre sobre el motivo por el cual Church utiliza la letra griega lambda (λ) como notación para la abstracción de funciones en el cálculo lambda, tal vez en parte debido a explicaciones contradictorias del propio Church. Según Cardone y Hindley (2006):

Por cierto, ¿por qué Church eligió la notación “λ”? En [una carta inédita de 1964 a Harald Dickson] afirmó claramente que provenía de la notación “ ” utilizada para la abstracción de clases por Whitehead y Russell , modificando primero “ ” a “ ” para distinguir la abstracción de funciones de la abstracción de clases, y luego cambiando “ ” a “λ” para facilitar la impresión.

Este origen también fue reportado en [Rosser, 1984, p.338]. Por otra parte, en sus últimos años Church dijo a dos investigadores que la elección fue más bien accidental: se necesitaba un símbolo y λ simplemente fue elegido.

Dana Scott también ha abordado esta cuestión en varias conferencias públicas. [17] Scott cuenta que una vez le planteó una pregunta sobre el origen del símbolo lambda a John W. Addison Jr., ex alumno y yerno de Church, quien luego le escribió una postal a su suegro:

Estimado Profesor Church,

Russell tenía el operador iota y Hilbert el operador épsilon . ¿Por qué eligió lambda como operador?

Según Scott, toda la respuesta de Church consistió en devolver la postal con la siguiente anotación: " eeny, meeny, miny, moe ".

Descripción informal

Motivación

Las funciones computables son un concepto fundamental en la informática y las matemáticas. El cálculo lambda proporciona una semántica sencilla para el cálculo que resulta útil para estudiar formalmente las propiedades del cálculo. El cálculo lambda incorpora dos simplificaciones que simplifican su semántica.La primera simplificación es que el cálculo lambda trata las funciones de forma "anónima"; no les da nombres explícitos. Por ejemplo, la función

puede reescribirse en forma anónima como

(que se lee como "una tupla de x e y se asigna a "). [d] De manera similar, la función

puede reescribirse en forma anónima como

donde la entrada simplemente se asigna a sí misma. [d]

La segunda simplificación es que el cálculo lambda solo utiliza funciones de una sola entrada. Una función ordinaria que requiere dos entradas, por ejemplo la función , se puede transformar en una función equivalente que acepte una sola entrada y, como salida, devuelva otra función que, a su vez, acepte una sola entrada. Por ejemplo,

se puede reelaborar en

Este método, conocido como currying , transforma una función que toma múltiples argumentos en una cadena de funciones, cada una con un solo argumento.

La aplicación de la función a los argumentos (5, 2), produce inmediatamente

,

Mientras que la evaluación de la versión al curry requiere un paso más.

// La definición de se ha utilizado en la expresión interna. Esto es como una β-reducción.
// La definición de se ha utilizado con . Nuevamente, similar a la β-reducción.

para llegar al mismo resultado.

El cálculo lambda

El cálculo lambda consiste en un lenguaje de términos lambda , que se definen mediante una sintaxis formal determinada, y un conjunto de reglas de transformación para manipular los términos lambda. Estas reglas de transformación pueden considerarse como una teoría ecuacional o como una definición operacional .

Como se describió anteriormente, al no tener nombres, todas las funciones en el cálculo lambda son funciones anónimas. Solo aceptan una variable de entrada, por lo que se utiliza la currificación para implementar funciones de varias variables.

Términos lambda

La sintaxis del cálculo lambda define algunas expresiones como válidas y otras como no válidas, de la misma forma que algunas cadenas de caracteres son válidas en programas C y otras no. Una expresión válida del cálculo lambda se denomina " término lambda ".

Las siguientes tres reglas dan una definición inductiva que se puede aplicar para construir todos los términos lambda sintácticamente válidos: [e]

Ningún otro término lambda es válido. Es decir, un término lambda es válido si y solo si se puede obtener mediante la aplicación repetida de estas tres reglas. Por conveniencia, se pueden omitir algunos paréntesis al escribir un término lambda. Por ejemplo, los paréntesis más externos generalmente no se escriben. Consulte § Notación, a continuación, para obtener una descripción explícita de qué paréntesis son opcionales. También es común extender la sintaxis presentada aquí con operaciones adicionales, lo que permite dar sentido a términos como El enfoque de este artículo es el cálculo lambda puro sin extensiones, pero los términos lambda extendidos con operaciones aritméticas se utilizan con fines explicativos.

Una abstracción denota una función anónima [g] que toma una única entrada x y devuelve t . Por ejemplo, es una abstracción que representa la función definida mediante el uso del término para t . El nombre es superfluo cuando se utiliza la abstracción. La sintaxis vincula la variable x en el término t . La definición de una función con una abstracción simplemente "configura" la función pero no la invoca.

Una aplicación representa la aplicación de una función t a una entrada s , es decir, representa el acto de llamar a la función t en la entrada s para producir . 

Un término lambda puede hacer referencia a una variable que no ha sido vinculada, como el término (que representa la definición de la función ). En este término, la variable y no ha sido definida y se considera una incógnita. La abstracción es un término sintácticamente válido y representa una función que suma su entrada a la aún desconocida y .

Se pueden utilizar paréntesis y pueden ser necesarios para aclarar términos. Por ejemplo,

  1. es de forma y por lo tanto es una abstracción, mientras que
  2. es de forma y por tanto es una aplicación. 

Los ejemplos 1 y 2 denotan términos diferentes, que difieren únicamente en la ubicación de los paréntesis. Tienen significados diferentes: el ejemplo 1 es una definición de función, mientras que el ejemplo 2 es una aplicación de función. La variable lambda x es un marcador de posición en ambos ejemplos.

Aquí, el ejemplo 1 define una función , donde es , una función anónima , con entrada ; mientras que el ejemplo 2, , es M aplicado a N, donde es el término lambda que se aplica a la entrada que es . Tanto el ejemplo 1 como el 2 se evaluarían como la función identidad . 

Funciones que operan sobre funciones

En el cálculo lambda, las funciones se consideran " valores de primera clase ", por lo que pueden usarse como entradas o devolverse como salidas de otras funciones.

Por ejemplo, el término lambda representa la función identidad , . Además, representa la función constante , la función que siempre devuelve , sin importar la entrada. Como ejemplo de una función que opera sobre funciones, la composición de funciones se puede definir como .

Existen varias nociones de "equivalencia" y "reducción" que permiten "reducir" los términos lambda a términos lambda "equivalentes".

Equivalencia alfa

Una forma básica de equivalencia, definible en términos lambda, es la equivalencia alfa . Capta la intuición de que la elección particular de una variable ligada, en una abstracción, no importa (normalmente). Por ejemplo, y son términos lambda alfa-equivalentes, y ambos representan la misma función (la función identidad). Los términos y no son alfa-equivalentes, porque no están ligados en una abstracción. En muchas presentaciones, es habitual identificar términos lambda alfa-equivalentes.

Las siguientes definiciones son necesarias para poder definir la β-reducción:

Variables libres

Las variables libres [h] de un término son aquellas variables que no están limitadas por una abstracción. El conjunto de variables libres de una expresión se define de forma inductiva:

Por ejemplo, el término lambda que representa la identidad no tiene variables libres, pero la función tiene una única variable libre, .

Sustituciones que evitan la captura

Supongamos que , y son términos lambda, y y son variables. La notación indica la sustitución de por en de una manera que evita la captura . Esto se define de la siguiente manera:

Por ejemplo, , y .

La condición de frescura (que requiere que no esté en las variables libres de ) es crucial para garantizar que la sustitución no cambie el significado de las funciones.

Por ejemplo, una sustitución que ignore la condición de frescura podría generar errores: . Esta sustitución errónea convertiría la función constante en la identidad .

En general, el incumplimiento de la condición de frescura se puede solucionar renombrando primero con una variable nueva adecuada. Por ejemplo, volviendo a nuestra noción correcta de sustitución, en la abstracción se puede renombrar con una variable nueva para obtener , y el significado de la función se conserva por sustitución.

β-reducción

La regla de β-reducción [b] establece que una aplicación de la forma se reduce al término . La notación se utiliza para indicar que β-reduce a . Por ejemplo, para cada , . Esto demuestra que realmente es la identidad. De manera similar, , lo que demuestra que es una función constante.

El cálculo lambda puede considerarse una versión idealizada de un lenguaje de programación funcional, como Haskell o Standard ML . Según esta perspectiva,La β-reducción corresponde a un paso computacional. Este paso puede repetirse mediante β-reducciones adicionales hasta que no queden más aplicaciones para reducir. En el cálculo lambda no tipificado, como se presenta aquí, este proceso de reducción puede no terminar. Por ejemplo, considere el término . Aquí . Es decir, el término se reduce a sí mismo en una única β-reducción y, por lo tanto, el proceso de reducción nunca terminará.

Otro aspecto del cálculo lambda sin tipo es que no distingue entre distintos tipos de datos. Por ejemplo, puede ser conveniente escribir una función que solo opere con números. Sin embargo, en el cálculo lambda sin tipo no hay forma de evitar que una función se aplique a valores de verdad , cadenas u otros objetos que no sean números.

Definición formal

Definición

Las expresiones lambda se componen de:

El conjunto de expresiones lambda, Λ , se puede definir inductivamente :

  1. Si x es una variable, entonces x ∈ Λ.
  2. Si x es una variable y M ∈ Λ, entonces x . M ) ∈ Λ.
  3. Si M , N ∈ Λ, entonces ( MN ) ∈ Λ.

Las instancias de la regla 2 se conocen como abstracciones y las instancias de la regla 3 se conocen como aplicaciones . [18] Véase § expresión reducible

Este conjunto de reglas puede escribirse en forma Backus-Naur como:

 < expresión >  :== < abstracción > | < aplicación > | < variable >  < abstracción >  :== λ < variable > . < expresión >  < aplicación >  :== ( < expresión >  < expresión > ) < variable >  :== v1 | v2 | ...

Notación

Para mantener despejada la notación de expresiones lambda, generalmente se aplican las siguientes convenciones:

Variables libres y variables ligadas

Se dice que el operador de abstracción, λ, vincula su variable donde sea que aparezca en el cuerpo de la abstracción. Se dice que las variables que caen dentro del alcance de una abstracción están vinculadas . En una expresión λ x . M , la parte λ x se suele llamar vinculante , como una pista de que la variable x se vincula anteponiendo λ x a M . Todas las demás variables se denominan libres . Por ejemplo, en la expresión λ y . xxy , y es una variable vinculada y x es una variable libre. Además, una variable está vinculada por su abstracción más cercana. En el siguiente ejemplo, la única aparición de x en la expresión está vinculada por el segundo lambda: λ x . yx . zx ).

El conjunto de variables libres de una expresión lambda, M , se denota como FV( M ) y se define por recursión sobre la estructura de los términos, de la siguiente manera:

  1. FV( x ) = { x }, donde x es una variable.
  2. FV(λ x . M ) = FV( M ) \ { x }. [i]
  3. FV( MN ) = FV( M ) ∪ FV( N ). [j]

Se dice que una expresión que no contiene variables libres es cerrada . Las expresiones lambda cerradas también se conocen como combinadores y son equivalentes a los términos de la lógica combinatoria .

Reducción

El significado de las expresiones lambda se define por cómo se pueden reducir las expresiones. [22]

Hay tres tipos de reducción:

También hablamos de equivalencias resultantes: dos expresiones son α-equivalentes si pueden ser α-convertidas en la misma expresión. La β-equivalencia y la η-equivalencia se definen de manera similar.

El término redex , abreviatura de expresión reducible , se refiere a subtérminos que pueden reducirse mediante una de las reglas de reducción. Por ejemplo, (λ x . M ) N es un β-redex al expresar la sustitución de N por x en M . La expresión a la que se reduce un redex se llama su reduct ; el reduct de (λ x . M ) N es M [ x  := N ]. [b]

Si x no es libre en M , λ x . M x es también un η-redex, con una reducción de M .

conversión α

La conversión α ( alpha -conversión), a veces conocida como α-renombrado, [23] permite cambiar los nombres de las variables ligadas. Por ejemplo, la conversión α de λ x . x podría dar como resultado λ y . y . Los términos que difieren solo por la conversión α se denominan α-equivalentes . Con frecuencia, en los usos del cálculo lambda, los términos α-equivalentes se consideran equivalentes.

Las reglas precisas para la conversión α no son completamente triviales. Primero, cuando se convierte α una abstracción, las únicas ocurrencias de variables que se renombran son aquellas que están ligadas a la misma abstracción. Por ejemplo, una conversión α de λ xx . x podría resultar en λ yx . x , pero no podría resultar en λ yx . y . Este último tiene un significado diferente del original. Esto es análogo a la noción de programación de sombreado de variables .

En segundo lugar, la conversión α no es posible si da como resultado que una variable sea capturada por una abstracción diferente. Por ejemplo, si reemplazamos x por y en λ xy . x , obtenemos λ yy . y , que no es en absoluto lo mismo.

En lenguajes de programación con alcance estático, la conversión α se puede utilizar para simplificar la resolución de nombres al garantizar que ningún nombre de variable enmascare un nombre en un alcance que lo contenga (ver cambio de nombre α para que la resolución de nombres sea trivial ).

En la notación del índice De Bruijn , dos términos α-equivalentes son sintácticamente idénticos.

Sustitución

La sustitución, escrita M [ x  := N ], es el proceso de reemplazar todas las ocurrencias libres de la variable x en la expresión M por la expresión N . La sustitución en términos del cálculo lambda se define por recursión en la estructura de términos, de la siguiente manera (nota: x e y son solo variables mientras que M y N son cualquier expresión lambda):

x [ x  := N ] = N
y [ x  := N ] = y , si xy
( M 1 M 2 )[ x  := N ] = M 1 [ x  := N ] M 2 [ x  := N ]
x . M )[ x  := N ] = λ x . M
y . M )[ x  := N ] = λ y .( M [ x  := N ]), si xy e y ∉ FV( N ) Véase más arriba para FV

Para sustituir en una abstracción, a veces es necesario realizar una conversión α de la expresión. Por ejemplo, no es correcto que (λ x . y )[ y  := x ] dé como resultado λ x . x , porque se suponía que la x sustituida era libre pero terminó siendo ligada. La sustitución correcta en este caso es λ z . x , hasta la equivalencia α. La sustitución se define de forma única hasta la equivalencia α. Consulte las sustituciones que evitan la captura más arriba .

β-reducción

La β-reducción ( reducción beta ) captura la idea de aplicación de funciones. La β-reducción se define en términos de sustitución: la β-reducción de (λ x . M ) N es M [ x  := N ]. [b]

Por ejemplo, asumiendo alguna codificación de 2, 7, ×, tenemos la siguiente β-reducción: (λ n . n × 2) 7 → 7 × 2.

Se puede ver que la β-reducción es lo mismo que el concepto de reducibilidad local en la deducción natural , a través del isomorfismo de Curry-Howard .

η-reducción

La η-reducción ( reducción eta ) expresa la idea de extensionalidad , [24] que en este contexto es que dos funciones son iguales si y sólo si dan el mismo resultado para todos los argumentos. La η-reducción convierte entre λ x . f x y f siempre que x no aparezca libre en f .

Se puede ver que la η-reducción es lo mismo que el concepto de completitud local en la deducción natural , a través del isomorfismo de Curry-Howard .

Formas normales y confluencia

Para el cálculo lambda no tipado, la β-reducción como regla de reescritura no es ni fuertemente normalizadora ni débilmente normalizadora .

Sin embargo, se puede demostrar que la β-reducción es confluente cuando se trabaja hasta la α-conversión (es decir, consideramos que dos formas normales son iguales si es posible α-convertir una en la otra).

Por lo tanto, tanto los términos fuertemente normalizados como los débiles tienen una forma normal única. En el caso de los términos fuertemente normalizados, cualquier estrategia de reducción garantiza la obtención de la forma normal, mientras que, en el caso de los términos débilmente normalizados, algunas estrategias de reducción pueden no lograr encontrarla.

Codificación de tipos de datos

El cálculo lambda básico se puede utilizar para modelar aritmética , operaciones booleanas, estructuras de datos y recursión, como se ilustra en las siguientes subsecciones i , ii , iii y § iv .

Aritmética en el cálculo lambda

Hay varias formas posibles de definir los números naturales en el cálculo lambda, pero los más comunes son los numerales de Church , que se pueden definir de la siguiente manera:

0 := λ fx . x
1 := λ f . λ x . f x
2 := λ f . λ x . f ( f x )
3 := λ f . λ x . f ( f ( f x ))

y así sucesivamente. O utilizando la sintaxis alternativa presentada anteriormente en Notación :

0 := λ fx . x
1 := λ fx . fx
2 := λ fx . f ( f x )
3 := λ fx . f ( f ( f x ))

Un numeral de Church es una función de orden superior : toma una función de un solo argumento f y devuelve otra función de un solo argumento. El numeral de Church n es una función que toma una función f como argumento y devuelve la n -ésima composición de f , es decir, la función f compuesta consigo misma n veces. Esto se denota f ( n ) y es de hecho la n -ésima potencia de f (considerada como un operador); f (0) se define como la función identidad. Tales composiciones repetidas (de una sola función f ) obedecen las leyes de los exponentes , por lo que estos numerales se pueden usar para aritmética. (En el cálculo lambda original de Church, se requería que el parámetro formal de una expresión lambda apareciera al menos una vez en el cuerpo de la función, lo que hacía imposible la definición anterior de 0 ).

Una forma de pensar en el numeral de la Iglesia n , que suele ser útil al analizar programas, es como una instrucción 'repetir n veces'. Por ejemplo, utilizando las funciones PAIR y NIL definidas a continuación, se puede definir una función que construya una lista (enlazada) de n elementos todos iguales a x repitiendo 'anteponer otro elemento x ' n veces, comenzando desde una lista vacía. El término lambda es

λ nx . n (PAR x ) NULO

Variando lo que se repite y variando a qué argumento se aplica esa función que se repite, se pueden lograr muchos efectos diferentes.

Podemos definir una función sucesora, que toma un numeral de Church n y devuelve n + 1 agregando otra aplicación de f , donde '(mf)x' significa que la función 'f' se aplica 'm' veces en 'x':

SUCC := λ nfx . f ( n f x )

Dado que la composición m -ésima de f compuesta con la composición n -ésima de f da la composición m + n -ésima de f , la adición se puede definir de la siguiente manera:

MÁS := λ mnfx . m f ( n f x )

PLUS se puede considerar como una función que toma dos números naturales como argumentos y devuelve un número natural; se puede verificar que

MÁS 2 3

y

5

son expresiones lambda β-equivalentes. Dado que sumar m a un número n se puede lograr sumando 1 m veces, una definición alternativa es:

MÁS := λ mn . m SUCC norte  [25]

De manera similar, la multiplicación se puede definir como

MULT := λ mnf . m ( n f ) [21]

Alternativamente

MULT := λ mn . metro (MÁS norte ) 0

ya que multiplicar m y n es lo mismo que repetir la función de sumar n m veces y luego aplicarla a cero. La exponenciación tiene una representación bastante simple en los números de la Iglesia, a saber:

POW := λ be . e b [1]

La función predecesora definida por PRED n = n − 1 para un entero positivo n y PRED 0 = 0 es considerablemente más difícil. La fórmula

PRED := λ nfx . nortegh . h ( g f )) (λ u . x ) (λ u . u )

se puede validar mostrando inductivamente que si T denota gh . h ( g f )) , entonces T ( n )u . x ) = (λ h . h ( f ( n −1) ( x ))) para n > 0 . A continuación se dan otras dos definiciones de PRED , una utilizando condicionales y la otra utilizando pares. Con la función predecesora, la resta es sencilla. Definiendo

SUB := λ metronorte . norte PRED m ,

SUB m n produce mn cuando m > n y 0 en caso contrario.

Lógica y predicados

Por convención, se utilizan las dos definiciones siguientes (conocidas como booleanos de Church) para los valores booleanos VERDADERO y FALSO :

VERDADERO := λ xy . x
FALSO := λ xy . y

Luego, con estos dos términos lambda, podemos definir algunos operadores lógicos (estas son solo formulaciones posibles; otras expresiones podrían ser igualmente correctas):

Y := λ pq . p q p
O := λ pq . p p q
NO := λ p . p FALSO VERDADERO
ENTONCES:= λ pab . pag

Ahora podemos calcular algunas funciones lógicas, por ejemplo:

Y VERDADERO FALSO
≡ (λ pq . p q p ) VERDADERO FALSO → β VERDADERO FALSO VERDADERO
≡ (λ xy . x ) FALSO VERDADERO → β FALSO

y vemos que Y VERDADERO FALSO es equivalente a FALSO .

Un predicado es una función que devuelve un valor booleano. El predicado más fundamental es ISZERO , que devuelve TRUE si su argumento es el numeral eclesiástico 0 , pero FALSE si su argumento es cualquier otro numeral eclesiástico:

ES CERO := λ norte . nx .FALSO) VERDADERO

El siguiente predicado prueba si el primer argumento es menor o igual que el segundo:

LEQ := λ mn .ISZERO (SUB m n ) ,

y como m = n , si LEQ m n y LEQ n m , es sencillo construir un predicado para la igualdad numérica.

La disponibilidad de predicados y la definición anterior de VERDADERO y FALSO hacen que sea conveniente escribir expresiones "si-entonces-de lo contrario" en el cálculo lambda. Por ejemplo, la función predecesora se puede definir como:

PRED := λ norte . ngk .ISZERO ( g 1) k (MÁS ( g k ) 1)) (λ v .0) 0

lo cual se puede verificar mostrando inductivamente que ngk .ISZERO ( g 1) k (PLUS ( g k ) 1)) (λ v .0) es la función suma n − 1 para n > 0.

Pares

Un par (2-tuplas) se puede definir en términos de VERDADERO y FALSO , utilizando la codificación Church para pares . Por ejemplo, PAIR encapsula el par ( x , y ), FIRST devuelve el primer elemento del par y SECOND devuelve el segundo.

PAR := λ xyf . f x y
PRIMERO := λ p . p VERDADERO
SEGUNDO := λ p . p FALSO
NULO := λ x .VERDADERO
NULO := λ p . pxy .FALSO)

Una lista enlazada se puede definir como NIL para la lista vacía o como el PAR de un elemento y una lista más pequeña. El predicado NULL prueba el valor NIL . (Alternativamente, con NIL := FALSE , la construcción lhtz .deal_with_head_ h _and_tail_ t ) (deal_with_nil) obvia la necesidad de una prueba NULL explícita).

Como ejemplo del uso de pares, la función de desplazamiento e incremento que asigna ( m , n ) a ( n , n + 1) se puede definir como

Φ := λ x .PAR (SEGUNDO x ) (SUCC (SEGUNDO x ))

lo que nos permite dar quizás la versión más transparente de la función predecesora:

PRED := λ n .PRIMERO ( n Φ (PAR 0 0)).

Técnicas de programación adicionales

Existe una gran cantidad de expresiones idiomáticas de programación para el cálculo lambda. Muchas de ellas se desarrollaron originalmente en el contexto del uso del cálculo lambda como base para la semántica de los lenguajes de programación , utilizando efectivamente el cálculo lambda como un lenguaje de programación de bajo nivel . Debido a que varios lenguajes de programación incluyen el cálculo lambda (o algo muy similar) como un fragmento, estas técnicas también se utilizan en la programación práctica, pero pueden percibirse como oscuras o extrañas.

Constantes con nombre

En el cálculo lambda, una biblioteca tomaría la forma de una colección de funciones definidas previamente, que como términos lambda son simplemente constantes particulares. El cálculo lambda puro no tiene un concepto de constantes nombradas ya que todos los términos lambda atómicos son variables, pero uno puede emular tener constantes nombradas dejando de lado una variable como el nombre de la constante, usando abstracción para unir esa variable en el cuerpo principal y aplicar esa abstracción a la definición deseada. Por lo tanto, para usar f para significar N (algún término lambda explícito) en M (otro término lambda, el "programa principal"), uno puede decir

f . M ) N

Los autores a menudo introducen azúcar sintáctico , como let , [k] para permitir escribir lo anterior en un orden más intuitivo.

sea ​​f = N en M

Al encadenar dichas definiciones, se puede escribir un "programa" de cálculo lambda como cero o más definiciones de funciones, seguidas de un término lambda que utiliza esas funciones que constituyen el cuerpo principal del programa.

Una restricción notable de este let es que el nombre f no debe estar definido en N , para que N quede fuera del alcance de la abstracción que vincula f ; esto significa que no se puede usar una definición de función recursiva como N con let . La construcción letrec [l] permitiría escribir definiciones de funciones recursivas.

Recursión y puntos fijos

La recursión es la definición de una función que se invoca a sí misma. Una definición que se contiene a sí misma dentro de sí misma, por valor, lleva a que todo el valor sea de tamaño infinito. Otras notaciones que admiten la recursión de forma nativa superan esto haciendo referencia a la definición de la función por nombre . El cálculo lambda no puede expresar esto: todas las funciones son anónimas en el cálculo lambda, por lo que no podemos hacer referencia por nombre a un valor que aún no se ha definido, dentro del término lambda que define ese mismo valor. Sin embargo, una expresión lambda puede recibirse a sí misma como su propio argumento, por ejemplo en  x . x x ) E . Aquí E debería ser una abstracción, aplicando su parámetro a un valor para expresar la recursión.

Consideremos la función factorial F( n ) definida recursivamente por

F( n ) = 1, si n = 0; de lo contrario n × F( n − 1) .

En la expresión lambda que representa esta función, se supondrá que un parámetro (normalmente el primero) recibe la expresión lambda como su valor, de modo que llamarlo (aplicarlo a un argumento) equivaldrá a una recursión. Por lo tanto, para lograr la recursión, el argumento que se pretende que haga referencia a sí mismo (llamado aquí r ) siempre debe pasarse a sí mismo dentro del cuerpo de la función, en un punto de llamada:

G := λ r . λ n .(1, si n = 0; de lo contrario n × ( r r ( n −1)))
con  r r x = F x = G r x  para cumplir, entonces  r = G  y
F := GG = (λ x . x x ) G

La autoaplicación logra la replicación aquí, pasando la expresión lambda de la función a la siguiente invocación como un valor de argumento, haciéndola disponible para ser referenciada y llamada allí.

Esto lo resuelve, pero requiere reescribir cada llamada recursiva como una aplicación propia. Nos gustaría tener una solución genérica, sin necesidad de reescribir nada:

G := λ r . λ n .(1, si n = 0; de lo contrario n × ( r ( n −1)))
con  r x = F x = G r x  para cumplir, entonces  r = G r =: FIJO G  y
F := FIJO G  donde  FIJO g  := ( r donde r = g r ) = g (FIJO g )
de modo que  FIX G = G (FIX G) = (λ n .(1, si n = 0; de lo contrario n × ((FIX G) ( n −1))))

Dado un término lambda cuyo primer argumento representa una llamada recursiva (por ejemplo, G aquí), el combinador de punto fijo FIX devolverá una expresión lambda autorreplicante que representa la función recursiva (aquí, F ). La función no necesita pasarse explícitamente a sí misma en ningún momento, ya que la autorreplicación se organiza de antemano, cuando se crea, para que se realice cada vez que se la llama. Por lo tanto, la expresión lambda original (FIX G) se vuelve a crear dentro de sí misma, en el punto de llamada, logrando la autorreferencia .

De hecho, existen muchas definiciones posibles para este operador FIX , siendo la más simple de ellas:

Y  := λ g .(λ x . g ( x x )) (λ x . g ( x x ))

En el cálculo lambda, Y g   es un punto fijo de g , ya que se expande a:

Y g
h .(λ x . h ( x x )) (λ x . h ( x x ))) g
x . g ( x x )) (λ x . g ( x x ))
g ((λ x . g ( x x )) (λ x . g ( x x )))
g ( Y g )

Ahora, para realizar nuestra llamada recursiva a la función factorial, simplemente llamaríamos a ( Y G) n , donde n es el número del que estamos calculando el factorial. Dado n = 4, por ejemplo, esto da:

( YG ) 4
G ( Y G) 4
rn .(1, si n = 0; de lo contrario n × ( r ( n −1)))) ( Y G) 4
n .(1, si n = 0; de lo contrario n × (( Y G) ( n −1)))) 4
1, si 4 = 0; de lo contrario 4 × (( Y G) (4−1))
4 × (G ( Y G) (4−1))
4 × ((λ n .(1, si n = 0; de lo contrario n × (( Y G) ( n −1)))) (4−1))
4 × (1, si 3 = 0; de lo contrario 3 × (( Y G) (3−1)))
4 × (3 × (G ( Y G) (3−1)))
4 × (3 × ((λ n .(1, si n = 0; de lo contrario n × (( Y G) ( n −1)))) (3−1)))
4 × (3 × (1, si 2 = 0; de lo contrario 2 × (( Y G) (2−1))))
4 × (3 × (2 × (G ( Y G) (2−1))))
4 × (3 × (2 × ((λ n .(1, si n = 0; de lo contrario n × (( Y G) ( n −1)))) (2−1))))
4 × (3 × (2 × (1, si 1 = 0; de lo contrario 1 × (( Y G) (1−1)))))
4 × (3 × (2 × (1 × (G ( Y G) (1−1)))))
4 × (3 × (2 × (1 × ((λ n .(1, si n = 0; de lo contrario n × (( Y G) ( n −1)))) (1−1)))))
4 × (3 × (2 × (1 × (1, si 0 = 0; de lo contrario 0 × (( Y G) (0−1))))))
4 × (3 × (2 × (1 × (1))))
24

Toda función definida recursivamente puede verse como un punto fijo de alguna función definida adecuadamente que cierra la llamada recursiva con un argumento adicional y, por lo tanto, utilizando Y , toda función definida recursivamente puede expresarse como una expresión lambda. En particular, ahora podemos definir claramente los predicados de resta, multiplicación y comparación de números naturales de forma recursiva.

Términos estándar

Ciertos términos tienen nombres comúnmente aceptados: [27] [28] [29]

yo  := λ x . x
S  := λ xyz . x z ( y z )
K  := λ x . λ y . x
B  := λ xyz . x ( y z )
C  := λ x . λ y . λ z . x z y
W  := λ x . λ y . x y y
ω o Δ o U  := λ x . x x
Ω  := ω ω

I es la función identidad. SK y BCKW forman sistemas completos de cálculo combinatorio que pueden expresar cualquier término lambda (consulte la siguiente sección). Ω es UU , el término más pequeño que no tiene forma normal. YI es otro término de este tipo. Y es estándar y se definió anteriormente, y también se puede definir como Y = BU(CBU) , de modo que Y g=g( Y g) . VERDADERO y FALSO definidos anteriormente se abrevian comúnmente como T y F.

Eliminación de abstracciones

Si N es un término lambda sin abstracción, pero que posiblemente contenga constantes nombradas ( combinadores ), entonces existe un término lambda T ( x , N ) que es equivalente a λ x . N pero carece de abstracción (excepto como parte de las constantes nombradas, si estas se consideran no atómicas). Esto también puede verse como variables anonimizadas, ya que T ( x , N ) elimina todas las ocurrencias de x de N , mientras que todavía permite que los valores de los argumentos se sustituyan en las posiciones donde N contiene una x . La función de conversión T puede definirse por:

T ( x , x ):= yo
T ( x , N ) := K N si x no es libre en N .
T ( x , MN ) : = ST ( x , M ) T ( x , N )

En cualquier caso, un término de la forma T ( x , N ) P se puede reducir haciendo que el combinador inicial I , K o S tome el argumento P , tal como lo haría la β-reducción de x . N ) P . I devuelve ese argumento. K descarta el argumento, tal como lo haría x . N ) si x no tiene ninguna ocurrencia libre en N . S pasa el argumento a ambos subtérminos de la aplicación y luego aplica el resultado del primero al resultado del segundo.

Los combinadores B y C son similares a S , pero pasan el argumento a un solo subtérmino de una aplicación ( B al subtérmino "argumento" y C al subtérmino "función"), ahorrando así un K posterior si no hay ocurrencia de x en un subtérmino. En comparación con B y C , el combinador S en realidad combina dos funcionalidades: reorganizar argumentos y duplicar un argumento para que pueda usarse en dos lugares. El combinador W solo hace esto último, lo que produce el sistema B, C, K, W como una alternativa al cálculo del combinador SKI .

Cálculo lambda tipificado

Un cálculo lambda tipado es un formalismo tipado que utiliza el símbolo lambda ( ) para denotar la abstracción de una función anónima. En este contexto, los tipos son normalmente objetos de naturaleza sintáctica que se asignan a términos lambda; la naturaleza exacta de un tipo depende del cálculo considerado (véase Tipos de cálculos lambda tipados ). Desde cierto punto de vista, los cálculos lambda tipados pueden verse como refinamientos del cálculo lambda no tipado, pero desde otro punto de vista, también pueden considerarse la teoría más fundamental y el cálculo lambda no tipado un caso especial con un solo tipo. [30]

Los cálculos lambda tipados son lenguajes de programación fundamentales y son la base de los lenguajes de programación funcional tipados como ML y Haskell y, de forma más indirecta, de los lenguajes de programación imperativos tipados . Los cálculos lambda tipados desempeñan un papel importante en el diseño de sistemas de tipos para lenguajes de programación; aquí la tipabilidad suele capturar propiedades deseables del programa, por ejemplo, el programa no provocará una violación de acceso a memoria.

Los cálculos lambda tipados están estrechamente relacionados con la lógica matemática y la teoría de la prueba a través del isomorfismo de Curry-Howard y pueden considerarse como el lenguaje interno de las clases de categorías , por ejemplo, el cálculo lambda tipado simplemente es el lenguaje de las categorías cartesianas cerradas (CCC).

Estrategias de reducción

El que un término sea normalizador o no, y el trabajo que se necesita hacer para normalizarlo si lo es, depende en gran medida de la estrategia de reducción utilizada. Las estrategias de reducción de cálculo lambda más comunes incluyen: [31] [32] [33]

Orden normal
El redex más externo a la izquierda se reduce primero. Es decir, siempre que sea posible, los argumentos se sustituyen en el cuerpo de una abstracción antes de que se reduzcan. Si un término tiene una forma beta-normal, la reducción de orden normal siempre alcanzará esa forma normal.
Orden de aplicación
La redex más interna y más a la izquierda se reduce primero. Como consecuencia, los argumentos de una función siempre se reducen antes de que se los sustituya en la función. A diferencia de la reducción de orden normal, la reducción de orden aplicativo puede no encontrar la forma beta-normal de una expresión, incluso si dicha forma normal existe. Por ejemplo, el término se reduce a sí mismo por orden aplicativo, mientras que el orden normal lo reduce a su forma beta-normal .
β-reducciones completas
Cualquier redex puede reducirse en cualquier momento. Esto significa, en esencia, que no existe ninguna estrategia de reducción en particular; en lo que respecta a la reducibilidad, "no hay nada que hacer".

Las estrategias de reducción débil no reducen bajo abstracciones lambda:

Llamada por valor
Similar al orden aplicativo, pero no se realizan reducciones dentro de las abstracciones. Esto es similar al orden de evaluación de lenguajes estrictos como C: los argumentos de una función se evalúan antes de llamar a la función, y los cuerpos de las funciones no se evalúan ni siquiera parcialmente hasta que se sustituyen los argumentos.
Llamar por nombre
Como el orden normal, pero no se realizan reducciones dentro de las abstracciones. Por ejemplo, λ x .(λ y . y ) x está en forma normal según esta estrategia, aunque contiene el redex y . y ) x .

Las estrategias de compartición reducen los cálculos que son "iguales" en paralelo:

Reducción óptima
Como orden normal, pero los cálculos que tienen la misma etiqueta se reducen simultáneamente.
Llamar por necesidad
Como se llama por nombre (por lo tanto, es débil), pero las aplicaciones de función que duplicarían términos en su lugar nombrarían el argumento. El argumento se puede evaluar "cuando sea necesario", momento en el que la vinculación del nombre se actualiza con el valor reducido. Esto puede ahorrar tiempo en comparación con la evaluación de órdenes normal.

Computabilidad

No existe ningún algoritmo que tome como entrada dos expresiones lambda cualesquiera y dé como salida VERDADERO o FALSO dependiendo de si una expresión se reduce a la otra. [13] Más precisamente, ninguna función computable puede decidir la cuestión. Este fue históricamente el primer problema para el que se pudo demostrar la indecidibilidad. Como es habitual en este tipo de pruebas, computable significa computable mediante cualquier modelo de cálculo que sea Turing completo . De hecho, la computabilidad se puede definir a través del cálculo lambda: una función F : NN de números naturales es una función computable si y solo si existe una expresión lambda f tal que para cada par de x , y en N , F ( x )= y si y solo si f x  = β y , donde x e y son los numerales de Church correspondientes a x e y , respectivamente y = β que significa equivalencia con β-reducción. Véase la tesis de Church-Turing para otros enfoques para definir la computabilidad y su equivalencia.  

La prueba de incomputabilidad de Church reduce primero el problema a determinar si una expresión lambda dada tiene una forma normal . Luego supone que este predicado es computable y, por lo tanto, puede expresarse en cálculo lambda. Basándose en trabajos anteriores de Kleene y construyendo una numeración de Gödel para expresiones lambda, construye una expresión lambda e que sigue de cerca la prueba del primer teorema de incompletitud de Gödel . Si e se aplica a su propio número de Gödel, resulta una contradicción.

Complejidad

La noción de complejidad computacional para el cálculo lambda es un poco complicada, porque el costo de una β-reducción puede variar dependiendo de cómo se implemente. [34] Para ser precisos, uno debe encontrar de alguna manera la ubicación de todas las ocurrencias de la variable ligada V en la expresión E , lo que implica un costo de tiempo, o uno debe realizar un seguimiento de las ubicaciones de las variables libres de alguna manera, lo que implica un costo de espacio. Una búsqueda ingenua de las ubicaciones de V en E es O ( n ) en la longitud n de E . Las cadenas de directores fueron un enfoque temprano que intercambió este costo de tiempo por un uso de espacio cuadrático. [35] De manera más general, esto ha llevado al estudio de sistemas que utilizan la sustitución explícita .

En 2014, se demostró que el número de pasos de β-reducción tomados por la reducción de orden normal para reducir un término es un modelo de costo de tiempo razonable , es decir, la reducción se puede simular en una máquina de Turing en un tiempo polinomialmente proporcional al número de pasos. [36] Este era un problema abierto desde hace mucho tiempo, debido a la explosión de tamaño , la existencia de términos lambda que crecen exponencialmente en tamaño para cada β-reducción. El resultado soluciona esto trabajando con una representación compartida compacta. El resultado deja claro que la cantidad de espacio necesario para evaluar un término lambda no es proporcional al tamaño del término durante la reducción. Actualmente no se sabe cuál sería una buena medida de la complejidad espacial. [37]

Un modelo irrazonable no significa necesariamente ineficiente. La reducción óptima reduce todos los cálculos con la misma etiqueta en un paso, evitando el trabajo duplicado, pero el número de pasos de β-reducción paralelos para reducir un término dado a la forma normal es aproximadamente lineal en el tamaño del término. Esto es demasiado pequeño para ser una medida de costo razonable, ya que cualquier máquina de Turing puede codificarse en el cálculo lambda en un tamaño linealmente proporcional al tamaño de la máquina de Turing. El verdadero costo de reducir los términos lambda no se debe a la β-reducción per se, sino más bien al manejo de la duplicación de redexes durante la β-reducción. [38] No se sabe si las implementaciones de reducción óptima son razonables cuando se miden con respecto a un modelo de costo razonable, como el número de pasos más a la izquierda-más a la forma normal, pero se ha demostrado para fragmentos del cálculo lambda que el algoritmo de reducción óptima es eficiente y tiene como máximo una sobrecarga cuadrática en comparación con el más a la izquierda-más a la externa. [37] Además, la implementación del prototipo BOHM de reducción óptima superó tanto a Caml Light como a Haskell en términos lambda puros. [38]

Cálculo lambda y lenguajes de programación

Como se señala en el artículo de Peter Landin de 1965 "Una correspondencia entre ALGOL 60 y la notación Lambda de Church", [39] los lenguajes de programación procedimental secuencial pueden entenderse en términos del cálculo lambda, que proporciona los mecanismos básicos para la abstracción procedimental y la aplicación de procedimientos (subprogramas).

Funciones anónimas

Por ejemplo, en Python la función "cuadrado" se puede expresar como una expresión lambda de la siguiente manera:

( lambda  x :  x ** 2 )

El ejemplo anterior es una expresión que se evalúa como una función de primera clase. El símbolo lambdacrea una función anónima, dada una lista de nombres de parámetros x(en este caso, solo un argumento) y una expresión que se evalúa como el cuerpo de la función. x**2Las funciones anónimas a veces se denominan expresiones lambda.

Por ejemplo, Pascal y muchos otros lenguajes imperativos han admitido durante mucho tiempo el paso de subprogramas como argumentos a otros subprogramas a través del mecanismo de punteros de función . Sin embargo, los punteros de función no son una condición suficiente para que las funciones sean tipos de datos de primera clase , porque una función es un tipo de datos de primera clase si y solo si se pueden crear nuevas instancias de la función en tiempo de ejecución. Y esta creación de funciones en tiempo de ejecución es compatible con Smalltalk , JavaScript y Wolfram Language , y más recientemente con Scala , Eiffel ("agentes"), C# ("delegados") y C++11 , entre otros.

Paralelismo y concurrencia

La propiedad de Church-Rosser del cálculo lambda significa que la evaluación (β-reducción) se puede llevar a cabo en cualquier orden , incluso en paralelo. Esto significa que son relevantes varias estrategias de evaluación no deterministas . Sin embargo, el cálculo lambda no ofrece ningún constructo explícito para el paralelismo . Se pueden agregar constructos como Futuros al cálculo lambda. Se han desarrollado otros cálculos de procesos para describir la comunicación y la concurrencia.

Semántica

El hecho de que los términos del cálculo lambda actúen como funciones sobre otros términos del cálculo lambda, e incluso sobre sí mismos, llevó a plantear preguntas sobre la semántica del cálculo lambda. ¿Podría asignarse un significado sensato a los términos del cálculo lambda? La semántica natural era encontrar un conjunto D isomorfo al espacio de funciones DD , de funciones sobre sí mismo. Sin embargo, no puede existir un D no trivial, por restricciones de cardinalidad porque el conjunto de todas las funciones desde D hasta D tiene mayor cardinalidad que D , a menos que D sea un conjunto singleton .

En la década de 1970, Dana Scott demostró que si solo se consideraban funciones continuas , se podía encontrar un conjunto o dominio D con la propiedad requerida, proporcionando así un modelo para el cálculo lambda. [40]

Este trabajo también formó la base para la semántica denotacional de los lenguajes de programación.

Variaciones y ampliaciones

Estas extensiones están en el cubo lambda :

Estos sistemas formales son extensiones del cálculo lambda que no están en el cubo lambda:

Estos sistemas formales son variaciones del cálculo lambda:

Estos sistemas formales están relacionados con el cálculo lambda:

Véase también

Lectura adicional

Monografías/libros de texto para estudiantes de posgrado
Documentos

Notas

  1. ^ Estas reglas producen expresiones como: . Los paréntesis se pueden eliminar si la expresión no es ambigua. Para algunas aplicaciones, se pueden incluir términos para operaciones y constantes lógicas y matemáticas.
  2. ^ abcd Barendregt, Barendsen (2000) llame a esta forma
    • axioma β : (λx.M[x]) N = M[N] , reescrito como (λx.M) N = M[x := N], "donde M[x := N] denota la sustitución de N por cada ocurrencia de x en M". [1] : 7  También denotado M[N/x], "la sustitución de N por x en M". [2]
  3. ^ Para una historia completa, véase "Historia del cálculo lambda y la lógica combinatoria" de Cardone y Hindley (2006).
  4. ^ ab se pronuncia " mapas a ".
  5. ^ La expresión e puede ser: variables x, abstracciones lambda o aplicaciones —en BNF, .— de Cálculo lambda simplemente tipado de Wikipedia #Sintaxis para cálculo lambda sin tipo
  6. ^ a veces se escribe en ASCII como
  7. ^ El término lambda representa la función escrita en forma anónima.
  8. ^ Las variables libres en la notación lambda y su cálculo son comparables al álgebra lineal y a los conceptos matemáticos del mismo nombre.
  9. ^ El conjunto de variables libres de M, pero con { x } eliminado
  10. ^ La unión del conjunto de variables libres de y el conjunto de variables libres de [1]
  11. ^ f . M ) N se puede pronunciar "sea f N en M".
  12. ^ Ariola y Blom [26] emplean 1) axiomas para un cálculo representacional que utiliza grafos lambda cíclicos bien formados extendidos con letrec , para detectar posibles árboles de desenrollado infinitos; 2) el cálculo representacional con β-reducción de grafos lambda con ámbito constituye la extensión cíclica de cálculo lambda de Ariola/Blom; 3) Ariola/Blom razonan sobre lenguajes estrictos que utilizan § call-by-value y comparan con el cálculo de Moggi y con el cálculo de Hasegawa. Conclusiones en la p. 111. [26]

Referencias

Algunas partes de este artículo se basan en material de FOLDOC , utilizado con permiso .

  1. ^ a b C Barendregt, Henk ; Barendsen, Erik (marzo de 2000), Introducción al cálculo Lambda (PDF)
  2. ^ sustitución explícita en el n Lab
  3. ^ Turing, Alan M. (diciembre de 1937). "Computabilidad y λ-definibilidad". The Journal of Symbolic Logic . 2 (4): 153–163. doi :10.2307/2268280. JSTOR  2268280. S2CID  2317046.
  4. ^ Coquand, Thierry (8 de febrero de 2006). Zalta, Edward N. (ed.). "Type Theory". The Stanford Encyclopedia of Philosophy (edición de verano de 2013) . Consultado el 17 de noviembre de 2020 .
  5. ^ Moortgat, Michael (1988). Investigaciones categóricas: aspectos lógicos y lingüísticos del cálculo de Lambek. Publicaciones Foris. ISBN 9789067653879.
  6. ^ Toque, Harry; Muskens, Reinhard, eds. (2008). Significado informático. Saltador. ISBN 978-1-4020-5957-5.
  7. ^ Mitchell, John C. (2003). Conceptos en lenguajes de programación. Cambridge University Press. pág. 57. ISBN 978-0-521-78098-8..
  8. ^ Chacón Sartori, Camilo (5 de diciembre de 2023). Introducción al cálculo lambda con Racket (Informe técnico). Archivado desde el original el 7 de diciembre de 2023.
  9. ^ Pierce, Benjamin C. Teoría de categorías básicas para científicos informáticos . p. 53.
  10. ^ Church, Alonzo (1932). "Un conjunto de postulados para la fundación de la lógica". Anales de Matemáticas . Serie 2. 33 (2): 346–366. doi :10.2307/1968337. JSTOR  1968337.
  11. ^ Kleene, Stephen C. ; Rosser, JB (julio de 1935). "La inconsistencia de ciertas lógicas formales". Anales de Matemáticas . 36 (3): 630. doi :10.2307/1968646. JSTOR  1968646.
  12. ^ Church, Alonzo (diciembre de 1942). "Revisión de Haskell B. Curry, La inconsistencia de ciertas lógicas formales ". The Journal of Symbolic Logic . 7 (4): 170–171. doi :10.2307/2268117. JSTOR  2268117.
  13. ^ ab Church, Alonzo (1936). "Un problema irresoluble de la teoría elemental de números". American Journal of Mathematics . 58 (2): 345–363. doi :10.2307/2371045. JSTOR  2371045.
  14. ^ Church, Alonzo (1940). "Una formulación de la teoría simple de tipos". Revista de lógica simbólica . 5 (2): 56–68. doi :10.2307/2266170. JSTOR  2266170. S2CID  15889861.
  15. ^ Partee, BBH; ter Meulen, A.; Wall, RE (1990). Métodos matemáticos en lingüística. Springer. ISBN 9789027722454. Recuperado el 29 de diciembre de 2016 .
  16. ^ Alama, Jesse. Zalta, Edward N. (ed.). "El cálculo lambda". The Stanford Encyclopedia of Philosophy (edición de verano de 2013) . Consultado el 17 de noviembre de 2020 .
  17. ^ Dana Scott, "Mirando hacia atrás; mirando hacia adelante", charla invitada en el taller en honor del 85.° cumpleaños de Dana Scott y de sus 50 años de teoría de dominios, 7 y 8 de julio, FLoC 2018 (charla del 7 de julio de 2018). El pasaje relevante comienza en 32:50. (Véase también este extracto de una charla de mayo de 2016 en la Universidad de Birmingham, Reino Unido).
  18. ^ Barendregt, Hendrik Pieter (1984). El cálculo lambda: su sintaxis y semántica. Estudios de lógica y fundamentos de las matemáticas. Vol. 103 (edición revisada). Holanda Septentrional. ISBN 0-444-87508-5.(Correcciones).
  19. ^ ab "Ejemplo de reglas de asociatividad". Lambda-bound.com . Consultado el 18 de junio de 2012 .
  20. ^ "La gramática básica de las expresiones Lambda". SoftOption . Algunos otros sistemas utilizan la yuxtaposición para indicar la aplicación, por lo que 'ab' significa 'a@b'. Esto está bien, excepto que requiere que las variables tengan una longitud de uno, de modo que sabemos que 'ab' son dos variables yuxtapuestas, no una variable de longitud 2. Pero queremos que las etiquetas como 'firstVariable' signifiquen una sola variable, por lo que no podemos utilizar esta convención de yuxtaposición.
  21. ^ ab Selinger, Peter (2008), Notas de clase sobre el cálculo lambda (PDF) , vol. 0804, Departamento de Matemáticas y Estadística, Universidad de Ottawa, pág. 9, arXiv : 0804.3434 , Bibcode :2008arXiv0804.3434S
  22. ^ de Queiroz, Ruy JGB (1988). "Una explicación teórica de la programación y el papel de las reglas de reducción". Dialectica . 42 (4): 265–282. doi :10.1111/j.1746-8361.1988.tb00919.x.
  23. ^ Turbak, Franklyn; Gifford, David (2008), Conceptos de diseño en lenguajes de programación , MIT press, pág. 251, ISBN 978-0-262-20175-9
  24. ^ Luke Palmer (29 de diciembre de 2010) Haskell-cafe: ¿Cuál es la motivación de las reglas η?
  25. ^ Felleisen, Matthias; Flatt, Matthew (2006), Lenguajes de programación y cálculos lambda (PDF) , pág. 26, archivado desde el original (PDF) el 5 de febrero de 2009;Una nota (consultada en 2017) en la ubicación original sugiere que los autores consideran que la obra originalmente referenciada ha sido reemplazada por un libro.
  26. ^ ab Zena M. Ariola y Stefan Blom, Proc. TACS '94 Sendai, Japón 1997 (1997) Cálculos lambda cíclicos 114 páginas.
  27. ^ Ker, Andrew D. "Cálculo Lambda y Tipos" (PDF) . p. 6 . Consultado el 14 de enero de 2022 .
  28. ^ Dezani-Ciancaglini, Mariangiola; Ghilezan, Silvia (2014). "Precisión de la subtipificación en tipos de intersección y unión" (PDF) . Reescritura y cálculos lambda tipados . Apuntes de clase en informática. Vol. 8560. pág. 196. doi :10.1007/978-3-319-08918-8_14. hdl :2318/149874. ISBN 978-3-319-08917-1. Recuperado el 14 de enero de 2022 .
  29. ^ Forster, Yannick; Smolka, Gert (agosto de 2019). "Call-by-Value Lambda Calculus as a Model of Computation in Coq" (PDF) . Revista de razonamiento automatizado . 63 (2): 393–413. doi :10.1007/s10817-018-9484-2. S2CID  53087112 . Consultado el 14 de enero de 2022 .
  30. ^ Tipos y lenguajes de programación, pág. 273, Benjamin C. Pierce
  31. ^ Pierce, Benjamin C. (2002). Tipos y lenguajes de programación. MIT Press . pág. 56. ISBN. 0-262-16209-1.
  32. ^ Sestoft, Peter (2002). "Demostración de la reducción del cálculo lambda" (PDF) . La esencia de la computación . Apuntes de clase en informática. Vol. 2566. págs. 420–435. doi :10.1007/3-540-36377-7_19. ISBN 978-3-540-00326-7. Recuperado el 22 de agosto de 2022 .
  33. ^ Biernacka, Małgorzata; Charatonik, Witold; Monótono, Tomasz (2022). Andrónico, junio; de Moura, Leonardo (eds.). "El zoológico de las estrategias de reducción del cálculo Lambda y Coq" (PDF) . 13.ª Conferencia Internacional sobre Demostración Interactiva de Teoremas (ITP 2022) . 237 . Schloss Dagstuhl – Leibniz-Zentrum für Informatik: 7:1–7:19. doi : 10.4230/LIPIcs.ITP.2022.7 . Consultado el 22 de agosto de 2022 .
  34. ^ Frandsen, Gudmund Skovbjerg; Sturtivant, Carl (26 de agosto de 1991). "¿Cuál es una implementación eficiente del cálculo λ?". Lenguajes de programación funcional y arquitectura informática: 5.ª conferencia de la ACM. Cambridge, MA, EE. UU., 26-30 de agosto de 1991. Actas . Lecture Notes in Computer Science. Vol. 523. Springer-Verlag. págs. 289–312. CiteSeerX 10.1.1.139.6913 . doi :10.1007/3540543961_14. ISBN .  9783540543961.
  35. ^ Sinot, F.-R. (2005). "Director Strings Revisited: A Generic Approach to the Efficient Representation of Free Variables in Higher-order Rewriting" (PDF) . Revista de lógica y computación . 15 (2): 201–218. doi :10.1093/logcom/exi010.
  36. ^ Accattoli, Beniamino; Dal Lago, Ugo (14 de julio de 2014). "La reducción beta es invariante, de hecho". Actas de la reunión conjunta de la vigésimo tercera conferencia anual de la EACSL sobre lógica en ciencias de la computación (CSL) y el vigésimo noveno simposio anual de la ACM/IEEE sobre lógica en ciencias de la computación (LICS) . pp. 1–10. arXiv : 1601.01233 . doi :10.1145/2603088.2603105. ISBN . 9781450328869. Número de identificación S2CID  11485010.
  37. ^ ab Accattoli, Beniamino (octubre de 2018). "(In)Eficiencia y modelos de costos razonables". Notas electrónicas en informática teórica . 338 : 23–43. doi : 10.1016/j.entcs.2018.10.003 .
  38. ^ ab Asperti, Andrea (16 de enero de 2017). "Acerca de la reducción eficiente de términos lambda". arXiv : 1701.04240v1 [cs.LO].
  39. ^ Landin, PJ (1965). "Una correspondencia entre ALGOL 60 y la notación Lambda de Church". Comunicaciones de la ACM . 8 (2): 89–101. doi : 10.1145/363744.363749 . S2CID  6505810.
  40. ^ Scott, Dana (1993). "Una alternativa de teoría de tipos a ISWIM, CUCH, OWHY" (PDF) . Theoretical Computer Science . 121 (1–2): 411–440. doi :10.1016/0304-3975(93)90095-B . Consultado el 1 de diciembre de 2022 .Escrito en 1969, ampliamente difundido como manuscrito inédito.
  41. ^ "Página de inicio de Greg Michaelson". Ciencias matemáticas y de la computación . Riccarton, Edimburgo: Universidad Heriot-Watt . Consultado el 6 de noviembre de 2022 .

Enlaces externos