Sortieren Sie eine Liste von Zahlen auf dem λ-Kalkül


8

Schreiben Sie einen Begriff auf den reinen untypisierten Lambda-Kalkül, der, wenn er auf eine kirchenkodierte Liste von Zahlen angewendet wird , ihn mit aufsteigenden oder absteigenden Zahlen zurückgibt. Kirchenlisten und -nummern müssen für ihre üblichen ADTs als Falten codiert werden:

-- 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))))

Beispieleingabe:

(λ 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)))))

Beispielausgabe:

(λ 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)))))

Die Punktzahl einer Einreichung wird wie folgt berechnet:

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

Die niedrigste Punktzahl gewinnt.


7
Die verlinkte Seite enthält drei verschiedene Kodierungen der Kirche für Listen, und nichts hindert sie daran, sich in Zukunft zu ändern. Damit die Frage eindeutig ist, müssen Sie die bestimmte Codierung, die Sie in der Frage berücksichtigen, explizit definieren. (Es wäre auch ratsam, die Kodierung der Zahlen zu definieren).
Peter Taylor

1
aufsteigende oder absteigende Reihenfolge - warum dürfen wir wählen?
Lynn

Ich habe einfach keinen Grund gefunden, es einzuschränken. Warum nicht?
MaiaVictor

Antworten:


3

Ich habe es geschafft, meine eigene Marke zu übertreffen:

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))))

Es gibt jedoch eine Einschränkung - dieser Begriff muss ein zusätzliches Argument mit der maximalen Größe der berücksichtigten Naturtöne erhalten. Zum Beispiel sort 4 [1,7,3,6,5]wird zurückkehren [1,3]und alles über oder gleich 4 ignorieren. Natürlich könnten Sie einfach unendlich geben (dh den Y-Kombinator):

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))))

Und es würde jede Liste natürlicher Zahlen sortieren, aber dieser Begriff hat offensichtlich keine normale Form mehr.


1

121 Zeichen / Punktzahl 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

Es ist in normaler Form und könnte durch Anheben gängiger Unterausdrücke verkürzt werden.


1

Hier ist eine Implementierung einer Einfügesortierung:

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

Hier wird pred nein Element von option nat: pred 0is zurückgegeben, Nonewährend pred (n+1)is Some n. Dann - m nkehrt ein Element option natdavon ist , Some (m-n)ob m>=noder Noneob m<n; und < m ngibt einen Booleschen Wert zurück. Schließlich insertverwendet eine interne Funktion ein Paar , wo der Rückkehr f l = (l, insert n l)(ein recht typisches Verfahren das Ende der Liste zu bekommen , um die Rekursion weitergegeben werden zusammen mit dem rekursiven Wert).

Nun werden einige Hinweise für die künftige Golf - Arbeit: tatsächlich nil, 0, Nonepassieren die gleiche Funktion sein , formal (und es scheint auch in snd). Dann würde ich sicherlich in Betracht ziehen, Beta-Reduzierungen an den letAussagen vorzunehmen (was natürlich der übliche syntaktische Zucker ist, wo dies let a = x in ybedeutet (\a.y)xund somit Punktzahl hat score(x) + score(y) + 2), um zu sehen, in welchen Fällen dies die Punktzahl reduzieren würde - was es definitiv für die Bindungen wäre, die sind nur einmal verwendet.

Dann kommen würde trickier Dinge: zum Beispiel, ich habe gerade bemerkt , dass formal pred = pair (pair (\m.Some(succ m)) (Some 0)) None, optpred = pair pred None, - = \m.pair optpred (Some m), die Sortierfunktion Definition beträgt pair insert nil, usw. , welche die Partitur etwas reduzieren könnte.


Bitte berechnen Sie Ihre Punktzahl und geben Sie sie in der Antwort an
Nathaniel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.