Ausführung-operation für jedes element in der Liste in swi-prolog und andere
Wie mache ich eine operation für jedes element einer Liste, in Ordnung?
Basierend auf diesen zwei Ressourcen:
- http://www.swi-prolog.org/pldoc/doc/swi/library/lists.pl
- http://www.swi-prolog.org/pldoc/doc_for?object=foreach/2
Stell ich immer verlassen können:
foreach(member(X, [1,2]), write(X)).
Ist, dass deterministische und kann ich wickeln Sie das Mitglied/2 Prädikat, wie ich das bitte in meinen eigenen Prädikate und noch immer Durchlaufen um?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, aber Sie haben sorgen, ob Ihr Prädikat zu scheitern. Wenn er kann, die übrigen Elemente in der Liste werden nicht bearbeitet, denn es erzeugt eine Verbindung, anstatt einen failure-driven-loop.
Wäre ich mehr daran interessiert, zu verwenden
maplist/2
da ich denke, es ist mehr verbreitet alsforeach/2
aber ich hatte auch nicht gesehen, diese option vor. 🙂Bearbeiten: Lassen Sie uns diskutieren, was ich meine, über failure-driven-loops.
Gibt es zwei primitive Iterationsverfahren in Prolog: Rekursion und failure-driven-loops. Sagen, ich will drucken Sie jedes Element in einer Liste. Die rekursive Methode geht wie folgt Aussehen:
So eine Liste gegeben wie
[1,2,3]
ist dies noch erweitern und zwar so:Dies ist, wie
member/2
ist in der Regel umgesetzt:Damit Sie sehen können, die rekursive Methode ist ziemlich einfach und allgemein.
Andere einfache, aber etwas verpönt-mit-Methode ist die Simulation ein Fehler, sich den backtracking-Mechanismus. Dies nennt man einen failure-driven-loop und sieht wie folgt aus:
Beim ausführen dieser version von
print_all/1
, was passiert, ist ein wenig komplexer als einfache Erweiterung.Mündlich, die
fail
Kräfte Prolog wieder bis auf den letzten Wahl Punkt es aus und versuchen Sie die nächste Lösung. Gut,write/1
undnl/0
nicht produzieren, Wahl Punkte, denn Sie haben nur eine Lösung, abermember/2
hat haben mehrere Lösungen—eine für jedes Element in der Liste. Also der Prolog nimmt jedes Element aus der Liste und druckt es. Schließlich, wennmember/2
läuft aus Lösungen, Prolog Rücken bis zu der vorherigen Auswahl Punkt, das ist der zweite Körper desprint_all/1
Prädikat, das immer gelingt. So sieht die Ausgabe die gleiche ist. Ich denke, dass die Menschen heute bevorzugen im Allgemeinen nicht zu verwenden, failure-driven-loops, aber ich verstehe nicht die Argumente gut genug, um zu parrot Sie sinnvoll.Einer Sache, die Ihnen helfen können, um zu sehen, was Los ist, verwenden Sie die
trace
Prädikat und Schritt durch die expansion der beiden Versionen, und sehen Sie, ob Sie den Sinn der Unterschiede. Meine Schreibweise oben ist völlig aus für diese Antwort vielleicht nicht so deutlich.Rückblick über das, was ich ursprünglich schrieb, und Ihrem eigentlichen Frage:
foreach
wird deterministischmember
wird immer Durchlaufen, um, weil die Listen sind so definiert, dass Sie müssen Zugriff auf jedes Element wiederumDarüber hinaus in diesen Tagen-zumindest auf dem S. O. Sie erhalten eine Menge Leute sagen, Sie zu verwenden
maplist
und seinesgleichen, so ist es wohl nicht nur zur Arbeit zu gehen, aber auch eine gute Idee.maplist/2
Tat etwas parallel hinter den kulissen.