我正在定义这样的规则:
person(p1).
person(p2).
near(X,Y) :-
person(X),
person(Y),
checkNear. % Not important how
我检查X
和Y
是否为人,然后检查它们是否靠近(它比这更复杂,但我简化了)。
问题在于我获得了对称解决方案:
?- near(X,Y).
X = p1, Y = p2 ;
X = p2, Y = p1.
在这种情况下,您如何强制每对一个解决方案?
只是要求一个解决方案不是一个选项,因为可能有一个人p3
需要考虑。
答案 0 :(得分:1)
我认为更简单的方法是使用标准的术语顺序@<
near(X, Y) :-
person(X),
person(Y),
X @< Y, % arbitrary, but breaks symmetry
checkNear.
答案 1 :(得分:-1)
如果仅检查X和Y是否为人,则无需删除镜像示例。
但是当你想要生成可能的解决方案时,你可以使用@CapelliC提供的解决方案,或者你可以生成一个符合X和Y条件的人的元组列表:
findall((X,Y), (person(X),person(Y), X\==Y),R).
然后你需要像这样删除镜像元组:
removedup([(X,Y)|[]],[(X,Y)]).
removedup([(X,Y)|L],R) :-
removedup(L,R1),
(member((Y,X),R1) ->
R = R1;
append([(X,Y)],R1,R)
).
您可以进一步使用此列表。例如:
checkNearAll([(List,Of)|Tuples]):-
checkNear(List,Of).
希望这会有所帮助。