变体谓词的这两种实现之间是否存在任何逻辑差异?
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.
变体谓词的这两种实现之间是否存在任何逻辑差异?
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.
既不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
。
bagof/3
2 定义(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))
.
请注意,此替换替换 allX
并将它们替换为g(X)
. 这怎么可能发生?事实上,Prolog 的典型术语表示为内存中的图形是不可能发生的。在 Prolog 中,节点X
是以某种方式在内存中的真实地址,您根本无法执行这样的操作。但在逻辑上,事情完全是在文本层面上。就像
sed 's/\<X\>/g(X)/g'
除了一个也可以同时替换变量。想想{ X ↦ Y, Y ↦ X}
。它们必须立即更换,否则f(X,Y)
会缩小为f(X,X)
or f(Y,Y)
。
因此,这个定义虽然形式上是完美的,但依赖于在 Prolog 系统中没有直接对应关系的概念。
当考虑不匹配的单边统一时,也会发生类似的问题,而是统一和匹配之间的常见情况。
根据 ISO/IEC 13211-1:1995 Cor.2:2012(草案):
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))
已经失败。