OP 实现了两个累加器式谓词来计算汉明距离 (hamm/4
和hamm2/4
),但不确定哪个更有意义。
让我们阅读使 OP 感到困惑的查询:“是否有一个 X 使得距离(a,X)为 1?”。以下是 Prolog 给出的“答案”:
?- hamm(a,X,0,1).
false. % wrong: should succeed conditionally
?- hamm2(a,X,0,1). % wrong: should succeed, but not unconditionally
true.
从逻辑的角度来看,这两种实现在上述测试中都表现不佳。让我们做一些坚定性的测试:
?- hamm(a,X,0,1),X=a. % right
false.
?- hamm(a,X,0,1),X=b. % wrong: should succeed as distance(a,b) is 1
false.
?- hamm2(a,X,0,1),X=a. % wrong: should fail as distance(a,a) is 0
X = a.
?- hamm2(a,X,0,1),X=b. % right
X = b.
请注意,在以前的查询中,错误成功hamm/4
时正确地失败hamm2/4
,反之亦然。所以两者都是半对半错,没有一个是坚定的。
可以做什么?
基于if_/3
并由(=)/3
@false 在此答案中提出,我为谓词实现了以下纯代码hamm3/4
:
:- use_module(library(clpfd)).
hamm3(A,B,V0,V) :-
if_(A = B, V0 = V, V #= V0+1).
现在让我们使用以下方法重复上述查询hamm3/4
:
?- hamm3(a,X,0,1).
dif(X,a).
?- hamm3(a,X,0,1),X=a.
false.
?- hamm3(a,X,0,1),X=b.
X = b.
有用! 最后,让我们通过最通用的查询来查看整个解决方案集 hamm3/4
:
?- hamm3(A,B,N0,N).
A = B, N0 = N ;
dif(A,B), N0+1 #= N.