关于Prolog中交换和传递等价实现的建议

时间:2013-01-11 00:49:07

标签: prolog transitive-closure

我想在Prolog中模拟具有交换性和传递性的等价性,这就是我所做的:等于/ 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分钟),我有大约2K symmetricalEqual / 2事实从相等/ 2计算得非常快,所以它必须是transitiveEqual / 2规则的原因,任何人都可以建议对此进行任何改进吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

感谢来自here的方法:

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

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