The correct way:
findall(person(Person),person(Person),ListOfPeople).
or
bagof(person(Person),person(Person),ListOfPeople).
Why doesn't your approach work? Consider
findall(Person,is_person(Person),ListOfPeople).
Prolog tries to fulfill is_person(Person)
.
There is a fact is_person(person(_)).
So, for Person = person(_)
, we are good! So person(_)
will be in the list.
And that's all, there are no other ways to derive is_person(Person)
.
To collect all the Person
, we really need to ask for the Person
which fulfills person(Person)
.
Thus:
findall(person(Person),person(Person),ListOfPeople).
Prolog will find three Person
which fulfill person(Person)
. As the result should not be a list of Person
but of person(Person)
we slap a person/1
around Person
in the 1st parameter, the template.
Alternatively (but a bit pointlessly), you could:
is_person(person(X)) :- person(X).
?- findall(X,is_person(X),ListOfPeople).
Here, Prolog collects all the X
for which is_person(person(X))
, which are all the X
which appear in a (fact) person(X)
. Thus X
is for example fred
. We slap a person/1
around fred
in the head of is_person/1
. Done.