使用Prolog获得唯一的结果

使用Prolog获得唯一的结果,prolog,prolog-dif,Prolog,Prolog Dif,我有一个返回的序言代码:[[vincent,vincent],[vincent,marcellus],[marcellus,vincent],[marcellus,marcellus],[Pumpking,Pumpking],[honey_bunny,honey_bunny] :- initialization main. loves(vincent, mia). loves(marcellus, mia). loves(pumpkin, honey_bunny). loves(honey_b

我有一个返回的序言代码:
[[vincent,vincent],[vincent,marcellus],[marcellus,vincent],[marcellus,marcellus],[Pumpking,Pumpking],[honey_bunny,honey_bunny]

:- initialization main.

loves(vincent, mia).
loves(marcellus, mia).
loves(pumpkin, honey_bunny).
loves(honey_bunny, pumpkin).

jealous(X, Y) :-
    loves(X, Z),
    loves(Y, Z).

main :- 
    findall([X, Y], jealous(X, Y), L),
    write(L),
    halt.
当X!=Y 我尝试了以下代码以获得与以前相同的结果

jealous(X, Y) :-
    X \== Y,
    loves(X, Z),
    loves(Y, Z).
通过
\=
,我得到了
[]

因此,如何只获取
[vincent,marcellus]

您尝试的解决方案中的目标顺序是错误的。当使用两个不同的变量调用时,
(\==)/2
标准谓词总是成功。解决方案是仅当谓词的参数实例化时才调用谓词:

jealous(X, Y) :-
    loves(X, Z),
    loves(Y, Z),
    X \== Y.
使用此修复程序,您的查询现在将返回:

?- findall([X, Y], jealous(X, Y), L).
L = [[vincent, marcellus], [marcellus, vincent]].
所以,没有人再嫉妒自己了。但你仍然得到了一个多余的解决方案。我们可以修改
嫉妒/2
谓词来对返回的解决方案中的名称进行排序。例如:

jealous(X, Y) :-
    loves(X0, Z),
    loves(Y0, Z),
    X0 \== Y0,
    (   X0 @< Y0 ->
        X = X0, Y = Y0
    ;   X = Y0, Y = X0
    ).

最后一项观察。对于表示一对,列表是一个糟糕的解决方案。传统的方法是使用
X-Y
(X,Y)
只要可能,使用
dif/2
而不是
(\==)/2

dif/2
将帮助您编写逻辑合理的程序

有关详细信息,请参阅

?- setof([X, Y], jealous(X, Y), L).
L = [[marcellus, vincent]].