давайте предположим, что вы спрашиваете union ([1,2], [2], R).
в соответствии с первым правилом union ([1 | [2]], [2], R) будет истинным, если member (1, [2]) -> false, тогда пролог проверит, что второе объединение правил ([1 | [2]], [2], [1 | R]) будет истинным, если + member(1, [2]) -> true и union ([2], [2], R)
сейчас, union ([2 | []], [2], R) будет истинным(1-е правило), если member (2, [2]) -> true и union ([], [2], R)
union ([], [2], R) будет истинным (3-е правило), если R = [2]
, поэтому R = [2] и, следовательно, первый вызов union возвращает [1 | [2]] = [1,2]
полезнуюинструмент для выяснения того, «как это делает пролог», - это trace / 0:
2 ?- trace.
true.
[trace] 2 ?- union([1,2],[2],R).
Call: (6) union([1, 2], [2], _G543) ? creep
Call: (7) lists:member(1, [2]) ? creep
Fail: (7) lists:member(1, [2]) ? creep
Redo: (6) union([1, 2], [2], _G543) ? creep
Call: (7) lists:member(1, [2]) ? creep
Fail: (7) lists:member(1, [2]) ? creep
Call: (7) union([2], [2], _G619) ? creep
Call: (8) lists:member(2, [2]) ? creep
Exit: (8) lists:member(2, [2]) ? creep
Call: (8) union([], [2], _G619) ? creep
Exit: (8) union([], [2], [2]) ? creep
Exit: (7) union([2], [2], [2]) ? creep
Exit: (6) union([1, 2], [2], [1, 2]) ? creep
R = [1, 2] .
в целом: List2 не изменяется, но предикат также не возвращает List2;возвращает список, созданный List2, и уникальные элементы List1