Der SKI-Kalkül ist eine Variante des Lambda-Kalküls, die keine Lambda-Ausdrücke verwendet. Stattdessen werden nur application und die Kombinatoren S , K und I verwendet. In dieser Herausforderung besteht Ihre Aufgabe darin, SKI-Begriffe in β-Normalform in Lambda-Begriffe zu übersetzen .
Eingangsspezifikation
Die Eingabe ist ein SKI-Begriff in der folgenden Textdarstellung. Sie können sich dafür entscheiden, eine optionale nachgestellte Zeile zu erhalten. Die Eingabe wird von den Zeichen zusammengesetzt ist S
, K
, I
, (
, und , )
und erfüllt die folgende Grammatik (in ABNF Form) zusammen mit sterm
dem Startsymbol ist durch :
sterm = sterm combinator ; application
sterm = combinator ;
sterm = '(' sterm ')' ; grouping
combinator = 'S' | 'K' | 'I' ; primitives
Ausgangsspezifikation
Die Ausgabe ist ein Lambda-Term ohne freie Variablen in der folgenden Textdarstellung. Sie können eine optionale nachgestellte Newline ausgeben. Die Ausgabe muss der folgenden Grammatik in ABNF-Form lterm
als Startsymbol entsprechen:
lterm = lterm operand ; application
lterm = ALPHA '.' lterm ; lambda
lterm = operand
operand = '(' lterm ')' ; grouping
operand = ALPHA ; variable (a letter)
Einschränkungen
Sie können davon ausgehen, dass die Eingabe eine β-Normalform hat. Sie können davon ausgehen, dass die β-Normalform höchstens 26 verschiedene Variablen verwendet. Sie können davon ausgehen, dass sowohl Eingabe als auch Ausgabe in 79 Zeichen darstellbar sind.
Beispieleingaben
Hier sind einige Beispieleingaben. Die Ausgabe ist eine mögliche Ausgabe für die angegebene Eingabe.
input output
I a.a
SKK a.a
KSK a.b.c.ac(bc)
SII a.aa
Wertung
Die kürzeste Lösung in Oktetten gewinnt. Gemeinsame Schlupflöcher sind verboten.
sterm
undlterm
Linksassoziativität verwenden, wenn Klammern fehlen.SKI
alsS(KI)
.Antworten:
Haskell , 232 Bytes
Probieren Sie es online!
Wie es funktioniert
Dies ist ein anderes Parser-Frontend als meine Antwort auf "Schreibe einen Interpreter für den untypisierten Lambda-Kalkül" , der auch eine ungolfed-Version mit Dokumentation enthält.
Kurz gesagt,
Term = T (Char -> String)
ist die Art der Lambda-Kalkül-Terme, die wissen, wie sie sich auf andere Terme anwenden (a :: Term -> Term -> Term
) und wie sie sich alsString
((%) :: Term -> Char -> String
) darstellen, eine anfängliche frische Variable als gegebenChar
. Wir können eine Funktion für Terme in einen Term mit konvertierenl :: (Term -> Term) -> Term
, und da die Anwendung des resultierenden Terms einfach die function (a (l f) == f
) aufruft , werden Terme bei der Anzeige automatisch auf die normale Form reduziert.quelle
Ruby, 323 Bytes
Ich kann nicht glauben, dass dieses Stück Mist überhaupt funktioniert:
Die Verwendung der Regex-Substitution zur Durchführung der β-Reduktion an rohen Saiten ist eine Sache von Tony-the-Pony. Dennoch sieht die Ausgabe zumindest für einfache Testfälle korrekt aus:
Hier ist die Handhabung
K(K(K(KK)))
mit einer Debug-Ausgabe, die auf meinem Laptop etwa 7 Sekunden dauert, da die Rekursion von regulären Ausdrücken langsam ist . Sie können die α-Umwandlung in Aktion sehen!quelle
Python 2, 674
Hinweis: nach
while 1:
werden 3 Zeilen mit einem Tabulatorzeichen eingerückt.Dies ist im Grunde der Code hinter http://ski.aditsu.net/ , übersetzt in Python, stark vereinfacht und stark golfen.
Referenz: (Dies ist wahrscheinlich weniger nützlich, da der Code jetzt komprimiert ist.)
V = variable Term
A = application Term
L = Lambda Begriff
c = variable Zähler
p = ersetzen Variable mit Term
r = reduzieren
m = final variable Umnummerieren
u interne Variable = Umnummerieren (für duplizierten Bedingungen)
s = string Umwandlung
(Parameter s = self)
C = Trennzeichen für die String-Konvertierung
I, K, S: Kombinatoren
E = parsen
Beispiele:
(Dieses ↑ wird erwartet, weil
SII(SII)
es nicht reduzierbar ist.)Vielen Dank an Mauris und Sp3000, die geholfen haben, ein paar Bytes zu töten :)
quelle
def m(a,b,c):return foo
inm=lambda a,b,c:foo
auch innerhalb von Klassen, die Ihnen viele Bytes könnten speichern.a.b.c.a(c)(b(c))
als gültiger Lambda-Ausdruck lesen : Was ist das(c)
?Common Lisp, 560 Bytes
"Endlich habe ich eine Verwendung für gefunden
PROGV
."Ungolfed
Beta-Reduktion
Variablen werden beim Reduzieren dynamisch mit
PROGV
neuen Common-Lisp-Symbolen verknüpftMAKE-SYMBOL
. Dadurch können Namenskollisionen (zB unerwünschtes Abschatten gebundener Variablen) vermieden werden. Ich hätte es gebrauchen könnenGENSYM
, aber wir möchten benutzerfreundliche Namen für Symbole haben. Deshalb werden Symbole mit Buchstaben von abis benannt z(wie in der Frage erlaubt).N
Stellt den Zeichencode des nächsten verfügbaren Buchstabens im aktuellen Bereich dar und beginnt mit 97, akaa .Hier ist eine besser lesbare Version von
R
(ohne dasW
Makro):Zwischenergebnisse
Analysieren von Zeichenfolge:
Reduzieren:
(Siehe Hinrichtungsspur)
Pretty-Print:
Tests
Ich verwende dieselbe Testsuite wie die Python-Antwort:
Das 8. Testbeispiel ist zu groß für die obige Tabelle:
a.a.a.a.a.b.a
korrekt ist und nicht so viele Buchstaben wie die Python Antwort zu verwenden, wo Bindungena
,b
,c
undd
sind nicht referenziert.Performance
Das Durchlaufen der oben genannten 7 bestandenen Tests und das Sammeln der Ergebnisse erfolgt sofort (SBCL-Ausgabe):
Hundertmaliges Durchführen desselben Tests hat zur Folge, dass der lokale Thread-Speicher in SBCL aufgrund einer bekannten Einschränkung in Bezug auf spezielle Variablen erschöpft ist. Mit CCL dauert das 10000-malige Aufrufen derselben Testsuite 3,33 Sekunden.
quelle