我认为我对统一存在根本性的误解。以下是我的两个条款:
test(func(X), X, 1) :- X == X.
test(func(X), Y, 0) :- X \== Y.
所以 - 如果我查询测试(func(X),Y,D),我希望它只能用第二个子句证明,而D将是0.这是因为(我想\我正在尝试)在第一个子句中确保X必须等于X.因此我的查询不应该统一,因为X与Y不同。我认为==测试两个操作数是相同的变量。而X和Y显然不是。
但是输出:
| ?- test(func(X), Y, D).
D = 1
Y = X ? ;
D = 0
所以它说如果Y = X,它与第一个子句统一。但是,Y不等于X.我在这里误解了什么?
答案 0 :(得分:2)
您的第一个答案D = 1, Y = X
符合您的第一个定义。我认为你期望当你查询?- test(func(X), Y, D).
时,第一个定义应该失败,因为X
和Y
是不同的变量,但第一个定义只有在两个变量时才能成功变量是相同的。
但是,在您的子句的开头,您有两次出现的相同变量:test(func(X), X, 1) :- X == X.
(正如@CapelliC指出的那样,X == X
在这里是多余的。)当您查询?- func(func(X), Y, D).
时,Prolog试图将这个条款与你的第一条规则的主管统一起来。它将func(X)
与func(X)
和Y
与X
和1
与1
统一。一旦此模式匹配统一成功,它就会测试规则的主体以查看是否满足条件。由于Y
已与X
统一,因此两个变量将匹配严格的相等条件 - 在模式匹配期间,您将Y
与{{1}相同的变量统一起来}}。
请注意以下两个问题:
X
第二种类似于令您困惑的查询所发生的情况。如果你根据@ CapelliC的建议重写你的第一条规则,
?- X == Y.
false.
?- Y = X, X == Y.
X = Y.
然后它将按预期运行,因为在这种情况下,第二个参数中的自由变量将与test(func(X), Y, 1) :- X == Y.
项中的变量统一,而则这两个变量不会满足严格的相等性(但如果这两个变量与基础术语统一,它们就会通过)。
答案 1 :(得分:1)
X == X
它是一种重言式(总是如此),显然你的第一个条款可以等同于
test(func(X), X, 1).
我认为你应该把它写成第二个
test(func(X), Y, 1) :- X == Y.