变体谓词的这两个实现之间是否存在逻辑差异?
variant1(X,Y) :-
subsumes_term(X,Y),
subsumes_term(Y,X).
variant2(X_,Y_) :-
copy_term(X_,X),
copy_term(Y_,Y),
numbervars(X, 0, N),
numbervars(Y, 0, N),
X == Y.
答案 0 :(得分:5)
variant1/2
和variant2/2
都没有实现作为语法变体的测试。但出于不同的原因。
目标variant1(f(X,Y),f(Y,X))
应该成功但失败。对于双方都出现相同变量的某些情况,variant1/2
的行为与预期不符。要解决此问题,请使用:
variant1a(X, Y) :-
copy_term(Y, YC),
subsumes_term(X, YC),
subsumes_term(YC, X).
目标variant2(f('$VAR'(0),_),f(_,'$VAR'(0)))
应该失败但成功。显然,variant2/2
假设其参数中没有'$VAR'/1
。
ISO / IEC 13211-1:1995定义如下变体:
7.1.6.1术语
的变体如果有一个双射
s
,则两个术语是变体 前者的变量对后者的变量如此 后一个术语来自替换中的每个变量X
前Xs
。注意
1例如,
f(A, B, A)
是f(X, Y, X)
的变体,
g(A, B)
是g(_, _)
的变体,P+Q
是
的变体P+Q
。2定义
bagof/3
时需要变量的概念 (8.10.2)和setof/3
(8.10.3)。
请注意,上面的Xs
不是变量名称,而是(X
)s
。所以s
在这里是一个双射,这是一个特殊的替代案例。
这里,所有示例都引用bagof/3
和setof/3
中的典型用法,其中变量总是不相交,但更常见的情况是存在公共变量。
在逻辑编程中,通常的定义是:
V
是T
的变体,如果存在σ和θ,那么
V
σ和T
相同T
θ和V
相同
换句话说,如果两者相互匹配,它们就是变体。然而,匹配的概念对于Prolog程序员来说是非常陌生的,也就是说,正式逻辑中使用的匹配概念。这是一个让许多Prolog程序员恐慌的案例:
考虑f(X)
和f(g(X))
。 f(g(X))
是否与f(X)
匹配?现在,许多Prolog程序员都会耸耸肩,并对发生检查的事情嗤之以鼻。但这与发生检查完全无关。他们匹配,是的,因为
f(X)
{X
↦g(X)
}与f(g(X))
相同。
请注意,此替换会替换所有X
,并将其替换为g(X)
。怎么会发生这种情况?事实上,Prolog的典型术语表示不能作为记忆中的图形发生。在Prolog中,节点X
在某种程度上是内存中的真实地址,您根本无法进行此类操作。但在逻辑上,事情完全是文本层面的。这就像
sed 's/\<X\>/g(X)/g'
除了一个人也可以同时替换变量 。想想{ X ↦ Y, Y ↦ X}
。必须立即更换它们,否则f(X,Y)
会缩小为f(X,X)
或f(Y,Y)
。
所以这个定义虽然形式上很完美,但依赖于在Prolog系统中没有直接对应的概念。
当考虑单方面统一不匹配时,会出现类似的问题,但是统一和匹配之间的常见情况。
根据ISO / IEC 13211-1:1995 Cor.2:2012(draft):
8.2.4 subsumes_term / 2
这个内置谓词提供了句法单边统一的测试。
8.2.4.1说明
subsumes_term(General, Specific)
如果有,则为真 替换θ这样 该a)
General
θ 和Specific
θ是相同的,和 b)Specific
θ和Specific
是完全相同的。程序上,
subsumes_term(General, Specific)
简单 相应成功或失败。没有副作用或 统一。
对于variant1/2
的定义,subsumes_term(f(X,Y),f(Y,X))
已失败。