使用 Prolog 获得独特的结果
Get unique results with Prolog
我有这个 Prolog 代码returns:[[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.
通过此修复,您的查询现在 returns:
?- findall([X, Y], jealous(X, Y), L).
L = [[vincent, marcellus], [marcellus, vincent]].
所以,没有人再嫉妒自己了。但是你仍然得到一个冗余的解决方案。我们可以将 jealous/2
谓词修改为 sort 返回的解决方案中的名称。例如:
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]].
最后的观察。列表是表示 对 的糟糕解决方案。传统的方法是使用 X-Y
或 (X, Y)
.
尽可能使用 dif/2
而不是 (\==)/2
。
dif/2
将帮助您编写逻辑合理的程序。
详情请看prolog-dif!
我有这个 Prolog 代码returns:[[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.
通过此修复,您的查询现在 returns:
?- findall([X, Y], jealous(X, Y), L).
L = [[vincent, marcellus], [marcellus, vincent]].
所以,没有人再嫉妒自己了。但是你仍然得到一个冗余的解决方案。我们可以将 jealous/2
谓词修改为 sort 返回的解决方案中的名称。例如:
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]].
最后的观察。列表是表示 对 的糟糕解决方案。传统的方法是使用 X-Y
或 (X, Y)
.
尽可能使用 dif/2
而不是 (\==)/2
。
dif/2
将帮助您编写逻辑合理的程序。
详情请看prolog-dif!