-2

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).
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Alex_ban
  • 221
  • 2
  • 11
  • The first one a) is part of a query, or RHS of a rule. The second one b) defines a rule. – nhahtdh Mar 13 '15 at 07:09
  • 3
    Where did you come across this code? Either way, the first is correct Prolog, while the second is not. –  Mar 13 '15 at 07:52

1 Answers1

0

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

lurker
  • 56,987
  • 9
  • 69
  • 103
  • See this question, which has the same code in it: http://stackoverflow.com/questions/25962835/prolog-differences-between-red-cut-and-green-cut –  Mar 13 '15 at 11:34
  • @Boris thanks for the cross-reference. Perhaps that's where the OP saw it as well. I decided to answer this particular question because I see that the OP has a fundamental misunderstanding of the semantics of a couple of different Prolog operators, although it it should be clear from a basic Prolog tutorial. – lurker Mar 13 '15 at 11:40
  • 1
    Sure, as they say, linked for "posterity" –  Mar 13 '15 at 12:55