На этом шаге мы рассмотрим поиск всех решений для цели сразу.
Преимущество рекурсии состоит в том, что, в отличие oт поиска с возвратом, она передает информацию (через параметры) от одного рекурсивного вызова к следующему. Поэтому рекурсивная процедура может хранить память о промежуточных результатах или счетчиках по мере того, как она выполняется.
Но есть одна вещь, которую поиск с возвратом может делать, а рекурсия - нет. Это поиск всех альтернативных решений в целевом утверждении. Может оказаться, что вам нужны все решения для целевого утверждении, и они необходимы все сразу, как часть единой сложной составной структуры данных. Встроенный предикат использует целевые утверждения в качестве одного из своих аргументов и собирает все решения для этого целевого утверждения в единый список. У предиката findall три аргумента:
domains
name,address=string
age=integer
list=age*
predicates
person(name,address,age)
sumlist(list,age,integer)
clauses
sumlist([],0,0).
sumlist([H |T],Sum,N):-
sumlist(T,S1,N1),
Sum=H+S1,
N=1+N1.
person("Sherlock Holmes","22B Baker Street",42).
person("Pete Spiers","Apt. 22, 21st Street", 36).
person("Mary Darrow", "Suite 2, Omega Home", 51).
goal
findall(Age,person(_, _, Age),L),
sumlist (L,Sum,N),
Ave=Sum/N,
write("Average=", Ave),nl.
Результат работы программы можно посмотреть на рис.1

Рис.1. Результат работы программы pro47_1.pro
Предложение findall в этой программе создает список L, в котором собраны все возвраты, полученные из предиката person. Если бы вы захотели собрать список из всех людей, которым 42 года, то вам следовало бы выполнить следующее подцелевое утверждение:
findall(Who,person(Who,_,42),List)
slist=string*
На следующем шаге мы рассмотрим составные списки.