Claro, este es un ejercicio de codificación estándar.
En primer lugar, deje que cualquier función computable biyectiva, llamada función de emparejamiento. Una opción estándar esp : N2→ N
p ( n , m ) = ( n + m ) ( n + m + 1 )2+ n
Se puede demostrar que se trata de una biyección, por lo tanto, dada cualquier natural , podemos calcular tal que .n , m p ( n , m ) = kkn , mp ( n , m ) = k
Para enumerar los términos lambda, arregle cualquier enumeración para nombres de variables: .X0 0, x1, x2, ...
Luego, para cada número natural , imprima , definido recursivamente de la siguiente manera:l a m b d a ( i )yol a m b da ( i )
- si es par, dejemos que y variablej = i / 2 x jyoj = i / 2Xj
- si es impar, dejemos quej = ( i - 1 ) / 2yoj = ( i - 1 ) / 2
- si es par, deje y encuentre tal que ; calcular ; solicitud de devoluciónk = j / 2 n , m p ( n , m ) = k N = l a m b d a ( n ) , M = l a m b d a ( m ) ( N M )jk = j / 2n , mp ( n , m ) = knorte= l a m b da ( n ) , M= l a m b da ( m )( NMETRO)
- si es impar, deje y encuentre tal que ; calcular ; abstracción de retornojk = ( j - 1 ) / 2n , mp ( n , m ) = kMETRO= l a m b da ( m )( λ xnorte. METRO )
Este programa está justificado por la siguiente biyección "algebraica" que involucra el conjunto de todos los términos lambda :Λ
Λ ≃ N + ( Λ2+ N × Λ )
que se lee como "los términos lambda, sintácticamente, son la unión disjunta de 1) variables (representadas como naturales), 2) aplicaciones (hechas por dos términos lambda) y 3) abstracción (un par variable / natural + término lambda ) ".
Dado eso, aplicamos recursivamente biyecciones computables ( ) y (el estándar par / impar) para obtener el algoritmo anterior.norte2≃ NpagsN + N ≃ N
Este procedimiento es general y funcionará en casi cualquier lenguaje generado a través de una gramática libre de contexto, que proporcionará un isomorfismo similar al anterior.
if n%2==0 ...
Si. Tome algo que enumere todas las cadenas ASCII posibles. Para cada salida, verifique si es una sintaxis válida de cálculo lambda que define una función; si no, sáltatelo. (Se puede hacer esa verificación). Enumera todas las funciones de cálculo lambda.
fuente
Como se ha mencionado, esto es solo enumerar términos de un lenguaje libre de contexto, por lo que definitivamente es factible. Pero hay más matemáticas interesantes detrás de esto, entrando en el campo de la combinatoria analítica.
El papel Contar y generar términos en el cálculo lambda binario contiene un tratamiento del problema de enumeración y mucho más. Para simplificar las cosas, usan algo llamado binario lambda calulus , que es solo una codificación de términos lambda usando índices de De Bruijn , por lo que no tiene que nombrar variables.
Ese documento también contiene código concreto de Haskell que implementa su algoritmo de generación. Definitivamente es efectivamente posible.
Resulta que escribí una implementación de su enfoque en Julia.
fuente
Seguro. Podemos generarlos directamente de acuerdo con la definición de términos lambda.
En Haskell, primero definimos el tipo de datos,
y luego con el uso de un justo (er)
join
,simplemente los enumeramos, por ejemplo
fjoin
es equivalente a Omega mónada 'sdiagonal
.fuente
Me he encontrado con una herramienta en línea que puede generar cadenas de muestra a partir de una expresión regular: https://www.browserling.com/tools/text-from-regex . Puede generar muchos términos lambda de muestra ingresando algo como esto:
Por supuesto, para obtener términos con niveles arbitrarios de anidamiento, necesitará usar una gramática libre de contexto, que es una herramienta más descriptiva para definir un lenguaje que una expresión regular. No he encontrado una herramienta existente para generar oraciones de lenguaje de muestra basadas en una definición gramatical sin contexto, pero no hay razón para que no se pueda construir.
fuente