1

我有这些条款:

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() 和一个()。我认为剪辑忽略了所有先前的选择点并且不会进行任何回溯。

有人可以解释确切的行为,为什么我错了?

4

2 回答 2

1

因为我没有立即理解你对 cut 所做的解释,所以我查看了你的代码。我的阅读大致如下:

  • c(A,B,C)在以下情况下为真:
    • a(A)d(B,C),
    • b(A)d(B,C)
  • d(B,C)当 时为真a(B),但仅适用于a(B)您遇到的第一次,并且不要寻找d(B,C)您可能在此下面找到的任何其他定义。

我的阅读是这样的,因为我对 cut 的解释是:承诺在这个谓词正文中遇到 cut 之前所做的选择,并在包含 cut 的子句下方丢弃这个谓词的子句。

我希望这至少对您有所帮助。

于 2013-05-15T13:36:25.243 回答
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.
于 2013-05-15T18:52:25.333 回答