Wie bekomme ich die Summe der gegebenen Zahlen in Prolog?

8

Ich bin neu im Prolog und mache einige Übungen zur Übung. Also versuche ich die Summe der angegebenen Zahlen in eine Liste zu bekommen. Ich versuche das zu benutzen:

%Vor%

( hier )

als mein Führer. Also das ist mein Code für die Summe:

%Vor%

wenn ich es kompiliere, heißt es

  

practice.pl:3: auswertbar listsum(_G139,_G140) existiert nicht   practice.pl:2: Singleton-Variablen: [X]

Wenn ich listsum(0, [1,2,3]). versuche, gibt es false zurück.

Ich verstehe immer noch nicht viel über Prolog und Liste und Rekursion in Prolog.

    
Zik 17.07.2012, 10:28
quelle

2 Antworten

24

Arithmetik

Wie Sie bereits festgestellt haben, kann die Arithmetik in Prolog mit dem Operator (is)/2 gehandhabt werden. Das liegt daran, dass in Prolog alles nur ein symbolischer Kalkül ist: Dinge haben standardmäßig keine Bedeutung, daher würde die Vereinheitlichung (=)/2 nicht wissen, dass sich (+)/2 beispielsweise auf den Zusatz bezieht.

Ihr Problem besteht nun darin, dass Sie innerhalb von (is)/2 ein reguläres Prädikat verwenden (hier ist es Ihr rekursiver Aufruf). Da (is)/2 nur arithmetisch arbeitet, wird der Prädikatsaufruf nicht ausgewertet. Es erkennt es nicht einmal, da es keine arithmetische Funktion ist.

Die Lösung hier wäre, das Ergebnis des rekursiven Aufrufs einer Variablen zu beeinflussen und sie dann im Aufruf (is)/2 zu verwenden:

%Vor%

Grundlegende Korrektheit

Aber wenn Sie diesen Code testen, erhalten Sie nicht das gewünschte Ergebnis. Der Grund ist, dass Sie in Ihrem Basisfall ein anderes Problem haben. Die Summe der leeren Liste ist nicht "irgendwas", wie du es schriftlich feststellst

%Vor%

( X ist eine freie Variable, daher kann alles sein).

Stattdessen ist es 0 :

%Vor%

Der resultierende Code lautet:

%Vor%

Reihenfolge der Argumente

Als Nebenbemerkung ist in Prolog eine Konvention, dass die Ausgabevariablen am Ende des Prädikats stehen sollten, während die Eingabevariablen am Anfang des Prädikats stehen sollten. Um sich wie gewünscht zu verhalten, könnten wir wie folgt umgestalten:

%Vor%

Tail Call Optimierung

Jetzt können wir dieses Prädikat mit fortgeschrittenen Techniken noch verbessern. Zum Beispiel könnten wir Tail-Calls einführen, so dass Tail Call Optimization (googlable) ausgeführt werden kann, dank eines Idioms der deklarativen Programmierung, das Akkumulator genannt wird:

%Vor%

Die Idee dahinter ist, ein Zwischenergebnis bei jedem Schritt der Rekursion zu aktualisieren (indem man den Wert des aktuellen Kopfs der Liste hinzufügt) und dann einfach angibt, dass dieser Zwischenwert der letzte ist, wenn die Liste leer ist Wert.

Allgemeinere Programme bekommen

Wie Sie vielleicht in Prolog bemerkt haben, können Prädikate ziemlich oft auf verschiedene Arten verwendet werden. Zum Beispiel kann length/2 verwendet werden, um die Länge einer Liste zu ermitteln:

%Vor%

oder um eine Skelettliste mit freien Variablen einer gewünschten Länge zu erstellen:

%Vor%

Hier haben Sie vielleicht bemerkt, dass Sie Prolog nicht fragen können, welche Listen eine Summe haben, die 6 ist:

%Vor%

Das liegt daran, dass Prolog, um rückwärts gehen zu können, eine Gleichung lösen müsste, wenn der Operator (is)/2 aufgerufen wird. Und während Ihrs einfach ist (nur Additionen), ist die Arithmetik im allgemeinen Fall nicht so lösbar.

Um dieses Problem zu überwinden, kann Constraint-Programmierung verwendet werden. Eine sehr schöne Bibliothek ist für SWI, clpfd verfügbar.

Die Syntax wäre hier:

%Vor%

Jetzt können wir unser Prädikat auf diese andere Weise verwenden, wie wir es gerne hätten:

%Vor%

Wir könnten sogar nach allen Lösungen für das Problem fragen:

%Vor%

Ich habe das nur erwähnt, damit Sie erkennen, dass die Verwendung von (is)/2 ziemlich oft vermieden werden sollte und die Verwendung von Constraint-Programmierung vorzuziehen ist, um die allgemeinsten Programme zu erhalten.

    
m09 17.07.2012, 11:01
quelle
2

Wenn möglich, verwenden Sie getaggte statt einfacher alter (is)/2 ( und Freunde).

clpfd bietet ein logisch reines Prädikat sum/3 , das Ihren Anforderungen entspricht!

    
repeat 05.05.2015 13:27
quelle

Tags und Links