我在dlv中有以下事实,知道(X,Y)意味着X知道Y.
knows(adam, dan).
knows(adam,alice).
knows(adam,peter).
knows(adam,eva).
knows(dan, adam).
knows(dan,alice).
knows(dan,peter).
knows(eva, alice).
knows(eva,peter).
knows(alice, peter).
knows(peter, alice).
我定义了以下谓词,
person(X) :- knows(X, _).
这将使所有人都了解事实。我试图找到一个流行的谓词(X)。这将给予受欢迎的人。它被定义为如果所有人都知道X则X很受欢迎。以上事实清单的答案是爱丽丝和彼得。我把它定义如下,
popular(X):-person(X),knows(_,X).
X很受欢迎,如果它是一个人,每个人都知道X.但是当我运行它时,我得到所有人的结果。我在哪里弄错了?
答案 0 :(得分:1)
根据原始帖子上的评论字符串,您已将流行定义为"某人已知的人#34;。因为 - 在你的知识库中 - 每个人都被某人所熟知,每个人都很受欢迎。
假设"一个受欢迎的人是每个人都知道的人,但受欢迎的人只知道其他受欢迎的人&#34 ;;如果我们想知道X是否受欢迎:
我将使用forall专注于第二种方式。花些时间自己运行一些测试来了解它是如何工作的。以下是您可能会做的一个示例:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
).
如果你运行这个,你会得到Alice和Peter作为答案。
但如果我们包括其他条件:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
),
forall(
knows(X,Z),
popular(Z)
).
最后一行说X需要知道那些流行的人......而且现在,如果你运行这个,你很可能会从本地堆栈中获得#'' 39; - 它是一个无底的递归定义。
你总是需要检查一个人是否受欢迎,知道是否有人知道某人是否受欢迎...尝试思考问题及其原因。有没有办法检查某人是否受欢迎而无需检查其他人是否受欢迎?如果有人知道'他们自己?如果两个人互相认识怎么办?这可能需要稍微复杂一些的方法来解决。
顺便说一句,请注意您对人的定义会让多个人回归 - 每个人都是他们认识的每个人的人。除了让每张支票花费更长时间(因为还有更多的人要检查),如果您决定采用第一种方法(计数方法),这可能会成为一个问题。
明确定义明确哪些人是有意义的,然后定义“知道'作为人与人之间的关系?
person('Alice').
person('Bob').
knows('Alice','Bob').
答案 1 :(得分:0)
正如lurker's comment中所述(我稍作修改和强调),你得到所有人的原因是
您已将人员定义为: X 是 X 知道某人的人。并且你已经定义了流行的: X 很受欢迎,如果 X 是一个人而且某人知道 X 。
但是你要定义: X 很受欢迎,如果 X 是一个人而每个人知道 X 。
以下是clingo 4的ASP解决方案.DLV在语法上可能略有不同。
% Project
person(P) :- knows(P, _).
% Separate helper predicate knows2/2.
% Not needed if polluting knows/2 with knows(X, X) is OK.
knows2(O, P) :- knows(O, P).
knows2(P, P) :- person(P).
% Everybody knows a popular person.
% When there is a person O that doesn't know P, #false is active.
% I.e. all rule instantiations where some O doesn't know P are discarded.
popular(P) :- person(P), #false : person(O), not knows2(O, P).
% Popular person knows only other popular persons.
% Redundant at this point, since the above rule already results
% in correct answer without further integrity constraints.
:- person(P), person(O), popular(P), not popular(O), knows(P, O).
#show popular/1.