简体   繁体   中英

How can I get facts from my knowledge base into a list?

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM