Prolog 关于交换和传递等价实现的建议‏;在序言中

Prolog 关于交换和传递等价实现的建议‏;在序言中,prolog,transitive-closure,Prolog,Transitive Closure,我想在Prolog中模拟等价性,它具有交换性和传递性的属性,下面是我所做的:equal/2将作为事实提供 symmetricEqual(A,B):- equal(A,B). symmetricEqual(A,B):- equal(B,A). transitiveEqualPath(A,B,_) :- symmetricEqual(A,B). transitiveEqualPath(B,C,IntermediateNodes) :- symmetricEqual(A,B),

我想在Prolog中模拟等价性,它具有交换性和传递性的属性,下面是我所做的:equal/2将作为事实提供

symmetricEqual(A,B):- equal(A,B). 
symmetricEqual(A,B):- equal(B,A).

transitiveEqualPath(A,B,_) :- symmetricEqual(A,B).

transitiveEqualPath(B,C,IntermediateNodes) :- 
    symmetricEqual(A,B), 
    \+ member(C,IntermediateNodes), 
    transitiveEqualPath(A,C,[B|IntermediateNodes]), B\==C.

transitiveEqual(A,B) :- transitiveEqualPath(A,B,[]).
但我在尝试计算transitiveEqual/2时遇到了上述解决方案的性能问题(大约需要20分钟),我从equal/2中快速计算了大约2K个对称equal/2事实,所以这一定是transitiveEqual/2规则的原因,有人能提出改进建议吗


非常感谢。

由以下人员提供:


请注意,
path/3,4
将回溯到枚举任何地面或变量
A
B
之间的所有可能路径。如果您的
equal/2
事实所隐含的图形很大,包含许多断开连接的组件,并且/或者您正在寻找所有的组合,那么这可能会非常昂贵。

感谢您的建议,但是,在我在SWI Prolog中使用您的代码后,在查询了?-TransiveEqual(A,B)之后,它没有产生任何结果。我总是得到A=B作为输出。有什么想法吗?啊,我错误地假设您使用谓词来测试
A
B
的绑定值,而不是使用它们来枚举回溯时的绑定。我将更新我的答案以处理这两种情况。
symmetricEquals(X,Y) :- equal(X,Y). 
symmetricEquals(X,Y) :- equal(Y,X). 

transitiveEqual(A, B) :-
    % look for an equality path from A to B
    path(A, B, _Path). 

path(A, B, Path) :-
    % build a path from A to B
    path(A, B, [A], Path).

path(A, B, _Acc, [B]) :-
    symmetricEquals(A, B).

path(A, B, Visited, [C|Path]) :-
    symmetricEquals(A, C),
    C \== B,
    \+ memberchk(C, Visited), 
    path(C, B, [C|Visited], Path).