我怎样才能将知识库中的事实放入列表中?

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

假设我有这些事实:

person(fred).
person(jim).
person(mary).

is_person(person(_)).

我想要一个像这样的列表:

[person(fred), person(jim), person(mary)]

但是我对 findall/3 的查询没有给出预期的结果:

?- findall(Person,is_person(Person),ListOfPeople).
ListOfPeople = [person(_5034)].

bagof/3类似:

?- bagof(Person,is_person(Person),ListOfPeople).
ListOfPeople = [person(_5940)].

我不明白为什么 findall/3bagof/3 会这样。

正确的方法:

findall(person(Person),person(Person),ListOfPeople).

bagof(person(Person),person(Person),ListOfPeople).

为什么您的方法不起作用?考虑

findall(Person,is_person(Person),ListOfPeople).

Prolog 尝试实现 is_person(Person)

有一个事实is_person(person(_)).

所以,对于Person = person(_),我们很好!所以 person(_) 将在列表中。

仅此而已,没有其他方法可以推导is_person(Person)

要收集所有 Person,我们确实需要请求满足 person(Person).

Person

因此:

findall(person(Person),person(Person),ListOfPeople).

Prolog 将找到满足 person(Person) 的三个 Person。由于结果不应该是 Person 的列表,而是 person(Person) 的列表,我们在模板的第一个参数 Person 周围添加了 person/1

或者(但有点毫无意义),你可以:

is_person(person(X)) :- person(X).

?- findall(X,is_person(X),ListOfPeople).

这里,Prolog收集了is_person(person(X))所对应的所有X,即出现在(事实)person(X)中的所有X。因此 X 例如 fred。我们在 is_person/1 的头部 fred 周围打了一个 person/1。完成。