Prolog 关于交换和传递等价实现的建议;在序言中
我想在Prolog中模拟等价性,它具有交换性和传递性的属性,下面是我所做的:equal/2将作为事实提供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),
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).