削减一个条款的开头和" cut",`!`和`fail`之间的关系

时间:2015-02-24 04:39:09

标签: prolog prolog-cut

将剪辑(!)放在条款的最开头是什么意思?

  p(X,Y) :- !, q(X), r(X,Y).

!fail之间的区别是什么?它们有什么关系?

感谢。
我认为对于fail,谓词只会“失败”大声笑,这与不回溯有什么不同?只是想确定:)

1 个答案:

答案 0 :(得分:4)

通常,当您想要确保某个变量实例的组合没有回溯时,可以使用它。显示一些代码(从the SWI-Prolog implementation借来一点:

read_lines(In, Ls) :-
    read_line_to_codes(In, Codes),
    read_lines_rest(Codes, In, Ls).

read_lines_rest(end_of_file, _, []) :- !.
read_lines_rest(Codes, In, [Codes|Rest]) :-
    read_line_to_codes(In, New_codes),
    read_lines_rest(New_codes, In, Rest).

现在,通过定义这些谓词,您可以将输入流(例如文件)读取到行列表中。我们正在使用library(readutil)中的read_line_to_codes/2。它将使用代表一行的代码列表或输入末尾的原子end_of_file来统一其第二个参数。

read_lines_read/3的第一个子句中,我们在谓词定义的头部使用统一。如果我们想要甚至考虑谓词,我们“要求”第一个参数必须是原子end_of_file。当(在输入结束时)该子句成功时,不考虑定义的第二个子句中的另一个可能的解决方案,并且谓词成功,在第三个参数中关闭列表。

在这里使用:

?- open('shortcut.pl', read, In), read_lines(In, Ls), forall(member(L,Ls), format("~s~n", [L])).
read_lines(In, Ls) :-
    read_line_to_codes(In, Codes),
    read_lines_rest(Codes, In, Ls).

read_lines_rest(end_of_file, _, []) :- !.
read_lines_rest(Codes, In, [Codes|Rest]) :-
    read_line_to_codes(In, New_codes),
    read_lines_rest(New_codes, In, Rest).
% variable instantiations

您应该注意到谓词只成功一次。尝试删除第一个子句中的剪切,看看会发生什么。

对于fail,是的,它使谓词失败(不成功)。此时,如果剩下任何选择点,Prolog将回溯到最近的选择点。