我有5个人在一个房间里。我会写一些规则来决定人们是快乐还是悲伤。然而,在我开始之前,我已经知道了--在5个人中,恰好有3个是快乐的,2个是悲伤的(没有一个可以是两者兼而有之)。因此,应该可以基于此进行推断:如果-无论如何-我知道这三个快乐的人是谁,那么我就可以推断出两个悲伤的人,反之亦然。
到目前为止,我得到的信息如下:
person(bob).
person(tim).
person(steve).
person(roy).
person(jack).
sad(bob).
sad(tim).
happy(X) :-
person(X),
\+ sad(X),
findall(Y, sad(Y), YS),
length(YS, 2).当被问到happy(X)时,Prolog会给我罗伊、史蒂夫和杰克,因为它已经知道这两个悲伤的人是谁了。问题:由于与happy/1的相互递归,我无法以相同的方式定义sad/1规则。我希望能够添加规则,以便上面示例中的结果保持不变,但以下初始化会将Bob和Tim列为sad:
person(bob).
person(tim).
person(steve).
person(roy).
person(jack).
happy(steve).
happy(roy).
happy(jack).有没有更好的方式让我思考这个问题?重要的是,我将能够在以后为sad/1和happy/1编写更多的规则,添加额外的逻辑,而不是基于5被分成3个happy和2个sad的知识来推断应该是可能的。
发布于 2015-12-02 05:34:07
整理逻辑是一个一致性问题,并避免给定谓词或事实的冲突含义。
您对sad/1的定义目前是这样一个事实,即对查询sad(X)的每次回溯都会产生一个结果。但是您对happy/1的定义会生成一个列表。剩下的问题就是如何定义sad/1来生成一个列表,这将与您当前将sad/1定义为查询相冲突,如果参数是一个悲伤的人,则该查询为真。
一种更一致的方法是将happy/1定义为sad/1的行为方式:
happy(X) :-
person(X),
\+ sad(X).然后,您可以定义列表版本:
happy_all(A) :-
findall(X, happy(X), A).
sad_all(A) :-
findall(X, sad(X), A).现在,上面假设你有明确的事实,person/1定义了所有有效的人的宇宙,sad/1定义了谁是可悲的人。它还假设,如果一个人不悲伤,那么他们一定是快乐的。
你可以反其道而行之,用happy/1事实来明确定义快乐的人,然后用不快乐的人来定义sad/1,假设一个人如果不悲伤就一定是快乐的:
sad(X) :-
person(X),
\+ sad(X).并且happy_all/1和sad_all/1谓词仍然适用。
如果你想将你的事实与happy/1和sad/1混在一起,这可能会产生一个一致性问题:(1)一个人不被定义为快乐或悲伤的情况……那它们是什么?以及(2)如果一个人被定义为既快乐又悲伤呢?
从语义上讲,你可能想要明确地定义sad/1和happy/1,如果你也允许某人既不快乐也不悲伤的话。您可以这样做:
person(bob).
person(tim).
person(steve).
person(roy).
person(jack).
sad(bob).
sad(tim).
happy(steve).
happy(roy).
happy_all(A) :-
findall(X, happy(X), A).
sad_all(A) :-
findall(X, sad(X), A).但不为happy/1或sad/1定义谓词,因为它们已经是事实。这让事情变得简单。我们只是不知道jack是快乐还是悲伤。
但是,如果我们想说,如果一个人不快乐或悲伤,那么他们必须是快乐的,并将这条规则重新加入其中。为了避免你提到的循环,我们不会把规则名称和事实名称混在一起。在这种情况下:
person(bob).
person(tim).
person(steve).
person(roy).
person(jack).
sad(bob).
sad(tim).
happy(steve).
happy(roy).
% A person is happy if they are, in fact, happy
happy_person(X) :-
happy(X),
% A person is happy if they are neither happy or sad
happy_person(X) :-
person(X),
\+ happy(X),
\+ sad(X).
% A person is sad if they are, in fact, sad
sad_person(X) :-
sad(X).
% Who are all the happy people?
happy_all(A) :-
findall(X, happy_person(X), A).
% Who are all the sad people?
sad_all(A) :-
findall(X, sad_person(X), A).https://stackoverflow.com/questions/34028651
复制相似问题