What is the difference between this two statements:
a) p(1),!
b) p(1):-!
I came across this code:
p(1).
p(2):-!.
p(3).
What if I rewrite this as :
p(1).
p(2),!.
p(3).
What is the difference between this two statements:
a) p(1),!
b) p(1):-!
I came across this code:
p(1).
p(2):-!.
p(3).
What if I rewrite this as :
p(1).
p(2),!.
p(3).
I believe you're looking at a very simplistic example which makes it appear that there is a similarity or equivalence of behavior between p(2) :- !
and p(2), !
. It looks like they're both querying p(2)
, and if successfully matching, moving on to the cut and truncating further backtracking. But that's not really how they both work.
The expression, p(2) :- !.
is a predicate clause which defines a rule that says, p(2)
is true, and don't bother checking for other solutions. When you make a query of the form p(X)
, Prolog will try to find a fact or rule head which matches it. In this case, p(2)
is a match and Prolog follows the rule. As a specific example, if you have:
p(2).
p(2).
And query:
| ?- p(X).
You get:
| ?- p(X).
X = 2 ? ;
X = 2
(1 ms) yes
| ?-
Whereas, if you have these fact
p(2) :- !.
p(2).
Then you get:
| ?- p(X).
X = 2
yes
| ?-
On the other hand, the expression p(2), !.
syntactically cannot occur at the "top level" in Prolog. In other words, this is not legal Prolog:
p(2), !.
p(2).
If you try to do this, you'll get an error something like:
error: user:1: native code procedure (',')/2 cannot be redefined (ignored)
Prolog thinks you're trying to redefine the ,
operator. That's because the expression p(2), !.
looks like:
','(p(2), !). % Create a definition for ','
And it is true that p(2) :- !
is known inside Prolog as the term, ':-'(p(2), !)
(p(2)
being the head of the clause) which it treats specially at the top level. However, p(2), !
syntactically needs to be part of a clause and not at the top level. In this context, the term p(2)
is not the head of a clause that Prolog is attempting to match. Instead, it's a query which is part of another Predicate clause. For example:
% Define 'foo'
foo :- p(2), !.
foo.
If we query:
| ?- foo.
yes
| ?-
You see that it succeeds and, due to the cut, leaves no choice points after succeeding once. On the other hand, if we define:
foo :- p(2).
foo.
Then the query behaves differently:
| ?- foo.
true ? ;
yes
Here, foo
succeeds and, due to lack of a cut and the additional foo
clause/fact, leaves a choice point. We tell Prolog to go for more solutions (;
) and we get one more, resulting in yes
.
I said all that to show that these are very different contexts for two different operators: ,
and :-
.