Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog Array Pipe Meaning

Tags:

syntax

prolog

Can anybody explain the following code? I know it returns true if X is left of Y but I do not understand the stuff with the pipe, underscore and R. Does it mean all other elements of the array except X and Y?

    left(X,Y,[X,Y|_]).
    left(X,Y,[_|R]) :- left(X,Y,R).
like image 537
TheWizard Avatar asked Mar 26 '26 06:03

TheWizard


2 Answers

If you are ever unsure about what a term "actually" denotes, you can use write_canonical/1 to obtain its canonical representation.

For example:

| ?-  write_canonical([X,Y|_]).
'.'(_16,'.'(_17,_18))

and also:

| ?-  write_canonical([a,b|c]).
'.'(a,'.'(b,c))

and in particular:

| ?-  write_canonical([a|b]).  
'.'(a,b)

This shows you that [a|b] is the term '.'(a,b), i.e., a term with functor . and two arguments.

To reinforce this point:

| ?- [a|b] == '.'(a,b).

yes
like image 170
mat Avatar answered Mar 28 '26 21:03

mat


@mat answered the original question posted quite precisely and completely. However, it seems you have a bigger question, asked in the comment, about "What does the predicate definition mean?"

Your predicate, left(X, Y, L), defines a relation between two values, X and Y, and a list, L. This predicate is true (a query succeeds) if X is immediately left of Y in the list L.

There are two ways this can be true. One is that the first two elements in the list are X and Y. Thus, your first clause reads:

left(X, Y, [X,Y|_]).

This says that X is immediately left of Y in the list [X,Y|_]. Note that we do not care what the tail of the list is, as it's irrelevant in this case, so we use _. You could use R here (or any other variable name) and write it as left(X, Y, [X,Y|R]). and it would function properly. However, you would get a singleton variable warning because you used R only once without any other references to it. The warning appears since, in some cases, this might mean you have done this by mistake. Also note that [X,Y|_] is a list of at least two elements, so you can't just leave out _ and write [X,Y] which is a list of exactly two elements.

The above clause is not the only case for X to be immediately left of Y in the list. What if they are not the first two elements in the list? You can include another rule which says that X is immediately left of Y in a list if X is immediately left of Y in the tail of the list. This, along with the base case above, will cover all the possibilities and gives a complete recursive definition of left/3:

left(X, Y, [_|R]) :- left(X, Y, R).

Here, the list is [_|R] and the tail of the list is R.

like image 30
lurker Avatar answered Mar 28 '26 22:03

lurker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!