关于对称关系的Prolog重复解

关于对称关系的Prolog重复解,prolog,relation,symmetric,Prolog,Relation,Symmetric,考虑一下这个小程序: married(bill, hillary). spouse(X, Y) :- married(X, Y); married(Y, X). likes(X, Y) :- spouse(X, Y). 现在我想评估一个目标 ?- likes(X, Y). X = bill Y = hillary ?; X = hillary Y = bill yes 有没有一种方法可以防止在回溯时重复这种对称关系,并且仍然保持目标的对称性,如?-likes(hillary,X)。?这里有

考虑一下这个小程序:

married(bill, hillary).
spouse(X, Y) :- married(X, Y); married(Y, X).
likes(X, Y) :- spouse(X, Y).
现在我想评估一个目标

?- likes(X, Y).
X = bill
Y = hillary ?;
X = hillary
Y = bill
yes 

有没有一种方法可以防止在回溯时重复这种对称关系,并且仍然保持目标的对称性,如
?-likes(hillary,X)。

这里有一种方法来定义
配偶/2

married(bill, hillary).
married(tom, mary).
married(sam, linda).

spouse(X, Y) :-
     \+ married(X, Y) -> married(Y, X) ; married(X, Y).
因此,如果没有办法使
已婚(X,Y)
为真,那么它将尝试
已婚(Y,X)
。否则,
已婚(X,Y)

表面上看来,以下稍微简单一点的谓词可能是等价的,但它不会找到所有的解决方案:

spouse(X, Y) :-
     married(X, Y) -> true ; married(Y, X).

| ?- spouse(X, Y).

X = bill
Y = hillary ? ;

(1 ms) yes
| ?-
附录

根据谢尔盖的观察:

| ?- Y = bill, spouse(X, Y).

X = hillary
Y = bill

yes
但是:

此结果是不一致的,因为通过将<代码>配偶/ 2 < /代码>考虑到对称解冗余的唯一解,谓词本质上是说,在任何给定时间,只有一个<代码>配偶(Bill,希拉里)和<代码>配偶(希拉里,Bill)可以是真的。如果第一个参数预定义为

bill
,则意味着第二个参数必须是
hillary
。如果两个参数均未实例化,并且
配偶(X,Y)
指示解决方案
X=bill
Y=hillary
,则后续查询
Y=bill
失败


因此,正如@Sergey在他的评论中所指出的,这种谓词必须谨慎使用,因为它的逻辑意义在某些上下文中是有限的,甚至是自相矛盾的。

没有办法定义谓词,使其仍然保留其关系属性并满足您的愿望,正如@SergeyDymchenko在评论中所说的那样

我不清楚你为什么想要这个。也许你想减少产量?然后简单地问另一个问题:

?- spouse(X,Y), X @=< Y.
?-配偶(X,Y),X@=
使用时需要注意:
Y=bill,likes(X,Y)。
会成功,但
likes(X,Y),Y=bill。
会失败。@SergeyDymchenko“缺陷”可能是定义
配偶(X,Y)不可避免的副作用
仅适用于
X
Y
中的唯一解决方案,包括它们的排列。一旦建立了
X
Y
对,根据定义,它们的交换为假。定义
喜欢
配偶
谓词(正如@false在他的回答中所暗示的那样)确实是一种奇怪的方式。@潜伏者:当你定义关系时,某些事情根本就不可能是。
| ?- spouse(X, Y), Y = bill.

no
?- spouse(X,Y), X @=< Y.