我想在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规则的原因,任何人都可以建议对此进行任何改进吗?
非常感谢。
答案 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
将回溯以枚举任何地面或变量A
与B
之间的所有可能路径。如果您的equal/2
事实所暗示的图表很大,包含许多断开连接的组件,并且/或者您正在寻找所有组合,那么这可能会非常昂贵。