繁体   English   中英

通过Prolog获得独特的结果

[英]Get unique results with Prolog

我有返回的此Prolog代码: [[vincent,vincent],[vincent,marcellus],[marcellus,vincent],[marcellus,marcellus],[pumpkin,pumpkin],[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]].

因此,没有人会嫉妒自己。 但是您仍然可以获得冗余解决方案。 我们可以修改jealous/2谓词以返回的解决方案中的名称进行排序 例如:

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

现在,通过使用setof/3而不是findall/3 ,我们得到:

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

最后的观察。 列表对于表示一是不好的解决方案。 传统方法是使用XY(X, Y)

尽可能使用dif/2代替(\\==)/2

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

有关详细信息,请参见

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM