Ordenar una lista de números en el cálculo λ


8

Escriba un término en el cálculo lambda puro sin tipo que, cuando se aplica a una lista de números codificada por la iglesia , lo devuelve con sus números ordenados en orden ascendente o descendente. Las listas y los números de la iglesia deben codificarse como pliegues para sus ADT habituales:

-- Usual ADTs for Lists and Nats (in Haskell, for example)
data List a = Cons a (List a) | Nil
data Nat a  = Succ (Nat a) | Zero

-- Their respective folds are the λ-calculus representation used on this challenge
church_list = (λ c n . (c ... (c ... (c ... n))))
church_num  = (λ succ zero . (succ (succ (succ ... zero))))

Entrada de ejemplo:

(λ cons nil .
    (cons (λ f x . (f x))                         -- 1
    (cons (λ f x . (f (f (f (f (f (f (f x)))))))) -- 7
    (cons (λ f x . (f (f x)))                     -- 2
    (cons (λ f x . (f (f (f x))))                 -- 3
    nil)))))

Salida de ejemplo:

(λ cons nil . 
    (cons (λ f x . (f x))                         -- 1
    (cons (λ f x . (f (f x)))                     -- 2
    (cons (λ f x . (f (f (f x))))                 -- 3
    (cons (λ f x . (f (f (f (f (f (f (f x)))))))) -- 7
    nil)))))

La puntuación de una presentación se calculará de la siguiente manera:

score(x)    = 1
score(λx.t) = score(t) + 1
score(t s)  = score(t) + score(s) + 1

La puntuación más baja gana.


77
La página vinculada proporciona tres codificaciones diferentes de la Iglesia para listas, y no hay nada que impida que cambie en el futuro. Para que la pregunta sea inequívoca, deberá definir la codificación particular que tiene en mente explícitamente en la pregunta. (También sería recomendable definir la codificación de los números).
Peter Taylor

1
orden ascendente o descendente : ¿por qué podemos elegir?
Lynn

Simplemente no encontré una razón para limitarlo. Por qué no?
MaiaVictor

Respuestas:


3

He logrado superar mi propia marca:

sort = λabcd.a(λef.f(λghi.g(λj.h(λkl.kj(ikl)))(hi))e(λgh.h))
       (λe.d)(λe.b(λf.e(f(λghi.hg)(λgh.cfh))))

Sin embargo, hay una advertencia: este término debe recibir un argumento adicional con el tamaño máximo de los productos naturales que se consideran. Por ejemplo, sort 4 [1,7,3,6,5]volverá [1,3], ignorando cualquier cosa anterior o igual a 4. Por supuesto, podría dar infinito (es decir, el combinador Y):

sort = λbcd.(λfx.f(x x))(λfx.f(x x))(λef.f(λghi.g(λj.h(λkl.kj(ikl)))
       (hi))e(λgh.h))(λe.d)(λe.b(λf.e(f(λghi.hg)(λgh.cfh))))

Y ordenaría cualquier lista de números naturales, pero este término obviamente ya no tiene una forma normal.


1

121 caracteres / puntuación 91

sort = λabc.a(λdefg.f(d(λhij.j(λkl.k(λmn.mhi)l)(h(λkl.l)i))
       (λhi.i(λjk.bd(jhk))(bd(h(λjk.j(λlm.m)k)c))))e)(λde.e)
       (λde.d(λfg.g)e)c

Está en forma normal y podría acortarse levantando subexpresiones comunes.


1

Aquí hay una implementación de un tipo de inserción:

let nil =       \f x.x in
let cons = \h t.\f x.f h (t f x) in
let 0 =       \f x.x in
let succ = \n.\f x.f (n f x) in
let None =    \a b.b in
let Some = \x.\a b.a x in
let pred = \n.n (\opt.opt (\m.Some(succ m)) (Some 0)) None in
let optpred = \opt.opt pred None in
let - = \m n.n optpred (Some m) in
let < = \m n.\trueval falseval.- m n (\diff.falseval) trueval in
let pair = \x y.\f.f x y in
let snd = \p.p (\x y.y) in
let insert = \n l.snd (l (\h recpair.recpair (\rawtail insertedtail.
  let rawlist = cons h rawtail in
    pair rawlist (< h n (cons h insertedtail) (cons n rawlist))))
  (pair nil (cons n nil))) in
\l.l insert nil

Aquí, pred ndevuelve un elemento de option nat: pred 0es Nonemientras que pred (n+1)es Some n. Luego, - m ndevuelve un elemento option natcuyo es Some (m-n)if m>=no Noneif m<n; y < m ndevuelve un booleano. Finalmente, insertutiliza una función interna que devuelve un par donde f l = (l, insert n l)(un método bastante típico para obtener el final de la lista para pasar a la recursión junto con el valor recursivo).

Ahora, algunas notas para futuros trabajos de golf: en realidad nil, 0, Noneresultan ser la misma función formalmente (y que también aparece en snd). Entonces, ciertamente consideraría hacer reducciones beta en las letdeclaraciones (que es, por supuesto, el azúcar sintáctico habitual donde let a = x in ysignifica (\a.y)xy, por lo tanto, tiene puntaje score(x) + score(y) + 2) para ver en qué casos hacerlo reduciría el puntaje, lo que definitivamente sería para los enlaces que son Solo se usa una vez.

Luego vendrían las cosas más difíciles: por ejemplo, me he dado cuenta de que formalmente pred = pair (pair (\m.Some(succ m)) (Some 0)) None, optpred = pair pred None, - = \m.pair optpred (Some m), la definición de función especie asciende a pair insert nil, etc., que podrían reducir ligeramente la puntuación.


Calcule su puntaje y dígalo en la respuesta
Nathaniel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.