Josephine
Josephine

Reputation: 457

Prolog: Related predicates with permuted arguments

Is there a way to declare the following in Prolog without being caught in an endless recursion?

left([X,Y], Z) :- left([Z,X], Y); left([Y,Z], X).

The semantics is that the list represents a vector given by two points and the second argument is a third point lying left of the vector.

A related question is, how one can declare the relation of "left" and "right" given by:

left([X,Y], Z) :- right([Y,X], Z).

without getting an endless recursion.

Upvotes: 0

Views: 102

Answers (1)

user1812457
user1812457

Reputation:

Unfortunately, you cannot do this directly in Prolog. You can express commutative relationships by introducing a predicate that enumerates the permutations for the fact, so for example:

left_of(A, B, C) :- left(A, B, C).
left_of(A, B, C) :- left(C, A, B).
left_of(A, B, C) :- left(B, C, A).

left(a, b, c).

Now the query should be

?- left_of(A, B, C).

Similarly, you should define right_of in terms of left.

Several things worth noting:

  1. Keep the three arguments separate, as shown. It is good practice not to introduce unnecessary structures.

  2. Prefer explicit clauses, instead of ;. It makes your code far more obvious. The ; is really easy to miss when reading the code; if you use it, put it at the beginning of the line, not in the middle somewhere or at the end

  3. Prolog implementations that support tabling do not have this problem.

Upvotes: 2

Related Questions