截断子句的开头以及"cut"、`!` 和`fail` 之间的关系
Cutting the beginning of a clause and the relation between "cut", `!`, and `fail`
在子句的最开头加上删减 (!
) 是什么意思?
p(X,Y) :- !, q(X), r(X,Y).
!
和 fail
有什么区别,它们有什么关系?
谢谢。
我在想对于 fail
,谓词将只是 "fail" 哈哈,这与不回溯不同吗?只是想确定:)
通常,当您要确保对某个变量实例化组合没有回溯时,您会使用它。显示一些代码(从 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
的第一个子句中,我们在谓词定义的头部使用了合一。我们 "demand" 如果我们想要甚至考虑谓词,第一个参数必须是原子 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 将回溯到最近的一个。
在子句的最开头加上删减 (!
) 是什么意思?
p(X,Y) :- !, q(X), r(X,Y).
!
和 fail
有什么区别,它们有什么关系?
谢谢。
我在想对于 fail
,谓词将只是 "fail" 哈哈,这与不回溯不同吗?只是想确定:)
通常,当您要确保对某个变量实例化组合没有回溯时,您会使用它。显示一些代码(从 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
的第一个子句中,我们在谓词定义的头部使用了合一。我们 "demand" 如果我们想要甚至考虑谓词,第一个参数必须是原子 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 将回溯到最近的一个。