Verwenden Sie arithmetische Operatoren als Tupelkonstruktoren und Konsolenpaare
Wenn Sie eine einzelne Struktur übergeben müssen, die aus zwei oder mehr Werten besteht, sollten Sie am besten eine Liste verwenden, z [A,B]
. Das ist allerdings sehr ausführlich.
Es gibt eine Alternative. Prolog-Werte können eine ziemlich willkürliche verschachtelte Struktur speichern, die nicht ausgewertet wird. Hier ist ein Beispiel, wie das funktioniert:
| ?- member(member(A,B),C).
C = [member(A,B)|_] ? ;
C = [_,member(A,B)|_] ? ;
(etc.)
member(A,B)
ist in dieser Situation nur ein benanntes Tupel, und das Äußere member
(das ein Funktionsaufruf ist) behandelt es als solches.
Auch wenn benannte Tupel in der Programmierung mit Prolog ohne Golfspiel ziemlich nützlich sind, scheinen sie möglicherweise noch ausführlicher zu sein als der Listenansatz. Wir können jedoch im Namen des Tupelkonstruktors ziemlich beliebige Zeichen verwenden (vorausgesetzt, sie werden korrekt in Anführungszeichen gesetzt). Anstelle von so etwas Süßem member
oder einem einzelnen Charakter a
können wir so etwas machen:
| ?- A = '-'('/'(1,2), '/'(3,4)).
A = 1/2-3/4
Hier sind '-'
und unsere Tupelkonstrukteure '/'
. Und es ist interessant zu sehen, was der hübsche Drucker mit ihnen gemacht hat. Für die Tupel wird die Infixnotation verwendet. Dies ist wirklich knapp und analysiert auf die gleiche Weise wie die vergleichbare arithmetische Operation. (Dies erklärt auch, warum Arithmetik is
nicht verwendet wird =
; A = 1+2
würde sich A
mit dem Tupel vereinigen '+'(1,2)
, so dass eine separate Syntax erforderlich ist, um den nicht bewerteten arithmetischen Ausdruck tatsächlich auszuwerten.) Da ein Tupelkonstruktor etwas aufgerufen werden muss , können Sie auch ein Zeichen verwenden, das eine Knappheit aufweist Syntax (und als Bonus -
und/
Dies sind auch einige der am häufigsten verwendeten Optionen in nicht-golfenem Code, wenn ein schneller Tupelkonstruktor anstelle eines aussagekräftigen Konstruktors verwendet werden soll, ähnlich wie dies i
häufig als Schleifenvariable verwendet wird Eingabe und Ausgabe, wenn Sie aus irgendeinem Grund ein Tupel dort haben wollen).
'-'
und '/'
sind eine gute Wahl für Tupelkonstruktoren, da sie einen guten und nützlichen Vorrang haben und es Ihnen ermöglichen, Tupel-Literale kurz zu schreiben. Beachten Sie jedoch, dass Sie sich keine Gedanken über die Priorität machen müssen, wenn im Programm Zwischenwerte erstellt werden. Prolog speichert die Tupel nicht als Quellcode, sondern als Baum. Hübsche Drucker können sie eindeutig ausgeben:
| ?- A = '-'('-'(1,2), '-'(3,4)).
A = 1-2-(3-4)
Da die Tupelsyntax so kurz f(A,B)
ist ( nicht kürzer als f(A-B)
), können Sie mehrere Prädikatsargumente kostenlos durch Tupel ersetzen. Wenn also ein Prädikat zwei oder mehr seiner Argumente an ein anderes Prädikat übergeben muss, können Sie sie häufig in Form bringen ein Tupel und übergeben Sie einfach das Tupel (obwohl dies erfordert, dass alle Aufrufe des Prädikats zusätzlich zum Prädikat selbst geändert werden, um eine geeignete Mischung aus Tupelkonstruktoren und Kommas zu verwenden).
Ein weiterer Vorteil dieser Syntax besteht darin, dass Sie Listen intern verwenden müssen (anstatt mit Standardprädikaten zusammenzuarbeiten). Eine Liste besteht im Grunde genommen nur aus verschachtelten Konsolenzellen, und eine Konsolenzelle ist nur ein Tupel mit Konstruktor '.'
, wie hier zu sehen ist:
| ?- Q = '.'('.'(A,B),'.'(C,D)).
Q = [[A|B],C|D]
Wenn Ihr Code Listen "manuell" verwendet, kann es sehr sinnvoll sein, einen weniger umfangreichen Tupelkonstruktor als zu verwenden '.'
. Eine häufige Wahl für mich ist die Darstellung einer Nachteile-Zelle als '/'(Tail,Head)
(da es sich um die am besten lesbare handelt, die Sie in der Debug-Ausgabe erhalten können, ohne Zeichen zu verschwenden). Beachten Sie, dass Sie wahrscheinlich auch Ihr eigenes []
Äquivalent haben möchten . Sie könnten es verwenden, []
aber es ist zwei Bytes lang und es gibt viele Ein-Byte-Atome (alle Kleinbuchstaben), die Sie stattdessen verwenden können.
So zum Beispiel die folgende Liste:
[1,2,3]
könnte in eine manuelle Darstellung mit der gleichen Anzahl von Zeichen wie folgt umgewandelt werden:
x/3/2/1
[H|T]
Dies bringt den Vorteil mit sich, dass Übereinstimmungen im Stil von Mustern jetzt enger T/H
und ein Test mit der leeren Liste x
eher als mit der längeren Liste geschrieben werden können []
. (Natürlich kommt dies mit dem offensichtlichen Nachteil , dass member
, append
usw., wird nicht auf dieser Darstellung arbeiten.)
prolog
Tag ist irgendwie nutzlos. Solange wir keine Interpret Prolog-Herausforderung haben, brauchen wir sie nicht.