das N ist N1 + 1, da diese Variablen nie einheitlich sind.
Ich denke, Sie meinen, dass sie nie instanziiert werden, d. H. Sie erhalten nie einen Wert. Die Vereinheitlichung von zwei Variablen kann sie instanziieren, aber es ist nicht notwendig. Zum Beispiel könnten Sie dies in einem Prolog REPL laufen:
?- N = N1.
N = N1.
während N
und N1
keinen Wert (noch) nicht haben, sie vereinigt sind; Wenn N1 später instanziiert wird, wird N ebenfalls mit dem gleichen Wert instanziiert. Ein anderes, weniger trivial, Beispiel:
?- [H|T] = L, L = [1|M], writeln(H).
1
H = 1,
T = M,
L = [1|M].
Es ist jedoch wahr, dass N
nie mit N1+1
vereinigt! is
wertet N1+1
und so aus, dass der Wert mit N
vereinheitlicht wird. Dies geschieht, nachdem der innere size([b,c,d],N1)
ausgewertet wurde, so dass die Variable N1
instanziiert wurde.
Im Wesentlichen wird die Ausführung so aussehen:
size([a,b,c,d],N).
size([b,c,d],N1)
size([c,d],N1)
size([d],N1)
size([],0)
N is 0+1.
N is 1+1.
N is 2+1.
N is 3+1.
die ein bisschen ist ineffizient, da wir alle Funktionsaufrufe im Speicher halten müssen; in Tail-Rekursion und Akkumulatoren schauen, um das zu beheben.
Beachten Sie auch, dass N1
nur instanziiert werden muss, weil is
den Ausdruck auswerten wird. Man könnte so etwas schreiben:
size([],0).
size([_|T], 1+ N1):-size(T,N1).
und wenn Sie es nennen:
?- size([1,2],N).
N = 0+1+1.
Spaß, ist es nicht? Vielleicht möchten Sie das letzte N, z. nennen Sie es als size([1,2],N), Result is N
. Ein Problem ist jedoch, dass wir eine Kette von 0+1+1+1+1+......
im Speicher halten, die sehr schnell sehr groß werden kann. Es ist also am besten, diesen Trick für Dinge zu verwenden, die nicht wachsen werden, z. Ausdrucksvorlagen
'N' ** ist ** definitiv vereinheitlicht durch die Zeit, die das 'ist' ausgewertet wird, weil', 'von links nach rechts ausgeführt wird, und der rekursive Aufruf bindet das 'N' - letztlich durch Vereinheitlichung (eine lokale Version of) es mit "0". –
Vielen Dank für die schnelle Antwort. Ich bin mir nicht sicher, ob ich verstehe, was du meinst. Wo im Trace-Prozess N vereinheitlichen mit 0? – JmanxC
Ich korrigiere mich selbst: 'N1 'ist zuerst vereinheitlicht, entweder mit' 0 'oder mit der untergeordneten' N 'von der Klausel' size ([H | T], N) ', und dann wird' N1' verwendet berechne die oberste Ebene "N". Der Trick besteht darin, zu verstehen, dass es in einem rekursiven Algorithmus * mehrere verschiedene Versionen von 'N' gibt, jede mit einem anderen Wert *. In Ihrem Beispiel wären diese verschiedenen 'N's an 0, 1, 2, 3 und 4 gebunden. –