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 :-.