Curry (Programmiersprache)

Curry ist eine experimentelle funktionelle Logikprogrammiersprache, die auf der Sprache von Haskell gestützt ist. Es verschmilzt Elemente der funktionellen und Logikprogrammierung einschließlich der Einschränkungsprogrammierintegration.

Es ist fast eine Obermenge von Haskell, an Unterstützung größtenteils Mangel habend, um Verwenden-Typ-Klassen zu überladen, die einige Durchführungen irgendwie als eine Spracherweiterung wie der Münsterer Curry-Bearbeiter zur Verfügung stellen.

Fundamente der funktionellen Logikprogrammierung

Grundlegende Konzepte

Ein funktionelles Programm ist eine Reihe von Funktionen, die durch Gleichungen oder Regeln definiert ist. Eine funktionelle Berechnung besteht daraus, Subausdrücke durch den gleichen (hinsichtlich der Funktionsdefinitionen) Subausdrücke zu ersetzen, bis kein Ersatz mehr (oder die Verminderungen) möglich ist und ein Wert oder normale Form erhalten wird. Betrachten Sie zum Beispiel die Funktion als doppelt definiert durch

verdoppeln Sie x = x+x

Der Ausdruck "" wird dadurch ersetzt. Die Letzteren können dadurch ersetzt werden, wenn wir den Maschinenbediener "" interpretieren, um durch einen unendlichen Satz von Gleichungen z.B usw. definiert zu werden. Auf eine ähnliche Weise kann man verschachtelte Ausdrücke bewerten (wo der zu ersetzende Subausdruck angesetzt wird):

'doppelt (1+2)' ' (1+2)' + (1+2)  3 + '(1+2)'  '3+3'  6

Es gibt auch eine andere Ordnung der Einschätzung, wenn wir die Argumente von Maschinenbedienern vom Recht bis linken ersetzen:

'doppelt (1+2)'  (1+2) + '(1+2)' ' (1+2)' +3  '3+3'  6

In diesem Fall führen beide Abstammungen zu demselben Ergebnis, ein als Zusammenfluss bekanntes Eigentum. Das folgt aus einem grundsätzlichen Eigentum von reinen funktionellen Sprachen, hat Verweisungsdurchsichtigkeit genannt: Der Wert eines geschätzten Ergebnisses hängt von der Ordnung oder Zeit der Einschätzung wegen der Abwesenheit von Nebenwirkungen nicht ab. Das vereinfacht das Denken über und die Wartung von reinen funktionellen Programmen.

Funktionelle Logikprogramme sind jedoch nicht immer Verweisungs-durchsichtig. Zusammengefasste Suchen können von der Ordnung der Einschätzung abhängen.

Da funktionelle Sprachen wie Haskell tun, unterstützt Curry die Definition von algebraischen Datentypen durch das Aufzählen ihrer Konstrukteure. Zum Beispiel besteht der Typ von Werten von Boolean aus den Konstrukteuren, und die wie folgt erklärt werden:

Daten Bool = Wahr | Falscher

Funktionen auf Booleans können durch das Muster-Zusammenbringen, d. h., durch die Versorgung mehrerer Gleichungen für verschiedene Argument-Werte definiert werden:

nicht Wahr = Falscher

nicht Falsch = Wahrer

Der Grundsatz des Ersetzens ist dadurch gleich ist gleich ist noch gültig vorausgesetzt, dass die wirklichen Argumente die erforderliche Form z.B haben:

nicht' (nicht Falsch)'  'nicht Wahr'  Falscher

Kompliziertere Datenstrukturen können durch rekursive Datentypen erhalten werden. Zum Beispiel, eine Liste von Elementen, wo der Typ von Elementen willkürlich ist (angezeigt durch

die Typ-Variable), ist entweder die leere Liste "" oder die nichtleere Liste, "" aus einem ersten Element und einer Liste bestehend

Datenliste = [] | a: Verzeichnen Sie einen

Der Typ "" wird gewöhnlich als geschrieben, und begrenzte Listen e1e2... werden en als e1e2... en geschrieben. Wir können Operationen auf rekursiven Typen durch induktive Definitionen wo Muster definieren, das Unterstützungen die günstige Trennung der verschiedenen Fälle vergleicht. Zum Beispiel kann die Verkettungsoperation "" auf polymorphen Listen wie folgt definiert werden (die fakultative Typ-Behauptung in der ersten Linie gibt an, dass "" zwei Listen als Eingang nimmt und eine Produktionsliste erzeugt, wo alle Listenelemente desselben unangegebenen Typs sind):

