请考虑以下代码:
a(X) :- b(X),!,c(X),fail.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
查询a(X).
生成
1 ?- a(X).
false.
2 ?-
但是使用此代码
a(X) :- b(X),!,c(X).
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
查询a(X).
会导致:
1 ?- a(X).
X = 1.
所以我的问题是,为什么fail/1
会产生错误?它应该强制回溯,对吧?我认为会检查b(1)
和c(1).
,为什么会失败呢?
答案 0 :(得分:2)
失败,因为fail
必须失败。
剪切删除了替代品,然后禁止通过X
绑定“返回”的值。尝试
a(X) :- b(X),c(X),fail.
...
你会得到
?- a(X).
X = 4.
答案 1 :(得分:1)
正如@CapelliC所说,a(X) :- b(X),!,c(X),fail.
的规则必须失败,因为他有fail
个组件。
在第一个代码示例中 - 检查从1
开始,组件b(1)
满意,之后它到达!
,因此不再执行可选检查。
有关cut
的更多说明,您可以检查将!
放在a(X) :- b(X),!,c(X),fail.
的末尾
a(X) :- b(X),c(X),fail,!.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
现在 -
?- a(X).
X = 4.
由于fail
位于!
之前,因此!
无法访问,因此cut
不会影响另一个可选的帐户。
修改:
fail
仅与他在那里写的规则相关,因此a(X) :- b(X),c(X),fail,!.
将永远导致失败,而不是a(X) :- d(X).
规则。
答案 2 :(得分:1)
示例:
a(X):- b(X),!,fail. %is the same as \+ a(X):- b(X).
“!”的合并和“失败”会给您 a(X)的负数。
它称为否定否定。
答案 3 :(得分:0)
a(X) :- b(X),c(X),fail.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
a(X).
X = 4
a(X) :- b(X),!,c(X).
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
a(X).
X = 1
a(X) :- b(X),!,c(X),fail.
a(X) :- d(X).
b(1).
b(4).
c(1).
c(3).
d(4).
a(X).
false