просто нужно простое объяснение .. пытаюсь собрать все вместе здесь.
lastitem([X|Xs],Out) :- lastitem(Xs,Out).
здесь трассировка: lastitem ([a, b, c], X).
[trace] 8 ?- lastitem([a,b,c],X).
Call: (6) lastitem([a, b, c], _G536) ? creep
Call: (7) lastitem([b, c], _G536) ? creep
Call: (8) lastitem([c], _G536) ? creep
Exit: (8) lastitem([c], c) ? creep
Exit: (7) lastitem([b, c], c) ? creep
шаг 1 говорит, что если lastitem (что-то, somethign) существует, то listem ([X | Xs], Out] .. поэтому вырезается A. шаг 2-3 делает то же самое ... но с W / B и C. теперь возникает вопрос: что происходит с пустым списком на шаге 4? Почему пустойсписок не выполняет lastitem (Xs, Out)? или я решаю неправильно?
Также может помочь словесное объяснение обратного отслеживания ... потому что в приложении я действительно получаю искаженное. У приложения нет целей, чтобы решить между шагами... но обратное не означает ... и мой ответ выше ... если вы проследите его, вы увидите, что переменная X всегда одинакова в обратном порядке или в этом примере. В приложении она изменяется.
append([],L,L).
append([H|T],L2,[H|L3]) :- append(T,L2,L3).
append([a, b, c], [1, 2, 3], _G518) % <-- variable L3 continues to change
append([b, c], [1, 2, 3], _G587) % <-- same
append([c], [1, 2, 3], _G590) % < -- same
append([], [1, 2, 3], _G593) % <-- same
append([], [1, 2, 3], [1, 2, 3])
append([c], [1, 2, 3], [c, 1, 2, 3])
append([b, c], [1, 2, 3], [b, c, 1, 2, 3])
append([a, b, c], [1, 2, 3], [a, b, c, 1, 2, 3])
X = [a, b, c, 1, 2, 3]