Prolog Fakultät Rekursion
Ich habe Probleme beim Verständnis der folgenden Faktoren-Programm
fact1(0,Result) :-
Result is 1.
fact1(N,Result) :-
N > 0,
N1 is N-1,
fact1(N1,Result1),
Result is Result1*N.
Wenn fact1
heißt geschachtelt innerhalb des zweiten fact1
, heißt das nicht, dass das die Letzte Zeile, die Result is Result1*N.
, wird nie aufgerufen? Oder in Prolog bedeutet die Letzte Zeile, die ausgeführt werden, bevor der rekursive Aufruf?
InformationsquelleAutor CyberShot | 2012-03-06
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, der rekursive Aufruf passiert zuerst! Es muss, oder anderes, das Letzte Klausel ist sinnlos. Der Algorithmus bricht ab zu:
Wie Sie sehen können, müssen Sie berechnen Sie das Ergebnis der Rekursion, bevor der Multiplikation, um wieder einen korrekten Wert!
Ihre prolog-Implementierung hat wahrscheinlich einen Weg, um die Ablaufverfolgung aktivieren, die ermöglichen würden Sie das ganze sehen-Algorithmus ausgeführt. Das könnte Ihnen helfen.
Ich hoffe, du meinst
factorial(0) => 1
🙂Was
factorial(-1)
? Mit der obigen definition der Abfrage?- fact1(-1,_).
zu Recht versagt;factorial
, wie es ist, nicht.InformationsquelleAutor Carl Norum
BTW wenn Sie erst einmal die grundlegende Rekursion verstanden haben, versuchen zu erreichen, tail recursion, Wann immer möglich, hier wäre es:
Tail recursion, im Gegensatz zu der Rekursion die Sie zuvor verwendet haben, können interpreter/compiler zu leeren Kontext, wenn Sie mit dem nächsten Schritt der Rekursion. Also nehmen wir an, Sie berechnen
factorial(1000)
Ihre version beibehalten wird 1000 Kontexten, während mir nur pflegen 1. Das bedeutet, dass Ihre version wird schließlich die Berechnung nicht das gewünschte Ergebnis, sondern nur crash auf einerOut of call stack memory
Fehler.Können Sie Lesen Sie mehr über ihn auf wikipedia.
factorial(0,0)
sollte fail---es funktioniert nicht.InformationsquelleAutor m09
Einen Recht einfachen Weg, es zu tun, ist dies:
Könnten Sie bitte Bearbeiten Ihre Antwort eine Erklärung zu geben, warum dieser code beantwortet die Frage? Code-nur die Antworten sind entmutigt, weil Sie nicht lehren, die Lösung.
InformationsquelleAutor Mohamed Hassan
Generell @m09 Antwort ist im Grunde Recht über die Wichtigkeit des tail-Rekursion.
Für große
N
Berechnung des Produkt anders gewinnt! Denke "binären Baum", nicht "lineare Liste"...Lassen Sie uns versuchen, beide Möglichkeiten und vergleichen Sie die Laufzeiten. Zuerst @m09 s
factorial/2
:Nächsten, wir tun es, Baum-Stil—mit meta-Prädikat
reduzieren/3
zusammen mit lambda-Ausdrücke:Letzten, lassen Sie uns definieren, und verwenden Sie dedizierte Hilfs-Prädikat
x_y_product/3
:Was zu gewinnen? Lassen Sie uns Fragen Sie die Stoppuhr!
InformationsquelleAutor repeat
InformationsquelleAutor Salma
Normalfall erklärt wird. Die Bedingungen, die N muss positiv sein, und multiplizieren mit dem vorherigen Begriff.
Ausführen:
InformationsquelleAutor Shashank Motepalli
Einen einfachen Weg :
InformationsquelleAutor rashedcs
Ich würde so etwas machen:
- Und eine tail-version wäre wie:
So für Sie zu rufen:
nicht-tail-rekursive Methode: Tatsache, (3, Ergebnis).
tail-rekursive Methode: tail_fact(3, 1, Ergebnis).
Dies könnte helfen 😉
?- fact(0,1), false.
nicht kündigen. Es sein sollte. Gleiche für?- tail_fact(0,1,0), false.
Ihr Recht!
fact(0,0).
fact(N, R):- fact_aux(N, R).
fact_aux(0, 1).
fact_aux(N, R):- N > 0, NewN is N - 1, fact_aux(NewN, Rec), R is N * Rec.
Etwas besser sind. Aber
?- fact(0,0).
ausfallen sollte. Gelingt es.btw. das sieht verdächtig ähnlich zu dieser vorherigen Antwort: stackoverflow.com/a/28799827/4609915
InformationsquelleAutor João R.
nicht-tailer Rekursion :
tailer Rekursion:
Das Prolog-system verwenden Sie?
Mit SWI-Prolog,
?- fact(10,F).
Schleifen und nicht eine Antwort geben.ja, ich bin mit visual-prolog. @wiederholen
es wurde ein problem in die Stopp-Bedingung in visual prolog in der Ausgabe richtig, aber hört nicht nach 0, so macht stack overflow
InformationsquelleAutor Peter Osama