Say I have these facts:
person(fred).
person(jim).
person(mary).
is_person(person(_)).
I would like to get a list like:
[person(fred), person(jim), person(mary)]
but my query with findall/3 does not give the expected result:
?- findall(Person,is_person(Person),ListOfPeople).
ListOfPeople = [person(_5034)].
Similarly with bagof/3:
?- bagof(Person,is_person(Person),ListOfPeople).
ListOfPeople = [person(_5940)].
I do not understand why findall/3 and bagof/3 behave like this.
The correct way:
or
Why doesn't your approach work? Consider
Prolog tries to fulfill
is_person(Person).There is a fact
is_person(person(_)).So, for
Person = person(_), we are good! Soperson(_)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 thePersonwhich fulfillsperson(Person).Thus:
Prolog will find three
Personwhich fulfillperson(Person). As the result should not be a list ofPersonbut ofperson(Person)we slap aperson/1aroundPersonin the 1st parameter, the template.Alternatively (but a bit pointlessly), you could:
Here, Prolog collects all the
Xfor whichis_person(person(X)), which are all theXwhich appear in a (fact)person(X). ThusXis for examplefred. We slap aperson/1aroundfredin the head ofis_person/1. Done.