简单prolog程序过早返回false
我已经有一段时间没有用Prolog编程了。今天,我试着做一个简单的程序。它列出了谁属于同一个家庭的一些事实。如果两个人属于同一个家庭,他们就不能互相赠送礼物。我想得到所有的人(或至少一个人)的人被允许给一个礼物简单prolog程序过早返回false,prolog,Prolog,我已经有一段时间没有用Prolog编程了。今天,我试着做一个简单的程序。它列出了谁属于同一个家庭的一些事实。如果两个人属于同一个家庭,他们就不能互相赠送礼物。我想得到所有的人(或至少一个人)的人被允许给一个礼物 family(john, jack). family(matt, ann). family(ann, jack). family(jordan, michael). family(michael, liz). sameFamily(X, Y) :- family(X, Y). sa
family(john, jack).
family(matt, ann).
family(ann, jack).
family(jordan, michael).
family(michael, liz).
sameFamily(X, Y) :-
family(X, Y).
sameFamily(X, X) :-
false.
sameFamilySym(X, Y) :-
sameFamily(X, Y).
sameFamilySym(X, Y) :-
sameFamily(Y, X).
sameFamilyTrans(X, Z) :-
sameFamilySym(X, Y),
sameFamilySym(Y, Z).
gift(X, Y) :-
not(sameFamilyTrans(X, Y)).
一些查询ifsameFamilyTrans/2
返回false
,而实际上它们应该返回true
sameFamilyTrans/2
显然是错误的。我想我需要保留一个中间及物性的列表。大概是这样的:
sameFamilyTrans(X, Z, [Y|Ys]) :-
sameFamilySym(X, Y, []),
sameFamilyTrans(Y, Z, Ys).
但我不知道怎么称呼这个
另外,如果有什么不同的话,我正在使用SWI Prolog。否定是以非常基本的方式在Prolog中实现的。只有当一个被否定的查询被充分实例化时,您才能从本质上得到一个有用的答案。为此,请定义一个关系
person/1
,该关系描述您考虑的所有人员。然后你可以写:
gift(X,Y) :-
person(X),
person(Y),
\+ sameFamily(X,Y).
sameFamily/2的定义还有另一个问题
是的,你的思路是对的。诀窍是使用空累加器调用传递闭包,并在每个步骤中检查是否找到循环(即,我们以前是否见过该家族成员)。正如“false”所指出的,在进入not之前,需要先实例化这些人
总之,这是可行的:
family(john, jack).
family(matt, ann).
family(ann, jack).
family(jordan, michael).
family(michael, liz).
sameFamily(X, Y) :-
family(X, Y).
sameFamilySym(X, Y) :-
sameFamily(X, Y).
sameFamilySym(X, Y) :-
sameFamily(Y, X).
sameFamilyTrans(X, Y, Acc) :-
sameFamilySym(X, Y),
not(member(Y,Acc)).
sameFamilyTrans(X, Z, Acc) :-
sameFamilySym(X, Y),
not(member(Y,Acc)),
sameFamilyTrans(Y, Z, [X|Acc]).
person(X) :- family(X, _).
person(X) :- family(_, X).
gift(X, Y) :-
person(X),
person(Y),
X \= Y,
not(sameFamilyTrans(X, Y, [])).
一点背景:传递闭包实际上不是一阶可定义的(cf.)。所以这可能会有点棘手。谢谢你的回答。我已经看过了
sameFamily/2
的定义,虽然它显然是错误的,但我还没有发现我的错误。你能给我指出正确的方向吗?我已经为它写了一个新的定义并更新了我的问题。@RaptorDotCpp:总是比较e解决方案集:setof(A-B,samf(A,B),ABs)
找到了所有解决方案吗?找到了所有正确的解决方案,但也找到了其他解决方案。这些解决方案不应该在那里。@RaptorDotCpp:sameFamilyTrans(X,Y)
失败。我知道这一点,但我不明白为什么。我是否需要以某种方式查询中间传递性?我将如何做?类似于我问题中的新代码?