2

假设我有这些事实:

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/3并且bagof/3表现得像这样。

4

1 回答 1

2

正确的方法:

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/1Person第一个参数模板中添加一个。

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

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

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

在这里,Prolog 收集了所有Xfor which is_person(person(X)),它们是所有X出现在 (fact) 中的person(X)。例如. X_ 我们在头上fred扇了一巴掌。完毕。person/1fredis_person/1

于 2020-12-02T16:28:17.113 回答