Reputation: 171
What does it mean to put the cut (!
) at the very beginning of a clause?
p(X,Y) :- !, q(X), r(X,Y).
What is the difference between !
and fail
and how are they related?
thanks.
I'm thinking that for fail
, the predicate will just "fail" lol which is different from not backtracking? just want to be sure :)
Upvotes: 2
Views: 594
Reputation:
Usually, you use this when you want to make sure that there is no backtracking on a certain combination of variable instantiations. To show some code (borrowed a bit from 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).
Now, with these predicates defined, you can read an input stream (a file, for example) to a list of lines. We are using read_line_to_codes/2
from library(readutil)
. It will unify its second argument with a list of codes representing a line, or the atom end_of_file
at the end of input.
In the first clause of read_lines_read/3
, we use unification in the head of the predicate definition. We "demand" that the first argument must be the atom end_of_file
if we want the predicate to be even considered. When (at the end of input) this clause succeeds, the other possible solution in the second clause of the definition is not taken in consideration, and the predicate succeeds, closing up the list in the third argument.
Here it is used:
?- 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
You should notice that the predicate succeeds exactly once. Try removing the cut in the first clause to see what happens.
As for the fail
, yes, it makes the predicate fail (not succeed). At this point, if there are any choice points left, Prolog will backtrack to the most recent one.
Upvotes: 4