(++)::->-> [ein]

[] ++ ys = ys

(x:xs) ++ ys = x: xs ++ ys

Außer seiner Anwendung für verschiedene Programmieraufgaben ist die Operation "" auch nützlich, um das Verhalten anderer Funktionen auf Listen anzugeben. Zum Beispiel kann das Verhalten einer letzten Funktion, der das letzte Element einer Liste nachgibt, wie folgt angegeben werden: für alle Listen l und Elemente e, l = e iff xsxse = l.

Gestützt auf dieser Spezifizierung kann man eine Funktion definieren, die diese Spezifizierung durch die Beschäftigung von Logikprogrammiereigenschaften befriedigt. Ähnlich in Logiksprachen stellen funktionelle Logiksprachen Suche nach Lösungen für existenziell gemessene Variablen zur Verfügung. Im Gegensatz zu reinen Logiksprachen unterstützen sie das Gleichungslösen über verschachtelte funktionelle Ausdrücke, so dass eine Gleichung wie xse = durch das Realisieren xs zur Liste und e zum Wert gelöst wird. Im Curry kann man die Operation letzt wie folgt definieren:

letzter l | xs ++ [e] =: = l = e wo xs, e freier

Hier wird das Symbol "" für equational Einschränkungen verwendet, um eine syntaktische Unterscheidung davon zur Verfügung zu stellen, Gleichungen zu definieren. Ähnlich werden Extravariablen (d. h., Variablen, die nicht in der linken Seite der Definieren-Gleichung vorkommen), durch "" ausführlich erklärt, um einige Gelegenheiten zur Verfügung zu stellen, durch Druckfehler verursachte Programmfehler zu entdecken. Eine bedingte Gleichung der Form l c r ist für die Verminderung anwendbar, wenn seine Bedingung c gelöst worden ist. Im Gegensatz zu rein funktionellen Sprachen, wo Bedingungen nur zu einem Wert von Boolean bewertet werden, unterstützen funktionelle Logiksprachen das Lösen von Bedingungen durch das Schätzen von Werten für den unknowns in der Bedingung. Wie besprochen, in der folgenden Abteilung schmäler zu werden, wird verwendet, um diese Art von Bedingungen zu lösen.

Das Einengen

Das Einengen ist ein Mechanismus, wodurch eine Variable zu einem Wert gebunden wird, der aus der Zahl von durch Einschränkungen auferlegten Alternativen ausgewählt ist. Jeder mögliche Wert wird in einer Ordnung mit dem Rest des in jedem Fall angerufenen Programms versucht, um die Gültigkeit der Schwergängigkeit zu bestimmen. Das Einengen ist eine Erweiterung der Logikprogrammierung, in der es eine ähnliche Suche durchführt, aber wirklich Werte als ein Teil der Suche erzeugen kann, anstatt gerade auf die Prüfung von ihnen beschränkt zu werden.

Das Einengen ist nützlich, weil es einer Funktion erlaubt, als eine Beziehung behandelt zu werden: Sein Wert kann "in beiden Richtungen" geschätzt werden. Die Curry-Beispiele der vorherigen Abteilung illustrieren das.

Wie bemerkt, in der vorherigen Abteilung kann vom Einengen als die Verminderung auf einem Programm-Begriff-Graphen gedacht werden, und es gibt häufig viele verschiedene Wege (Strategien), einen gegebenen Begriff-Graphen zu reduzieren. Antoy. hat in den 1990er Jahren bewiesen, dass eine besondere schmäler werdende Strategie, das erforderliche Einengen, im Sinne des Tuns mehrerer Verminderungen optimal ist, um zu einer "normalen Form" entsprechend einer Lösung zu kommen, die unter dem Ton und den ganzen Strategien minimal ist. Das erforderliche Einengen entspricht einer faulen Strategie im Gegensatz zur SLD-Entschlossenheitsstrategie der Einleitung.

Links


Bernard Bolzano / Darstellung von Adjoint einer Lüge-Gruppe
Impressum & Datenschutz