如何删除/阻止对称解决方案

时间:2015-07-29 08:49:41

标签: prolog

我正在定义这样的规则:

person(p1).
person(p2).

near(X,Y) :-
  person(X),
  person(Y),
  checkNear.       % Not important how

我检查XY是否为人,然后检查它们是否靠近(它比这更复杂,但我简化了)。

问题在于我获得了对称解决方案:

?- near(X,Y).
X = p1, Y = p2 ;
X = p2, Y = p1.

在这种情况下,您如何强制每对一个解决方案?

只是要求一个解决方案不是一个选项,因为可能有一个人p3需要考虑。

2 个答案:

答案 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).

希望这会有所帮助。