我有这些条款:
a(1).
a(2).
b(a).
c(A,B,C) :- a(A),d(B,C).
c(A,B,C) :- b(A),d(B,C).
d(B,C) :- a(B),!,a(C).
d(B,_) :- b(B).
当我运行查询c(X,Y,Z)时,答案是:
X = 1, Y = 1, Z = 1 ;
X = 1, Y = 1, Z = 2 ;
X = 2, Y = 1, Z = 1 ;
X = 2, Y = 1, Z = 2 ;
X = a, Y = 1, Z = 1 ;
X = a, Y = 1, Z = 2.
所以基本上,切割算子(在这里d(B,C): - a(B),!,a(C)。)忽略最近的选择点,即它不进一步搜索d ()和a()。我认为削减忽略了所有以前的选择点,不会做任何回溯。
有人可以解释确切的行为,为什么我错了?
答案 0 :(得分:1)
因为我没有立即理解你对剪辑做了什么的解释,所以我查看了你的代码。我的阅读大致如下:
c(A,B,C)
在以下时间为真:
a(A)
和d(B,C)
,b(A)
和d(B,C)
d(B,C)
在a(B)
时为真,但仅适用于您遇到的第一个a(B)
,并且不会查找您在此下方可能找到的任何其他d(B,C)
定义之一。我的阅读是这样的,因为我对切割的解释是:在这个谓词体内遇到切割之前做出选择,并在包含切割的子句下面丢弃该谓词的子句。
我希望这至少对远程有帮助。
答案 1 :(得分:0)
我做了一些阅读,剪辑工作如下:
1. Kills off the parent choice-point
2. Commits to all the choices made going through the rule
因此:
1. d(B,_) :- b(B). is not explored
2. B in d(B,C) :- a(B),!,a(C). is irrevocably bound to 1.